summaryrefslogtreecommitdiff
path: root/chromium/net/cert
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cert')
-rw-r--r--chromium/net/cert/cert_net_fetcher.h79
-rw-r--r--chromium/net/cert/cert_verify_proc.cc111
-rw-r--r--chromium/net/cert/cert_verify_proc.h22
-rw-r--r--chromium/net/cert/cert_verify_proc_android.cc26
-rw-r--r--chromium/net/cert/cert_verify_proc_blacklist.inc10
-rw-r--r--chromium/net/cert/cert_verify_proc_ios.cc25
-rw-r--r--chromium/net/cert/cert_verify_proc_mac.cc119
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.cc24
-rw-r--r--chromium/net/cert/cert_verify_proc_openssl.cc21
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc282
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.cc1681
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.h29
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist_unittest.cc237
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist_unittest1.gperf9
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc21
-rw-r--r--chromium/net/cert/cert_verify_result.cc3
-rw-r--r--chromium/net/cert/cert_verify_result.h25
-rw-r--r--chromium/net/cert/crl_set_storage.cc5
-rw-r--r--chromium/net/cert/ct_known_logs.cc1
-rw-r--r--chromium/net/cert/ct_known_logs_static-inc.h10
-rw-r--r--chromium/net/cert/ct_log_response_parser.cc7
-rw-r--r--chromium/net/cert/ct_log_response_parser_unittest.cc1
-rw-r--r--chromium/net/cert/ct_log_verifier_util.h2
-rw-r--r--chromium/net/cert/ct_objects_extractor.cc2
-rw-r--r--chromium/net/cert/ct_objects_extractor.h3
-rw-r--r--chromium/net/cert/ct_objects_extractor_unittest.cc3
-rw-r--r--chromium/net/cert/ct_policy_enforcer.h6
-rw-r--r--chromium/net/cert/ct_policy_enforcer_unittest.cc84
-rw-r--r--chromium/net/cert/ct_policy_status.h6
-rw-r--r--chromium/net/cert/ct_serialization.cc8
-rw-r--r--chromium/net/cert/ct_serialization.h2
-rw-r--r--chromium/net/cert/ct_serialization_unittest.cc5
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc20
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.h8
-rw-r--r--chromium/net/cert/ct_verifier.h18
-rw-r--r--chromium/net/cert/do_nothing_ct_verifier.cc25
-rw-r--r--chromium/net/cert/do_nothing_ct_verifier.h67
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.cc60
-rw-r--r--chromium/net/cert/internal/cert_errors.h1
-rw-r--r--chromium/net/cert/internal/cert_issuer_source.h37
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_aia.cc110
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_aia.h11
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc351
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_nss.cc62
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_nss.h40
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_nss_unittest.cc62
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_static.cc1
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_static.h1
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_static_unittest.cc133
-rw-r--r--chromium/net/cert/internal/cert_issuer_source_sync_unittest.h210
-rw-r--r--chromium/net/cert/internal/completion_status.h17
-rw-r--r--chromium/net/cert/internal/name_constraints.cc5
-rw-r--r--chromium/net/cert/internal/name_constraints_unittest.cc41
-rw-r--r--chromium/net/cert/internal/nist_pkits_unittest.h6
-rw-r--r--chromium/net/cert/internal/parse_certificate_unittest.cc284
-rw-r--r--chromium/net/cert/internal/parse_ocsp.cc1
-rw-r--r--chromium/net/cert/internal/parsed_certificate_unittest.cc303
-rw-r--r--chromium/net/cert/internal/path_builder.cc340
-rw-r--r--chromium/net/cert/internal/path_builder.h37
-rw-r--r--chromium/net/cert/internal/path_builder_pkits_unittest.cc3
-rw-r--r--chromium/net/cert/internal/path_builder_unittest.cc376
-rw-r--r--chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc4
-rw-r--r--chromium/net/cert/internal/trust_store.cc3
-rw-r--r--chromium/net/cert/internal/trust_store.h28
-rw-r--r--chromium/net/cert/internal/trust_store_collection.cc23
-rw-r--r--chromium/net/cert/internal/trust_store_collection.h38
-rw-r--r--chromium/net/cert/internal/trust_store_collection_unittest.cc170
-rw-r--r--chromium/net/cert/internal/trust_store_in_memory.cc6
-rw-r--r--chromium/net/cert/internal/trust_store_in_memory.h11
-rw-r--r--chromium/net/cert/internal/trust_store_nss.cc80
-rw-r--r--chromium/net/cert/internal/trust_store_nss.h21
-rw-r--r--chromium/net/cert/internal/trust_store_nss_unittest.cc120
-rw-r--r--chromium/net/cert/internal/trust_store_test_helpers.cc95
-rw-r--r--chromium/net/cert/internal/trust_store_test_helpers.h68
-rw-r--r--chromium/net/cert/internal/verify_certificate_chain.h1
-rw-r--r--chromium/net/cert/internal/verify_signed_data.cc1
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.cc62
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.h15
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc49
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc5
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h1
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier_unittest.cc1
-rw-r--r--chromium/net/cert/nss_cert_database.cc18
-rw-r--r--chromium/net/cert/nss_cert_database.h14
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos.h6
-rw-r--r--chromium/net/cert/nss_cert_database_unittest.cc46
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos.cc1
-rw-r--r--chromium/net/cert/ocsp_revocation_status.h6
-rw-r--r--chromium/net/cert/ocsp_verify_result.h11
-rw-r--r--chromium/net/cert/signed_tree_head.h2
-rw-r--r--chromium/net/cert/test_keychain_search_list_mac.h6
-rw-r--r--chromium/net/cert/test_root_certs.h2
-rw-r--r--chromium/net/cert/x509_cert_types.cc6
-rw-r--r--chromium/net/cert/x509_cert_types.h2
-rw-r--r--chromium/net/cert/x509_cert_types_unittest.cc37
-rw-r--r--chromium/net/cert/x509_certificate.cc3
-rw-r--r--chromium/net/cert/x509_certificate.h42
-rw-r--r--chromium/net/cert/x509_certificate_ios.cc23
-rw-r--r--chromium/net/cert/x509_certificate_known_roots_win.h2
-rw-r--r--chromium/net/cert/x509_certificate_mac.cc37
-rw-r--r--chromium/net/cert/x509_certificate_net_log_param.h6
-rw-r--r--chromium/net/cert/x509_certificate_nss.cc46
-rw-r--r--chromium/net/cert/x509_certificate_openssl.cc18
-rw-r--r--chromium/net/cert/x509_certificate_win.cc27
-rw-r--r--chromium/net/cert/x509_util.cc2
-rw-r--r--chromium/net/cert/x509_util.h1
106 files changed, 2236 insertions, 4429 deletions
diff --git a/chromium/net/cert/cert_net_fetcher.h b/chromium/net/cert/cert_net_fetcher.h
index f8344702bea..2a45fe3b6f7 100644
--- a/chromium/net/cert/cert_net_fetcher.h
+++ b/chromium/net/cert/cert_net_fetcher.h
@@ -19,59 +19,42 @@ class GURL;
namespace net {
-class URLRequestContext;
-
-// CertNetFetcher is an asynchronous interface for fetching AIA URLs and CRL
-// URLs.
-//
-// -------------------------
-// Cancellation of requests
-// -------------------------
-//
-// * Network requests started by the CertNetFetcher can be cancelled by
-// deleting the Request object. Cancellation means the request's callback
-// will no longer be invoked.
-//
-// * If the CertNetFetcher is deleted then any outstanding
-// requests are automatically cancelled.
-//
-// * Cancelling a request within the execution of a callback is allowed.
-//
-// * Deleting the CertNetFetcher from within the execution of a callback is
-// allowed.
-//
-// -------------------------
-// Threading
-// -------------------------
+// CertNetFetcher is a synchronous interface for fetching AIA URLs and CRL
+// URLs. It is shared between a caller thread (which starts and waits for
+// fetches), and a network thread (which does the actual fetches). It can be
+// shutdown from the network thread to cancel outstanding requests.
//
-// The CertNetFetcher is expected to be operated from a single thread, which has
-// an IO message loop. The URLRequestContext will be accessed from this same
-// thread, and callbacks will be posted to this message loop.
-//
-// For more details see the design document:
-// https://docs.google.com/a/chromium.org/document/d/1CdS9YOnPdAyVZBJqHY7ZJ6tUlU71OCvX8kHnaVhf144/edit
-class NET_EXPORT CertNetFetcher {
+// A Request object is returned when starting a fetch. The consumer can
+// use this as a handle for aborting the request (by freeing it), or reading
+// the result of the request (WaitForResult)
+class NET_EXPORT CertNetFetcher
+ : public base::RefCountedThreadSafe<CertNetFetcher> {
public:
class Request {
public:
virtual ~Request() {}
- };
- // Callback invoked on request completion. If the Error is OK, then the
- // vector contains the response bytes.
- using FetchCallback =
- base::Callback<void(Error, const std::vector<uint8_t>&)>;
+ // WaitForResult() can be called at most once.
+ //
+ // It will block and wait for the (network) request to complete, and
+ // then write the result into the provided out-parameters.
+ virtual void WaitForResult(Error* error, std::vector<uint8_t>* bytes) = 0;
+ };
// This value can be used in place of timeout or max size limits.
enum { DEFAULT = -1 };
CertNetFetcher() {}
- // Deletion implicitly cancels any outstanding requests.
- virtual ~CertNetFetcher() {}
+ // Shuts down the CertNetFetcher and cancels outstanding network requests. It
+ // is not guaranteed that any outstanding or subsequent
+ // Request::WaitForResult() calls will be completed. Shutdown() must be called
+ // from the network thread. It can be called more than once, but must be
+ // called before the CertNetFetcher is destroyed.
+ virtual void Shutdown() = 0;
- // The Fetch*() methods start an asynchronous request which can be cancelled
- // by deleting the returned Request. Here is the meaning of the common
+ // The Fetch*() methods start a request which can be cancelled by
+ // deleting the returned Request. Here is the meaning of the common
// parameters:
//
// * url -- The http:// URL to fetch.
@@ -81,30 +64,30 @@ class NET_EXPORT CertNetFetcher {
// * max_response_bytes -- The maximum size of the response body. If this
// size is exceeded then the request will fail. To use a default timeout
// pass DEFAULT.
- // * callback -- The callback that will be invoked on completion of the job.
virtual WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCaIssuers(
const GURL& url,
int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) = 0;
+ int max_response_bytes) = 0;
virtual WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCrl(
const GURL& url,
int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) = 0;
+ int max_response_bytes) = 0;
virtual WARN_UNUSED_RESULT std::unique_ptr<Request> FetchOcsp(
const GURL& url,
int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) = 0;
+ int max_response_bytes) = 0;
+
+ protected:
+ virtual ~CertNetFetcher() {}
private:
+ friend class base::RefCountedThreadSafe<CertNetFetcher>;
DISALLOW_COPY_AND_ASSIGN(CertNetFetcher);
};
} // namespace net
-#endif // NET_CERT_NET_CERT_NET_FETCHER_H_
+#endif // NET_CERT_CERT_NET_FETCHER_H_
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index 413abb4b2fb..d9462561012 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -369,6 +369,69 @@ bool AreSHA1IntermediatesAllowed() {
#endif
};
+// Sets the "has_*" boolean members in |verify_result| that correspond with
+// the the presence of |hash| somewhere in the certificate chain (excluding the
+// trust anchor).
+void MapHashAlgorithmToBool(X509Certificate::SignatureHashAlgorithm hash,
+ CertVerifyResult* verify_result) {
+ switch (hash) {
+ case X509Certificate::kSignatureHashAlgorithmMd2:
+ verify_result->has_md2 = true;
+ break;
+ case X509Certificate::kSignatureHashAlgorithmMd4:
+ verify_result->has_md4 = true;
+ break;
+ case X509Certificate::kSignatureHashAlgorithmMd5:
+ verify_result->has_md5 = true;
+ break;
+ case X509Certificate::kSignatureHashAlgorithmSha1:
+ verify_result->has_sha1 = true;
+ break;
+ case X509Certificate::kSignatureHashAlgorithmOther:
+ break;
+ }
+}
+
+// Sets to true the |verify_result->has_*| boolean members for the hash
+// algorithms present in the certificate chain.
+//
+// This considers the hash algorithms in all certificates except trusted
+// certificates.
+//
+// In the case of a successful verification the trust anchor is the final
+// certificate in the chain (either the final intermediate, or the leaf
+// certificate).
+//
+// Whereas if verification was uncessful, the chain may be partial, and the
+// final certificate may not be a trust anchor. This heuristic is used
+// in both successful and failed verifications, despite this ambiguity (failure
+// to tag one of the signature algorithms should only affect the final error).
+void ComputeSignatureHashAlgorithms(CertVerifyResult* verify_result) {
+ const X509Certificate::OSCertHandles& intermediates =
+ verify_result->verified_cert->GetIntermediateCertificates();
+
+ // If there are no intermediates, then the leaf is trusted or verification
+ // failed.
+ if (intermediates.empty())
+ return;
+
+ DCHECK(!verify_result->has_sha1);
+
+ // Fill in hash algorithms for the leaf certificate.
+ MapHashAlgorithmToBool(X509Certificate::GetSignatureHashAlgorithm(
+ verify_result->verified_cert->os_cert_handle()),
+ verify_result);
+ verify_result->has_sha1_leaf = verify_result->has_sha1;
+
+ // Fill in hash algorithms for the intermediate cerificates, excluding the
+ // final one (which is the trust anchor).
+ for (size_t i = 0; i + 1 < intermediates.size(); ++i) {
+ MapHashAlgorithmToBool(
+ X509Certificate::GetSignatureHashAlgorithm(intermediates[i]),
+ verify_result);
+ }
+}
+
} // namespace
// static
@@ -420,6 +483,8 @@ int CertVerifyProc::Verify(X509Certificate* cert,
int rv = VerifyInternal(cert, hostname, ocsp_response, flags, crl_set,
additional_trust_anchors, verify_result);
+ ComputeSignatureHashAlgorithms(verify_result);
+
UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallback",
verify_result->common_name_fallback_used);
if (!verify_result->is_issued_by_known_root) {
@@ -448,7 +513,7 @@ int CertVerifyProc::Verify(X509Certificate* cert,
}
if (IsNonWhitelistedCertificate(*verify_result->verified_cert,
- verify_result->public_key_hashes)) {
+ verify_result->public_key_hashes, hostname)) {
verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
rv = MapCertStatusToNetError(verify_result->cert_status);
}
@@ -476,30 +541,28 @@ int CertVerifyProc::Verify(X509Certificate* cert,
verify_result->cert_status |= CERT_STATUS_SHA1_SIGNATURE_PRESENT;
// Flag certificates using weak signature algorithms.
- // The CA/Browser Forum Baseline Requirements (beginning with v1.2.1)
- // prohibits SHA-1 certificates from being issued beginning on
- // 1 January 2016. Ideally, all of SHA-1 in new certificates would be
- // disabled on this date, but enterprises need more time to transition.
- // As the risk is greatest for publicly trusted certificates, prevent
- // those certificates from being trusted from that date forward.
- //
- // TODO(mattm): apply the SHA-1 deprecation check to all certs unless
- // CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS flag is present.
+
+ // Legacy SHA-1 behaviour:
+ // - Reject all publicly trusted SHA-1 leaf certs issued after
+ // 2016-01-01.
+ bool legacy_sha1_issue = verify_result->has_sha1_leaf &&
+ verify_result->is_issued_by_known_root &&
+ IsPastSHA1DeprecationDate(*cert);
+
+ // Current SHA-1 behaviour:
+ // - Reject all SHA-1
+ // - ... unless it's not publicly trusted and SHA-1 is allowed
+ // - ... or SHA-1 is in the intermediate and SHA-1 intermediates are
+ // allowed for that platform. See https://crbug.com/588789
+ bool current_sha1_issue =
+ (verify_result->is_issued_by_known_root ||
+ !(flags & CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS)) &&
+ (verify_result->has_sha1_leaf ||
+ (verify_result->has_sha1 && !AreSHA1IntermediatesAllowed()));
+
if (verify_result->has_md5 ||
- // Current SHA-1 behaviour:
- // - Reject all publicly trusted SHA-1
- // - ... unless it's in the intermediate and SHA-1 intermediates are
- // allowed for that platform. See https://crbug.com/588789
- (!sha1_legacy_mode_enabled &&
- (verify_result->is_issued_by_known_root &&
- (verify_result->has_sha1_leaf ||
- (verify_result->has_sha1 && !AreSHA1IntermediatesAllowed())))) ||
- // Legacy SHA-1 behaviour:
- // - Reject all publicly trusted SHA-1 leaf certs issued after
- // 2016-01-01.
- (sha1_legacy_mode_enabled && (verify_result->has_sha1_leaf &&
- verify_result->is_issued_by_known_root &&
- IsPastSHA1DeprecationDate(*cert)))) {
+ (sha1_legacy_mode_enabled && legacy_sha1_issue) ||
+ (!sha1_legacy_mode_enabled && current_sha1_issue)) {
verify_result->cert_status |= CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
// Avoid replacing a more serious error, such as an OS/library failure,
// by ensuring that if verification failed, it failed with a certificate
diff --git a/chromium/net/cert/cert_verify_proc.h b/chromium/net/cert/cert_verify_proc.h
index 352610f22e5..33f87ee3f62 100644
--- a/chromium/net/cert/cert_verify_proc.h
+++ b/chromium/net/cert/cert_verify_proc.h
@@ -88,9 +88,25 @@ class NET_EXPORT CertVerifyProc
VerifyRejectsSHA1AfterDeprecationLegacyMode);
// Performs the actual verification using the desired underlying
- // cryptographic library. On entry, |verify_result->verified_cert|
- // is set to |cert|, the unverified chain. If no chain is built, the
- // value must be left untouched.
+ //
+ // On entry, |verify_result| will be default-initialized as a successful
+ // validation, with |verify_result->verified_cert| set to |cert|.
+ //
+ // Implementations are expected to fill in all applicable fields, excluding:
+ //
+ // * ocsp_result
+ // * has_md2
+ // * has_md4
+ // * has_md5
+ // * has_sha1
+ // * has_sha1_leaf
+ //
+ // which will be filled in by |Verify()|. If an error code is returned,
+ // |verify_result->cert_status| should be non-zero, indicating an
+ // error occurred.
+ //
+ // On success, net::OK should be returned, with |verify_result| updated to
+ // reflect the successfully verified chain.
virtual int VerifyInternal(X509Certificate* cert,
const std::string& hostname,
const std::string& ocsp_response,
diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc
index 2cb12f75c23..f90f5721c3d 100644
--- a/chromium/net/cert/cert_verify_proc_android.cc
+++ b/chromium/net/cert/cert_verify_proc_android.cc
@@ -79,32 +79,6 @@ bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
chain.push_back(verify_result->verified_cert->os_cert_handle());
chain.insert(chain.end(), intermediates.begin(), intermediates.end());
- // If the chain successfully verified, ignore the trust anchor (the last
- // certificate). Otherwise, assume the chain is partial. This is not entirely
- // correct, as a full chain may have been constructed and then failed to
- // validate. However, if that is the case, the more serious error will
- // override any SHA-1 considerations.
- size_t correction_for_root =
- (status == android::CERT_VERIFY_STATUS_ANDROID_OK) ? 1 : 0;
- for (size_t i = 0; i < chain.size() - correction_for_root; ++i) {
- int sig_alg = OBJ_obj2nid(chain[i]->sig_alg->algorithm);
- if (sig_alg == NID_md2WithRSAEncryption) {
- verify_result->has_md2 = true;
- } else if (sig_alg == NID_md4WithRSAEncryption) {
- verify_result->has_md4 = true;
- } else if (sig_alg == NID_md5WithRSAEncryption ||
- sig_alg == NID_md5WithRSA) {
- verify_result->has_md5 = true;
- } else if (sig_alg == NID_sha1WithRSAEncryption ||
- sig_alg == NID_dsaWithSHA || sig_alg == NID_dsaWithSHA1 ||
- sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
- sig_alg == NID_ecdsa_with_SHA1) {
- verify_result->has_sha1 = true;
- if (i == 0)
- verify_result->has_sha1_leaf = true;
- }
- }
-
// Extract the public key hashes.
for (size_t i = 0; i < verified_chain.size(); i++) {
base::StringPiece spki_bytes;
diff --git a/chromium/net/cert/cert_verify_proc_blacklist.inc b/chromium/net/cert/cert_verify_proc_blacklist.inc
index b2bb55464a3..3ca92f144eb 100644
--- a/chromium/net/cert/cert_verify_proc_blacklist.inc
+++ b/chromium/net/cert/cert_verify_proc_blacklist.inc
@@ -5,7 +5,7 @@
// The certificate(s) that were misissued, and which represent these SPKIs,
// are stored within net/data/ssl/blacklist. Further details about the
// rationale is documented in net/data/ssl/blacklist/README.md
-static const size_t kNumBlacklistedSPKIs = 34u;
+static const size_t kNumBlacklistedSPKIs = 36u;
static const uint8_t
kBlacklistedSPKIs[kNumBlacklistedSPKIs][crypto::kSHA256Length] = {
// ead610e6e90b439f2ecb51628b0932620f6ef340bd843fca38d3181b8f4ba197.pem
@@ -24,6 +24,10 @@ static const uint8_t
{0x1a, 0xf5, 0x6c, 0x98, 0xff, 0x04, 0x3e, 0xf9, 0x2b, 0xeb, 0xff,
0x54, 0xce, 0xbb, 0x4d, 0xd6, 0x7a, 0x25, 0xba, 0x95, 0x6c, 0x81,
0x7f, 0x3e, 0x6d, 0xd3, 0xc1, 0xe5, 0x2e, 0xb5, 0x84, 0xc1},
+ // e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem
+ {0x1f, 0x42, 0x24, 0xce, 0xc8, 0x4f, 0xc9, 0x9c, 0xed, 0x88, 0x1f,
+ 0xf6, 0xfc, 0xfd, 0x3e, 0x21, 0xf8, 0xc5, 0x19, 0xc5, 0x47, 0xaa,
+ 0x6a, 0x5d, 0xd3, 0xde, 0x24, 0x73, 0x02, 0xce, 0x50, 0xd1},
// 2c998e761160c3b06d82faa9fdc7545d9bda9eb60310f992aa510a6280b74245.pem
{0x2c, 0x99, 0x8e, 0x76, 0x11, 0x60, 0xc3, 0xb0, 0x6d, 0x82, 0xfa,
0xa9, 0xfd, 0xc7, 0x54, 0x5d, 0x9b, 0xda, 0x9e, 0xb6, 0x03, 0x10,
@@ -78,6 +82,10 @@ static const uint8_t
{0x9b, 0x8a, 0x93, 0xde, 0xcc, 0xcf, 0xba, 0xfc, 0xf4, 0xd0, 0x4d,
0x34, 0x42, 0x12, 0x8f, 0xb3, 0x52, 0x18, 0xcf, 0xe4, 0x37, 0xa3,
0xd8, 0xd0, 0x32, 0x8c, 0x99, 0xf8, 0x90, 0x89, 0xe4, 0x50},
+ // 1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
+ {0x9d, 0xd5, 0x5f, 0xc5, 0x73, 0xf5, 0x46, 0xcb, 0x6a, 0x38, 0x31,
+ 0xd1, 0x11, 0x2d, 0x87, 0x10, 0xa6, 0xf4, 0xf8, 0x2d, 0xc8, 0x7f,
+ 0x5f, 0xae, 0x9d, 0x3a, 0x1a, 0x02, 0x8d, 0xd3, 0x6e, 0x4b},
// 0d136e439f0ab6e97f3a02a540da9f0641aa554e1d66ea51ae2920d51b2f7217.pem
// 4fee0163686ecbd65db968e7494f55d84b25486d438e9de558d629d28cd4d176.pem
// 8a1bd21661c60015065212cc98b1abb50dfd14c872a208e66bae890f25c448af.pem
diff --git a/chromium/net/cert/cert_verify_proc_ios.cc b/chromium/net/cert/cert_verify_proc_ios.cc
index 2ab30ed07e4..19dc20fa722 100644
--- a/chromium/net/cert/cert_verify_proc_ios.cc
+++ b/chromium/net/cert/cert_verify_proc_ios.cc
@@ -104,12 +104,6 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
DCHECK_LT(0, CFArrayGetCount(cert_chain));
- verify_result->has_md2 = false;
- verify_result->has_md4 = false;
- verify_result->has_md5 = false;
- verify_result->has_sha1 = false;
- verify_result->has_sha1_leaf = false;
-
SecCertificateRef verified_cert = nullptr;
std::vector<SecCertificateRef> verified_chain;
for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
@@ -124,8 +118,6 @@ void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
std::string der_bytes;
if (!X509Certificate::GetDEREncoded(chain_cert, &der_bytes))
return;
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_bytes.data());
- bssl::UniquePtr<X509> x509_cert(d2i_X509(NULL, &bytes, der_bytes.size()));
base::StringPiece spki_bytes;
if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
@@ -144,23 +136,6 @@ void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
i == count - 1) {
continue;
}
-
- int sig_alg = OBJ_obj2nid(x509_cert->sig_alg->algorithm);
- if (sig_alg == NID_md2WithRSAEncryption) {
- verify_result->has_md2 = true;
- } else if (sig_alg == NID_md4WithRSAEncryption) {
- verify_result->has_md4 = true;
- } else if (sig_alg == NID_md5WithRSAEncryption ||
- sig_alg == NID_md5WithRSA) {
- verify_result->has_md5 = true;
- } else if (sig_alg == NID_sha1WithRSAEncryption ||
- sig_alg == NID_dsaWithSHA || sig_alg == NID_dsaWithSHA1 ||
- sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
- sig_alg == NID_ecdsa_with_SHA1) {
- verify_result->has_sha1 = true;
- if (i == 0)
- verify_result->has_sha1_leaf = true;
- }
}
if (!verified_cert) {
NOTREACHED();
diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc
index 08f1b887f59..46d1cc864b8 100644
--- a/chromium/net/cert/cert_verify_proc_mac.cc
+++ b/chromium/net/cert/cert_verify_proc_mac.cc
@@ -177,23 +177,12 @@ OSStatus CreateTrustPolicies(int flags, ScopedCFTypeRef<CFArrayRef>* policies) {
return noErr;
}
-// Stores the constructed certificate chain |cert_chain| and information about
-// the signature algorithms used into |*verify_result|. If the leaf cert in
-// |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that
-// in |*leaf_is_weak|. |cert_chain| must not be empty.
-void GetCertChainInfo(CFArrayRef cert_chain,
- CSSM_TP_APPLE_EVIDENCE_INFO* chain_info,
- CertVerifyResult* verify_result,
- bool* leaf_is_weak) {
+// Stores the constructed certificate chain |cert_chain| into
+// |*verify_result|. |cert_chain| must not be empty.
+void CopyCertChainToVerifyResult(CFArrayRef cert_chain,
+ CertVerifyResult* verify_result) {
DCHECK_LT(0, CFArrayGetCount(cert_chain));
- *leaf_is_weak = false;
- verify_result->has_md2 = false;
- verify_result->has_md4 = false;
- verify_result->has_md5 = false;
- verify_result->has_sha1 = false;
- verify_result->has_sha1_leaf = false;
-
SecCertificateRef verified_cert = NULL;
std::vector<SecCertificateRef> verified_chain;
for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
@@ -204,6 +193,29 @@ void GetCertChainInfo(CFArrayRef cert_chain,
} else {
verified_chain.push_back(chain_cert);
}
+ }
+ if (!verified_cert) {
+ NOTREACHED();
+ return;
+ }
+
+ verify_result->verified_cert =
+ X509Certificate::CreateFromHandle(verified_cert, verified_chain);
+}
+
+// Returns true if the intermediates (excluding trusted certificates) use a
+// weak hashing algorithm, but the target does not use a weak hash.
+bool IsWeakChainBasedOnHashingAlgorithms(
+ CFArrayRef cert_chain,
+ CSSM_TP_APPLE_EVIDENCE_INFO* chain_info) {
+ DCHECK_LT(0, CFArrayGetCount(cert_chain));
+
+ bool intermediates_contain_weak_hash = false;
+ bool leaf_uses_weak_hash = false;
+
+ for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
+ SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) ||
(chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) {
@@ -215,57 +227,26 @@ void GetCertChainInfo(CFArrayRef cert_chain,
continue;
}
- x509_util::CSSMCachedCertificate cached_cert;
- OSStatus status = cached_cert.Init(chain_cert);
- if (status)
- continue;
- x509_util::CSSMFieldValue signature_field;
- status = cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm,
- &signature_field);
- if (status || !signature_field.field())
- continue;
- // Match the behaviour of OS X system tools and defensively check that
- // sizes are appropriate. This would indicate a critical failure of the
- // OS X certificate library, but based on history, it is best to play it
- // safe.
- const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm =
- signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>();
- if (!sig_algorithm)
- continue;
-
- const CSSM_OID* alg_oid = &sig_algorithm->algorithm;
- if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA)) {
- verify_result->has_md2 = true;
- if (i == 0)
- *leaf_is_weak = true;
- } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA)) {
- verify_result->has_md4 = true;
- if (i == 0)
- *leaf_is_weak = true;
- } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA)) {
- verify_result->has_md5 = true;
- if (i == 0)
- *leaf_is_weak = true;
- } else if (CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) ||
- CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
- CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
- CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
- CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
- CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
- verify_result->has_sha1 = true;
- if (i == 0) {
- verify_result->has_sha1_leaf = true;
- *leaf_is_weak = true;
- }
+ X509Certificate::SignatureHashAlgorithm hash_algorithm =
+ X509Certificate::GetSignatureHashAlgorithm(chain_cert);
+
+ switch (hash_algorithm) {
+ case X509Certificate::kSignatureHashAlgorithmMd2:
+ case X509Certificate::kSignatureHashAlgorithmMd4:
+ case X509Certificate::kSignatureHashAlgorithmMd5:
+ case X509Certificate::kSignatureHashAlgorithmSha1:
+ if (i == 0) {
+ leaf_uses_weak_hash = true;
+ } else {
+ intermediates_contain_weak_hash = true;
+ }
+ break;
+ case X509Certificate::kSignatureHashAlgorithmOther:
+ break;
}
}
- if (!verified_cert) {
- NOTREACHED();
- return;
- }
- verify_result->verified_cert =
- X509Certificate::CreateFromHandle(verified_cert, verified_chain);
+ return !leaf_uses_weak_hash && intermediates_contain_weak_hash;
}
using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>;
@@ -842,14 +823,8 @@ int VerifyWithGivenFlags(X509Certificate* cert,
DCHECK(untrusted);
DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
} else {
- CertVerifyResult temp_verify_result;
- bool leaf_is_weak = false;
- GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
- &leaf_is_weak);
weak_chain =
- !leaf_is_weak &&
- (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
- temp_verify_result.has_md5 || temp_verify_result.has_sha1);
+ IsWeakChainBasedOnHashingAlgorithms(temp_chain, temp_chain_info);
}
// Set the result to the current chain if:
// - This is the first verification attempt. This ensures that if
@@ -894,9 +869,7 @@ int VerifyWithGivenFlags(X509Certificate* cert,
verify_result->cert_status |= CERT_STATUS_REVOKED;
if (CFArrayGetCount(completed_chain) > 0) {
- bool leaf_is_weak_unused = false;
- GetCertChainInfo(completed_chain, chain_info, verify_result,
- &leaf_is_weak_unused);
+ CopyCertChainToVerifyResult(completed_chain, verify_result);
}
// As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
diff --git a/chromium/net/cert/cert_verify_proc_nss.cc b/chromium/net/cert/cert_verify_proc_nss.cc
index 1ac27cb48ef..59cfa03235a 100644
--- a/chromium/net/cert/cert_verify_proc_nss.cc
+++ b/chromium/net/cert/cert_verify_proc_nss.cc
@@ -191,30 +191,6 @@ void GetCertChainInfo(CERTCertList* cert_list,
}
verified_chain.push_back(node->cert);
}
-
- SECAlgorithmID& signature = node->cert->signature;
- SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm);
- switch (oid_tag) {
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- verify_result->has_md5 = true;
- break;
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- verify_result->has_md2 = true;
- break;
- case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
- verify_result->has_md4 = true;
- break;
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
- case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
- verify_result->has_sha1 = true;
- if (i == 0)
- verify_result->has_sha1_leaf = true;
- break;
- default:
- break;
- }
}
if (root_cert)
diff --git a/chromium/net/cert/cert_verify_proc_openssl.cc b/chromium/net/cert/cert_verify_proc_openssl.cc
index 988bdec1e2e..d822bc00d6c 100644
--- a/chromium/net/cert/cert_verify_proc_openssl.cc
+++ b/chromium/net/cert/cert_verify_proc_openssl.cc
@@ -104,27 +104,6 @@ void GetCertChainInfo(X509_STORE_CTX* store_ctx,
} else {
verified_chain.push_back(cert);
}
-
- // Only check the algorithm status for certificates that are not in the
- // trust store.
- if (i < static_cast<size_t>(store_ctx->last_untrusted)) {
- int sig_alg = OBJ_obj2nid(cert->sig_alg->algorithm);
- if (sig_alg == NID_md2WithRSAEncryption) {
- verify_result->has_md2 = true;
- } else if (sig_alg == NID_md4WithRSAEncryption) {
- verify_result->has_md4 = true;
- } else if (sig_alg == NID_md5WithRSAEncryption ||
- sig_alg == NID_md5WithRSA) {
- verify_result->has_md5 = true;
- } else if (sig_alg == NID_sha1WithRSAEncryption ||
- sig_alg == NID_dsaWithSHA || sig_alg == NID_dsaWithSHA1 ||
- sig_alg == NID_dsaWithSHA1_2 || sig_alg == NID_sha1WithRSA ||
- sig_alg == NID_ecdsa_with_SHA1) {
- verify_result->has_sha1 = true;
- if (i == 0)
- verify_result->has_sha1_leaf = true;
- }
- }
}
// Set verify_result->verified_cert and
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index 862f7c8690c..2e3a0f5d458 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -38,6 +38,7 @@
#endif
#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "base/mac/mac_util.h"
#include "net/cert/test_keychain_search_list_mac.h"
#endif
@@ -122,6 +123,16 @@ bool SupportsDetectingKnownRoots() {
return true;
}
+bool WeakKeysAreInvalid() {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ // Starting with Mac OS 10.12, certs with weak keys are treated as
+ // (recoverable) invalid certificate errors.
+ return base::mac::IsAtLeastOS10_12();
+#else
+ return false;
+#endif
+}
+
// Template helper to load a series of certificate files into a CertificateList.
// Like CertTestUtil's CreateCertificateListFromFile, except it can load a
// series of individual certificates (to make the tests clearer).
@@ -407,7 +418,7 @@ TEST_F(CertVerifyProcTest, RejectWeakKeys) {
EXPECT_NE(OK, error);
EXPECT_EQ(CERT_STATUS_WEAK_KEY,
verify_result.cert_status & CERT_STATUS_WEAK_KEY);
- EXPECT_NE(CERT_STATUS_INVALID,
+ EXPECT_EQ(WeakKeysAreInvalid() ? CERT_STATUS_INVALID : 0,
verify_result.cert_status & CERT_STATUS_INVALID);
} else {
EXPECT_THAT(error, IsOk());
@@ -882,8 +893,6 @@ TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
// that were issued after 1 January 2016, while still allowing those from
// before that date, with SHA-1 in the intermediate, or from an enterprise
// CA.
-//
-// TODO(rsleevi): This code should be removed in M57.
TEST_F(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecationLegacyMode) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(CertVerifyProc::kSHA1LegacyMode);
@@ -928,7 +937,7 @@ TEST_F(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecationLegacyMode) {
EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
// Enterprise issued SHA-1 leaf certificates issued on/after 1 January 2016
- // remain accepted until SHA-1 is disabled.
+ // remain accepted.
verify_result.Reset();
dummy_result.Reset();
dummy_result.is_issued_by_known_root = false;
@@ -1208,39 +1217,32 @@ TEST_F(CertVerifyProcTest, CRLSet) {
TEST_F(CertVerifyProcTest, CRLSetLeafSerial) {
CertificateList ca_cert_list =
- CreateCertificateListFromFile(GetTestCertsDirectory(),
- "quic_root.crt",
+ CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, ca_cert_list.size());
ScopedTestRoot test_root(ca_cert_list[0].get());
- CertificateList intermediate_cert_list =
- CreateCertificateListFromFile(GetTestCertsDirectory(),
- "quic_intermediate.crt",
- X509Certificate::FORMAT_AUTO);
+ CertificateList intermediate_cert_list = CreateCertificateListFromFile(
+ GetTestCertsDirectory(), "intermediate_ca_cert.pem",
+ X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, intermediate_cert_list.size());
X509Certificate::OSCertHandles intermediates;
intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
CertificateList cert_list = CreateCertificateListFromFile(
- GetTestCertsDirectory(), "quic_test.example.com.crt",
+ GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, cert_list.size());
- scoped_refptr<X509Certificate> leaf =
- X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
- intermediates);
+ scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
+ cert_list[0]->os_cert_handle(), intermediates);
+ ASSERT_TRUE(leaf);
int flags = 0;
CertVerifyResult verify_result;
- int error = Verify(leaf.get(),
- "test.example.com",
- flags,
- NULL,
- empty_cert_list_,
+ int error = Verify(leaf.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
&verify_result);
EXPECT_THAT(error, IsOk());
- EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT, verify_result.cert_status);
// Test revocation by serial number of a certificate not under the root.
scoped_refptr<CRLSet> crl_set;
@@ -1250,12 +1252,8 @@ TEST_F(CertVerifyProcTest, CRLSetLeafSerial) {
&crl_set_bytes));
ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
- error = Verify(leaf.get(),
- "test.example.com",
- flags,
- crl_set.get(),
- empty_cert_list_,
- &verify_result);
+ error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
+ empty_cert_list_, &verify_result);
EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
}
@@ -1392,6 +1390,11 @@ TEST_F(CertVerifyProcTest, CRLSetDuringPathBuilding) {
// The verifier should rollback until it just tries A(B) alone, at which point
// it will pull B(F) & F(E) from the keychain and succeed.
TEST_F(CertVerifyProcTest, MacCRLIntermediate) {
+ if (base::mac::IsAtLeastOS10_12()) {
+ // TODO(crbug.com/671889): Investigate SecTrustSetKeychains issue on Sierra.
+ LOG(INFO) << "Skipping test, SecTrustSetKeychains does not work on 10.12";
+ return;
+ }
const char* const kPath2Files[] = {
"multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem",
"multi-root-E-by-E.pem"};
@@ -1631,7 +1634,7 @@ TEST_F(CertVerifyProcTest, RejectsPublicSHA1IntermediatesUnlessAllowed) {
}
}
-TEST_F(CertVerifyProcTest, AcceptsPrivateSHA1) {
+TEST_F(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) {
scoped_refptr<X509Certificate> cert(
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
ASSERT_TRUE(cert);
@@ -1642,10 +1645,19 @@ TEST_F(CertVerifyProcTest, AcceptsPrivateSHA1) {
result.is_issued_by_known_root = false;
verify_proc_ = new MockCertVerifyProc(result);
+ // SHA-1 should be rejected by default for private roots...
int flags = 0;
CertVerifyResult verify_result;
int error = Verify(cert.get(), "127.0.0.1", flags, nullptr /* crl_set */,
empty_cert_list_, &verify_result);
+ EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+
+ // ... unless VERIFY_ENABLE_SHA1_LOCAL_ANCHORS was supplied.
+ flags = CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
+ verify_result.Reset();
+ error = Verify(cert.get(), "127.0.0.1", flags, nullptr /* crl_set */,
+ empty_cert_list_, &verify_result);
EXPECT_THAT(error, IsOk());
EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
}
@@ -1665,14 +1677,20 @@ struct WeakDigestTestData {
int expected_algorithms;
};
+const char* StringOrDefault(const char* str, const char* default_value) {
+ if (!str)
+ return default_value;
+ return str;
+}
+
// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
// to output the parameter that was passed. Without this, it will simply
// attempt to print out the first twenty bytes of the object, which depending
// on platform and alignment, may result in an invalid read.
void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
- *os << "root: "
- << (data.root_cert_filename ? data.root_cert_filename : "none")
- << "; intermediate: " << data.intermediate_cert_filename
+ *os << "root: " << StringOrDefault(data.root_cert_filename, "none")
+ << "; intermediate: "
+ << StringOrDefault(data.intermediate_cert_filename, "none")
<< "; end-entity: " << data.ee_cert_filename;
}
@@ -1684,31 +1702,35 @@ class CertVerifyProcWeakDigestTest
virtual ~CertVerifyProcWeakDigestTest() {}
};
-// Test that the underlying cryptographic library properly surfaces the
-// algorithms used in the chain. Some libraries, like NSS, don't return
-// the failing chain on error, and thus not all tests can be run.
+// Test that the CertVerifyProc::Verify() properly surfaces the (weak) hashing
+// algorithms used in the chain.
TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
WeakDigestTestData data = GetParam();
base::FilePath certs_dir = GetTestCertsDirectory();
- ScopedTestRoot test_root;
+ scoped_refptr<X509Certificate> intermediate_cert;
+ scoped_refptr<X509Certificate> root_cert;
+
+ // Build |intermediates| as the full chain (including trust anchor).
+ X509Certificate::OSCertHandles intermediates;
+
+ if (data.intermediate_cert_filename) {
+ intermediate_cert =
+ ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
+ ASSERT_TRUE(intermediate_cert);
+ intermediates.push_back(intermediate_cert->os_cert_handle());
+ }
+
if (data.root_cert_filename) {
- scoped_refptr<X509Certificate> root_cert =
- ImportCertFromFile(certs_dir, data.root_cert_filename);
- ASSERT_TRUE(root_cert);
- test_root.Reset(root_cert.get());
+ root_cert = ImportCertFromFile(certs_dir, data.root_cert_filename);
+ ASSERT_TRUE(root_cert);
+ intermediates.push_back(root_cert->os_cert_handle());
}
- scoped_refptr<X509Certificate> intermediate_cert =
- ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
- ASSERT_TRUE(intermediate_cert);
scoped_refptr<X509Certificate> ee_cert =
ImportCertFromFile(certs_dir, data.ee_cert_filename);
ASSERT_TRUE(ee_cert);
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate_cert->os_cert_handle());
-
scoped_refptr<X509Certificate> ee_chain =
X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
intermediates);
@@ -1716,8 +1738,16 @@ TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
int flags = 0;
CertVerifyResult verify_result;
- Verify(ee_chain.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
- &verify_result);
+
+ // Use a mock CertVerifyProc that returns success with a verified_cert of
+ // |ee_chain|.
+ //
+ // This is sufficient for the purposes of this test, as the checking for weak
+ // hashing algorithms is done by CertVerifyProc::Verify().
+ scoped_refptr<CertVerifyProc> proc =
+ new MockCertVerifyProc(CertVerifyResult());
+ proc->Verify(ee_chain.get(), "127.0.0.1", std::string(), flags, nullptr,
+ empty_cert_list_, &verify_result);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD2), verify_result.has_md2);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD4), verify_result.has_md4);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD5), verify_result.has_md5);
@@ -1726,34 +1756,16 @@ TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
verify_result.has_sha1_leaf);
}
-// Unlike TEST/TEST_F, which are macros that expand to further macros,
-// INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
-// stringizes the arguments. As a result, macros passed as parameters (such as
-// prefix or test_case_name) will not be expanded by the preprocessor. To work
-// around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
-// pre-processor will expand macros such as MAYBE_test_name before
-// instantiating the test.
-#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
- INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
-
// The signature algorithm of the root CA should not matter.
const WeakDigestTestData kVerifyRootCATestData[] = {
{"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
{"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#endif
{"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
-#if defined(OS_ANDROID)
-#define MAYBE_VerifyRoot DISABLED_VerifyRoot
-#else
-#define MAYBE_VerifyRoot VerifyRoot
-#endif
-INSTANTIATE_TEST_CASE_P(MAYBE_VerifyRoot,
+INSTANTIATE_TEST_CASE_P(VerifyRoot,
CertVerifyProcWeakDigestTest,
testing::ValuesIn(kVerifyRootCATestData));
@@ -1761,97 +1773,66 @@ INSTANTIATE_TEST_CASE_P(MAYBE_VerifyRoot,
const WeakDigestTestData kVerifyIntermediateCATestData[] = {
{"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
{"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#endif
{"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
"weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
-// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
-#define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
-#else
-#define MAYBE_VerifyIntermediate VerifyIntermediate
-#endif
-WRAPPED_INSTANTIATE_TEST_CASE_P(
- MAYBE_VerifyIntermediate,
- CertVerifyProcWeakDigestTest,
- testing::ValuesIn(kVerifyIntermediateCATestData));
+
+INSTANTIATE_TEST_CASE_P(VerifyIntermediate,
+ CertVerifyProcWeakDigestTest,
+ testing::ValuesIn(kVerifyIntermediateCATestData));
// The signature algorithm of end-entity should be properly detected.
const WeakDigestTestData kVerifyEndEntityTestData[] = {
{ "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_md5_ee.pem", EXPECT_MD5 | EXPECT_SHA1 },
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
{ "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_md4_ee.pem", EXPECT_MD4 | EXPECT_SHA1 },
-#endif
{ "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
"weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_SHA1 },
};
-// Disabled on NSS - NSS caches chains/signatures in such a way that cannot
-// be cleared until NSS is cleanly shutdown, which is not presently supported
-// in Chromium.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
-#define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
-#else
-#define MAYBE_VerifyEndEntity VerifyEndEntity
-#endif
-WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
- CertVerifyProcWeakDigestTest,
- testing::ValuesIn(kVerifyEndEntityTestData));
-// Incomplete chains should still report the status of the intermediate.
+INSTANTIATE_TEST_CASE_P(VerifyEndEntity,
+ CertVerifyProcWeakDigestTest,
+ testing::ValuesIn(kVerifyEndEntityTestData));
+
+// Incomplete chains do not report the status of the intermediate.
+// Note: really each of these tests should also expect the digest algorithm of
+// the intermediate (included as a comment). However CertVerifyProc::Verify() is
+// unable to distinguish that this is an intermediate and not a trust anchor, so
+// this intermediate is treated like a trust anchor.
const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
{NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
+ /*EXPECT_MD5 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
{NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
-#endif
+ /*EXPECT_MD4 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
{NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
- EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
+ /*EXPECT_MD2 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
};
-// Disabled on NSS - libpkix does not return constructed chains on error,
-// preventing us from detecting/inspecting the verified chain.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
-#define MAYBE_VerifyIncompleteIntermediate \
- DISABLED_VerifyIncompleteIntermediate
-#else
-#define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
-#endif
-WRAPPED_INSTANTIATE_TEST_CASE_P(
+
+INSTANTIATE_TEST_CASE_P(
MAYBE_VerifyIncompleteIntermediate,
CertVerifyProcWeakDigestTest,
testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
-// Incomplete chains should still report the status of the end-entity.
+// Incomplete chains should report the status of the end-entity.
+// Note: really each of these tests should also expect EXPECT_SHA1 (included as
+// a comment). However CertVerifyProc::Verify() is unable to distinguish that
+// this is an intermediate and not a trust anchor, so this intermediate is
+// treated like a trust anchor.
const WeakDigestTestData kVerifyIncompleteEETestData[] = {
- { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
- EXPECT_MD5 | EXPECT_SHA1 },
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
- { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
- EXPECT_MD4 | EXPECT_SHA1 },
-#endif
- { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
- EXPECT_MD2 | EXPECT_SHA1 },
+ {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
+ /*EXPECT_SHA1 |*/ EXPECT_MD5},
+ {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
+ /*EXPECT_SHA1 |*/ EXPECT_MD4},
+ {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
+ /*EXPECT_SHA1 |*/ EXPECT_MD2},
};
-// Disabled on NSS - libpkix does not return constructed chains on error,
-// preventing us from detecting/inspecting the verified chain.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
-#define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
-#else
-#define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
-#endif
-WRAPPED_INSTANTIATE_TEST_CASE_P(
- MAYBE_VerifyIncompleteEndEntity,
- CertVerifyProcWeakDigestTest,
- testing::ValuesIn(kVerifyIncompleteEETestData));
+
+INSTANTIATE_TEST_CASE_P(VerifyIncompleteEndEntity,
+ CertVerifyProcWeakDigestTest,
+ testing::ValuesIn(kVerifyIncompleteEETestData));
// Differing algorithms between the intermediate and the EE should still be
// reported.
@@ -1860,23 +1841,26 @@ const WeakDigestTestData kVerifyMixedTestData[] = {
"weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD5 },
{ "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
"weak_digest_md5_ee.pem", EXPECT_MD2 | EXPECT_MD5 },
-#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
- // MD4 is not supported by OS X / NSS
{ "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
"weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD4 },
-#endif
};
-// NSS does not support MD4 and does not enable MD2 by default, making all
-// permutations invalid.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
-#define MAYBE_VerifyMixed DISABLED_VerifyMixed
-#else
-#define MAYBE_VerifyMixed VerifyMixed
-#endif
-WRAPPED_INSTANTIATE_TEST_CASE_P(
- MAYBE_VerifyMixed,
- CertVerifyProcWeakDigestTest,
- testing::ValuesIn(kVerifyMixedTestData));
+
+INSTANTIATE_TEST_CASE_P(VerifyMixed,
+ CertVerifyProcWeakDigestTest,
+ testing::ValuesIn(kVerifyMixedTestData));
+
+// The EE is a trusted certificate. Even though it uses weak hashes, these
+// should not be reported.
+const WeakDigestTestData kVerifyTrustedEETestData[] = {
+ {NULL, NULL, "weak_digest_md5_ee.pem", 0},
+ {NULL, NULL, "weak_digest_md4_ee.pem", 0},
+ {NULL, NULL, "weak_digest_md2_ee.pem", 0},
+ {NULL, NULL, "weak_digest_sha1_ee.pem", 0},
+};
+
+INSTANTIATE_TEST_CASE_P(VerifyTrustedEE,
+ CertVerifyProcWeakDigestTest,
+ testing::ValuesIn(kVerifyTrustedEETestData));
// For the list of valid hostnames, see
// net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
@@ -1938,15 +1922,17 @@ TEST_P(CertVerifyProcNameTest, VerifyCertName) {
}
}
-WRAPPED_INSTANTIATE_TEST_CASE_P(
- VerifyName,
- CertVerifyProcNameTest,
- testing::ValuesIn(kVerifyNameData));
+INSTANTIATE_TEST_CASE_P(VerifyName,
+ CertVerifyProcNameTest,
+ testing::ValuesIn(kVerifyNameData));
#if defined(OS_MACOSX) && !defined(OS_IOS)
// Test that CertVerifyProcMac reacts appropriately when Apple's certificate
// verifier rejects a certificate with a fatal error. This is a regression
// test for https://crbug.com/472291.
+// (Since 10.12, this causes a recoverable error instead of a fatal one.)
+// TODO(mattm): Try to find a different way to cause a fatal error that works
+// on 10.12.
TEST_F(CertVerifyProcTest, LargeKey) {
// Load root_ca_cert.pem into the test root store.
ScopedTestRoot test_root(
@@ -1963,7 +1949,7 @@ TEST_F(CertVerifyProcTest, LargeKey) {
int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
&verify_result);
EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
- EXPECT_EQ(CERT_STATUS_INVALID, verify_result.cert_status);
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
}
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.cc b/chromium/net/cert/cert_verify_proc_whitelist.cc
index 5c53a77a36c..2ba4166d4d8 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist.cc
@@ -6,6 +6,7 @@
#include <cstdlib>
+#include "net/base/lookup_string_in_fixed_set.h"
#include "net/cert/x509_certificate.h"
namespace net {
@@ -46,1604 +47,7 @@ const uint8_t kWosignKeys[][crypto::kSHA256Length] = {
0x21, 0x9f, 0xe0, 0xe9, 0xe3, 0xa3, 0x82, 0xa1,
0xb3, 0xcb, 0x66, 0xc9, 0x39, 0x55, 0xde, 0x75 },
};
-
-// SHA-256 hashes of the leaf certificates whitelisted as issued by CNNIC's
-// DV root.
-const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
- { 0x00, 0xc5, 0x9f, 0x5e, 0xf3, 0xb4, 0x6d, 0xbc,
- 0xa0, 0xa8, 0xbb, 0xa5, 0x0a, 0x72, 0xd4, 0xe1,
- 0x83, 0x9a, 0x94, 0xfb, 0x1a, 0x58, 0x5a, 0xd7,
- 0x2a, 0x7a, 0xac, 0x3c, 0x72, 0x56, 0x1f, 0xc0 },
- { 0x02, 0x01, 0x4e, 0x80, 0xf5, 0xc4, 0xf3, 0x8b,
- 0xa9, 0xd9, 0x04, 0x79, 0x1a, 0x63, 0xf6, 0x4d,
- 0x05, 0xf9, 0xe2, 0x03, 0xa1, 0xf1, 0x2b, 0x06,
- 0xd6, 0x55, 0x94, 0x01, 0x41, 0x0e, 0x73, 0x36 },
- { 0x02, 0x35, 0x38, 0xe2, 0x48, 0x15, 0x28, 0x75,
- 0x29, 0x2f, 0x2c, 0x83, 0x9a, 0xb3, 0x2b, 0xc7,
- 0x35, 0x1e, 0x2b, 0x29, 0x99, 0x1d, 0x66, 0xae,
- 0xa6, 0x16, 0xcb, 0x0b, 0x26, 0xa5, 0xe3, 0x75 },
- { 0x02, 0xec, 0x35, 0xf5, 0x83, 0x4c, 0xd2, 0xc3,
- 0x43, 0x33, 0x39, 0x9a, 0xea, 0x6b, 0xda, 0x84,
- 0x68, 0xab, 0x8d, 0x74, 0xef, 0x6c, 0xa5, 0x2d,
- 0x33, 0x7a, 0x30, 0x69, 0x4c, 0x3f, 0x95, 0xa4 },
- { 0x03, 0xe0, 0x6e, 0x0b, 0x7a, 0x2c, 0xba, 0xe4,
- 0xb6, 0x8b, 0xce, 0x5f, 0x83, 0xe7, 0xa9, 0x31,
- 0x6e, 0xd7, 0x82, 0x3e, 0x8d, 0x94, 0x85, 0x38,
- 0xf1, 0x94, 0x3f, 0xa4, 0x27, 0xd7, 0x91, 0x0e },
- { 0x04, 0x0f, 0x53, 0x7a, 0x51, 0x95, 0x95, 0xcc,
- 0xff, 0xde, 0x35, 0xe0, 0xd1, 0x28, 0xb7, 0x99,
- 0x92, 0x2b, 0xa9, 0x37, 0xa2, 0xe8, 0x65, 0x84,
- 0x36, 0x62, 0xf1, 0xf4, 0x50, 0x02, 0xb8, 0x2d },
- { 0x07, 0x19, 0x4f, 0x47, 0xf4, 0xce, 0xd0, 0x96,
- 0xd1, 0x06, 0x8d, 0x34, 0x49, 0x3b, 0x67, 0x37,
- 0x14, 0x45, 0x16, 0x93, 0xa6, 0xa2, 0x71, 0x2f,
- 0x70, 0x8f, 0x59, 0x36, 0x12, 0x11, 0xc6, 0x21 },
- { 0x07, 0x8f, 0xee, 0x58, 0x8a, 0x2c, 0x55, 0xc8,
- 0xe2, 0xc1, 0x78, 0x71, 0xaa, 0xb6, 0xe4, 0x00,
- 0xb3, 0xfd, 0xbc, 0xdc, 0xf3, 0x91, 0x46, 0xa0,
- 0x89, 0x37, 0xf9, 0xac, 0x06, 0xa1, 0xb8, 0xbd },
- { 0x08, 0x21, 0x0a, 0xc3, 0xa2, 0x95, 0x56, 0xf6,
- 0x8d, 0x33, 0xb4, 0x40, 0x87, 0x9c, 0x54, 0x63,
- 0x64, 0x04, 0xe9, 0x7c, 0x4d, 0x9f, 0x97, 0x82,
- 0x23, 0xd2, 0x42, 0xab, 0xe5, 0x38, 0x5e, 0x4e },
- { 0x08, 0xc2, 0xd3, 0x17, 0xa8, 0x4a, 0x3c, 0xbe,
- 0x38, 0xde, 0x64, 0xa2, 0x4d, 0xd4, 0x27, 0x91,
- 0x09, 0xe2, 0xbc, 0x02, 0x2b, 0x93, 0xb1, 0x05,
- 0xa8, 0x94, 0xa5, 0x1a, 0xdc, 0x3e, 0xe5, 0xcc },
- { 0x09, 0x9f, 0x3e, 0x71, 0xb5, 0x00, 0xd1, 0x5b,
- 0x03, 0x7b, 0x93, 0xaa, 0x5f, 0xb4, 0x16, 0x19,
- 0x0a, 0xd1, 0xdf, 0x86, 0x73, 0xab, 0x31, 0xa8,
- 0xf6, 0xd9, 0x7f, 0x59, 0x5e, 0x8e, 0x16, 0xe9 },
- { 0x09, 0xeb, 0xdd, 0x1b, 0x7f, 0xfa, 0x4e, 0xd7,
- 0x4b, 0xeb, 0xae, 0x96, 0xba, 0x10, 0x65, 0xdc,
- 0x7d, 0xa1, 0xc5, 0xd3, 0x18, 0x3c, 0xc5, 0x94,
- 0x19, 0xe9, 0x78, 0x36, 0xaf, 0x7f, 0x6d, 0x70 },
- { 0x0a, 0x01, 0x88, 0x81, 0x2c, 0x9d, 0xe8, 0x8a,
- 0x2f, 0x0a, 0x5c, 0x4c, 0x57, 0xe6, 0xf9, 0xa8,
- 0x15, 0x69, 0xe9, 0xc7, 0x09, 0xc0, 0x95, 0x40,
- 0x80, 0xe5, 0xe4, 0xe6, 0x62, 0x85, 0x6d, 0xf8 },
- { 0x0a, 0x42, 0x19, 0x7e, 0x48, 0x70, 0xb2, 0x34,
- 0x20, 0xf5, 0x51, 0x9f, 0xb8, 0x39, 0xb6, 0xcc,
- 0x83, 0x03, 0x52, 0x9a, 0xa9, 0x06, 0x9a, 0xd1,
- 0xa0, 0x90, 0x86, 0xcf, 0x6c, 0xba, 0x07, 0xc2 },
- { 0x0b, 0x03, 0xe1, 0x27, 0xc2, 0xe3, 0x3e, 0xad,
- 0xbc, 0xb0, 0x99, 0x80, 0x46, 0xcc, 0x9b, 0xa7,
- 0x33, 0x46, 0x3e, 0x0c, 0xa6, 0x43, 0x52, 0x27,
- 0x81, 0xb0, 0x3d, 0x81, 0x53, 0x97, 0xeb, 0x4f },
- { 0x0b, 0x1e, 0x1e, 0x73, 0x43, 0xa0, 0xe9, 0x1c,
- 0x2a, 0x27, 0xdd, 0x2a, 0x4d, 0x7e, 0x6b, 0xf1,
- 0xe8, 0x04, 0x4b, 0x58, 0xce, 0x1a, 0xe8, 0x1e,
- 0x27, 0xd8, 0x14, 0xfd, 0x2d, 0xc0, 0x18, 0x93 },
- { 0x0b, 0x48, 0xd5, 0x5c, 0xac, 0x84, 0xfd, 0xee,
- 0x15, 0xd8, 0x1a, 0xff, 0x99, 0x07, 0xbb, 0x9a,
- 0x57, 0x11, 0xa9, 0x5c, 0xe2, 0x3a, 0x8d, 0x4d,
- 0x5e, 0x88, 0x62, 0xbf, 0x15, 0xa7, 0x6a, 0x75 },
- { 0x0b, 0xfe, 0xa1, 0x38, 0x31, 0x67, 0x3e, 0xc9,
- 0x69, 0xd0, 0x5f, 0xd8, 0x67, 0xb6, 0x69, 0xf2,
- 0x71, 0x24, 0xaf, 0xeb, 0x7c, 0x60, 0x8c, 0xfe,
- 0x54, 0xcf, 0x46, 0x33, 0x06, 0xcc, 0x99, 0x2e },
- { 0x0c, 0xb9, 0x31, 0x93, 0xf1, 0x65, 0x26, 0xe1,
- 0xd1, 0x65, 0x52, 0x11, 0x7b, 0xa2, 0x1a, 0xac,
- 0xb9, 0xf1, 0xd7, 0xa8, 0x93, 0x56, 0xa3, 0x5d,
- 0xe4, 0xf6, 0x65, 0xe9, 0x39, 0x90, 0x79, 0x38 },
- { 0x0d, 0x16, 0x1b, 0xb9, 0xca, 0x0d, 0x20, 0xe4,
- 0x67, 0x35, 0x89, 0x67, 0x22, 0x78, 0xb0, 0xa3,
- 0xc5, 0xe2, 0x69, 0x30, 0xa4, 0xdc, 0x3a, 0x82,
- 0x16, 0x85, 0x43, 0x24, 0x27, 0xc7, 0x31, 0x5a },
- { 0x0d, 0x71, 0xc8, 0xca, 0x16, 0x56, 0x59, 0xef,
- 0xaf, 0x69, 0x65, 0x29, 0x28, 0x9a, 0xae, 0x25,
- 0xd9, 0xc4, 0x2a, 0x1b, 0xbb, 0x03, 0x5a, 0x2b,
- 0x8c, 0x61, 0x14, 0x7e, 0x1b, 0x8b, 0x90, 0x52 },
- { 0x0e, 0xfd, 0x68, 0x73, 0xd6, 0x0e, 0x77, 0x96,
- 0x2d, 0xf6, 0x00, 0x16, 0xdc, 0x3b, 0xaf, 0x9c,
- 0xa7, 0x1e, 0x7d, 0x86, 0x19, 0xe7, 0xeb, 0xaa,
- 0x3a, 0xf2, 0xdc, 0xb5, 0xba, 0x24, 0xde, 0xc2 },
- { 0x0e, 0xff, 0x3c, 0xff, 0xda, 0x4a, 0x3e, 0x87,
- 0x23, 0x4a, 0x86, 0xc7, 0x0d, 0x49, 0x8c, 0x62,
- 0x60, 0x7f, 0x37, 0x44, 0xea, 0x71, 0xf1, 0x83,
- 0x1d, 0xcf, 0xca, 0xf3, 0xaf, 0x15, 0x56, 0x9c },
- { 0x10, 0x83, 0x6d, 0xa0, 0xcd, 0x6a, 0xc0, 0x95,
- 0xdd, 0x7a, 0xc3, 0x4d, 0x99, 0x01, 0x90, 0x9a,
- 0x8e, 0xf8, 0x4d, 0x6e, 0xe0, 0x5b, 0x83, 0x43,
- 0x03, 0xd4, 0x7f, 0xc0, 0xa5, 0xf9, 0x14, 0xfa },
- { 0x11, 0xa4, 0x02, 0x7b, 0x45, 0xfc, 0x9a, 0x6f,
- 0x40, 0x21, 0x25, 0xc3, 0xca, 0x22, 0x68, 0xe0,
- 0x15, 0xa3, 0x1b, 0xa4, 0xfd, 0xb0, 0x05, 0x9d,
- 0x66, 0x6b, 0x73, 0xc8, 0x51, 0xd5, 0x35, 0x92 },
- { 0x12, 0x6b, 0x1b, 0xa6, 0x38, 0xc7, 0xe6, 0x99,
- 0xbc, 0xbc, 0x54, 0xf5, 0x79, 0xac, 0xd3, 0x9f,
- 0xe6, 0x1d, 0x08, 0x22, 0x5f, 0xe5, 0xb1, 0xf9,
- 0x01, 0x88, 0xb2, 0x3f, 0xd8, 0x43, 0x3e, 0x8e },
- { 0x13, 0x5d, 0x3e, 0xda, 0x6e, 0x55, 0x9b, 0xf5,
- 0xee, 0x23, 0x0a, 0xa5, 0xba, 0x59, 0xbb, 0x6a,
- 0x2a, 0x0f, 0x07, 0x82, 0x2f, 0xed, 0x38, 0x44,
- 0x7e, 0x6a, 0xbc, 0x5c, 0x23, 0xaa, 0xd0, 0x27 },
- { 0x13, 0x6a, 0x40, 0x09, 0x81, 0xb1, 0xa3, 0xe0,
- 0x5f, 0xdc, 0xac, 0x20, 0xa2, 0x36, 0xf8, 0x6e,
- 0x94, 0xe5, 0xee, 0x58, 0x59, 0xd8, 0xfd, 0x45,
- 0xe9, 0xe9, 0xc5, 0xa6, 0xc5, 0xc0, 0xa4, 0x13 },
- { 0x14, 0x21, 0x28, 0xa6, 0x65, 0x1c, 0xdc, 0x18,
- 0x70, 0xc2, 0x67, 0x5e, 0xc0, 0xb0, 0xef, 0x32,
- 0xb5, 0xd4, 0xc1, 0x55, 0x35, 0x8e, 0x7e, 0xd9,
- 0x5a, 0x98, 0xe8, 0x3b, 0x1a, 0xd8, 0xbe, 0x4d },
- { 0x14, 0x47, 0x25, 0xa6, 0x79, 0x1c, 0x60, 0x0c,
- 0x4c, 0x2c, 0xf3, 0x94, 0x3f, 0x3e, 0xcf, 0x40,
- 0xd6, 0x31, 0xd7, 0x60, 0xe4, 0x51, 0xef, 0x28,
- 0x29, 0xaf, 0xfb, 0xee, 0x74, 0x80, 0xad, 0x17 },
- { 0x15, 0x27, 0x2a, 0xbc, 0x1f, 0x0c, 0x4d, 0x1d,
- 0x1a, 0x92, 0x08, 0x73, 0x55, 0xa1, 0xe0, 0x42,
- 0x6c, 0x2b, 0xb5, 0xb4, 0x37, 0x30, 0x00, 0xb8,
- 0x2c, 0x2c, 0xca, 0xb7, 0xfa, 0xd6, 0xfa, 0x20 },
- { 0x15, 0x48, 0x1f, 0xde, 0x4e, 0x3f, 0x72, 0x49,
- 0x66, 0x87, 0xdf, 0x57, 0x5f, 0xb5, 0xb1, 0x27,
- 0xbd, 0x6d, 0xeb, 0x66, 0x1d, 0xd9, 0x07, 0x71,
- 0x8b, 0xa0, 0x65, 0xc7, 0xda, 0x66, 0x76, 0xd1 },
- { 0x15, 0x5a, 0x88, 0x39, 0x60, 0x8b, 0x77, 0x25,
- 0x34, 0x6a, 0x72, 0x40, 0xe4, 0xe2, 0x50, 0x3a,
- 0xcc, 0x7b, 0x8b, 0xef, 0x0b, 0x1b, 0xe6, 0x15,
- 0xb9, 0x02, 0x4a, 0x88, 0xe6, 0x52, 0x11, 0xf9 },
- { 0x15, 0x5d, 0x88, 0x6e, 0x99, 0x1d, 0x40, 0x0a,
- 0xbf, 0x2f, 0x83, 0xc2, 0x80, 0xd1, 0x24, 0x6d,
- 0xce, 0x02, 0xa6, 0x28, 0x31, 0x26, 0xc6, 0x17,
- 0xe4, 0x17, 0xd2, 0xb7, 0xea, 0xc1, 0x19, 0x24 },
- { 0x17, 0x3d, 0xe2, 0x60, 0xe2, 0x2d, 0x76, 0x9d,
- 0x2d, 0x54, 0x99, 0xc8, 0x22, 0x0d, 0x86, 0xed,
- 0xe3, 0x48, 0xda, 0x1e, 0x57, 0xc1, 0xe7, 0xc8,
- 0x15, 0x07, 0xfb, 0x3e, 0x6b, 0xd7, 0x3b, 0x7f },
- { 0x18, 0x1e, 0xbb, 0x29, 0x8d, 0x20, 0x68, 0x5c,
- 0x48, 0xf7, 0x53, 0x89, 0x80, 0xc5, 0x63, 0xc8,
- 0xf7, 0x48, 0x95, 0x4c, 0xf2, 0x64, 0x41, 0x9a,
- 0x72, 0xfc, 0xc6, 0x34, 0x0a, 0x10, 0x23, 0x80 },
- { 0x19, 0xff, 0xe6, 0xc6, 0x7a, 0x35, 0x86, 0xfc,
- 0x48, 0x6c, 0xe2, 0x07, 0xfa, 0x2a, 0xf6, 0x62,
- 0xf5, 0x50, 0xfc, 0x51, 0x2f, 0xdd, 0x78, 0x17,
- 0xe3, 0x86, 0xc9, 0x4a, 0x7b, 0xde, 0x37, 0xa9 },
- { 0x1a, 0x9e, 0xc6, 0x8c, 0xed, 0xb6, 0xbd, 0x94,
- 0x0c, 0x95, 0x34, 0xe6, 0x84, 0xbb, 0x04, 0x9f,
- 0xf1, 0xe2, 0x3b, 0x66, 0xa1, 0x33, 0x01, 0x2f,
- 0xc3, 0x99, 0xeb, 0x4f, 0xb5, 0xd3, 0xaa, 0x35 },
- { 0x1b, 0x7b, 0xf8, 0xd9, 0xe8, 0x29, 0x3c, 0x53,
- 0xdd, 0x59, 0xec, 0x97, 0xfe, 0x16, 0xf0, 0xea,
- 0xb4, 0x68, 0x5b, 0x95, 0xce, 0x14, 0xd2, 0x62,
- 0x3e, 0x70, 0x94, 0x2c, 0xff, 0x25, 0xe7, 0x30 },
- { 0x1b, 0xd7, 0xb3, 0x62, 0xbc, 0x14, 0x66, 0xfa,
- 0xc0, 0x5e, 0xc5, 0x9e, 0x12, 0xe8, 0x1b, 0xe7,
- 0x35, 0x38, 0xc4, 0x97, 0x28, 0xf5, 0xad, 0xba,
- 0x2d, 0x81, 0xfc, 0xdb, 0xc4, 0x65, 0x7c, 0x1b },
- { 0x1b, 0xec, 0xfe, 0x78, 0xce, 0x5e, 0x77, 0xa9,
- 0x77, 0xbb, 0x5f, 0xe3, 0x49, 0x91, 0x06, 0xc6,
- 0x4c, 0xf2, 0xb0, 0x76, 0x16, 0x59, 0x49, 0x04,
- 0x11, 0x17, 0xcd, 0x8a, 0xbc, 0xd9, 0x05, 0xd4 },
- { 0x1b, 0xf4, 0x8a, 0x83, 0x3c, 0xe4, 0x05, 0x64,
- 0x8c, 0xc0, 0xbd, 0xd3, 0xb5, 0xb8, 0xc1, 0x8e,
- 0xb5, 0x13, 0x15, 0x34, 0x29, 0x3a, 0xb2, 0x63,
- 0x44, 0xb5, 0x00, 0x76, 0x48, 0x11, 0x41, 0xed },
- { 0x1c, 0x04, 0x82, 0x0f, 0x7b, 0x4a, 0x2f, 0x1e,
- 0x38, 0x5d, 0xe1, 0xde, 0x16, 0xb2, 0x22, 0x6e,
- 0x88, 0x3d, 0x9c, 0x34, 0x66, 0x3e, 0x1b, 0x64,
- 0xe8, 0x5b, 0x98, 0x0e, 0xaf, 0xf0, 0xb9, 0xd3 },
- { 0x1d, 0x9e, 0xc0, 0x06, 0xa5, 0x26, 0xfa, 0xb5,
- 0xce, 0x2e, 0x71, 0xfd, 0xfc, 0x07, 0xc0, 0x11,
- 0xf7, 0x65, 0x7b, 0xf8, 0x5f, 0x5d, 0x03, 0x52,
- 0xb8, 0xcb, 0x21, 0x8d, 0x4f, 0xcb, 0xc4, 0x43 },
- { 0x1e, 0x78, 0xf8, 0x08, 0x84, 0xe3, 0x2a, 0x2e,
- 0xa5, 0xad, 0x1e, 0xe8, 0x35, 0x88, 0xac, 0xdb,
- 0x18, 0x4a, 0x4a, 0x6e, 0x87, 0x56, 0x5b, 0xf5,
- 0x03, 0xb5, 0x69, 0x7a, 0xbf, 0xae, 0x64, 0xa4 },
- { 0x1f, 0x11, 0x85, 0xa5, 0x21, 0xe2, 0x8e, 0x95,
- 0x17, 0x1c, 0xf3, 0x86, 0x07, 0x8a, 0x76, 0x4a,
- 0x9a, 0x3e, 0x71, 0xc2, 0x59, 0xbc, 0xdc, 0x5f,
- 0x8e, 0x66, 0xe1, 0xb5, 0x20, 0x55, 0xa2, 0x6d },
- { 0x1f, 0x23, 0xd7, 0xa6, 0x38, 0x17, 0x1f, 0x6d,
- 0x09, 0x99, 0x64, 0xe0, 0xfa, 0x01, 0x72, 0x1c,
- 0x06, 0xcc, 0xeb, 0x8e, 0xa2, 0x98, 0xbf, 0xd0,
- 0x04, 0x8e, 0x13, 0x8d, 0x98, 0xfc, 0x36, 0x24 },
- { 0x1f, 0xc7, 0xf8, 0x10, 0x4e, 0x27, 0xff, 0x2a,
- 0x45, 0x56, 0xf9, 0x1e, 0x05, 0x42, 0x17, 0xc5,
- 0x8f, 0x69, 0x3f, 0x70, 0x36, 0x25, 0x9e, 0x39,
- 0x80, 0xb5, 0x59, 0x5b, 0x04, 0x3d, 0x11, 0x92 },
- { 0x20, 0x0b, 0x49, 0xbd, 0xd6, 0x35, 0x02, 0x57,
- 0xcc, 0xd4, 0xe6, 0xad, 0xe1, 0xcb, 0x75, 0x13,
- 0x8d, 0xd6, 0xd9, 0x06, 0xfe, 0xf3, 0x49, 0xc0,
- 0xc9, 0x86, 0xa5, 0x1b, 0x29, 0xb9, 0xe5, 0x2d },
- { 0x21, 0x78, 0xe8, 0x28, 0x3a, 0x73, 0x39, 0x6e,
- 0x08, 0xc0, 0xa1, 0x1a, 0x88, 0x72, 0xfa, 0x4a,
- 0x9f, 0xcc, 0x05, 0x67, 0x0c, 0xee, 0xff, 0xb8,
- 0x95, 0x83, 0x8e, 0xb6, 0x59, 0xde, 0x38, 0xdb },
- { 0x22, 0x01, 0x71, 0xf7, 0x0e, 0x1f, 0xc3, 0xc4,
- 0xf7, 0x8d, 0xa6, 0xc8, 0xb1, 0xd7, 0x2c, 0x3b,
- 0xa8, 0x31, 0x9a, 0x46, 0xf8, 0x19, 0x2d, 0x1e,
- 0x19, 0xb9, 0xe2, 0x9a, 0xba, 0x18, 0xee, 0x87 },
- { 0x23, 0x19, 0xcb, 0x3d, 0x58, 0xc6, 0xd5, 0x53,
- 0x62, 0x5d, 0xe5, 0xf4, 0x25, 0x2b, 0xf0, 0x29,
- 0xab, 0x83, 0x05, 0xeb, 0xf2, 0x2f, 0xa2, 0x3e,
- 0x99, 0x73, 0x04, 0x66, 0xde, 0x24, 0xd6, 0xc3 },
- { 0x23, 0x8a, 0x80, 0xcc, 0x9b, 0x58, 0x9a, 0xdc,
- 0x89, 0xb7, 0xa8, 0xf3, 0x4d, 0xdf, 0x12, 0x48,
- 0x73, 0x4b, 0x9f, 0x7f, 0x78, 0x20, 0xb6, 0x04,
- 0x07, 0x66, 0xc5, 0x41, 0x3a, 0xd2, 0xbd, 0xef },
- { 0x23, 0x9c, 0x79, 0x5f, 0x0c, 0x55, 0xa5, 0x53,
- 0x16, 0x2a, 0x9c, 0xa0, 0x6e, 0x88, 0x01, 0xe1,
- 0x19, 0xbd, 0xff, 0x54, 0x35, 0x4a, 0x3f, 0x68,
- 0x43, 0xcf, 0x2a, 0x2f, 0xa6, 0x01, 0x75, 0x8e },
- { 0x24, 0x62, 0x52, 0x48, 0x32, 0xc1, 0x54, 0xd8,
- 0x4d, 0xf5, 0x8e, 0xd7, 0x75, 0x22, 0x3b, 0xbe,
- 0x25, 0x7d, 0xea, 0xf7, 0x0e, 0xf9, 0xd2, 0x08,
- 0x61, 0x4e, 0xc0, 0xf5, 0x97, 0x7f, 0x6d, 0x58 },
- { 0x24, 0x6d, 0x0c, 0x31, 0x48, 0x72, 0x75, 0x59,
- 0xf9, 0x9a, 0xd0, 0xc1, 0x50, 0x37, 0x70, 0x06,
- 0xb7, 0xa1, 0x7a, 0x60, 0x3a, 0x47, 0x3b, 0x6a,
- 0xac, 0xd2, 0x4e, 0x16, 0xc6, 0xc5, 0x1b, 0x42 },
- { 0x25, 0x1b, 0xb7, 0xc5, 0x42, 0x33, 0xda, 0x44,
- 0xbf, 0x53, 0xb5, 0x8a, 0xf2, 0x9a, 0xe1, 0x74,
- 0xb9, 0x78, 0xba, 0xdb, 0x89, 0xa9, 0x50, 0xab,
- 0x3e, 0x5f, 0x9b, 0x4d, 0x0d, 0xcd, 0xbc, 0x62 },
- { 0x26, 0x03, 0xcb, 0xdf, 0x69, 0x75, 0xe3, 0x68,
- 0x83, 0x7f, 0x95, 0x1a, 0x00, 0x49, 0xfd, 0xc3,
- 0xc4, 0xb2, 0x39, 0xf0, 0x82, 0xf6, 0xbf, 0x89,
- 0x5d, 0xb8, 0xf3, 0x27, 0x05, 0xe6, 0x9c, 0xf3 },
- { 0x27, 0x50, 0x11, 0x93, 0xe4, 0x61, 0xca, 0xce,
- 0x55, 0x32, 0xfa, 0xd5, 0xd5, 0xb2, 0x7e, 0x01,
- 0x16, 0x57, 0x92, 0xe0, 0x4f, 0x24, 0x21, 0x93,
- 0x2f, 0x39, 0x28, 0xaf, 0x9f, 0xcd, 0xa4, 0xf3 },
- { 0x27, 0xa8, 0x41, 0xae, 0xcf, 0xe0, 0xa1, 0x39,
- 0x37, 0x51, 0xc2, 0x55, 0xf9, 0x06, 0xdb, 0x9e,
- 0x88, 0x6b, 0xba, 0x4d, 0x7c, 0x44, 0xec, 0x63,
- 0xce, 0x7d, 0xc6, 0xde, 0xc1, 0x8b, 0xb9, 0x20 },
- { 0x28, 0x07, 0x10, 0x60, 0x44, 0x03, 0x45, 0xd0,
- 0x0e, 0x80, 0xb9, 0xd7, 0xcb, 0xe1, 0x87, 0xc1,
- 0xd8, 0xb0, 0xf2, 0xef, 0x5d, 0x0a, 0xac, 0x9c,
- 0xce, 0xef, 0x9a, 0x8c, 0x5a, 0x06, 0xf3, 0x02 },
- { 0x28, 0xd9, 0x51, 0x84, 0xb5, 0xea, 0x14, 0x0f,
- 0x47, 0x4f, 0x3a, 0xf6, 0xce, 0x70, 0x52, 0xe8,
- 0x59, 0x3c, 0xf3, 0xa5, 0x01, 0x0f, 0x52, 0x24,
- 0x1a, 0x1e, 0x36, 0x64, 0x60, 0xe5, 0x91, 0x9e },
- { 0x29, 0x01, 0x93, 0xe3, 0x7a, 0x38, 0x87, 0xfd,
- 0x36, 0x15, 0xdf, 0x12, 0x2e, 0x95, 0x21, 0x17,
- 0x42, 0x15, 0xee, 0x68, 0xf7, 0x44, 0xb2, 0xfa,
- 0x35, 0xd2, 0x9c, 0x5d, 0xf1, 0x08, 0xf5, 0x5b },
- { 0x2a, 0x0f, 0x70, 0x67, 0x6e, 0x18, 0x4d, 0x49,
- 0x39, 0xa4, 0x04, 0xde, 0x35, 0xac, 0x84, 0xab,
- 0x81, 0xaf, 0xec, 0x36, 0x17, 0xe7, 0xe1, 0xbf,
- 0x34, 0x67, 0xd4, 0x19, 0x25, 0x5d, 0xd8, 0x17 },
- { 0x2a, 0xa6, 0x47, 0x8c, 0xc7, 0x5d, 0x67, 0xa8,
- 0xca, 0x55, 0xb2, 0xe1, 0x63, 0xfd, 0xbb, 0xbc,
- 0x9d, 0x74, 0xb4, 0xe5, 0xf3, 0x7b, 0x7d, 0xbd,
- 0x13, 0xc9, 0x4e, 0x85, 0x8d, 0x40, 0xda, 0xd0 },
- { 0x2c, 0x82, 0x47, 0x4f, 0x0e, 0xf6, 0xcb, 0x65,
- 0x0a, 0x13, 0xef, 0x20, 0x99, 0x6e, 0x65, 0x7b,
- 0x67, 0x24, 0xf0, 0xa0, 0xd5, 0xee, 0x24, 0x6d,
- 0x26, 0xbb, 0xfa, 0x0a, 0xbb, 0x2c, 0x22, 0xe1 },
- { 0x2c, 0x9b, 0xe1, 0x2d, 0xa4, 0x99, 0xea, 0xbb,
- 0x2f, 0xfd, 0xf9, 0x91, 0x6f, 0x2b, 0x27, 0x18,
- 0x81, 0x19, 0x5b, 0x74, 0x19, 0xbd, 0x1e, 0xef,
- 0x8d, 0x50, 0x77, 0x2a, 0xb9, 0x46, 0x4a, 0xa8 },
- { 0x2c, 0xbd, 0xd5, 0x6c, 0xe4, 0xb4, 0x06, 0x09,
- 0xe9, 0xaa, 0x52, 0x1e, 0xaa, 0x76, 0xac, 0x7e,
- 0x55, 0x73, 0x7b, 0xf4, 0x3e, 0x2b, 0x0c, 0x30,
- 0xdd, 0xcf, 0x59, 0x87, 0x2e, 0xab, 0xe7, 0x7b },
- { 0x2d, 0xde, 0xe4, 0x5f, 0x72, 0x78, 0x38, 0xde,
- 0xad, 0xe6, 0x7e, 0x9c, 0xa7, 0x05, 0xeb, 0xb4,
- 0xc2, 0xe9, 0x40, 0xae, 0x1b, 0x9d, 0x62, 0x35,
- 0x72, 0x18, 0x04, 0x58, 0x31, 0xe9, 0x8f, 0xde },
- { 0x2e, 0x5d, 0xd2, 0x55, 0x09, 0x6d, 0x64, 0x83,
- 0x10, 0x5c, 0xb6, 0x03, 0x6c, 0x59, 0x17, 0x57,
- 0xfd, 0x98, 0x49, 0x70, 0x66, 0x05, 0x3f, 0x83,
- 0x39, 0xe4, 0xd8, 0xd0, 0xc3, 0x75, 0x49, 0x03 },
- { 0x2e, 0xd2, 0x05, 0x8f, 0x39, 0xea, 0xba, 0x5c,
- 0xb3, 0xd7, 0xdf, 0x24, 0xca, 0x74, 0xa7, 0x7d,
- 0xdc, 0x12, 0x06, 0x01, 0x52, 0x7b, 0x0f, 0x51,
- 0x06, 0x91, 0x05, 0xca, 0x88, 0x37, 0x6e, 0x20 },
- { 0x30, 0x7b, 0x09, 0x34, 0xef, 0x97, 0x85, 0xe7,
- 0x08, 0xed, 0x48, 0x1a, 0x99, 0x7a, 0x8a, 0x88,
- 0xb7, 0xbf, 0x22, 0xdd, 0x26, 0xaa, 0x17, 0x17,
- 0x31, 0xb8, 0xf7, 0xe0, 0xd5, 0x97, 0xb7, 0x08 },
- { 0x30, 0xe0, 0x69, 0x80, 0x9c, 0x79, 0x90, 0xf0,
- 0xb5, 0xf2, 0x66, 0xe8, 0x94, 0x59, 0x96, 0x42,
- 0xe8, 0x53, 0x50, 0xab, 0x82, 0x81, 0x05, 0x34,
- 0xc7, 0xf3, 0xfd, 0x67, 0x0c, 0x1b, 0xeb, 0x18 },
- { 0x31, 0x53, 0x47, 0x52, 0xb6, 0xf5, 0x48, 0x20,
- 0x91, 0x5c, 0x39, 0x5b, 0xee, 0x97, 0x5b, 0xc5,
- 0x4e, 0x3f, 0x07, 0xc0, 0x8c, 0xd3, 0x4c, 0x5a,
- 0x51, 0x15, 0xde, 0xf0, 0x17, 0xdb, 0x2b, 0x54 },
- { 0x31, 0xb8, 0x3e, 0x01, 0x90, 0x98, 0x95, 0xbc,
- 0x74, 0x2d, 0x6b, 0xe8, 0x40, 0x0a, 0xde, 0x51,
- 0xb2, 0x09, 0x83, 0xf6, 0x83, 0xa2, 0xaa, 0xee,
- 0xb2, 0x5f, 0x58, 0xdf, 0x98, 0x1b, 0xde, 0x0d },
- { 0x32, 0xef, 0x13, 0x33, 0x86, 0xbf, 0x0c, 0x63,
- 0xcf, 0x29, 0xd6, 0x2b, 0x0d, 0x76, 0x88, 0x9e,
- 0x9d, 0x9d, 0x53, 0x2e, 0xe4, 0x90, 0x38, 0x94,
- 0x4d, 0xbc, 0x21, 0x49, 0xd8, 0xca, 0xa5, 0xd1 },
- { 0x33, 0xd1, 0x6c, 0xd9, 0xe8, 0x2e, 0xdf, 0xfd,
- 0x0b, 0x3a, 0xfb, 0x46, 0xa6, 0x84, 0xc5, 0xa0,
- 0xd1, 0x2f, 0x2b, 0x40, 0x58, 0x6d, 0x53, 0x2f,
- 0x6a, 0xab, 0x54, 0xce, 0xbc, 0x42, 0x33, 0xd3 },
- { 0x34, 0x06, 0x4f, 0xf9, 0x3b, 0x27, 0x4c, 0xf5,
- 0xa7, 0x24, 0xec, 0x19, 0x64, 0x50, 0x4a, 0x71,
- 0x0a, 0xb9, 0x7b, 0xa1, 0x10, 0x3c, 0xd9, 0xb9,
- 0x8c, 0x81, 0xd0, 0xab, 0xcf, 0x3b, 0x19, 0xbd },
- { 0x34, 0x65, 0xc2, 0xf9, 0xa0, 0xcf, 0x36, 0xe5,
- 0xee, 0xf0, 0x27, 0x1c, 0x52, 0x91, 0x2d, 0x58,
- 0x6f, 0xb2, 0x0b, 0x94, 0x43, 0xe7, 0xd5, 0x82,
- 0xa3, 0xe2, 0x23, 0x93, 0xfa, 0xc8, 0x1b, 0xb4 },
- { 0x34, 0x87, 0x46, 0xbf, 0xd4, 0x98, 0xc3, 0xf5,
- 0xc8, 0x68, 0x5e, 0xea, 0xac, 0x57, 0x87, 0x2d,
- 0x3b, 0x47, 0xe6, 0x02, 0xf4, 0x97, 0xe9, 0xf0,
- 0x28, 0x54, 0x12, 0x32, 0x59, 0xfb, 0xe1, 0x69 },
- { 0x36, 0x45, 0xef, 0x7f, 0x5d, 0x15, 0xa5, 0x46,
- 0x7e, 0x85, 0x30, 0x7d, 0xda, 0x15, 0xcb, 0xbb,
- 0x55, 0xb7, 0x30, 0xae, 0xf8, 0xef, 0x9c, 0x71,
- 0x5d, 0x7d, 0x9f, 0xb4, 0x7f, 0xdf, 0x33, 0xad },
- { 0x36, 0xb4, 0xfe, 0x74, 0x3b, 0x6d, 0xf4, 0x4a,
- 0x71, 0x3e, 0x91, 0x4c, 0xab, 0xfb, 0xf2, 0xbe,
- 0x60, 0x24, 0x9b, 0x46, 0x43, 0x4d, 0x04, 0x43,
- 0x59, 0x12, 0x5a, 0x10, 0x6a, 0x37, 0xeb, 0x1c },
- { 0x36, 0xf5, 0xa9, 0x7d, 0x79, 0x3f, 0x84, 0x97,
- 0x44, 0xd6, 0xab, 0x39, 0xb7, 0xa8, 0x18, 0xf8,
- 0x17, 0x6e, 0x65, 0x20, 0xdc, 0x86, 0x3d, 0xce,
- 0x43, 0xb3, 0x98, 0xc3, 0x0b, 0x5e, 0xdb, 0x09 },
- { 0x38, 0x23, 0x4e, 0x55, 0x9d, 0x30, 0x27, 0xd1,
- 0x61, 0xda, 0x8c, 0x98, 0x88, 0x04, 0x9a, 0x4d,
- 0x20, 0xac, 0xf2, 0x00, 0x90, 0xad, 0x1a, 0x22,
- 0x2b, 0x73, 0x9a, 0xc8, 0x6e, 0xb7, 0x6f, 0x06 },
- { 0x39, 0x02, 0x27, 0xce, 0x88, 0x1c, 0x71, 0x8b,
- 0x59, 0xa6, 0xbc, 0x31, 0x90, 0xd5, 0x17, 0xe7,
- 0x1e, 0x1e, 0x58, 0x66, 0x93, 0xc8, 0xbf, 0x8a,
- 0x30, 0x27, 0x26, 0x20, 0x13, 0xfe, 0x16, 0x63 },
- { 0x39, 0x21, 0x5c, 0xaa, 0x37, 0x1a, 0xbe, 0x57,
- 0x6a, 0xb9, 0x3b, 0x18, 0xc2, 0xf3, 0x75, 0x5e,
- 0xe2, 0x6f, 0x8c, 0x3a, 0xdb, 0x75, 0x9b, 0x6f,
- 0x34, 0x78, 0x9f, 0xb8, 0xec, 0xf0, 0x54, 0x28 },
- { 0x39, 0x7d, 0x00, 0x6e, 0xf8, 0xaf, 0xb2, 0x0f,
- 0x43, 0x61, 0xa6, 0xc9, 0x72, 0xf0, 0xc5, 0x7c,
- 0xc0, 0x87, 0x74, 0x01, 0x06, 0x12, 0x78, 0x3f,
- 0xba, 0xbc, 0xb8, 0xd6, 0xf6, 0x03, 0x9e, 0x2c },
- { 0x3a, 0xcf, 0x85, 0x3c, 0x4e, 0x45, 0x02, 0xbd,
- 0x82, 0xd5, 0x85, 0xd5, 0xe0, 0x82, 0xc4, 0xb3,
- 0xad, 0x03, 0xcd, 0xb6, 0xb5, 0x05, 0xca, 0x80,
- 0x47, 0x19, 0x88, 0xec, 0x4c, 0x58, 0x99, 0x9e },
- { 0x3a, 0xea, 0x2c, 0xef, 0xae, 0x63, 0x44, 0xff,
- 0xae, 0x67, 0x49, 0x4c, 0x68, 0x4e, 0x1e, 0xbf,
- 0x87, 0x95, 0x40, 0xb5, 0x3d, 0x40, 0xf5, 0x16,
- 0x9f, 0x78, 0x89, 0x7f, 0x1b, 0x38, 0xab, 0x66 },
- { 0x3b, 0x47, 0x85, 0x0b, 0xf8, 0x4c, 0x4c, 0xf2,
- 0xca, 0x6c, 0x31, 0xb3, 0x78, 0x39, 0xc9, 0x50,
- 0x76, 0x63, 0x70, 0xd7, 0xf4, 0xb6, 0x4a, 0xd0,
- 0x18, 0x55, 0xca, 0xcf, 0xe3, 0x51, 0x2f, 0xc3 },
- { 0x3b, 0xaa, 0x31, 0x31, 0x70, 0x68, 0xac, 0xe0,
- 0x89, 0xae, 0xb4, 0xa8, 0x8d, 0x7e, 0xde, 0xbe,
- 0x94, 0xab, 0x4a, 0xce, 0x46, 0xbb, 0xd2, 0x68,
- 0x3e, 0x3f, 0xdf, 0xf5, 0x59, 0x30, 0x0f, 0x93 },
- { 0x3c, 0x38, 0x36, 0x2e, 0x16, 0x8b, 0xb4, 0xa7,
- 0x59, 0xc4, 0x80, 0x55, 0x1c, 0xb1, 0x65, 0x6f,
- 0x6a, 0x96, 0x8b, 0x9b, 0x43, 0xcb, 0xe0, 0xd7,
- 0x39, 0x75, 0x4a, 0xb7, 0x8a, 0x28, 0x87, 0x0e },
- { 0x3c, 0x84, 0xa8, 0xb3, 0x4d, 0x0f, 0x95, 0xca,
- 0xc6, 0xfa, 0xaa, 0xb6, 0x22, 0xc2, 0x74, 0x46,
- 0xb4, 0xc4, 0x72, 0xdf, 0x34, 0x53, 0xd7, 0x54,
- 0x64, 0xc0, 0x96, 0x23, 0x86, 0x56, 0xb9, 0xd4 },
- { 0x3d, 0x14, 0x47, 0x2d, 0xce, 0x4a, 0xfd, 0xc2,
- 0x27, 0x6c, 0x81, 0x47, 0x97, 0xc7, 0xbc, 0x7a,
- 0x6c, 0x14, 0xf7, 0x95, 0x3e, 0x7e, 0x9f, 0xea,
- 0x69, 0x51, 0x04, 0x0f, 0x2d, 0xaf, 0xbe, 0x9a },
- { 0x3e, 0x8e, 0x9b, 0xad, 0x8e, 0xd9, 0xb5, 0x72,
- 0x38, 0x2e, 0x59, 0x8d, 0x2d, 0x73, 0x67, 0xe1,
- 0xfd, 0x6a, 0xf6, 0x95, 0x25, 0x00, 0x9d, 0x67,
- 0xb4, 0xe8, 0xaf, 0x80, 0xd9, 0x15, 0x85, 0x49 },
- { 0x3f, 0x27, 0xbd, 0xca, 0x9b, 0x0e, 0x42, 0xf3,
- 0xf6, 0xd0, 0x91, 0x2c, 0x92, 0xe2, 0xda, 0x65,
- 0xcb, 0x35, 0x8f, 0x0b, 0x8f, 0x80, 0x5b, 0xec,
- 0x5d, 0xe9, 0x32, 0x51, 0xd9, 0xc4, 0xb1, 0x99 },
- { 0x3f, 0x2e, 0xa6, 0x4e, 0xfb, 0xd6, 0xbf, 0xc4,
- 0x0a, 0xf0, 0xad, 0x46, 0xa4, 0xa2, 0x57, 0x84,
- 0x19, 0xd8, 0x68, 0x6e, 0x38, 0x98, 0x8b, 0x91,
- 0x47, 0x01, 0x8c, 0x36, 0x29, 0x31, 0xe4, 0xf9 },
- { 0x3f, 0x4f, 0x28, 0x8b, 0xaf, 0x5b, 0xde, 0x86,
- 0x72, 0xd6, 0xad, 0xd1, 0x50, 0xe3, 0x23, 0x79,
- 0x49, 0x9a, 0x16, 0xc5, 0x81, 0xfb, 0x77, 0x37,
- 0xec, 0x49, 0x80, 0xe4, 0xf9, 0xc3, 0x3d, 0x4d },
- { 0x3f, 0x92, 0x54, 0x89, 0x64, 0xcc, 0xde, 0xfb,
- 0x29, 0x96, 0x5a, 0x27, 0xc1, 0x6c, 0x2f, 0xed,
- 0x28, 0xd9, 0xb9, 0x14, 0x0e, 0x4f, 0xb5, 0x5b,
- 0x37, 0x22, 0x4c, 0x67, 0xb2, 0xa0, 0x55, 0x1f },
- { 0x40, 0x58, 0xec, 0x4a, 0x7a, 0x7b, 0xa0, 0xb8,
- 0x65, 0xa7, 0x39, 0xa0, 0x0c, 0x85, 0xf3, 0x44,
- 0x58, 0x79, 0xd6, 0x5e, 0x1d, 0x42, 0x2e, 0xed,
- 0x07, 0x65, 0x5a, 0x8e, 0x3e, 0xc3, 0x18, 0xcf },
- { 0x41, 0x29, 0x6b, 0x9f, 0xaa, 0xd6, 0x41, 0x33,
- 0xfc, 0xcb, 0xa6, 0xba, 0x74, 0x54, 0x11, 0xec,
- 0xc9, 0x11, 0xfd, 0x8e, 0xd5, 0x41, 0x90, 0x0f,
- 0x9e, 0x20, 0x36, 0x08, 0xee, 0xa3, 0x59, 0x2d },
- { 0x41, 0x88, 0x71, 0x80, 0x7e, 0xdc, 0xed, 0xa8,
- 0x57, 0xd7, 0xe8, 0x48, 0x31, 0x71, 0x81, 0xe1,
- 0xe8, 0x33, 0xf5, 0x4c, 0x89, 0xa6, 0x11, 0xa2,
- 0x30, 0xad, 0x99, 0x06, 0x5d, 0x45, 0x86, 0x95 },
- { 0x41, 0xa6, 0x8d, 0xfd, 0x90, 0xda, 0x6d, 0x12,
- 0x09, 0x84, 0x85, 0xbf, 0x6f, 0x87, 0x24, 0x5f,
- 0x4e, 0xc0, 0x54, 0x71, 0xda, 0x59, 0xd0, 0x81,
- 0x06, 0x01, 0x53, 0xa2, 0x22, 0x25, 0x23, 0x7f },
- { 0x42, 0x08, 0x71, 0xd8, 0xac, 0x49, 0x3c, 0xf9,
- 0x46, 0x8b, 0xb3, 0x76, 0x97, 0x6d, 0x65, 0x5e,
- 0xf0, 0xaf, 0xaa, 0xc2, 0x3d, 0x77, 0x00, 0x92,
- 0x20, 0xc3, 0xaf, 0x8b, 0xdd, 0x37, 0x5a, 0x24 },
- { 0x42, 0x5d, 0x4e, 0xbf, 0x1b, 0xde, 0x0b, 0xf8,
- 0xd1, 0xdb, 0xd3, 0x3d, 0x8d, 0x16, 0x34, 0xc4,
- 0xfa, 0xfe, 0xb6, 0xf8, 0x05, 0xf1, 0xcc, 0xb5,
- 0x34, 0xac, 0xb7, 0x2a, 0xed, 0xa2, 0xcd, 0x0a },
- { 0x44, 0x12, 0x63, 0x80, 0xa0, 0x73, 0xfe, 0xa1,
- 0xa2, 0x00, 0x4f, 0x71, 0x1d, 0xf2, 0xca, 0x47,
- 0xc2, 0xc4, 0xb4, 0xff, 0x64, 0x4e, 0x76, 0xaf,
- 0xbe, 0x27, 0x97, 0xc9, 0x63, 0x7c, 0x6a, 0xf9 },
- { 0x44, 0x25, 0xdd, 0xfb, 0xba, 0xfb, 0xe1, 0xaa,
- 0xce, 0x25, 0x85, 0x70, 0x48, 0x96, 0x9d, 0xc8,
- 0x9d, 0xf5, 0x97, 0x7b, 0xb2, 0xe3, 0x34, 0x7c,
- 0x9c, 0xeb, 0x0e, 0x5a, 0x7b, 0x68, 0xc5, 0x31 },
- { 0x45, 0x63, 0xcf, 0x13, 0xc2, 0x49, 0x2c, 0xaa,
- 0x92, 0xf5, 0x5b, 0x17, 0x26, 0x3a, 0xdd, 0x72,
- 0x04, 0xa8, 0x0f, 0xe6, 0x24, 0x0c, 0x4d, 0x63,
- 0xe8, 0x39, 0x59, 0x58, 0xf6, 0x94, 0xcd, 0x33 },
- { 0x45, 0xcb, 0x86, 0xca, 0x97, 0x52, 0x29, 0xb7,
- 0xd5, 0xda, 0xfc, 0x05, 0xeb, 0x0c, 0x53, 0x65,
- 0x82, 0x3a, 0x91, 0xa9, 0x8b, 0x7d, 0xbe, 0x81,
- 0xab, 0x5f, 0x17, 0x8b, 0x2d, 0xa4, 0xad, 0x9e },
- { 0x46, 0x9b, 0xd8, 0x04, 0xe9, 0x98, 0xae, 0x27,
- 0x9a, 0xc3, 0xfe, 0x1b, 0x52, 0x88, 0x46, 0xe7,
- 0xae, 0xc7, 0x6c, 0x56, 0xb8, 0x0b, 0x40, 0xf3,
- 0x24, 0x20, 0x8f, 0x5a, 0x9f, 0x64, 0x5c, 0xb5 },
- { 0x46, 0xcd, 0x08, 0x08, 0x8d, 0x36, 0x06, 0x2c,
- 0x56, 0x71, 0x09, 0x2c, 0x02, 0x76, 0x7a, 0x25,
- 0x0d, 0xe7, 0x0b, 0xf3, 0xe1, 0x53, 0x63, 0x69,
- 0x66, 0xe6, 0x6e, 0xc5, 0x7e, 0x8e, 0xe9, 0xf5 },
- { 0x47, 0x84, 0xf6, 0xcd, 0x59, 0x3d, 0x7b, 0x31,
- 0x2e, 0xb1, 0xf6, 0x19, 0xe1, 0x11, 0xdf, 0x3b,
- 0x48, 0x6d, 0x1b, 0xf8, 0x37, 0x15, 0xad, 0x8d,
- 0xab, 0xa5, 0x72, 0xaf, 0xb2, 0x61, 0xd5, 0xbe },
- { 0x47, 0x8c, 0xdd, 0x82, 0x3f, 0x81, 0x7d, 0x21,
- 0x8b, 0xf5, 0xdd, 0xa4, 0xc3, 0xe9, 0x9e, 0x7f,
- 0xa3, 0x10, 0x9b, 0x67, 0xbd, 0x0c, 0x9b, 0x1f,
- 0x40, 0x75, 0x96, 0x65, 0xb9, 0xec, 0x3f, 0xf2 },
- { 0x48, 0xc5, 0xd4, 0xff, 0x5d, 0x08, 0x4a, 0xc1,
- 0x95, 0xb1, 0xa6, 0xa2, 0x19, 0xf8, 0x1b, 0xbd,
- 0xf9, 0xd2, 0xe5, 0xc0, 0x70, 0xec, 0x97, 0xdf,
- 0x3c, 0xb0, 0xb7, 0x3e, 0xf4, 0x70, 0xdc, 0xe9 },
- { 0x49, 0xdc, 0xf8, 0xfa, 0x68, 0xe9, 0x2b, 0x5c,
- 0x21, 0xfe, 0xf9, 0x3d, 0x26, 0x0c, 0x24, 0x8c,
- 0xe3, 0xbe, 0x98, 0x62, 0x68, 0x68, 0xe7, 0x5a,
- 0x3f, 0x63, 0x34, 0xbb, 0x7d, 0xc1, 0x81, 0xec },
- { 0x4b, 0x1f, 0xc8, 0x2d, 0x24, 0x72, 0x92, 0x7a,
- 0xc1, 0x7c, 0x58, 0x43, 0x07, 0xcb, 0x96, 0xd6,
- 0xfd, 0xdb, 0x8d, 0x50, 0xa5, 0x29, 0x53, 0x07,
- 0xd3, 0x0c, 0x75, 0x88, 0x59, 0x6a, 0xd4, 0x0b },
- { 0x4b, 0x51, 0xfc, 0x11, 0x4b, 0xac, 0x8e, 0x2d,
- 0x2a, 0xf2, 0xae, 0x56, 0x84, 0x42, 0x9c, 0xca,
- 0xab, 0x21, 0x39, 0xc9, 0xb3, 0x51, 0xbf, 0x7e,
- 0x1b, 0x03, 0x0a, 0xe8, 0x62, 0x4a, 0xc1, 0x72 },
- { 0x4c, 0xd0, 0xd6, 0x7e, 0xcc, 0x3b, 0x01, 0xc8,
- 0xc2, 0x63, 0x4e, 0x7a, 0x73, 0x76, 0x12, 0xf6,
- 0x3a, 0x17, 0xff, 0x51, 0x0a, 0x77, 0xa8, 0x04,
- 0xbb, 0x33, 0x1b, 0x2b, 0xe5, 0x8d, 0xfe, 0x0c },
- { 0x4d, 0xcf, 0xeb, 0xdc, 0x15, 0x4b, 0x0c, 0x85,
- 0x46, 0x7f, 0x6f, 0x52, 0xad, 0x80, 0x4e, 0x19,
- 0x1d, 0x5b, 0xc8, 0x13, 0x51, 0x72, 0x0e, 0xc0,
- 0xd1, 0x9b, 0xd2, 0x5b, 0xf8, 0xf0, 0xa5, 0x53 },
- { 0x4f, 0x19, 0xdd, 0x12, 0x92, 0x4c, 0xe0, 0xc1,
- 0x4f, 0x82, 0xc0, 0x56, 0xc7, 0xd4, 0x2b, 0xac,
- 0x43, 0xd0, 0x13, 0x3a, 0xaf, 0x89, 0xc1, 0xef,
- 0xdc, 0xfa, 0x3c, 0x3e, 0x47, 0x09, 0x7d, 0x59 },
- { 0x4f, 0xfb, 0x59, 0x19, 0xbc, 0x38, 0x5c, 0x8c,
- 0x58, 0xe4, 0x62, 0xbf, 0x13, 0x22, 0x10, 0xd8,
- 0xb7, 0x86, 0x12, 0xd0, 0xc2, 0x2a, 0x6b, 0x6a,
- 0x68, 0x2e, 0x0b, 0x9e, 0x9c, 0x9f, 0x9a, 0x44 },
- { 0x50, 0xf4, 0x78, 0x1e, 0xb1, 0xc1, 0x46, 0x70,
- 0xd9, 0xa5, 0x52, 0xc3, 0x49, 0x5f, 0xb9, 0xf6,
- 0xae, 0x86, 0x8a, 0xb1, 0xc9, 0xd9, 0x83, 0xe0,
- 0x82, 0x68, 0x65, 0xa1, 0x02, 0xec, 0xa6, 0xd3 },
- { 0x51, 0x6a, 0x2f, 0x33, 0x60, 0xc7, 0x6f, 0xc4,
- 0x6a, 0xb2, 0x88, 0x7f, 0x88, 0xe8, 0xd0, 0x8e,
- 0xfb, 0xd8, 0x44, 0x5a, 0xa7, 0xbb, 0xd2, 0x29,
- 0xdf, 0xc7, 0x1a, 0x90, 0x4f, 0x55, 0xae, 0xb4 },
- { 0x52, 0x1f, 0x6c, 0x6a, 0x84, 0x36, 0x65, 0x79,
- 0xca, 0x2d, 0xea, 0xeb, 0x23, 0x15, 0xbf, 0x8e,
- 0x53, 0x1c, 0x9f, 0xa4, 0x7b, 0x89, 0x9d, 0xa2,
- 0x72, 0x16, 0xa9, 0x98, 0x82, 0x86, 0xaf, 0xe5 },
- { 0x52, 0xff, 0x8b, 0x6e, 0x98, 0xb0, 0x96, 0x19,
- 0x90, 0x03, 0xde, 0x97, 0xbc, 0xcf, 0xd2, 0xa7,
- 0xf1, 0xac, 0x57, 0xa8, 0x31, 0x35, 0xb9, 0x55,
- 0xff, 0x68, 0x63, 0x36, 0xa6, 0x91, 0xd5, 0xca },
- { 0x53, 0x79, 0x64, 0x58, 0xda, 0x97, 0xce, 0x36,
- 0x78, 0xf2, 0xd1, 0xd9, 0xb2, 0xa5, 0xb2, 0xfb,
- 0x30, 0x75, 0xea, 0xfa, 0xf6, 0xff, 0x04, 0x78,
- 0xb5, 0x72, 0xdd, 0xfd, 0x70, 0x99, 0xae, 0xe2 },
- { 0x53, 0x82, 0xd6, 0xba, 0xb5, 0x78, 0x51, 0xd9,
- 0xb5, 0x8c, 0x17, 0x54, 0x46, 0xbf, 0x2d, 0x1b,
- 0xb7, 0x86, 0xa5, 0x30, 0xfb, 0xf0, 0xae, 0xcd,
- 0x12, 0xea, 0xb8, 0xa9, 0xa5, 0xb4, 0x96, 0x60 },
- { 0x53, 0x9c, 0xa9, 0xe1, 0xf0, 0x6a, 0xf2, 0x10,
- 0x7f, 0x96, 0xbf, 0x4b, 0x7d, 0xd4, 0xce, 0xcd,
- 0x9e, 0xd1, 0x1a, 0x38, 0xd6, 0x70, 0x91, 0x69,
- 0x9c, 0x56, 0x26, 0xe2, 0x7a, 0x1f, 0x54, 0xa5 },
- { 0x55, 0x21, 0xf9, 0x63, 0x57, 0x81, 0x58, 0xb8,
- 0xd0, 0xe7, 0xc4, 0x91, 0xcd, 0xb8, 0x5c, 0x3d,
- 0xe9, 0xd5, 0x2e, 0xa5, 0x1f, 0xfc, 0xb0, 0x93,
- 0xd3, 0x12, 0x28, 0x11, 0x13, 0x14, 0x97, 0xeb },
- { 0x55, 0xd0, 0xeb, 0xe3, 0x2c, 0xba, 0x09, 0xf6,
- 0x58, 0x4d, 0x9e, 0x7b, 0x57, 0x92, 0xa4, 0x03,
- 0xc2, 0x1d, 0x39, 0xd6, 0xe1, 0xf5, 0xe8, 0xed,
- 0x37, 0xb9, 0x3f, 0xa6, 0x1d, 0x88, 0x35, 0x16 },
- { 0x58, 0x1a, 0xde, 0x64, 0x84, 0x95, 0xb4, 0xb1,
- 0x62, 0x9c, 0x3c, 0x7c, 0x78, 0xef, 0xbe, 0xf2,
- 0x75, 0x06, 0x56, 0x65, 0xb2, 0x41, 0x1c, 0x0e,
- 0x5f, 0xcf, 0xbc, 0x7e, 0xb4, 0xbe, 0x34, 0x0b },
- { 0x59, 0xc9, 0xe8, 0xdf, 0x03, 0x0b, 0x1c, 0xd5,
- 0x89, 0xa8, 0xb3, 0x4f, 0xe7, 0x42, 0x51, 0xea,
- 0xd5, 0xa5, 0xfb, 0xe9, 0xe6, 0x13, 0x67, 0xca,
- 0x76, 0xaf, 0xd9, 0xdd, 0xd9, 0xc6, 0xf1, 0x6f },
- { 0x59, 0xe9, 0xfa, 0x2f, 0xf0, 0x76, 0x89, 0x33,
- 0x28, 0x33, 0xc6, 0x40, 0xf5, 0x05, 0xfa, 0x24,
- 0x09, 0xeb, 0x88, 0x93, 0x32, 0x57, 0xc1, 0x93,
- 0xb0, 0x07, 0xd3, 0xa2, 0x89, 0x6a, 0x98, 0x50 },
- { 0x59, 0xee, 0x9b, 0x36, 0x80, 0xae, 0x20, 0x56,
- 0x83, 0x9c, 0x0b, 0xf6, 0x9e, 0xe6, 0x63, 0x26,
- 0x57, 0x16, 0xa8, 0xe2, 0x4c, 0xc6, 0x49, 0x95,
- 0xfb, 0xa6, 0xcb, 0x6f, 0x0c, 0x12, 0x39, 0xdc },
- { 0x5a, 0x84, 0xaf, 0xe6, 0x74, 0x05, 0xab, 0xe8,
- 0x4a, 0x0c, 0xd4, 0x2c, 0x2b, 0xa2, 0xe4, 0xc8,
- 0x8f, 0x35, 0xe0, 0xa5, 0x95, 0xe5, 0x69, 0xa3,
- 0xe1, 0x86, 0x69, 0x44, 0x40, 0x5b, 0xe7, 0x36 },
- { 0x5a, 0x8e, 0x86, 0x21, 0x2c, 0x06, 0x33, 0x94,
- 0x94, 0xf8, 0x5b, 0x5f, 0x85, 0x11, 0xdf, 0x00,
- 0x00, 0x23, 0x94, 0x07, 0x8f, 0xfc, 0x77, 0x4d,
- 0x43, 0x6f, 0x0d, 0x63, 0x86, 0xd7, 0xa6, 0xf7 },
- { 0x5a, 0xc0, 0x98, 0x2d, 0xa0, 0xc8, 0x3d, 0x0b,
- 0xa9, 0x38, 0x1a, 0x5c, 0xd8, 0x7b, 0x80, 0xd1,
- 0x10, 0xf2, 0x6e, 0xe8, 0x39, 0x27, 0x1b, 0xc2,
- 0x70, 0x60, 0x8f, 0xd1, 0x43, 0x7f, 0x55, 0xb0 },
- { 0x5c, 0x7f, 0xf0, 0x55, 0xc2, 0xfd, 0x03, 0x3f,
- 0x34, 0xc4, 0xc4, 0xf7, 0xc4, 0xfb, 0x7d, 0xda,
- 0xaa, 0xfb, 0x43, 0x56, 0xc5, 0x60, 0xc9, 0x9e,
- 0xdf, 0xf0, 0x74, 0xda, 0x04, 0xaf, 0x65, 0x7c },
- { 0x5c, 0xd2, 0x44, 0x6a, 0x8e, 0x4a, 0x0f, 0xa7,
- 0xe3, 0xcd, 0xf8, 0x00, 0x5d, 0xed, 0xce, 0xba,
- 0xe9, 0xe6, 0x81, 0x9a, 0x8a, 0x69, 0x87, 0x31,
- 0x55, 0x5b, 0x7d, 0xc9, 0xd0, 0xa2, 0x3f, 0xc0 },
- { 0x5c, 0xeb, 0xeb, 0xd8, 0x34, 0x01, 0xb7, 0x0b,
- 0xac, 0xb5, 0x4f, 0x66, 0xa9, 0xb7, 0x78, 0x55,
- 0x69, 0x6e, 0xce, 0x16, 0x7f, 0xe6, 0xc6, 0x0a,
- 0x05, 0x16, 0x8b, 0xe4, 0x39, 0x19, 0xc8, 0x0f },
- { 0x5f, 0x8b, 0x88, 0x8e, 0xe9, 0x6c, 0x0c, 0x0f,
- 0x5a, 0x91, 0x72, 0x90, 0xac, 0xa6, 0x5a, 0xfd,
- 0x6e, 0xbd, 0xae, 0x05, 0xa0, 0x2a, 0xaf, 0x04,
- 0x29, 0xe9, 0x72, 0xec, 0x01, 0x90, 0xec, 0xfc },
- { 0x62, 0x2e, 0xc3, 0xbe, 0x7c, 0xf5, 0xe4, 0xe6,
- 0x3f, 0x74, 0x18, 0x69, 0x28, 0x74, 0x40, 0x05,
- 0xcb, 0xb7, 0x8d, 0xf3, 0x06, 0xb8, 0x67, 0xc3,
- 0xfc, 0xad, 0x5e, 0x2b, 0xa7, 0x53, 0x96, 0x83 },
- { 0x62, 0x6f, 0x7e, 0xb4, 0xfd, 0x9b, 0x71, 0xff,
- 0xaa, 0x0c, 0x8e, 0xc9, 0x65, 0x54, 0x64, 0xe6,
- 0x5e, 0x7f, 0x96, 0xcf, 0xa3, 0x82, 0x73, 0x97,
- 0x41, 0x35, 0x66, 0xaa, 0x2c, 0xc1, 0xe5, 0x72 },
- { 0x63, 0x64, 0x15, 0x61, 0x77, 0xdc, 0xdf, 0x60,
- 0x4d, 0xf9, 0x1e, 0x31, 0x32, 0x2e, 0x57, 0x74,
- 0x69, 0x1e, 0x0c, 0x41, 0xfa, 0x0d, 0x2f, 0x25,
- 0x7a, 0xd7, 0xf9, 0xf0, 0x25, 0x98, 0x14, 0x45 },
- { 0x65, 0x66, 0x00, 0xa4, 0x5e, 0x45, 0x6a, 0xba,
- 0x5b, 0x00, 0x8d, 0x87, 0x91, 0x54, 0xb7, 0x69,
- 0x0d, 0x7f, 0x27, 0x31, 0x02, 0x09, 0x7d, 0x8f,
- 0xd8, 0xc3, 0xde, 0xab, 0x30, 0xd8, 0x4a, 0xb2 },
- { 0x65, 0xed, 0x61, 0xa8, 0x8c, 0x55, 0xef, 0xb0,
- 0x38, 0x07, 0x1a, 0xee, 0xde, 0xf8, 0xe1, 0x83,
- 0xe2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xeb, 0x99,
- 0x68, 0x0c, 0xd2, 0x44, 0x72, 0x73, 0x6b, 0xec },
- { 0x66, 0x50, 0xb2, 0xea, 0x64, 0x4c, 0x3f, 0x4e,
- 0x8c, 0x9e, 0x3c, 0x46, 0xac, 0xea, 0xc4, 0x52,
- 0x33, 0xd8, 0x66, 0xe3, 0x98, 0xff, 0x90, 0xeb,
- 0x59, 0xb2, 0xc6, 0x25, 0x20, 0x82, 0xac, 0x04 },
- { 0x66, 0xbe, 0x7e, 0xa1, 0x13, 0x8b, 0xcb, 0xa4,
- 0xde, 0x0b, 0x41, 0x28, 0x5d, 0x9a, 0x13, 0x3f,
- 0xa7, 0xf5, 0x70, 0xa3, 0xc8, 0x13, 0x55, 0x79,
- 0xb8, 0x60, 0x19, 0x9d, 0x0a, 0x51, 0x45, 0x7c },
- { 0x69, 0x01, 0x4b, 0xbc, 0x84, 0x29, 0xd8, 0x5f,
- 0x41, 0xc2, 0x22, 0xd9, 0x7f, 0x7e, 0xd5, 0x35,
- 0xcf, 0x81, 0x23, 0x9a, 0xf2, 0x7a, 0xcc, 0x88,
- 0x70, 0xdc, 0xd4, 0x08, 0x34, 0x8b, 0x48, 0xba },
- { 0x69, 0x21, 0x1f, 0x36, 0x3a, 0x2d, 0xbe, 0x01,
- 0x5b, 0x31, 0xcb, 0xd9, 0xfc, 0x5e, 0x94, 0xc2,
- 0xf6, 0xf4, 0x3c, 0x58, 0xdb, 0xde, 0xe9, 0xe3,
- 0xe4, 0x6b, 0x19, 0xd7, 0x59, 0xbb, 0xb8, 0x81 },
- { 0x69, 0x75, 0x67, 0xbb, 0xac, 0x94, 0xee, 0xc3,
- 0xe6, 0xfa, 0x4a, 0x4e, 0x46, 0xfa, 0x51, 0x74,
- 0x05, 0xf3, 0x77, 0xc0, 0xde, 0xe3, 0xd4, 0x29,
- 0x91, 0x4e, 0x6b, 0x7e, 0xa0, 0x8c, 0xb1, 0xa6 },
- { 0x6a, 0xac, 0xc5, 0x09, 0x2f, 0x12, 0xbc, 0x94,
- 0xa0, 0xad, 0x0e, 0x9e, 0xf6, 0x36, 0x43, 0x7d,
- 0x36, 0x0d, 0xc7, 0xc9, 0xf1, 0x40, 0x44, 0x17,
- 0xa3, 0x36, 0x91, 0x94, 0x4e, 0x76, 0x31, 0x36 },
- { 0x6b, 0x4a, 0x8c, 0xb6, 0x07, 0xf5, 0x1c, 0x83,
- 0x0d, 0xe7, 0x20, 0xf4, 0xbb, 0xde, 0xdf, 0x49,
- 0x10, 0x15, 0x13, 0xdf, 0xd1, 0xdb, 0x0b, 0x0a,
- 0x97, 0xcc, 0x3f, 0xdd, 0x9a, 0x39, 0xc6, 0xe7 },
- { 0x6c, 0x8f, 0xd1, 0xe6, 0xe1, 0x1b, 0xaf, 0xa6,
- 0x17, 0x78, 0x13, 0xa0, 0x44, 0x40, 0xb1, 0xb9,
- 0x6a, 0x1c, 0xdb, 0x7c, 0x2d, 0x70, 0x3f, 0x55,
- 0xde, 0x85, 0x7c, 0x80, 0xa8, 0x9e, 0x73, 0x25 },
- { 0x6c, 0xc6, 0xdc, 0xda, 0x58, 0xc6, 0x1f, 0xb2,
- 0x86, 0x70, 0xd1, 0xc2, 0x01, 0x76, 0x57, 0xb0,
- 0xc5, 0xd6, 0x1a, 0x26, 0xc9, 0xcb, 0xd1, 0xea,
- 0x75, 0x5c, 0x68, 0x20, 0xb5, 0xf6, 0xd6, 0x7d },
- { 0x6d, 0x32, 0xf4, 0x93, 0x40, 0x56, 0xee, 0x17,
- 0x14, 0xca, 0x72, 0x70, 0x3f, 0x64, 0x46, 0x9b,
- 0x98, 0x58, 0xfc, 0x39, 0x96, 0x4b, 0x4c, 0x03,
- 0x93, 0xb3, 0x7d, 0xde, 0xab, 0x8b, 0x19, 0x75 },
- { 0x6e, 0x1a, 0x88, 0x63, 0xf2, 0x93, 0x4b, 0x39,
- 0x01, 0x23, 0x7e, 0x84, 0xd0, 0x76, 0x27, 0x04,
- 0x23, 0x06, 0x78, 0x7f, 0x2d, 0xe0, 0x66, 0x30,
- 0xbd, 0x37, 0xd8, 0x03, 0x94, 0x35, 0xbf, 0xca },
- { 0x6e, 0x99, 0x8d, 0xdd, 0xf2, 0x93, 0x9b, 0xfe,
- 0x8c, 0xc5, 0x2a, 0x48, 0x0a, 0xc0, 0x6d, 0x69,
- 0x71, 0xc5, 0xa3, 0xda, 0x97, 0xcf, 0x3e, 0xf0,
- 0x1a, 0xf2, 0x9d, 0x74, 0x72, 0x62, 0x31, 0xe2 },
- { 0x6f, 0x3b, 0xb3, 0x4b, 0x5d, 0x32, 0x91, 0xdf,
- 0xb3, 0xe4, 0x12, 0x71, 0xa1, 0xd7, 0x30, 0xcd,
- 0xbc, 0xff, 0xc1, 0x0b, 0x68, 0x05, 0x9d, 0xcc,
- 0xd3, 0x1c, 0x47, 0x4b, 0xb7, 0x44, 0x16, 0xe5 },
- { 0x6f, 0xbd, 0xcd, 0xf1, 0xb4, 0x37, 0x9f, 0xc4,
- 0x73, 0xab, 0x5e, 0xea, 0x4e, 0xc2, 0xf4, 0x84,
- 0xce, 0x91, 0xd1, 0x0e, 0x31, 0x34, 0x5f, 0x15,
- 0xa7, 0x6a, 0x84, 0x85, 0xb8, 0xff, 0xfb, 0x7e },
- { 0x70, 0xb8, 0xec, 0xd5, 0x62, 0xec, 0x3d, 0x9f,
- 0x48, 0x64, 0x75, 0x2a, 0x3a, 0x8c, 0x54, 0x39,
- 0x93, 0xb4, 0x38, 0x72, 0x8f, 0xe2, 0x71, 0x81,
- 0xf4, 0xc0, 0x8d, 0xe6, 0xa0, 0xd8, 0xb7, 0x9a },
- { 0x72, 0x1b, 0x1f, 0x92, 0x9d, 0xa7, 0xea, 0xf8,
- 0x96, 0x24, 0x64, 0x7b, 0xa3, 0xcc, 0x4e, 0x1e,
- 0xd1, 0x57, 0x54, 0xab, 0x83, 0x6e, 0x33, 0x58,
- 0xb0, 0x35, 0xa1, 0xf2, 0x27, 0x4a, 0x43, 0xbe },
- { 0x72, 0x81, 0xda, 0x0d, 0x8c, 0xe9, 0xd5, 0x3e,
- 0xa3, 0xd1, 0xf5, 0x93, 0x5c, 0x58, 0x21, 0xea,
- 0x8d, 0x9a, 0xf1, 0xce, 0x0b, 0xca, 0xf8, 0x82,
- 0x5d, 0x78, 0x3f, 0x37, 0xea, 0xc3, 0x4f, 0x40 },
- { 0x72, 0xe7, 0x49, 0x87, 0x21, 0x0c, 0x7e, 0xf6,
- 0x67, 0x46, 0xe4, 0x9a, 0x96, 0xdf, 0x55, 0xcc,
- 0x6f, 0xad, 0xf7, 0xa6, 0x31, 0xc7, 0xae, 0x3f,
- 0x3e, 0x9e, 0x18, 0x72, 0x3d, 0xe5, 0x2a, 0x6e },
- { 0x73, 0x3b, 0x42, 0x24, 0x25, 0x8d, 0xee, 0x07,
- 0x0e, 0xdf, 0xa3, 0x41, 0x1f, 0xbc, 0x9b, 0xad,
- 0x31, 0x65, 0xbe, 0x66, 0x0f, 0x34, 0x0a, 0xa2,
- 0x30, 0x8a, 0x5a, 0x33, 0x23, 0xfa, 0xbf, 0xa7 },
- { 0x74, 0x8e, 0xbb, 0x72, 0xd1, 0x02, 0x04, 0xf4,
- 0x04, 0x10, 0xbe, 0x70, 0x80, 0xbf, 0xe7, 0xee,
- 0x63, 0x1f, 0xc0, 0x4d, 0x1f, 0xdb, 0x50, 0x72,
- 0x04, 0x4b, 0xfa, 0x55, 0x7a, 0xdf, 0x6e, 0x5a },
- { 0x74, 0xe2, 0xcc, 0xcf, 0x62, 0xd5, 0xb9, 0xf9,
- 0x00, 0xb4, 0x14, 0x73, 0xca, 0x44, 0xe6, 0x87,
- 0x96, 0x38, 0x74, 0x3d, 0x8f, 0xee, 0x66, 0xee,
- 0x71, 0x8c, 0x18, 0xd8, 0xf1, 0x12, 0x15, 0xd1 },
- { 0x76, 0x98, 0x67, 0x60, 0xac, 0xfe, 0x55, 0x59,
- 0xa2, 0xa2, 0xab, 0x2a, 0x4e, 0x85, 0x49, 0x83,
- 0xc5, 0xfd, 0xe6, 0x73, 0xce, 0x8e, 0xb1, 0x71,
- 0x23, 0x49, 0x48, 0x64, 0x86, 0x7a, 0x98, 0xb1 },
- { 0x78, 0x0c, 0x33, 0xfe, 0x95, 0x4c, 0xc4, 0xdb,
- 0x39, 0x04, 0xd7, 0x6a, 0x68, 0x58, 0xbc, 0xd1,
- 0x01, 0x7f, 0x52, 0xda, 0x59, 0x9d, 0x36, 0xda,
- 0xe6, 0x66, 0xc0, 0x4e, 0x41, 0xaf, 0x8d, 0xcd },
- { 0x78, 0xc9, 0x30, 0x40, 0x5a, 0x72, 0x0d, 0x9f,
- 0x00, 0x66, 0xdd, 0x88, 0xa2, 0xa8, 0xda, 0xfb,
- 0xbe, 0x6c, 0xd6, 0x5d, 0x54, 0xb7, 0x76, 0x06,
- 0x42, 0x1b, 0x45, 0x43, 0x8c, 0x65, 0x8a, 0xd4 },
- { 0x79, 0x8f, 0x83, 0xb1, 0xc4, 0xc6, 0x5c, 0x4d,
- 0x5d, 0xea, 0x13, 0x03, 0x53, 0x53, 0xd8, 0xed,
- 0xe5, 0xd7, 0x1d, 0x99, 0x47, 0xf4, 0x34, 0xfd,
- 0xea, 0x0d, 0xbc, 0x1e, 0xc8, 0x2f, 0x45, 0x35 },
- { 0x7b, 0xfe, 0x47, 0xae, 0xba, 0x8b, 0x0a, 0x3a,
- 0x94, 0x5a, 0x88, 0xd8, 0xef, 0x18, 0x91, 0xc9,
- 0x89, 0x97, 0x8a, 0xbf, 0x12, 0x2e, 0xc5, 0xe0,
- 0x51, 0x4b, 0xe3, 0x6c, 0x3a, 0x7f, 0x22, 0x9b },
- { 0x7d, 0x20, 0xc7, 0xa9, 0x27, 0x26, 0x2b, 0xe7,
- 0x38, 0xd2, 0x58, 0xd0, 0xfd, 0x97, 0x6e, 0x9a,
- 0xf3, 0x6e, 0xf7, 0x99, 0x5f, 0x05, 0xe2, 0x87,
- 0x6a, 0x29, 0xae, 0xbc, 0x3a, 0x24, 0xaa, 0xce },
- { 0x7e, 0x2e, 0xdb, 0x9d, 0x38, 0xf9, 0x29, 0x3c,
- 0xdd, 0xd6, 0x03, 0xb1, 0x75, 0xc9, 0xb2, 0x05,
- 0xac, 0x0b, 0x55, 0x3a, 0x4b, 0xf5, 0xfb, 0x08,
- 0xc2, 0x46, 0xec, 0xf9, 0xc8, 0x49, 0xdb, 0x28 },
- { 0x7f, 0x95, 0x9b, 0x06, 0x34, 0xda, 0x94, 0xfa,
- 0xca, 0xda, 0xb0, 0x21, 0xcf, 0x94, 0x20, 0x78,
- 0x16, 0x00, 0x36, 0x13, 0xef, 0x09, 0xeb, 0x54,
- 0xf6, 0x48, 0x60, 0x50, 0x08, 0x19, 0x02, 0x75 },
- { 0x7f, 0x9a, 0x69, 0xcf, 0xa2, 0xf5, 0x0c, 0x13,
- 0xe1, 0xb7, 0x11, 0xdd, 0x6b, 0x14, 0x69, 0x2b,
- 0xdb, 0x77, 0xd9, 0xff, 0xd8, 0xc1, 0x10, 0xae,
- 0x5d, 0x05, 0xa4, 0xcb, 0x73, 0x12, 0x37, 0x48 },
- { 0x7f, 0xcc, 0xa8, 0xb5, 0xf5, 0xe3, 0x3b, 0xca,
- 0x6d, 0xe0, 0x9c, 0x14, 0xaf, 0xbb, 0xe0, 0xc3,
- 0x41, 0x21, 0xac, 0xbb, 0x22, 0x22, 0x9f, 0x44,
- 0xee, 0x5c, 0x3f, 0x4d, 0xde, 0x73, 0x50, 0x55 },
- { 0x80, 0x20, 0x56, 0xe1, 0xdb, 0x9d, 0x9b, 0x73,
- 0x21, 0xd1, 0xff, 0xbb, 0xe1, 0x2f, 0x5c, 0xbe,
- 0xde, 0xc3, 0x6d, 0x0b, 0x5e, 0xc2, 0xa4, 0xe1,
- 0x8d, 0x99, 0x54, 0x36, 0x4c, 0xec, 0x81, 0x29 },
- { 0x80, 0x97, 0x63, 0x4c, 0xe3, 0x3d, 0x41, 0x53,
- 0x3d, 0x41, 0x5d, 0xaf, 0xdb, 0x8b, 0xa1, 0x91,
- 0xc0, 0x30, 0x52, 0xac, 0x8b, 0xaa, 0x25, 0x54,
- 0x34, 0x77, 0x3a, 0x16, 0x4b, 0x91, 0x1d, 0x6e },
- { 0x80, 0xd0, 0x17, 0x09, 0x34, 0xd2, 0x2a, 0xea,
- 0x73, 0x3f, 0x11, 0x5e, 0x52, 0x42, 0xc6, 0xb8,
- 0x6d, 0x7f, 0xcf, 0xb4, 0x90, 0x4e, 0x65, 0xb7,
- 0xb7, 0xb9, 0x07, 0xf2, 0xca, 0x94, 0xed, 0x71 },
- { 0x81, 0x1d, 0xf2, 0xf4, 0x73, 0x6f, 0x85, 0x62,
- 0xe2, 0x02, 0xfd, 0x00, 0x75, 0x32, 0xf1, 0xde,
- 0x40, 0x17, 0x86, 0x1e, 0xfa, 0xbe, 0x67, 0x34,
- 0x20, 0xc2, 0x7f, 0x2e, 0x2a, 0x33, 0xfa, 0xc1 },
- { 0x81, 0x1e, 0x37, 0x86, 0x37, 0xb1, 0xd2, 0xcb,
- 0xb1, 0x89, 0xaf, 0xd6, 0x74, 0x95, 0xfe, 0x8a,
- 0xb9, 0xd8, 0x3a, 0x74, 0x2e, 0x35, 0x8c, 0xbb,
- 0xdb, 0xd1, 0x54, 0x98, 0xbf, 0x9c, 0x7b, 0x56 },
- { 0x81, 0xa0, 0xf1, 0xd0, 0x29, 0x46, 0x8e, 0xe8,
- 0x66, 0x36, 0x4a, 0x19, 0x8a, 0x26, 0x08, 0x58,
- 0x30, 0xc2, 0xa4, 0x16, 0xe4, 0x9e, 0x22, 0x4c,
- 0xe8, 0x09, 0x66, 0xfc, 0xc4, 0x99, 0xd6, 0x36 },
- { 0x82, 0x56, 0x8b, 0x3b, 0xb3, 0xc6, 0x55, 0xd7,
- 0xf2, 0x2d, 0x8c, 0x97, 0xa5, 0x66, 0x9c, 0xc8,
- 0x34, 0xa2, 0xdd, 0x7c, 0xda, 0xe7, 0x5a, 0x26,
- 0x45, 0x59, 0x55, 0x16, 0x46, 0x55, 0x8e, 0x14 },
- { 0x82, 0x7c, 0x8c, 0x80, 0x11, 0x1f, 0xf2, 0x21,
- 0xc3, 0xeb, 0x1e, 0xf5, 0xc0, 0xd5, 0xd4, 0x34,
- 0x48, 0x31, 0x86, 0xe2, 0x09, 0x00, 0x75, 0x63,
- 0x15, 0x8e, 0x9e, 0x76, 0xd2, 0x79, 0x0f, 0x1c },
- { 0x82, 0x92, 0x67, 0xc5, 0xad, 0x70, 0xe5, 0x45,
- 0x18, 0x02, 0x3a, 0xb7, 0x85, 0xfa, 0x3c, 0xde,
- 0xd6, 0x6f, 0x42, 0x5d, 0xe1, 0xf3, 0x2f, 0xcd,
- 0x72, 0x1b, 0x49, 0x46, 0x3a, 0x5a, 0x5f, 0x5b },
- { 0x83, 0x34, 0xea, 0xb8, 0x1c, 0x60, 0x4e, 0x99,
- 0xd5, 0x40, 0x51, 0x3e, 0xf2, 0xe3, 0x7a, 0xba,
- 0x71, 0x4f, 0x07, 0xb2, 0xba, 0x01, 0x0a, 0xd7,
- 0x1d, 0xc4, 0xe1, 0x1a, 0x92, 0x18, 0xc1, 0x8c },
- { 0x83, 0x54, 0x7a, 0xca, 0x3c, 0xed, 0x73, 0xdf,
- 0x99, 0x14, 0xf3, 0x15, 0x60, 0x74, 0x63, 0x79,
- 0x29, 0x4c, 0x76, 0x0e, 0xf9, 0xa8, 0xb7, 0x6e,
- 0x00, 0x06, 0x46, 0xc7, 0x39, 0x07, 0x21, 0x65 },
- { 0x83, 0x89, 0xc8, 0x79, 0xb6, 0x3b, 0x82, 0x9d,
- 0x2d, 0x39, 0xa8, 0xcf, 0xb7, 0x87, 0xe7, 0x72,
- 0x77, 0xd5, 0xcf, 0xa3, 0xe3, 0x6f, 0xda, 0xcb,
- 0xab, 0x4d, 0x18, 0xb2, 0xb0, 0x4e, 0x32, 0x94 },
- { 0x84, 0x23, 0xb3, 0xf1, 0xcc, 0x85, 0x2b, 0x49,
- 0xcf, 0x81, 0xb7, 0xd5, 0xff, 0x51, 0xa7, 0xa5,
- 0x6a, 0x84, 0x78, 0x3a, 0x2d, 0xf7, 0x43, 0x61,
- 0xff, 0x2e, 0xee, 0x0f, 0x92, 0x12, 0xc1, 0x59 },
- { 0x84, 0x7b, 0x5f, 0x1e, 0xeb, 0x2a, 0x44, 0x13,
- 0xc8, 0xfa, 0x37, 0x98, 0x21, 0x97, 0x37, 0xe1,
- 0x92, 0xba, 0x72, 0x72, 0xa1, 0x08, 0xb7, 0x17,
- 0x28, 0xa8, 0xd1, 0x65, 0x17, 0xf6, 0x1e, 0x9d },
- { 0x85, 0x31, 0xb2, 0xbf, 0xc5, 0x45, 0x79, 0xe8,
- 0xf1, 0x8f, 0x27, 0xb2, 0xe6, 0xec, 0xc0, 0xf8,
- 0x90, 0x64, 0xee, 0x86, 0x87, 0x0e, 0xcc, 0x8b,
- 0xbe, 0x0c, 0xe6, 0x86, 0xec, 0xda, 0x2c, 0x17 },
- { 0x85, 0x76, 0x0f, 0x59, 0x51, 0x90, 0xe9, 0xb4,
- 0x67, 0x8b, 0xbf, 0x44, 0xef, 0xb5, 0xcf, 0x8f,
- 0x6b, 0x19, 0x37, 0xa9, 0xb8, 0x6b, 0x31, 0xb7,
- 0x51, 0xbe, 0xcf, 0x72, 0x18, 0x03, 0xb0, 0x1c },
- { 0x85, 0xf0, 0x79, 0x36, 0xb4, 0x29, 0x1f, 0x36,
- 0xd9, 0xb7, 0x5f, 0x42, 0xe8, 0xb7, 0xee, 0x8a,
- 0x64, 0xe6, 0x32, 0xa1, 0x18, 0x11, 0x65, 0xfe,
- 0x72, 0xb4, 0x88, 0x23, 0xc3, 0xd9, 0x9d, 0x9d },
- { 0x86, 0x12, 0x9f, 0xe7, 0x61, 0x99, 0x4d, 0x7b,
- 0x64, 0xe4, 0x02, 0x85, 0x8f, 0x88, 0xc5, 0x2b,
- 0x3e, 0xb9, 0xc0, 0x71, 0xff, 0xbe, 0x80, 0x02,
- 0x80, 0xac, 0x8c, 0x0c, 0x6f, 0x79, 0xe7, 0xa6 },
- { 0x86, 0x19, 0x6b, 0x0f, 0xd3, 0x0f, 0x8f, 0x57,
- 0x56, 0x98, 0xb5, 0xee, 0xf2, 0x69, 0xd0, 0x69,
- 0x2f, 0x88, 0xad, 0xea, 0xc4, 0x83, 0x6a, 0x62,
- 0x67, 0xab, 0xc8, 0x36, 0x23, 0x34, 0x00, 0x86 },
- { 0x86, 0xcf, 0xec, 0xbe, 0x82, 0xba, 0xdb, 0x93,
- 0x14, 0x75, 0xf1, 0x9e, 0xcd, 0x6e, 0xa6, 0x7d,
- 0x59, 0xc2, 0xc7, 0x00, 0x78, 0xb6, 0xcc, 0x56,
- 0xbf, 0xdc, 0x27, 0x55, 0x47, 0x67, 0xf2, 0x3f },
- { 0x86, 0xd1, 0x8b, 0xcd, 0xde, 0x16, 0x45, 0x42,
- 0x48, 0x6e, 0x56, 0x44, 0x2c, 0xe1, 0xb8, 0x8b,
- 0x1a, 0x10, 0x73, 0x7c, 0xbd, 0x5e, 0xa4, 0xaa,
- 0xb8, 0xd5, 0xb8, 0xaf, 0x51, 0xf5, 0x29, 0x09 },
- { 0x87, 0x5f, 0x57, 0x42, 0x4c, 0x90, 0x2b, 0x24,
- 0xe8, 0x1c, 0x27, 0xd1, 0xca, 0xf2, 0x74, 0xb1,
- 0x7d, 0x72, 0x0d, 0xf8, 0x07, 0x8b, 0x6f, 0x2a,
- 0x5c, 0x3b, 0xb8, 0xd8, 0xdf, 0xf0, 0x55, 0x00 },
- { 0x88, 0x8d, 0x6d, 0x77, 0xd8, 0x1c, 0x62, 0x91,
- 0xcb, 0x84, 0xd9, 0xd6, 0x56, 0x27, 0x82, 0xfd,
- 0x2e, 0xb3, 0x42, 0x5d, 0x49, 0x1e, 0x68, 0x74,
- 0x20, 0x28, 0x4b, 0x76, 0xa1, 0xde, 0xbf, 0xab },
- { 0x89, 0xaf, 0x0e, 0x54, 0xc7, 0x62, 0x77, 0x86,
- 0x93, 0x52, 0x9d, 0x0a, 0x95, 0x0b, 0x78, 0x33,
- 0xf5, 0xea, 0xba, 0xf3, 0x42, 0x79, 0x72, 0x60,
- 0x7f, 0xb2, 0xc7, 0x0c, 0x96, 0xa3, 0x21, 0x61 },
- { 0x89, 0xda, 0xc7, 0x89, 0x6b, 0x46, 0xf2, 0xfc,
- 0x8b, 0xea, 0x62, 0x11, 0xff, 0x98, 0xb6, 0x1f,
- 0xaa, 0x15, 0x7b, 0xa8, 0xc4, 0xad, 0x6f, 0xd1,
- 0x75, 0x92, 0x75, 0xce, 0x39, 0x41, 0xc3, 0x28 },
- { 0x8a, 0x09, 0x85, 0xbf, 0x86, 0xe8, 0xc9, 0xb9,
- 0x17, 0xec, 0x84, 0xda, 0x2a, 0x56, 0x73, 0x1e,
- 0x75, 0x2a, 0xa0, 0xdc, 0x52, 0x87, 0xc2, 0xbf,
- 0x39, 0x51, 0x0b, 0xb3, 0xf0, 0xf2, 0x0a, 0xd1 },
- { 0x8a, 0xaf, 0x36, 0x3c, 0xc9, 0xd8, 0x44, 0x15,
- 0xa7, 0xeb, 0x0d, 0x72, 0xda, 0x08, 0xb3, 0x58,
- 0x80, 0x68, 0x55, 0x9c, 0xb0, 0xa9, 0xae, 0x92,
- 0xb8, 0xf4, 0x60, 0x2e, 0xda, 0x23, 0x82, 0xaa },
- { 0x8a, 0xb2, 0x77, 0x62, 0xf4, 0xa2, 0xe3, 0x11,
- 0x22, 0x04, 0x96, 0x98, 0x39, 0x99, 0xc8, 0xc4,
- 0x60, 0x96, 0x3d, 0xfc, 0x1b, 0x88, 0x51, 0x11,
- 0x1d, 0xa4, 0x1d, 0x3f, 0x3b, 0x0a, 0x6e, 0x94 },
- { 0x8a, 0xd1, 0xd5, 0x48, 0x95, 0x27, 0xb5, 0x28,
- 0xe5, 0xb5, 0xd6, 0xa5, 0x95, 0x78, 0x87, 0x08,
- 0x88, 0x8a, 0x3f, 0xb1, 0x9f, 0x2c, 0x7c, 0x8b,
- 0x38, 0x07, 0x0e, 0x1f, 0x38, 0x98, 0x96, 0x8b },
- { 0x8a, 0xdb, 0x49, 0xd4, 0x15, 0x53, 0x56, 0x70,
- 0x5b, 0x64, 0x42, 0x6a, 0x99, 0x0f, 0x58, 0xb3,
- 0xa0, 0x71, 0xef, 0x78, 0x2e, 0x6c, 0x09, 0x53,
- 0x07, 0xd7, 0x74, 0x74, 0xd5, 0xb5, 0x7a, 0x62 },
- { 0x8b, 0x3a, 0x10, 0x35, 0xc3, 0xfd, 0xf3, 0x45,
- 0xfb, 0x70, 0x80, 0x44, 0x83, 0xa5, 0x04, 0x49,
- 0xa3, 0xd7, 0x60, 0xc6, 0xba, 0x48, 0xf5, 0xb8,
- 0x2d, 0x6b, 0xb2, 0x62, 0xed, 0x9d, 0xe3, 0x73 },
- { 0x8b, 0x3a, 0x75, 0xcb, 0xc3, 0x62, 0xd2, 0x35,
- 0x57, 0x0e, 0x5d, 0xe7, 0x04, 0x29, 0x38, 0x70,
- 0x8a, 0x1b, 0x0f, 0xce, 0xb4, 0x59, 0x86, 0x2a,
- 0x38, 0x67, 0xb7, 0x34, 0xcd, 0xcb, 0x97, 0x94 },
- { 0x8c, 0x3e, 0x7c, 0x1d, 0xcc, 0x7d, 0xd8, 0xe7,
- 0xd8, 0xbf, 0x7b, 0x5b, 0x3a, 0xe5, 0xe0, 0x27,
- 0x2e, 0x81, 0x1a, 0xb9, 0xf3, 0xc3, 0xc5, 0x38,
- 0xe5, 0x74, 0x71, 0x77, 0xe6, 0x2d, 0x62, 0x92 },
- { 0x8c, 0x7c, 0x65, 0x7b, 0xda, 0x13, 0xca, 0x62,
- 0xf2, 0x9a, 0x65, 0xc6, 0xd5, 0x19, 0x3a, 0x93,
- 0xcf, 0x6c, 0x58, 0x77, 0x18, 0xad, 0xca, 0x67,
- 0x15, 0x8e, 0x97, 0xd3, 0x6a, 0x62, 0x3e, 0xca },
- { 0x8c, 0xa6, 0x79, 0x62, 0xc4, 0xa8, 0x09, 0x13,
- 0x33, 0xf2, 0x4e, 0xfd, 0x60, 0xee, 0x70, 0xcf,
- 0xed, 0xdb, 0xd6, 0x41, 0x59, 0x04, 0x70, 0x9e,
- 0x78, 0x5c, 0x33, 0x1b, 0x1e, 0xf5, 0x8f, 0x8e },
- { 0x8e, 0x18, 0xfd, 0xbd, 0xb0, 0x08, 0x16, 0x00,
- 0x35, 0xfa, 0xf5, 0x01, 0x5b, 0xe7, 0xda, 0xf4,
- 0x63, 0xb5, 0xc4, 0x14, 0xea, 0xbc, 0x8b, 0x89,
- 0xf3, 0xdb, 0xa2, 0x05, 0xab, 0x09, 0xa6, 0x43 },
- { 0x8f, 0x10, 0x10, 0x47, 0x93, 0xe8, 0x55, 0x42,
- 0xbc, 0x06, 0x04, 0xd6, 0xcf, 0x21, 0x5f, 0x78,
- 0x80, 0xbd, 0x6a, 0x4d, 0xd0, 0xfd, 0xf1, 0xe7,
- 0xa5, 0xb9, 0xca, 0x12, 0x46, 0xf5, 0xc4, 0x09 },
- { 0x8f, 0x71, 0x27, 0x76, 0x2e, 0xe7, 0x51, 0x69,
- 0xbd, 0xc3, 0x5b, 0x04, 0xa7, 0x28, 0xe9, 0xd3,
- 0x1b, 0x7e, 0x4d, 0x37, 0x89, 0xaa, 0x2c, 0x46,
- 0xd8, 0xa3, 0x1b, 0x3d, 0xfa, 0x81, 0xa9, 0x7e },
- { 0x8f, 0x94, 0x15, 0x92, 0x6f, 0x40, 0x49, 0xea,
- 0x41, 0x8a, 0x30, 0x7c, 0x76, 0x36, 0xe4, 0x9b,
- 0x14, 0x4f, 0xa5, 0x3e, 0x52, 0xe1, 0x04, 0x15,
- 0x5f, 0x58, 0x03, 0x5e, 0x45, 0x41, 0xcd, 0x6e },
- { 0x90, 0xe2, 0x51, 0x86, 0x7f, 0x6b, 0x0c, 0x14,
- 0xbd, 0x9b, 0x51, 0x0c, 0xfd, 0xa8, 0x48, 0x49,
- 0x72, 0xfd, 0xf0, 0xe0, 0x6d, 0xc1, 0x1f, 0x5d,
- 0x1d, 0x59, 0x0b, 0xe3, 0xfc, 0x38, 0xdf, 0xf0 },
- { 0x91, 0x90, 0xf8, 0x25, 0x51, 0x0c, 0x65, 0x98,
- 0xe1, 0x9d, 0x17, 0xdb, 0xbe, 0x6e, 0x7c, 0x82,
- 0x31, 0x86, 0x9c, 0xa7, 0xf6, 0xe3, 0x07, 0xa2,
- 0xc2, 0xcc, 0x54, 0x77, 0x8d, 0x4a, 0x89, 0xb3 },
- { 0x92, 0x3f, 0x0f, 0x8c, 0x40, 0x5a, 0x02, 0xe6,
- 0x82, 0xc4, 0xb4, 0x66, 0x5a, 0x7e, 0xe7, 0x16,
- 0xaa, 0x57, 0xe0, 0xa5, 0x86, 0xc2, 0x4a, 0x16,
- 0x5a, 0xad, 0x7e, 0x5b, 0xda, 0x22, 0x78, 0x24 },
- { 0x92, 0x71, 0x44, 0x12, 0x1c, 0x23, 0x63, 0x57,
- 0x07, 0xe9, 0x40, 0x7f, 0x7f, 0xff, 0x6a, 0x64,
- 0x63, 0x5d, 0x7c, 0xe9, 0x06, 0x66, 0xd4, 0x29,
- 0x94, 0x09, 0x7a, 0xf4, 0x0c, 0x31, 0x36, 0xfb },
- { 0x94, 0xdc, 0x80, 0x07, 0x49, 0x1d, 0xa8, 0xbf,
- 0xb7, 0x39, 0x14, 0xad, 0xce, 0xf7, 0x1a, 0x12,
- 0x41, 0x58, 0xba, 0xd1, 0x7b, 0xa8, 0x8f, 0xa9,
- 0x46, 0x57, 0x9b, 0xbc, 0x2d, 0x64, 0x97, 0x8d },
- { 0x95, 0x68, 0x33, 0xae, 0xe6, 0x61, 0x19, 0x26,
- 0xe9, 0x52, 0x72, 0xa1, 0xf5, 0x88, 0xf9, 0x2a,
- 0xf5, 0x2c, 0xae, 0x70, 0x7a, 0xcd, 0xcc, 0x82,
- 0x63, 0x99, 0x7b, 0xfa, 0x8c, 0x71, 0x9c, 0xa8 },
- { 0x95, 0x89, 0xda, 0xc9, 0xec, 0xe7, 0x6d, 0xf5,
- 0x72, 0x01, 0x96, 0xdc, 0x58, 0x6d, 0x17, 0x9d,
- 0x73, 0x5d, 0xf7, 0x17, 0x92, 0x6c, 0x06, 0x1e,
- 0xa7, 0x0c, 0x40, 0x85, 0x64, 0x8f, 0xf3, 0x12 },
- { 0x96, 0xa4, 0x59, 0x90, 0xfc, 0xd0, 0x1c, 0x9c,
- 0x2a, 0xf0, 0x64, 0x5f, 0x87, 0xb9, 0x69, 0x8b,
- 0x05, 0xaf, 0xe6, 0x94, 0x32, 0xeb, 0x57, 0x01,
- 0x08, 0x20, 0x13, 0xba, 0xc5, 0xb0, 0x55, 0x60 },
- { 0x96, 0xeb, 0x44, 0xaa, 0x6a, 0x20, 0x49, 0xe6,
- 0xba, 0xff, 0xe6, 0xb5, 0x21, 0xc4, 0xad, 0x8c,
- 0x58, 0x77, 0x26, 0xca, 0xa0, 0x12, 0xe8, 0xfb,
- 0x8e, 0x8e, 0x21, 0x89, 0x77, 0xbf, 0x1d, 0xf6 },
- { 0x97, 0x4f, 0x51, 0xa6, 0x04, 0x68, 0x48, 0xfa,
- 0xa7, 0xb3, 0x3f, 0xd2, 0x39, 0x13, 0x86, 0x42,
- 0x8b, 0xd5, 0x24, 0xea, 0xeb, 0xa8, 0x01, 0x4e,
- 0x6d, 0x1f, 0xe2, 0x54, 0x38, 0x3f, 0x41, 0x79 },
- { 0x97, 0x8d, 0x6f, 0x1e, 0x9a, 0xa3, 0xa3, 0xce,
- 0xb1, 0xad, 0xa6, 0x09, 0xe2, 0x00, 0x95, 0xfb,
- 0xc3, 0x3a, 0x6b, 0xbc, 0x6a, 0x21, 0xd8, 0x0a,
- 0x4e, 0xcb, 0x27, 0x3c, 0x60, 0xac, 0x2a, 0xc7 },
- { 0x99, 0xa5, 0x5f, 0x76, 0xcb, 0xea, 0x0f, 0x3e,
- 0x60, 0x71, 0xd3, 0x82, 0x18, 0x1a, 0xf6, 0xcb,
- 0x25, 0xbd, 0xc5, 0x87, 0x5e, 0x29, 0xf0, 0xf4,
- 0xd7, 0x19, 0xa9, 0xd3, 0x5b, 0x5b, 0xd6, 0xbf },
- { 0x9a, 0x4b, 0x49, 0x93, 0xb4, 0xed, 0x8c, 0x27,
- 0xe7, 0x7f, 0x3c, 0x8a, 0xaf, 0xdb, 0xdc, 0x11,
- 0x1a, 0x36, 0xb7, 0x3c, 0xca, 0xdb, 0x87, 0x04,
- 0x98, 0x25, 0x00, 0xd1, 0xb0, 0xf1, 0x09, 0xf2 },
- { 0x9a, 0xae, 0x9d, 0x45, 0xaa, 0x04, 0x03, 0x06,
- 0x4b, 0xc5, 0xa7, 0x4d, 0xd0, 0x32, 0x5d, 0xa4,
- 0x1e, 0x12, 0xcf, 0x58, 0x6c, 0x46, 0x2e, 0xe0,
- 0x6c, 0x2b, 0xb4, 0x56, 0xf8, 0x44, 0x1c, 0x4f },
- { 0x9b, 0x8f, 0x9f, 0xc4, 0xaf, 0xa7, 0x04, 0x0d,
- 0x4e, 0x59, 0x4d, 0x66, 0x7c, 0x44, 0x44, 0xb5,
- 0x25, 0x88, 0x20, 0xc0, 0x8f, 0x89, 0x91, 0x0e,
- 0xd3, 0x42, 0x1c, 0xb4, 0xa9, 0x7b, 0xb7, 0x9e },
- { 0x9c, 0x70, 0x8d, 0x5b, 0xab, 0x37, 0xf5, 0xb6,
- 0xbc, 0x8a, 0x77, 0x53, 0x12, 0x57, 0x2a, 0xb2,
- 0x79, 0x21, 0x6d, 0x55, 0x6d, 0xa7, 0x4a, 0xc2,
- 0xa7, 0xc0, 0x41, 0xe8, 0xce, 0xb0, 0xbe, 0x0a },
- { 0x9d, 0x6b, 0xdf, 0xcf, 0x0c, 0xbf, 0xfe, 0xea,
- 0x3b, 0x1a, 0xc7, 0xe9, 0x63, 0xcb, 0xb5, 0xf2,
- 0x7f, 0xbd, 0xa8, 0x9d, 0x27, 0x77, 0xf6, 0x0e,
- 0x56, 0x5b, 0x27, 0x78, 0x54, 0xef, 0xb0, 0x19 },
- { 0x9d, 0xac, 0x33, 0x14, 0xb2, 0x5b, 0xb7, 0x9a,
- 0x39, 0xcd, 0x01, 0xec, 0x4b, 0x33, 0xa1, 0x2f,
- 0x47, 0x51, 0x2f, 0x54, 0x09, 0xff, 0x09, 0x5d,
- 0x40, 0xaa, 0xd6, 0x20, 0x84, 0xef, 0x15, 0xbe },
- { 0x9f, 0x24, 0x5c, 0x0a, 0x0e, 0xc6, 0x3a, 0xaa,
- 0xcb, 0xf9, 0x69, 0xc6, 0xfc, 0x24, 0xa1, 0x07,
- 0x15, 0x83, 0xb7, 0x79, 0xa5, 0x8a, 0xb6, 0x23,
- 0xdd, 0x15, 0x31, 0xa2, 0xca, 0x9f, 0x87, 0x51 },
- { 0x9f, 0xaf, 0x1c, 0x11, 0xa3, 0xc7, 0xe2, 0x41,
- 0xf8, 0x63, 0x71, 0x97, 0xe8, 0x99, 0x68, 0xdb,
- 0x86, 0x6a, 0xd0, 0x1a, 0x5d, 0x4e, 0xd5, 0x34,
- 0x59, 0x48, 0x65, 0xb9, 0x70, 0x75, 0xf2, 0x60 },
- { 0xa0, 0x05, 0x20, 0xb9, 0x68, 0xbf, 0xcb, 0x63,
- 0x40, 0x87, 0x9f, 0xa8, 0x43, 0x82, 0x0c, 0xec,
- 0x95, 0x45, 0x86, 0x0f, 0xe2, 0x9e, 0x2f, 0x8f,
- 0xee, 0x00, 0xb0, 0x0f, 0xf8, 0x43, 0x42, 0x74 },
- { 0xa0, 0xc2, 0xd2, 0x07, 0xa4, 0x7e, 0x18, 0xd0,
- 0x37, 0x14, 0xd5, 0xb3, 0x44, 0x5d, 0x88, 0xbe,
- 0x81, 0xff, 0x5e, 0x1d, 0x16, 0x07, 0x3d, 0xc1,
- 0x16, 0x6b, 0xb5, 0x44, 0x8f, 0xf6, 0x52, 0xdf },
- { 0xa1, 0x50, 0x03, 0x2f, 0x4e, 0xf5, 0xd4, 0xfe,
- 0xb0, 0xae, 0x4a, 0xe1, 0xcd, 0x54, 0x35, 0xba,
- 0x04, 0xa9, 0xb6, 0xa0, 0xf9, 0x0e, 0x2f, 0x3c,
- 0x4b, 0x8a, 0x7b, 0x69, 0xe7, 0xc8, 0x7e, 0x43 },
- { 0xa1, 0x97, 0x7d, 0x0c, 0x92, 0x7c, 0x21, 0xeb,
- 0x47, 0x6f, 0x67, 0xbe, 0xfe, 0xd6, 0xcf, 0x2c,
- 0x61, 0xb7, 0x45, 0xf0, 0xce, 0x8d, 0x26, 0x58,
- 0x3d, 0x03, 0xb2, 0x70, 0x02, 0xd5, 0xcd, 0xaf },
- { 0xa2, 0x6c, 0x37, 0x5e, 0xb3, 0x19, 0x6e, 0x28,
- 0x3b, 0xec, 0x60, 0x3d, 0xb6, 0xbb, 0xda, 0xe2,
- 0x49, 0x55, 0xe4, 0xba, 0x91, 0x0c, 0xd4, 0x2d,
- 0x9e, 0xac, 0x55, 0xca, 0xc6, 0x10, 0x3a, 0xb9 },
- { 0xa3, 0xa4, 0xfc, 0x03, 0xe1, 0x75, 0xf2, 0x68,
- 0x02, 0x57, 0x46, 0x34, 0xde, 0x70, 0x7d, 0x2f,
- 0x92, 0xf4, 0xd0, 0xcb, 0x90, 0xcd, 0xb6, 0x1d,
- 0xd1, 0x95, 0x8b, 0xcf, 0x0c, 0x55, 0x20, 0x86 },
- { 0xa6, 0x62, 0xfc, 0x81, 0xc9, 0x09, 0x34, 0xb9,
- 0xb4, 0xd6, 0x30, 0xb5, 0xd8, 0x2e, 0x86, 0xf2,
- 0x36, 0x3e, 0xc1, 0x5c, 0xcf, 0xcd, 0xaf, 0xa7,
- 0xa2, 0x0c, 0x9b, 0x4e, 0x3a, 0x90, 0x0d, 0xd1 },
- { 0xa6, 0xa4, 0xa3, 0xf6, 0x1f, 0xa5, 0x8c, 0xe9,
- 0x70, 0xb4, 0x58, 0xb7, 0xc3, 0x7c, 0x05, 0x2e,
- 0xad, 0x1e, 0xb2, 0x0b, 0x85, 0x67, 0xe3, 0x51,
- 0xad, 0x8e, 0x6f, 0xba, 0x49, 0xc2, 0x69, 0x2c },
- { 0xa6, 0xde, 0x6c, 0x3b, 0x8c, 0x14, 0x05, 0xcb,
- 0xe1, 0x2d, 0xb4, 0x09, 0x97, 0x61, 0x71, 0xac,
- 0xb5, 0x1f, 0xb3, 0xdc, 0xfb, 0xb7, 0x6e, 0xe3,
- 0x84, 0x95, 0x39, 0xcd, 0x8a, 0xb0, 0x66, 0xdf },
- { 0xa8, 0x53, 0xad, 0xc1, 0xc2, 0x18, 0x59, 0xaf,
- 0x7c, 0x46, 0x2b, 0x4a, 0xa0, 0xa5, 0x74, 0xca,
- 0x9f, 0xee, 0xfb, 0x18, 0x5a, 0x1f, 0xdb, 0xb6,
- 0xc1, 0x0e, 0x17, 0xd6, 0x01, 0xb7, 0x09, 0x8f },
- { 0xa8, 0xdf, 0xf0, 0x6a, 0x17, 0x35, 0xb4, 0x6d,
- 0x17, 0xda, 0xeb, 0xc3, 0x43, 0x43, 0x18, 0x31,
- 0x3b, 0x2d, 0x9e, 0x7c, 0x3e, 0xf4, 0x8f, 0x28,
- 0x53, 0x75, 0x35, 0x13, 0xe1, 0xb2, 0x53, 0xa8 },
- { 0xa8, 0xe3, 0x8c, 0x6e, 0xc0, 0x93, 0xf5, 0xaf,
- 0x53, 0x88, 0xf1, 0xe7, 0x66, 0xd7, 0x5f, 0xfb,
- 0x57, 0xdd, 0xbe, 0x3e, 0x9d, 0xc2, 0xe0, 0xbe,
- 0x57, 0xbb, 0x88, 0x36, 0x46, 0xc5, 0xc0, 0x32 },
- { 0xa9, 0x0b, 0x8d, 0xe1, 0x7f, 0x6b, 0x68, 0x37,
- 0x56, 0x21, 0x2d, 0xb3, 0xab, 0x34, 0x89, 0x6e,
- 0x91, 0x70, 0x93, 0x11, 0x3e, 0x47, 0xca, 0x35,
- 0x96, 0x2e, 0xac, 0xca, 0x9c, 0xb3, 0x86, 0xf0 },
- { 0xaa, 0x4b, 0xb3, 0x6f, 0x51, 0xd3, 0xc5, 0x33,
- 0xb5, 0x27, 0x23, 0xcf, 0x66, 0xa5, 0xa9, 0x9f,
- 0xc1, 0x2f, 0x11, 0xd4, 0xcc, 0x12, 0x87, 0x56,
- 0xa5, 0xa3, 0xe8, 0x9c, 0x57, 0xbb, 0x97, 0x51 },
- { 0xaa, 0xeb, 0xfe, 0x2d, 0x21, 0xb7, 0xe5, 0x35,
- 0x1b, 0xb9, 0x99, 0x69, 0x44, 0x44, 0x19, 0xef,
- 0x21, 0xc9, 0x68, 0x8c, 0xe0, 0x53, 0x24, 0x88,
- 0x84, 0xca, 0xb0, 0xb8, 0x95, 0x10, 0x30, 0xff },
- { 0xab, 0x41, 0x28, 0x10, 0x9c, 0xab, 0x8a, 0x58,
- 0x7c, 0x8f, 0xf4, 0xc7, 0xf6, 0x87, 0x34, 0x49,
- 0x98, 0x18, 0xd1, 0x3f, 0x52, 0x26, 0x76, 0xd0,
- 0x66, 0xb3, 0x52, 0x17, 0x6f, 0xd2, 0x35, 0x96 },
- { 0xab, 0x80, 0xd9, 0xba, 0x0a, 0xef, 0xad, 0x7b,
- 0xec, 0xce, 0x7f, 0x5e, 0x61, 0x59, 0x9a, 0xf5,
- 0x26, 0x69, 0xbf, 0x59, 0x50, 0x7f, 0x8e, 0xf1,
- 0x99, 0x13, 0xc4, 0x2e, 0xe1, 0x29, 0xda, 0xf0 },
- { 0xab, 0xeb, 0x6a, 0xa0, 0xd1, 0xb0, 0xe0, 0x49,
- 0xd6, 0x9d, 0xf8, 0x3a, 0xdd, 0x19, 0xf7, 0x26,
- 0x8a, 0x38, 0xde, 0x6c, 0x00, 0x72, 0x60, 0x68,
- 0xc2, 0xee, 0xe4, 0x55, 0x44, 0xf6, 0xd6, 0x7a },
- { 0xac, 0x1b, 0x4c, 0x64, 0x6c, 0xae, 0xfb, 0x10,
- 0x8a, 0x54, 0xca, 0xb5, 0x4a, 0x96, 0xe9, 0x66,
- 0x6e, 0x72, 0xa8, 0x20, 0x22, 0x44, 0xef, 0x3d,
- 0x7c, 0xa9, 0x34, 0xdf, 0xcc, 0x24, 0xfc, 0xa7 },
- { 0xad, 0x69, 0x54, 0x5f, 0x9f, 0x85, 0x25, 0x5f,
- 0xe4, 0x16, 0x51, 0x3d, 0x94, 0xdb, 0x31, 0x50,
- 0x5f, 0x38, 0x4b, 0x52, 0x3c, 0x2c, 0xa2, 0x6e,
- 0xdc, 0x0a, 0x54, 0x9a, 0x8f, 0x16, 0x26, 0xf9 },
- { 0xae, 0x03, 0x19, 0xfe, 0xa6, 0xa6, 0x5e, 0x84,
- 0xe8, 0x54, 0xb5, 0x15, 0x50, 0xea, 0x44, 0x4f,
- 0xa3, 0xb8, 0xbb, 0x50, 0xae, 0x93, 0x74, 0x01,
- 0x3c, 0xfe, 0xf3, 0x88, 0x73, 0x5d, 0x0b, 0xd3 },
- { 0xaf, 0x1f, 0x37, 0x1f, 0x34, 0x84, 0x57, 0x51,
- 0x65, 0x2d, 0xc7, 0x48, 0x23, 0xf3, 0x01, 0x5c,
- 0x5a, 0x11, 0xca, 0x65, 0x3f, 0x28, 0x70, 0x1e,
- 0xdd, 0x4a, 0x7e, 0x0d, 0x23, 0x17, 0x1b, 0xbb },
- { 0xaf, 0x6b, 0x80, 0x51, 0x47, 0x14, 0x0a, 0x0e,
- 0x41, 0x81, 0xd8, 0x6a, 0x7e, 0x8f, 0x07, 0x69,
- 0xb6, 0x1d, 0x46, 0xd7, 0xb6, 0xfa, 0xc6, 0xe6,
- 0xf9, 0x59, 0x6d, 0xe9, 0x4a, 0xa8, 0xe2, 0xe8 },
- { 0xb0, 0x5c, 0x14, 0x33, 0x61, 0x75, 0x9b, 0xe1,
- 0x52, 0xfd, 0x76, 0xa5, 0xff, 0xa4, 0x87, 0x2d,
- 0xd4, 0x2e, 0xa0, 0x60, 0xae, 0x40, 0xa3, 0x83,
- 0x13, 0xb7, 0xb5, 0x4a, 0xec, 0x06, 0x73, 0xc2 },
- { 0xb0, 0xe0, 0xe1, 0x6c, 0x5f, 0x69, 0x1f, 0x66,
- 0xa9, 0x57, 0x3b, 0xd3, 0xcf, 0x43, 0xf9, 0xdf,
- 0xd2, 0xad, 0x3e, 0x56, 0x15, 0x54, 0x63, 0x7f,
- 0x1e, 0x7b, 0x71, 0x91, 0x4d, 0x62, 0x73, 0x38 },
- { 0xb2, 0xdc, 0x86, 0x25, 0x6c, 0xcf, 0xf4, 0xbb,
- 0x14, 0xfd, 0x70, 0x27, 0x9f, 0xcc, 0x3c, 0xe9,
- 0x25, 0xc5, 0x1f, 0xb7, 0x17, 0xe5, 0x87, 0x6f,
- 0x29, 0x1b, 0xa1, 0x70, 0x73, 0x43, 0x85, 0x68 },
- { 0xb3, 0x0d, 0x88, 0x44, 0x30, 0x43, 0xf5, 0xf3,
- 0x72, 0x32, 0xbb, 0x9b, 0xac, 0xb9, 0x94, 0xc5,
- 0xba, 0xe9, 0x3a, 0x46, 0xfc, 0x87, 0xf1, 0x51,
- 0x29, 0xc9, 0x74, 0x69, 0xa5, 0x81, 0x4e, 0xca },
- { 0xb3, 0x1a, 0xf0, 0xc2, 0xe5, 0x1e, 0xa2, 0x1c,
- 0x91, 0x04, 0xf9, 0x4f, 0xaa, 0x66, 0xe0, 0xcc,
- 0xc0, 0x41, 0x34, 0xd5, 0x80, 0x9a, 0x2a, 0x26,
- 0x70, 0xa3, 0xb7, 0xbc, 0x7d, 0xd9, 0x64, 0xf8 },
- { 0xb3, 0xf4, 0xb1, 0x6f, 0x8e, 0xce, 0xbb, 0x41,
- 0x47, 0x4f, 0x92, 0x4f, 0xee, 0xf9, 0xb0, 0xbd,
- 0x97, 0x9b, 0x36, 0x36, 0xc3, 0x4f, 0xf2, 0x72,
- 0x3f, 0x67, 0x3c, 0x8e, 0xee, 0x2a, 0xf1, 0x52 },
- { 0xb5, 0xe5, 0xdc, 0xde, 0xcb, 0x8d, 0xeb, 0x27,
- 0x13, 0x4f, 0x02, 0xa5, 0x18, 0x79, 0x43, 0x16,
- 0xf0, 0x8f, 0xaf, 0x9c, 0x2b, 0x1f, 0xda, 0xd6,
- 0xd4, 0x86, 0x61, 0xf5, 0x7e, 0xa6, 0x45, 0xd9 },
- { 0xb7, 0x06, 0xde, 0x1b, 0xd1, 0xee, 0x2f, 0x4c,
- 0xec, 0x6c, 0xe0, 0x92, 0x02, 0x2b, 0x49, 0x32,
- 0x81, 0xe2, 0x9a, 0x21, 0x73, 0x50, 0x8c, 0x9b,
- 0xd0, 0xfb, 0xc2, 0xc3, 0xd9, 0x68, 0xe3, 0xe7 },
- { 0xb7, 0xa2, 0xae, 0x06, 0x06, 0xaa, 0x2c, 0xfb,
- 0x27, 0x01, 0xb3, 0xb2, 0x77, 0xf4, 0xd7, 0x12,
- 0x54, 0x70, 0x48, 0x7e, 0xfd, 0x94, 0x05, 0x85,
- 0x7f, 0xfc, 0xe4, 0xbf, 0x29, 0x10, 0x5e, 0x68 },
- { 0xb8, 0x74, 0x36, 0x95, 0x1c, 0xec, 0x37, 0x7e,
- 0xef, 0x73, 0xde, 0x4b, 0x74, 0xf2, 0x83, 0xc4,
- 0x2b, 0x2c, 0xcb, 0x1c, 0xa3, 0x7c, 0x5b, 0x30,
- 0xaa, 0xd6, 0x55, 0xa7, 0x40, 0x1a, 0x3d, 0x2f },
- { 0xb9, 0x8d, 0x83, 0x38, 0x55, 0xc3, 0x67, 0x88,
- 0x62, 0xb6, 0x2f, 0x36, 0x50, 0xdb, 0x00, 0xa3,
- 0x45, 0xf4, 0x6a, 0x0e, 0x8e, 0x01, 0x1a, 0x20,
- 0x01, 0x3f, 0xd8, 0xed, 0xce, 0x25, 0x27, 0x0d },
- { 0xba, 0x51, 0xaf, 0xf5, 0xd5, 0xd3, 0x10, 0x5f,
- 0x34, 0xa2, 0xb3, 0x3a, 0x83, 0xe3, 0xad, 0xfd,
- 0x12, 0xd7, 0x9c, 0xa6, 0x05, 0x90, 0x9d, 0x96,
- 0x03, 0x3e, 0x32, 0xa5, 0xcf, 0x2f, 0x71, 0xf6 },
- { 0xbb, 0x5c, 0xb3, 0x78, 0xb7, 0xb9, 0x48, 0x7f,
- 0xa6, 0x1b, 0xc0, 0x91, 0x3d, 0xa1, 0xdf, 0x26,
- 0xa1, 0xcf, 0xef, 0xf7, 0x45, 0x2d, 0x9b, 0xa3,
- 0x6c, 0xac, 0x47, 0xa8, 0x5c, 0x7f, 0xf3, 0x48 },
- { 0xbc, 0x14, 0x2e, 0xba, 0xc2, 0x78, 0xa8, 0xfe,
- 0x8c, 0xa8, 0xbc, 0x2c, 0x62, 0xfb, 0xcc, 0x40,
- 0x17, 0xff, 0x24, 0x96, 0x98, 0xbe, 0xed, 0xfb,
- 0x1e, 0xf3, 0x6f, 0x37, 0x5f, 0xb3, 0x9f, 0x72 },
- { 0xbd, 0x2e, 0x2f, 0x37, 0xc9, 0x66, 0xc3, 0x86,
- 0xd9, 0x70, 0x44, 0xfd, 0xe3, 0xe3, 0xf9, 0x00,
- 0xfb, 0x1a, 0x0b, 0x04, 0x03, 0xb5, 0x81, 0x72,
- 0x5f, 0x34, 0xe3, 0xc1, 0x90, 0x05, 0x60, 0x56 },
- { 0xbe, 0xb9, 0x09, 0x0c, 0x92, 0xd1, 0x6b, 0xd0,
- 0x5a, 0xf3, 0x91, 0x5a, 0x39, 0xcc, 0x2a, 0xfa,
- 0x9f, 0x6a, 0x8a, 0x6f, 0xbe, 0xd4, 0xfe, 0x54,
- 0xd9, 0xde, 0x32, 0x49, 0x23, 0xb3, 0x93, 0x5a },
- { 0xbf, 0x38, 0xe6, 0xae, 0x32, 0x0f, 0x69, 0x16,
- 0x16, 0x0d, 0xa6, 0x06, 0x86, 0x83, 0xbf, 0x49,
- 0xf2, 0xb2, 0x2b, 0x25, 0x24, 0x84, 0x63, 0x68,
- 0xf5, 0x04, 0x51, 0x81, 0x52, 0x40, 0x25, 0x9a },
- { 0xbf, 0x60, 0xae, 0xb3, 0x91, 0xc0, 0xfb, 0xd0,
- 0x49, 0x53, 0x52, 0x6d, 0xa9, 0xfd, 0x59, 0x96,
- 0x9a, 0x82, 0xf1, 0xee, 0x81, 0xa7, 0x97, 0x98,
- 0xa4, 0x17, 0x1e, 0x14, 0x59, 0x39, 0x19, 0x67 },
- { 0xbf, 0xf4, 0x3a, 0x97, 0x20, 0x48, 0x2d, 0x13,
- 0x4c, 0xd5, 0xee, 0x8a, 0x88, 0x99, 0xe1, 0xa7,
- 0x36, 0xbf, 0x54, 0xa2, 0xb7, 0x86, 0x26, 0x9c,
- 0x0d, 0xcb, 0x8b, 0xa1, 0x92, 0xa8, 0x1f, 0xa4 },
- { 0xc0, 0x09, 0xa1, 0xbe, 0x5b, 0xe8, 0xaf, 0xb5,
- 0x25, 0x8e, 0x12, 0x85, 0x5c, 0x64, 0xd0, 0x4d,
- 0x13, 0xe8, 0xcc, 0xc4, 0x7b, 0x02, 0xbf, 0x3b,
- 0x51, 0xc6, 0xe1, 0x18, 0x05, 0xae, 0xec, 0xeb },
- { 0xc0, 0x9f, 0xfa, 0x0e, 0xdd, 0x16, 0xba, 0x55,
- 0xf2, 0x3c, 0xea, 0xf7, 0x2b, 0x11, 0x34, 0xe9,
- 0x28, 0xdb, 0xa1, 0xc2, 0x34, 0x5a, 0x5a, 0xb5,
- 0x63, 0x1e, 0x25, 0x41, 0x24, 0x05, 0x4a, 0xdb },
- { 0xc0, 0xab, 0xd1, 0xc3, 0x56, 0x2f, 0xbc, 0x7f,
- 0xf7, 0xbd, 0x38, 0x95, 0x54, 0x60, 0xc3, 0xfc,
- 0x43, 0x55, 0x0d, 0x97, 0x7f, 0x25, 0xe3, 0x43,
- 0xd4, 0x9c, 0xd4, 0xaf, 0xad, 0xf2, 0x09, 0x3c },
- { 0xc0, 0xfe, 0xb7, 0x2a, 0x5f, 0x33, 0x16, 0x5c,
- 0x0d, 0xc7, 0xc4, 0x24, 0x7e, 0x23, 0xf3, 0x8c,
- 0xc6, 0x1f, 0x25, 0x24, 0x42, 0xb2, 0xf6, 0x13,
- 0x40, 0x92, 0xde, 0x3b, 0xad, 0x7e, 0x45, 0x0d },
- { 0xc1, 0x77, 0x12, 0x97, 0xa4, 0xe8, 0xdc, 0x53,
- 0x75, 0x19, 0x5e, 0x1b, 0x63, 0x04, 0x2b, 0x59,
- 0x19, 0x09, 0xf1, 0xd7, 0xeb, 0x5d, 0x25, 0xf2,
- 0x97, 0xae, 0x7a, 0x61, 0xc1, 0x53, 0x8f, 0x9e },
- { 0xc1, 0x86, 0xbe, 0x26, 0xe4, 0x47, 0x89, 0x7c,
- 0x48, 0x3c, 0x43, 0xfd, 0xc0, 0x86, 0xe2, 0x60,
- 0x74, 0x17, 0xeb, 0x3e, 0xa7, 0x88, 0xec, 0x03,
- 0x10, 0xa7, 0x9d, 0xa9, 0x24, 0x1d, 0x16, 0xde },
- { 0xc1, 0xde, 0x5f, 0xa3, 0x92, 0x13, 0x68, 0x58,
- 0x11, 0xa5, 0xba, 0x93, 0x12, 0x1d, 0xe7, 0xa3,
- 0x95, 0x98, 0x4e, 0x84, 0x44, 0x4e, 0x58, 0xf1,
- 0x63, 0xb7, 0xa6, 0x20, 0xae, 0x3b, 0xbf, 0xa8 },
- { 0xc2, 0xad, 0xdf, 0x99, 0xcf, 0xc4, 0x2c, 0xe0,
- 0xe5, 0xa0, 0x93, 0xbc, 0xbf, 0x87, 0x40, 0x7c,
- 0x61, 0x1f, 0x9d, 0x0a, 0xbf, 0x2a, 0x35, 0xd6,
- 0xe8, 0x03, 0xa3, 0x8e, 0xcb, 0x92, 0xc7, 0xb3 },
- { 0xc2, 0xe7, 0x92, 0x11, 0x6a, 0x05, 0x00, 0x00,
- 0xbd, 0x47, 0x59, 0x1d, 0x93, 0x04, 0x71, 0xe6,
- 0x17, 0x4c, 0x93, 0x85, 0xf5, 0xdc, 0x32, 0xb7,
- 0x62, 0x31, 0x65, 0x5f, 0xc8, 0x5e, 0x22, 0xe2 },
- { 0xc3, 0x79, 0x03, 0xc5, 0x3a, 0xe6, 0x02, 0xec,
- 0x96, 0x9e, 0xc3, 0x3f, 0x63, 0xfe, 0x9a, 0xb2,
- 0x0c, 0x39, 0x5f, 0x83, 0x0d, 0x30, 0xe4, 0xee,
- 0x9d, 0x8d, 0xd9, 0x05, 0x92, 0x1e, 0xc1, 0xa0 },
- { 0xc3, 0xcf, 0x54, 0x16, 0xa5, 0x31, 0xaf, 0x4b,
- 0xfa, 0xe8, 0x9c, 0x45, 0x14, 0x3f, 0x20, 0xcc,
- 0x1b, 0x3e, 0x18, 0x1d, 0x29, 0xc2, 0xd0, 0xe8,
- 0xff, 0x7d, 0x3f, 0x2a, 0x66, 0xb1, 0x82, 0xfe },
- { 0xc4, 0x98, 0xa1, 0xb6, 0x9f, 0x54, 0x40, 0x86,
- 0x17, 0x47, 0x47, 0x71, 0x5a, 0x27, 0x4d, 0x3f,
- 0xb5, 0x90, 0x19, 0xbe, 0x09, 0x21, 0x31, 0xbc,
- 0xfa, 0xa8, 0x3a, 0x39, 0x5f, 0x7e, 0x57, 0x3c },
- { 0xc4, 0xe2, 0x8d, 0xd8, 0x3f, 0xe3, 0x0c, 0x96,
- 0x33, 0x8c, 0xef, 0x77, 0x73, 0xc6, 0xdf, 0xca,
- 0x6c, 0xe4, 0xfa, 0x96, 0x41, 0xbe, 0xab, 0x38,
- 0x05, 0xa8, 0xef, 0xb6, 0xcd, 0xc3, 0xcf, 0x0a },
- { 0xc5, 0x00, 0xb8, 0x3f, 0x3e, 0x06, 0x6c, 0xd1,
- 0xdd, 0x0e, 0xbc, 0xd7, 0x3d, 0xd4, 0x01, 0x61,
- 0xb9, 0x25, 0x9a, 0xa7, 0x7a, 0xb8, 0xa6, 0x47,
- 0xe8, 0x57, 0x1f, 0xf3, 0x37, 0xcf, 0x94, 0x6d },
- { 0xc5, 0x29, 0x5b, 0xa6, 0xe2, 0x7e, 0x72, 0x10,
- 0x22, 0xfe, 0xb2, 0x1e, 0x78, 0xeb, 0x7b, 0x03,
- 0x57, 0xc9, 0xcd, 0x56, 0x5b, 0xd0, 0xe5, 0x96,
- 0x72, 0xf6, 0x66, 0x34, 0x2b, 0x79, 0x94, 0x9d },
- { 0xc6, 0x12, 0x75, 0x6b, 0xa5, 0x42, 0x34, 0x4a,
- 0xdc, 0x1b, 0x80, 0xe9, 0x38, 0x84, 0x5a, 0x1e,
- 0xd6, 0xe9, 0x38, 0xfe, 0xf4, 0x0d, 0x04, 0xec,
- 0x86, 0x55, 0x8f, 0x4b, 0x21, 0x05, 0x2f, 0xd2 },
- { 0xc6, 0x17, 0xe0, 0x85, 0x5b, 0xf1, 0x4f, 0xbf,
- 0x21, 0xaf, 0x00, 0x82, 0x25, 0xca, 0xbe, 0x40,
- 0x4f, 0x73, 0x8c, 0x27, 0x8a, 0x4a, 0x42, 0x87,
- 0xf1, 0xee, 0x38, 0x01, 0x27, 0xc5, 0x61, 0xfa },
- { 0xc6, 0xa4, 0x24, 0xbf, 0x7c, 0xfe, 0x31, 0x72,
- 0x74, 0x7a, 0x47, 0x14, 0xa0, 0xef, 0xb9, 0x17,
- 0x93, 0x8c, 0x5e, 0xbd, 0x59, 0x12, 0x9d, 0xed,
- 0x7a, 0x81, 0x18, 0xc7, 0xf6, 0x59, 0xd1, 0x33 },
- { 0xc6, 0xad, 0x1d, 0x7a, 0x14, 0x1a, 0x91, 0x75,
- 0x2d, 0x31, 0xfb, 0xc1, 0x06, 0x16, 0xbf, 0x1c,
- 0xa2, 0xfb, 0x5b, 0x02, 0xe8, 0x46, 0xb5, 0x9e,
- 0x63, 0x34, 0x6b, 0x31, 0x92, 0xa7, 0x52, 0x92 },
- { 0xc7, 0x01, 0x83, 0x64, 0x38, 0xf3, 0x7b, 0xea,
- 0x8a, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xf8,
- 0x8d, 0x9a, 0x11, 0x5e, 0x00, 0x92, 0x46, 0xd2,
- 0x7f, 0x48, 0x9f, 0xa7, 0x18, 0x51, 0x88, 0xa8 },
- { 0xc7, 0xff, 0x8e, 0xfd, 0xec, 0xdf, 0x00, 0xd1,
- 0xfc, 0x8d, 0x55, 0x2d, 0x2a, 0x70, 0x70, 0xe5,
- 0xe3, 0x3d, 0x42, 0xe5, 0x90, 0xf5, 0x86, 0xc6,
- 0xae, 0xde, 0x03, 0x2b, 0x2d, 0x86, 0x7b, 0xd5 },
- { 0xc7, 0xff, 0xb4, 0x9f, 0xbc, 0x94, 0x72, 0x24,
- 0x5c, 0x8e, 0x95, 0xde, 0x62, 0x9a, 0xf5, 0xc1,
- 0xbf, 0xea, 0xc5, 0x50, 0x04, 0xc1, 0x54, 0x82,
- 0x3a, 0x58, 0xba, 0xe8, 0x05, 0x6e, 0x3c, 0x64 },
- { 0xc8, 0x37, 0xd6, 0xf2, 0xab, 0x14, 0x79, 0x91,
- 0x42, 0xed, 0x3c, 0x79, 0xbe, 0xd9, 0x44, 0x1e,
- 0x92, 0x50, 0xbd, 0x05, 0x20, 0x25, 0xad, 0x8a,
- 0xf4, 0x40, 0x41, 0xac, 0x19, 0xef, 0xbb, 0x4c },
- { 0xc9, 0x72, 0xf4, 0xf9, 0x6e, 0x71, 0x33, 0xe1,
- 0x6e, 0x55, 0x57, 0xa0, 0x57, 0xb1, 0xd4, 0x2b,
- 0xa9, 0x2d, 0x98, 0x5c, 0xae, 0xe7, 0x3c, 0xaf,
- 0xda, 0xeb, 0x55, 0xec, 0xa2, 0xe4, 0xab, 0xb0 },
- { 0xc9, 0x78, 0x37, 0x2c, 0x9e, 0x11, 0x60, 0x71,
- 0xb6, 0x1b, 0x90, 0x92, 0xa9, 0xaa, 0x96, 0x81,
- 0x62, 0x36, 0x55, 0xa6, 0x6f, 0x4f, 0xcb, 0xc4,
- 0xd3, 0xa6, 0x7e, 0xfd, 0x56, 0x72, 0x48, 0x30 },
- { 0xca, 0x55, 0x6f, 0x82, 0xc9, 0x68, 0x4c, 0x9a,
- 0xf3, 0x55, 0x7d, 0x3e, 0x2d, 0x88, 0xaf, 0x92,
- 0xed, 0x25, 0x9c, 0x20, 0xff, 0xd1, 0xdd, 0xe9,
- 0xf7, 0x9d, 0x6b, 0x92, 0xc6, 0x1e, 0xe1, 0xb9 },
- { 0xca, 0xbe, 0x25, 0x56, 0xf1, 0xbb, 0x56, 0x57,
- 0x0c, 0xef, 0x3a, 0x87, 0x03, 0x32, 0x71, 0xa1,
- 0xf2, 0x1d, 0x09, 0xb7, 0xfd, 0x04, 0x12, 0x83,
- 0x18, 0xe5, 0xe7, 0xbc, 0xe3, 0xa2, 0x01, 0xe2 },
- { 0xca, 0xdc, 0xd5, 0xae, 0x1b, 0x75, 0x6a, 0xb7,
- 0x41, 0xb3, 0x56, 0x9c, 0x42, 0xa5, 0x41, 0x1f,
- 0x09, 0x3e, 0x4e, 0x1f, 0x01, 0x2e, 0xc5, 0x79,
- 0x91, 0xcb, 0xd6, 0xdb, 0xe0, 0x8f, 0xaa, 0xc1 },
- { 0xcb, 0x7a, 0x43, 0x8d, 0x16, 0xe4, 0xa5, 0xf3,
- 0xc5, 0x6f, 0xdf, 0x19, 0x1e, 0x1d, 0xaf, 0x9f,
- 0x32, 0x5c, 0x65, 0x0b, 0xd6, 0x2f, 0x07, 0xc4,
- 0x67, 0x71, 0x72, 0x07, 0x35, 0x1a, 0xe3, 0x29 },
- { 0xcc, 0x30, 0xd8, 0x19, 0xde, 0x54, 0x05, 0xf6,
- 0x49, 0xc8, 0xb7, 0xa8, 0x14, 0x8f, 0x26, 0xd7,
- 0x71, 0x08, 0x3e, 0xc5, 0x18, 0xf9, 0xb6, 0x6f,
- 0xf5, 0x47, 0xf2, 0x82, 0x2d, 0x11, 0x93, 0x6d },
- { 0xcc, 0x65, 0xcd, 0xc5, 0x33, 0x62, 0xd4, 0x21,
- 0x62, 0x7e, 0xae, 0xf5, 0xd0, 0xc8, 0xe4, 0xc4,
- 0xe2, 0x40, 0xad, 0xe0, 0xc9, 0xd4, 0x20, 0xbe,
- 0x67, 0x1e, 0x70, 0xf0, 0xfb, 0xac, 0x8d, 0x0a },
- { 0xcd, 0xb1, 0x62, 0x53, 0xd2, 0x2e, 0xd5, 0xd4,
- 0x26, 0xcf, 0xa1, 0xb0, 0x5c, 0xec, 0xd8, 0x6e,
- 0xf1, 0xb7, 0xde, 0xaa, 0x07, 0xc5, 0x70, 0x5e,
- 0xbb, 0xaf, 0x7d, 0x9a, 0x80, 0x7d, 0x56, 0x16 },
- { 0xcd, 0xc0, 0x39, 0xf3, 0xa2, 0xd1, 0xbb, 0xa5,
- 0xe8, 0x09, 0x4e, 0x55, 0x23, 0xcf, 0x60, 0x47,
- 0x09, 0x7d, 0x4b, 0x3c, 0xd4, 0xec, 0x4e, 0xd6,
- 0xaa, 0x8e, 0xb7, 0xb4, 0xd8, 0xb5, 0x77, 0x7d },
- { 0xcd, 0xc4, 0xea, 0x92, 0x02, 0xe3, 0x3e, 0xdd,
- 0x0f, 0x2d, 0x3a, 0xe8, 0x6a, 0xca, 0xc7, 0xfb,
- 0x25, 0x35, 0x4b, 0x02, 0x23, 0x5b, 0x09, 0x33,
- 0xaa, 0x81, 0xa3, 0x13, 0xb5, 0xfd, 0xfe, 0xec },
- { 0xce, 0x4c, 0x2f, 0x8f, 0x16, 0x46, 0x8a, 0x58,
- 0x88, 0xe9, 0x0f, 0x73, 0x4e, 0x4d, 0x22, 0x02,
- 0xdf, 0xad, 0xbf, 0xa6, 0x6f, 0x5b, 0x35, 0x75,
- 0x2b, 0xaa, 0x76, 0x21, 0xa7, 0x60, 0xb0, 0x88 },
- { 0xce, 0x81, 0x44, 0x58, 0x54, 0x03, 0x1f, 0x3d,
- 0x0f, 0x5c, 0x88, 0x75, 0x46, 0x4d, 0xcd, 0x5b,
- 0xa6, 0xc8, 0x90, 0xf4, 0x49, 0xb3, 0x20, 0x7b,
- 0xca, 0x2b, 0xc9, 0x61, 0x82, 0x2d, 0x27, 0xc4 },
- { 0xcf, 0xa0, 0xc0, 0x0c, 0xb2, 0xfb, 0x4b, 0x85,
- 0x7a, 0xad, 0x22, 0xb1, 0x3a, 0x90, 0xe3, 0x46,
- 0xa0, 0x3e, 0x6b, 0x79, 0xab, 0xd5, 0xd2, 0x75,
- 0xb5, 0x43, 0x24, 0x68, 0x17, 0x92, 0xd6, 0xd1 },
- { 0xd0, 0xf5, 0x93, 0xc1, 0xa8, 0x1b, 0x1e, 0xf8,
- 0x51, 0x69, 0x81, 0xee, 0x56, 0xf1, 0xd5, 0x98,
- 0xa2, 0xa6, 0x03, 0x48, 0x8c, 0x67, 0x8c, 0x1b,
- 0x7b, 0xbe, 0xa6, 0x44, 0x6b, 0x00, 0x83, 0xad },
- { 0xd2, 0x90, 0x3c, 0xa2, 0x55, 0x17, 0x27, 0xed,
- 0x01, 0x71, 0xcc, 0x4a, 0x43, 0xb3, 0xca, 0xe0,
- 0x09, 0xb7, 0x47, 0xb9, 0xf4, 0xf8, 0x48, 0x72,
- 0x92, 0x27, 0xbf, 0x59, 0x02, 0xf2, 0x3e, 0x47 },
- { 0xd2, 0xe8, 0xa1, 0x23, 0x7a, 0x93, 0xf5, 0x78,
- 0xd1, 0xba, 0x8f, 0x09, 0xe4, 0xff, 0x10, 0x7b,
- 0x62, 0x35, 0x78, 0x85, 0x42, 0xaa, 0x61, 0x83,
- 0xd1, 0x76, 0xdb, 0xf1, 0xc8, 0x8d, 0xcf, 0xb6 },
- { 0xd5, 0x04, 0x88, 0x96, 0x86, 0x07, 0x29, 0xa8,
- 0xfa, 0x5d, 0x23, 0x57, 0x81, 0x2b, 0xa5, 0x6c,
- 0xbe, 0x84, 0xc9, 0xab, 0x7d, 0x14, 0xdf, 0x47,
- 0x64, 0xe0, 0xb6, 0x62, 0x0f, 0xa3, 0x20, 0x10 },
- { 0xd5, 0x41, 0xa7, 0x7e, 0x13, 0x6e, 0x9e, 0x70,
- 0x3b, 0xb9, 0x9f, 0x80, 0x68, 0xcf, 0xee, 0x86,
- 0xa4, 0xb9, 0xf0, 0x89, 0xe0, 0x2d, 0x0c, 0x6c,
- 0xb6, 0xd4, 0xa3, 0x94, 0x6c, 0x6b, 0x16, 0x7a },
- { 0xd5, 0x83, 0x94, 0x96, 0xcd, 0xc8, 0x5b, 0xe3,
- 0xd1, 0xf1, 0xac, 0x65, 0x2e, 0xfa, 0x92, 0xbe,
- 0xa3, 0xb0, 0x61, 0xc1, 0x3d, 0xad, 0x5a, 0x82,
- 0x11, 0x22, 0xcf, 0xe9, 0xc7, 0x1a, 0x5a, 0x32 },
- { 0xd5, 0xa4, 0xee, 0x46, 0x95, 0xb5, 0x65, 0xa6,
- 0x7e, 0x50, 0x48, 0x66, 0xfe, 0x5b, 0xa3, 0xc0,
- 0xed, 0xca, 0xee, 0xd5, 0x2a, 0xd0, 0xaf, 0x07,
- 0xe6, 0x79, 0x17, 0x73, 0x85, 0x12, 0xc8, 0xf5 },
- { 0xd6, 0x25, 0xc0, 0x59, 0x2b, 0x25, 0xdc, 0x03,
- 0xaa, 0x7e, 0x87, 0x8e, 0x6a, 0x85, 0x09, 0x1b,
- 0xaa, 0x07, 0x8d, 0x26, 0x8b, 0xbd, 0xb4, 0x9f,
- 0x09, 0x67, 0x94, 0x08, 0x61, 0x2d, 0x1e, 0xfe },
- { 0xd6, 0xd1, 0xb3, 0x5c, 0xbc, 0x12, 0xfb, 0x1c,
- 0x70, 0xa0, 0xb4, 0x3b, 0xa5, 0x9a, 0xb3, 0xd3,
- 0x22, 0x5f, 0x37, 0x32, 0x64, 0xdd, 0x87, 0xfb,
- 0xca, 0x00, 0x61, 0xec, 0x1c, 0x4d, 0xa1, 0x1a },
- { 0xd7, 0x32, 0x49, 0x74, 0xb5, 0x60, 0x09, 0x62,
- 0x17, 0x61, 0xf7, 0xc0, 0xff, 0x68, 0x9d, 0xde,
- 0x47, 0x74, 0x99, 0x85, 0xe1, 0xee, 0x8b, 0x5c,
- 0x89, 0x61, 0xdd, 0x8f, 0x6a, 0x78, 0xbb, 0xf5 },
- { 0xd9, 0x2e, 0x3e, 0xe3, 0x82, 0xc8, 0xdc, 0xaf,
- 0xa0, 0x39, 0x3d, 0x9f, 0x9a, 0x00, 0xbf, 0x4c,
- 0xd9, 0xd5, 0x64, 0x26, 0x2b, 0x18, 0x0f, 0x68,
- 0x16, 0x0b, 0x20, 0x34, 0xc5, 0x44, 0xd1, 0x0a },
- { 0xd9, 0x65, 0xf7, 0x41, 0x62, 0x04, 0xda, 0x83,
- 0x1a, 0xf6, 0x6b, 0xfa, 0x8f, 0x90, 0xd1, 0x41,
- 0xe9, 0x93, 0xf0, 0x00, 0x21, 0x33, 0xf2, 0x8d,
- 0xe9, 0x7f, 0x56, 0x4a, 0x1d, 0x60, 0x4e, 0xcc },
- { 0xda, 0xdf, 0x97, 0x13, 0x34, 0x14, 0xad, 0x51,
- 0x3f, 0xc7, 0x50, 0x14, 0xe9, 0x56, 0x65, 0xda,
- 0xd7, 0x76, 0xb1, 0x50, 0x4b, 0x15, 0x67, 0x43,
- 0x4f, 0xd8, 0x2a, 0x79, 0xa2, 0x20, 0xe9, 0xa1 },
- { 0xda, 0xff, 0xd4, 0x05, 0x6f, 0xc3, 0x68, 0xfa,
- 0x64, 0x8d, 0x0e, 0xd8, 0x9b, 0x5d, 0xe0, 0xee,
- 0x93, 0x1f, 0x1b, 0x33, 0x84, 0x78, 0xab, 0xf5,
- 0x69, 0x29, 0xa9, 0x4d, 0x3b, 0xd6, 0x1d, 0x46 },
- { 0xde, 0xcd, 0xb9, 0xfc, 0x1d, 0xde, 0xc9, 0x7e,
- 0x09, 0xc3, 0x02, 0x6a, 0xce, 0xb7, 0x6b, 0xda,
- 0xe9, 0xde, 0xb6, 0x62, 0x75, 0x1d, 0xda, 0x34,
- 0x9d, 0x2f, 0xa6, 0xbd, 0x75, 0xca, 0x59, 0x14 },
- { 0xde, 0xd1, 0x9a, 0xd5, 0xde, 0x99, 0x65, 0xd9,
- 0x22, 0x5c, 0x1b, 0xba, 0x5f, 0xb4, 0xd8, 0x90,
- 0xc8, 0xe5, 0xc0, 0x35, 0xe4, 0x85, 0x27, 0x52,
- 0xb6, 0x69, 0xb0, 0x40, 0x0f, 0x24, 0xf1, 0x74 },
- { 0xdf, 0x30, 0xbf, 0x8d, 0x1b, 0xf9, 0x37, 0x8e,
- 0x43, 0x3e, 0xf9, 0xe1, 0xb3, 0xa2, 0x28, 0xa0,
- 0x7e, 0x36, 0x58, 0xa5, 0xbc, 0x43, 0x88, 0x23,
- 0x45, 0x4d, 0xb0, 0x6a, 0x67, 0x94, 0x4c, 0x6e },
- { 0xe0, 0x0b, 0xd7, 0x86, 0xd1, 0xf2, 0xf4, 0x46,
- 0xc4, 0xba, 0x83, 0x99, 0xd4, 0xd8, 0xd5, 0xa0,
- 0xd1, 0x98, 0x57, 0x8f, 0x42, 0x99, 0xfd, 0xfd,
- 0xaf, 0xf7, 0x8c, 0x3f, 0x67, 0x71, 0xf3, 0x94 },
- { 0xe0, 0x8b, 0x2c, 0xc2, 0x7a, 0xe8, 0xe2, 0xef,
- 0x1a, 0x33, 0x01, 0x7a, 0x9a, 0xc2, 0x5d, 0xda,
- 0xfb, 0x5e, 0xa1, 0x12, 0xc9, 0x56, 0xb0, 0x02,
- 0xfe, 0x6c, 0x79, 0x80, 0x14, 0xaa, 0x90, 0x65 },
- { 0xe1, 0xb2, 0xe8, 0x6b, 0x0d, 0xa8, 0x69, 0xe9,
- 0x25, 0x26, 0x6c, 0x1b, 0x56, 0x88, 0x34, 0x5a,
- 0x17, 0xb0, 0xf6, 0xe2, 0xa2, 0x14, 0x94, 0x54,
- 0x7e, 0xac, 0x09, 0x7c, 0x8b, 0xf5, 0x3c, 0x5a },
- { 0xe1, 0xd6, 0x44, 0xa0, 0x96, 0xbd, 0x8a, 0x6c,
- 0xac, 0xbb, 0xda, 0x3e, 0x7f, 0xc3, 0x38, 0xea,
- 0xdd, 0xc1, 0x2f, 0x23, 0x6c, 0x72, 0x61, 0xe4,
- 0x5f, 0x8a, 0xd2, 0xd8, 0x42, 0x42, 0x4f, 0x72 },
- { 0xe2, 0x24, 0x10, 0xb5, 0xa6, 0x7f, 0xed, 0xc2,
- 0x64, 0x69, 0x4c, 0x44, 0x9d, 0x84, 0xfa, 0x1a,
- 0x02, 0xbc, 0x8b, 0x21, 0x28, 0xc1, 0x25, 0x60,
- 0x71, 0x58, 0xc9, 0x1b, 0x05, 0x38, 0x6c, 0x6a },
- { 0xe2, 0xa8, 0x47, 0xc3, 0xf0, 0x9b, 0xeb, 0x6f,
- 0x05, 0x68, 0x6f, 0x17, 0x79, 0x1b, 0x05, 0xf1,
- 0xfe, 0x25, 0xf7, 0x71, 0x86, 0x9c, 0x42, 0x63,
- 0xa5, 0x5b, 0x94, 0x18, 0x77, 0xe4, 0x79, 0x04 },
- { 0xe2, 0xf3, 0x9a, 0x9d, 0x48, 0xa3, 0x22, 0x10,
- 0x55, 0xb3, 0xc8, 0xa3, 0xeb, 0x14, 0x39, 0xd6,
- 0xb8, 0x73, 0x01, 0x3e, 0xe4, 0xd0, 0x97, 0x12,
- 0x20, 0x64, 0xf2, 0x7e, 0xc0, 0x3d, 0xd4, 0xda },
- { 0xe2, 0xf5, 0xde, 0x57, 0xcd, 0x67, 0x24, 0x9a,
- 0x7e, 0x1f, 0x45, 0x5b, 0x85, 0xc0, 0x6f, 0x0d,
- 0x80, 0x9e, 0x75, 0xa5, 0x5c, 0x6b, 0x05, 0x48,
- 0x16, 0xe0, 0x19, 0x89, 0x9a, 0x3a, 0x02, 0xff },
- { 0xe4, 0xf1, 0xde, 0x31, 0xcd, 0xaa, 0x6d, 0x9e,
- 0xb1, 0xaa, 0xfd, 0x10, 0x81, 0x27, 0xa2, 0xf0,
- 0xa8, 0xfb, 0x6d, 0xa8, 0x5a, 0x04, 0x14, 0xad,
- 0x24, 0x99, 0x47, 0xc4, 0x8d, 0x24, 0x92, 0xc5 },
- { 0xe6, 0x44, 0xd1, 0x1c, 0x37, 0x07, 0x0f, 0x89,
- 0x69, 0x33, 0x08, 0x17, 0x8d, 0x6b, 0xe4, 0x95,
- 0x94, 0x96, 0x92, 0xc1, 0xfb, 0xeb, 0x30, 0xed,
- 0x32, 0x9b, 0x74, 0x02, 0x7f, 0xcf, 0xfd, 0x48 },
- { 0xe6, 0xb0, 0xf2, 0xe2, 0x5b, 0xd5, 0x16, 0xe4,
- 0xbb, 0xa3, 0x7a, 0x2b, 0xf2, 0xe2, 0xc7, 0x2a,
- 0x1e, 0x53, 0x9c, 0x60, 0x30, 0xf3, 0xcf, 0x9b,
- 0xbe, 0x5e, 0x79, 0x72, 0x8d, 0x68, 0x64, 0x78 },
- { 0xe6, 0xe5, 0x4d, 0xe7, 0xb4, 0x97, 0x54, 0xd3,
- 0x57, 0xb0, 0xa8, 0xd9, 0x4a, 0x4d, 0x4f, 0x80,
- 0xac, 0xd1, 0x99, 0x4c, 0xcc, 0x1c, 0x99, 0x08,
- 0xe9, 0xf0, 0xd9, 0x21, 0xe4, 0x28, 0xb8, 0x38 },
- { 0xe7, 0x0c, 0xbb, 0x7a, 0xf7, 0xaa, 0x20, 0xb9,
- 0x89, 0x0b, 0xc1, 0xf9, 0xfa, 0x00, 0xd8, 0x09,
- 0x0b, 0x5a, 0xc9, 0x82, 0x5e, 0xa9, 0xd2, 0xfd,
- 0xf7, 0x7c, 0xa4, 0xda, 0xe9, 0x44, 0x51, 0xb2 },
- { 0xe8, 0x16, 0xf9, 0x92, 0x94, 0xa1, 0x3a, 0xc2,
- 0xfa, 0x2b, 0xfb, 0x76, 0xc2, 0x2d, 0xfa, 0x71,
- 0xbc, 0x3d, 0xa4, 0x8f, 0x67, 0x1e, 0xf7, 0x7c,
- 0x00, 0xaa, 0x8e, 0x45, 0x9b, 0x7c, 0xc8, 0x2a },
- { 0xe9, 0xd4, 0x98, 0x51, 0xbf, 0x78, 0x37, 0x6d,
- 0x54, 0x08, 0x2d, 0x1e, 0xb8, 0x2b, 0xd2, 0xdc,
- 0x96, 0x82, 0x07, 0x09, 0xb7, 0x77, 0x2d, 0x3f,
- 0xbc, 0xa3, 0x90, 0x08, 0x8b, 0x54, 0xc4, 0x53 },
- { 0xe9, 0xf5, 0x71, 0xc7, 0x71, 0x64, 0xab, 0xea,
- 0xe1, 0x85, 0x28, 0x37, 0x5c, 0xfd, 0xc7, 0x21,
- 0x9a, 0x6b, 0xde, 0x46, 0x1b, 0x19, 0x73, 0xbe,
- 0x2b, 0xb8, 0xbd, 0xf0, 0xda, 0x78, 0xb2, 0xb4 },
- { 0xeb, 0x11, 0x63, 0xaa, 0xef, 0xe8, 0xfd, 0x88,
- 0xe1, 0x32, 0x7b, 0x48, 0xa9, 0xc0, 0x06, 0x2e,
- 0x06, 0xf0, 0xa6, 0xea, 0xa0, 0xa0, 0x18, 0x24,
- 0x7f, 0x9f, 0xa4, 0xe3, 0x4e, 0x3a, 0x47, 0x4c },
- { 0xec, 0x4b, 0xbd, 0xeb, 0x15, 0x12, 0x1d, 0x96,
- 0x76, 0x4d, 0x6c, 0x01, 0xb2, 0x7e, 0xd5, 0xae,
- 0x86, 0x46, 0x5c, 0x46, 0xd5, 0xa4, 0x0e, 0x34,
- 0xae, 0xfc, 0x09, 0x2d, 0x3e, 0x8b, 0xb1, 0x76 },
- { 0xec, 0x5f, 0xa4, 0x73, 0x12, 0x1e, 0x3f, 0x49,
- 0xf0, 0x95, 0x3a, 0x2a, 0x91, 0x83, 0x39, 0xe3,
- 0x6f, 0x3c, 0xb6, 0xb8, 0xd8, 0xb8, 0x9e, 0x91,
- 0x74, 0x23, 0xda, 0xce, 0xac, 0xe6, 0xd5, 0x8a },
- { 0xec, 0xce, 0x4e, 0x52, 0x82, 0xfd, 0x2e, 0xe0,
- 0x03, 0xa4, 0x03, 0x2c, 0x80, 0xd3, 0x32, 0x1a,
- 0x69, 0x47, 0x25, 0x98, 0x94, 0x59, 0x09, 0xcb,
- 0x25, 0x55, 0x7a, 0xa8, 0x47, 0x74, 0x2d, 0xdf },
- { 0xed, 0x5b, 0xb8, 0x6a, 0x95, 0xa5, 0xfe, 0x2b,
- 0x17, 0x08, 0xf2, 0x56, 0x75, 0x4a, 0x89, 0xc4,
- 0x29, 0x67, 0x9b, 0x30, 0x75, 0x8e, 0xe0, 0x12,
- 0x2b, 0x9e, 0x50, 0x85, 0x8d, 0xe2, 0x10, 0x4b },
- { 0xed, 0xc1, 0xbf, 0x3e, 0xfb, 0xf7, 0xe1, 0xd9,
- 0x5e, 0x19, 0xc5, 0x5e, 0xca, 0xe7, 0x7e, 0x83,
- 0x69, 0x46, 0xab, 0x0a, 0x26, 0xa7, 0x8e, 0x32,
- 0xa4, 0x72, 0xc9, 0xd3, 0x6c, 0x69, 0xce, 0xcd },
- { 0xed, 0xf4, 0xdf, 0x97, 0x2c, 0xad, 0x6c, 0x47,
- 0x0b, 0xab, 0x5d, 0x66, 0x42, 0xf6, 0x60, 0xb8,
- 0x42, 0xd6, 0xc9, 0x73, 0x07, 0x44, 0x93, 0xe4,
- 0xef, 0x1b, 0xbf, 0x31, 0x1a, 0x92, 0x79, 0x95 },
- { 0xee, 0x34, 0xe1, 0xa1, 0x9b, 0xc8, 0x89, 0xf8,
- 0x5f, 0x7f, 0x0f, 0x5b, 0xf8, 0x72, 0xb1, 0xac,
- 0x56, 0x5e, 0xc6, 0xf1, 0x9d, 0xb5, 0x17, 0xba,
- 0x4e, 0xd7, 0x55, 0xc4, 0x18, 0x5f, 0x69, 0xe8 },
- { 0xef, 0x36, 0xa2, 0x29, 0x89, 0x65, 0xe4, 0x98,
- 0x84, 0x59, 0xb9, 0x21, 0x6a, 0xb3, 0x3c, 0x3c,
- 0xa8, 0x42, 0xd2, 0x16, 0x83, 0xb6, 0x2a, 0x2b,
- 0xf1, 0x53, 0x0d, 0x30, 0xb0, 0xae, 0x78, 0x25 },
- { 0xef, 0xaf, 0xca, 0x84, 0x90, 0x30, 0x7b, 0x0f,
- 0x62, 0x2b, 0xf4, 0x3a, 0x0e, 0xb3, 0xc5, 0x1a,
- 0xcb, 0xdd, 0xde, 0xdc, 0x23, 0x92, 0xf1, 0x61,
- 0xac, 0xed, 0x16, 0x71, 0xa6, 0x53, 0x60, 0x7e },
- { 0xef, 0xd1, 0xe0, 0xe7, 0x3f, 0xa8, 0x71, 0x00,
- 0xb7, 0x6a, 0x93, 0x23, 0x49, 0xc4, 0x5d, 0x09,
- 0xb2, 0x8b, 0x2d, 0x8a, 0x00, 0x17, 0x19, 0xa5,
- 0x8d, 0xfa, 0xcc, 0x74, 0x84, 0xc7, 0xcf, 0x42 },
- { 0xf0, 0x6b, 0x35, 0x95, 0x36, 0xd1, 0x34, 0x32,
- 0x8b, 0x36, 0x00, 0x4d, 0xa9, 0xa9, 0x19, 0x0c,
- 0x3a, 0x76, 0x69, 0xe8, 0x27, 0x8d, 0xb9, 0xf7,
- 0x58, 0x57, 0xc4, 0x8d, 0x64, 0x4b, 0xe2, 0x03 },
- { 0xf0, 0xcf, 0xc7, 0x79, 0x13, 0x39, 0x7d, 0xe2,
- 0x38, 0xed, 0xb5, 0x9f, 0x0f, 0x99, 0x23, 0xc6,
- 0xd4, 0x11, 0x0a, 0x4b, 0x3a, 0xc8, 0xac, 0x76,
- 0x55, 0x6a, 0x0c, 0x92, 0x44, 0xf0, 0x3f, 0xc1 },
- { 0xf2, 0xb1, 0x95, 0x84, 0x6e, 0xe2, 0xb9, 0xab,
- 0x5f, 0x18, 0xe6, 0x80, 0x21, 0xf8, 0xdf, 0x7c,
- 0x0b, 0x60, 0x58, 0xde, 0xde, 0x86, 0xc5, 0xd5,
- 0x90, 0xf2, 0xe8, 0x64, 0x3a, 0xfe, 0x04, 0x52 },
- { 0xf2, 0xe5, 0x30, 0x0c, 0x39, 0xf2, 0x86, 0xc6,
- 0x78, 0x99, 0x90, 0x9c, 0x7c, 0xe7, 0x35, 0x9b,
- 0x09, 0x45, 0xd2, 0xaf, 0xd3, 0x4a, 0x6d, 0xd6,
- 0x9e, 0x08, 0xcd, 0xa5, 0x44, 0xc8, 0x7b, 0x3a },
- { 0xf3, 0x0c, 0x0a, 0xed, 0x70, 0x6d, 0x22, 0x55,
- 0x5f, 0x07, 0x09, 0x6a, 0xf4, 0xb8, 0xbe, 0xdc,
- 0x16, 0x3c, 0x0f, 0x6e, 0xd5, 0x34, 0x6e, 0xfc,
- 0x28, 0xe8, 0xcf, 0xaf, 0x84, 0x2f, 0xa5, 0xd9 },
- { 0xf6, 0x13, 0xd5, 0x90, 0x46, 0xd1, 0x66, 0x71,
- 0xd3, 0xc5, 0x60, 0x17, 0x6f, 0x3d, 0x77, 0xfd,
- 0xc5, 0x1e, 0x5f, 0x57, 0xb5, 0xe4, 0x8a, 0xe7,
- 0xa4, 0xb9, 0x70, 0x0a, 0x11, 0xd4, 0x69, 0x3a },
- { 0xf6, 0x54, 0x6b, 0x2f, 0xfe, 0x2b, 0xae, 0xf7,
- 0x35, 0xe8, 0x25, 0x67, 0xa6, 0xe2, 0x36, 0x75,
- 0x03, 0x94, 0xc1, 0x19, 0x14, 0x09, 0x87, 0x0c,
- 0x6f, 0xbe, 0x95, 0x2d, 0x08, 0xa3, 0x3a, 0xba },
- { 0xf8, 0x64, 0x44, 0x3e, 0x2f, 0x63, 0x9e, 0x7c,
- 0xff, 0xd2, 0x42, 0x21, 0xf6, 0x1b, 0xbf, 0xf0,
- 0x7c, 0xce, 0x5c, 0x61, 0xdd, 0xb1, 0x68, 0xb3,
- 0xb4, 0x04, 0xd7, 0xc8, 0xcd, 0xca, 0x18, 0xb2 },
- { 0xf8, 0x94, 0xf9, 0x67, 0x36, 0x9c, 0xe7, 0xcf,
- 0xa3, 0x1a, 0xc1, 0x9a, 0x66, 0x65, 0xb0, 0xc4,
- 0x24, 0xba, 0x40, 0x8a, 0xd5, 0xd3, 0x65, 0xf1,
- 0x68, 0xd8, 0xbe, 0xeb, 0x79, 0xf4, 0x89, 0xf3 },
- { 0xf8, 0xcf, 0x1e, 0x08, 0x6a, 0x6a, 0x06, 0x3f,
- 0xad, 0x25, 0x74, 0x25, 0xaa, 0xe7, 0x20, 0x01,
- 0x40, 0x05, 0xb4, 0x15, 0x91, 0x2d, 0xbb, 0x8c,
- 0x0b, 0xc9, 0x99, 0xaf, 0x48, 0x48, 0xcf, 0xe5 },
- { 0xfb, 0x9a, 0xf7, 0x9d, 0xea, 0x18, 0xaf, 0x62,
- 0x99, 0x85, 0x0e, 0x25, 0x15, 0x9b, 0x4f, 0xb2,
- 0x24, 0xcb, 0xb0, 0xf1, 0x4e, 0xad, 0x7e, 0x85,
- 0xf6, 0x0c, 0x2a, 0xb2, 0x09, 0xea, 0x45, 0x0d },
- { 0xfb, 0xc4, 0xc9, 0xba, 0xcf, 0xe3, 0xda, 0x64,
- 0x13, 0x18, 0x26, 0x6b, 0x72, 0x58, 0x56, 0x00,
- 0x35, 0xbc, 0x64, 0x60, 0x8e, 0x34, 0xb9, 0x90,
- 0xca, 0x92, 0xa5, 0x52, 0xf3, 0x14, 0x21, 0x61 },
- { 0xfb, 0xed, 0xd3, 0x88, 0x89, 0xf0, 0xb4, 0x1f,
- 0x73, 0x4d, 0xe2, 0xf4, 0xc9, 0xd6, 0xf2, 0x7c,
- 0x8d, 0x4a, 0xa9, 0xab, 0x73, 0x64, 0x91, 0xe1,
- 0x64, 0xe1, 0x21, 0xb7, 0xbc, 0xaf, 0x44, 0xe8 },
- { 0xfc, 0x01, 0xa5, 0x5a, 0x36, 0xcc, 0x8b, 0x7b,
- 0x7c, 0xa2, 0xea, 0xb0, 0x84, 0x60, 0xc2, 0x8d,
- 0x1d, 0x6c, 0xd8, 0x9c, 0x57, 0x59, 0x94, 0x05,
- 0xd5, 0x37, 0x4b, 0x91, 0xaa, 0xeb, 0xc8, 0x79 },
- { 0xfc, 0x4d, 0x9a, 0x37, 0xe5, 0xf7, 0x32, 0x72,
- 0xd0, 0xa9, 0xdf, 0xcc, 0xe9, 0x03, 0x12, 0xc7,
- 0x52, 0xe1, 0xb5, 0x2e, 0xb6, 0x54, 0xc4, 0x2c,
- 0x36, 0x94, 0x4b, 0x90, 0x2a, 0x30, 0x41, 0x07 },
- { 0xfc, 0x56, 0xdb, 0xa1, 0xe7, 0xaf, 0xbd, 0xaa,
- 0x07, 0x33, 0xc6, 0x91, 0x1c, 0x5f, 0x1f, 0x18,
- 0x28, 0xcb, 0x12, 0x98, 0x31, 0x40, 0x1a, 0x3c,
- 0xfd, 0xea, 0xa7, 0x24, 0x62, 0x95, 0x35, 0x94 },
- { 0xfc, 0x83, 0xc2, 0x89, 0x89, 0x5a, 0x92, 0x08,
- 0xc9, 0xb1, 0x7a, 0x16, 0xbc, 0xe5, 0xce, 0x80,
- 0xe8, 0xf4, 0xa0, 0x77, 0x21, 0x25, 0x29, 0xce,
- 0x0b, 0xc7, 0xf5, 0x42, 0xc6, 0xcb, 0xde, 0x1a },
- { 0xfc, 0xa6, 0x23, 0x5d, 0x2a, 0xa4, 0xb1, 0xb2,
- 0x51, 0x50, 0x78, 0x57, 0xb4, 0xf0, 0x08, 0xdf,
- 0xd5, 0x27, 0x04, 0x2c, 0xe0, 0x45, 0x01, 0xaa,
- 0xe2, 0x9d, 0xd2, 0x05, 0xbb, 0xef, 0xce, 0x0d },
- { 0xfc, 0xe7, 0x34, 0xe1, 0x2b, 0x8e, 0xfb, 0x43,
- 0x12, 0x71, 0xbf, 0xf6, 0x7a, 0x7a, 0x0a, 0x93,
- 0xb2, 0x19, 0xdd, 0x5e, 0x5d, 0xcc, 0x12, 0x58,
- 0x59, 0x4d, 0x96, 0xfc, 0xe1, 0x93, 0xb8, 0x60 },
- { 0xfd, 0x9c, 0xfe, 0x14, 0xda, 0xd8, 0x97, 0x8c,
- 0x5b, 0xc8, 0x88, 0x93, 0x8f, 0x16, 0xf3, 0xb3,
- 0x98, 0xf7, 0x63, 0xa3, 0xad, 0xaf, 0xaa, 0x4a,
- 0xd9, 0x41, 0xb7, 0xe3, 0x87, 0xeb, 0x4f, 0x4a },
- { 0xfd, 0xed, 0x92, 0xcb, 0x40, 0x91, 0x66, 0x82,
- 0x3a, 0x35, 0xe2, 0x17, 0xf3, 0x0b, 0x38, 0xc4,
- 0x86, 0xf8, 0x3e, 0xf2, 0xd4, 0xf2, 0x7b, 0x05,
- 0xf1, 0x8c, 0x74, 0x49, 0x81, 0x33, 0x9a, 0x1c },
- { 0xfe, 0x26, 0xb2, 0xa6, 0x45, 0xa3, 0x1a, 0x91,
- 0x11, 0x00, 0x09, 0x9a, 0xa9, 0xa2, 0x93, 0x9f,
- 0x49, 0xe9, 0xfb, 0xea, 0x64, 0x48, 0x7b, 0xdf,
- 0x68, 0xa5, 0x23, 0x70, 0x32, 0x92, 0xd6, 0xa0 },
- { 0xfe, 0x42, 0x1b, 0x24, 0x4e, 0x0e, 0x81, 0x6d,
- 0x9f, 0x26, 0xb3, 0x52, 0xc8, 0x31, 0xd9, 0x30,
- 0xe1, 0xc1, 0xc5, 0xd2, 0xfa, 0x4e, 0x0a, 0x1c,
- 0x77, 0x96, 0xa1, 0xf2, 0x02, 0x0e, 0xf1, 0x67 },
- { 0xfe, 0x4f, 0x35, 0x6c, 0x7f, 0x9b, 0xfc, 0x17,
- 0xff, 0xcb, 0x68, 0xd0, 0x76, 0x4e, 0xcb, 0x2a,
- 0x87, 0xca, 0xa0, 0xae, 0x4c, 0xb5, 0x66, 0x62,
- 0x21, 0x04, 0xd3, 0x6f, 0xfb, 0x52, 0xcb, 0x29 },
- { 0xff, 0x82, 0x6e, 0x2d, 0x0c, 0xb7, 0x71, 0x68,
- 0x68, 0x67, 0x5a, 0xe4, 0xb4, 0x31, 0xb6, 0x37,
- 0x1e, 0x9f, 0x0c, 0xdf, 0xcc, 0xb4, 0x9d, 0x43,
- 0xba, 0x30, 0x49, 0xbf, 0xdd, 0x2c, 0x41, 0xb1 },
- { 0xff, 0xdc, 0x6b, 0x85, 0xfe, 0x7b, 0x10, 0x83,
- 0xb5, 0x41, 0x6f, 0x80, 0x6f, 0xc2, 0x44, 0xb9,
- 0xe4, 0xdf, 0x42, 0x99, 0xfb, 0xe3, 0xf6, 0x81,
- 0xaf, 0x3f, 0x5c, 0xf4, 0x22, 0x5a, 0x8e, 0xaf },
-};
-
-// SHA-256 hashes of leaf certificates issued by CNNIC's EV root.
-const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
- { 0xb5, 0xef, 0x42, 0xc4, 0xbc, 0xed, 0xf1, 0x7b,
- 0xec, 0xc7, 0x5b, 0xf4, 0x63, 0x66, 0x49, 0xce,
- 0xbf, 0xf8, 0x71, 0x1b, 0xce, 0xff, 0xfa, 0x69,
- 0x5c, 0xc2, 0x52, 0xfa, 0x57, 0x4d, 0x42, 0x18 },
- { 0xb6, 0x82, 0x3c, 0x9d, 0xbc, 0x8e, 0x8c, 0x05,
- 0x4b, 0xcf, 0x60, 0xf2, 0x38, 0x21, 0xac, 0x6c,
- 0x58, 0x19, 0x73, 0x51, 0xea, 0xcf, 0xa5, 0x57,
- 0x4c, 0xf0, 0x41, 0xb4, 0xce, 0x6b, 0x84, 0x04 },
- { 0xdf, 0x69, 0xf9, 0x6a, 0x85, 0x67, 0x8f, 0x6c,
- 0xaf, 0x3f, 0xde, 0x25, 0xec, 0xfb, 0x5d, 0xf4,
- 0x74, 0x70, 0x87, 0xc2, 0xaf, 0x3b, 0x00, 0x65,
- 0xfb, 0x15, 0x10, 0x55, 0xcb, 0xcb, 0xa8, 0xc1 },
- { 0xee, 0x0c, 0xf6, 0x2b, 0x9d, 0x8e, 0x42, 0xa2,
- 0x23, 0xb9, 0xa9, 0x60, 0xb5, 0xe9, 0x67, 0x0c,
- 0xcc, 0x34, 0x6d, 0x89, 0x93, 0x8f, 0xfa, 0x5d,
- 0xf7, 0x98, 0x65, 0xe4, 0x13, 0xd6, 0x31, 0x54 },
-};
-
-const PublicKeyWhitelist kBuiltinWhitelist[] = {
- // C=CN, O=China Internet Network Information Center,
- // CN=China Internet Network Information Center EV Certificates Root
- // Expires: August 31 2030.
- { { 0x9d, 0xd5, 0x5f, 0xc5, 0x73, 0xf5, 0x46, 0xcb,
- 0x6a, 0x38, 0x31, 0xd1, 0x11, 0x2d, 0x87, 0x10,
- 0xa6, 0xf4, 0xf8, 0x2d, 0xc8, 0x7f, 0x5f, 0xae,
- 0x9d, 0x3a, 0x1a, 0x02, 0x8d, 0xd3, 0x6e, 0x4b },
- kCNNICEVWhitelist, arraysize(kCNNICEVWhitelist)
- },
- // C=CN, O=CNNIC, CN=CNNIC ROOT
- // Expires: April 16 2027.
- { { 0x1f, 0x42, 0x24, 0xce, 0xc8, 0x4f, 0xc9, 0x9c,
- 0xed, 0x88, 0x1f, 0xf6, 0xfc, 0xfd, 0x3e, 0x21,
- 0xf8, 0xc5, 0x19, 0xc5, 0x47, 0xaa, 0x6a, 0x5d,
- 0xd3, 0xde, 0x24, 0x73, 0x02, 0xce, 0x50, 0xd1 },
- kCNNICDVWhitelist, arraysize(kCNNICDVWhitelist)
- },
-};
// clang-format on
-const size_t kBuiltinWhitelistSize = arraysize(kBuiltinWhitelist);
-
-const PublicKeyWhitelist* g_whitelist = kBuiltinWhitelist;
-size_t g_whitelist_size = kBuiltinWhitelistSize;
-
-// Comparator to compare a SHA256HashValue with a uint8_t array containing a
-// raw SHA-256 hash. Return value follows memcmp semantics.
-int CompareSHA256HashValueToRawHash(const void* key, const void* element) {
- const SHA256HashValue* search_key =
- reinterpret_cast<const SHA256HashValue*>(key);
- return memcmp(search_key->data, element, sizeof(search_key->data));
-}
// Comparator to compare a (SHA-256) HashValue with a uint8_t array containing
// a raw SHA-256 hash. Return value follows memcmp semantics.
@@ -1652,55 +56,74 @@ int CompareHashValueToRawHash(const void* key, const void* element) {
return memcmp(search_key->data(), element, search_key->size());
}
+namespace wosign {
+#include "net/data/ssl/wosign/wosign_domains-inc.cc"
} // namespace
-bool IsNonWhitelistedCertificate(const X509Certificate& cert,
- const HashValueVector& public_key_hashes) {
- // 2016-10-21 00:00:00 UTC
- const base::Time last_wosign_cert =
- base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1477008000);
+} // namespace
+bool IsNonWhitelistedCertificate(const X509Certificate& cert,
+ const HashValueVector& public_key_hashes,
+ base::StringPiece hostname) {
for (const auto& hash : public_key_hashes) {
if (hash.tag != HASH_VALUE_SHA256)
continue;
// Check for WoSign/StartCom certificates.
if (bsearch(&hash, kWosignKeys, arraysize(kWosignKeys),
- crypto::kSHA256Length, CompareHashValueToRawHash) != nullptr &&
- (cert.valid_start().is_null() || cert.valid_start().is_max() ||
- cert.valid_start() > last_wosign_cert)) {
- return true;
- }
-
- // Check the public key whitelist.
- for (size_t i = 0; i < g_whitelist_size; ++i) {
- if (memcmp(hash.data(), g_whitelist[i].public_key,
- crypto::kSHA256Length) != 0) {
- continue;
+ crypto::kSHA256Length, CompareHashValueToRawHash) != nullptr) {
+ // 2016-10-21 00:00:00 UTC
+ const base::Time last_wosign_cert =
+ base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1477008000);
+
+ // Don't allow new certificates.
+ if (cert.valid_start().is_null() || cert.valid_start().is_max() ||
+ cert.valid_start() > last_wosign_cert) {
+ return true;
}
- const SHA256HashValue leaf_hash =
- X509Certificate::CalculateFingerprint256(cert.os_cert_handle());
- void* result = bsearch(
- &leaf_hash, g_whitelist[i].whitelist, g_whitelist[i].whitelist_size,
- crypto::kSHA256Length, CompareSHA256HashValueToRawHash);
- if (result == nullptr)
- return true; // Hash was not found on the public key whitelist.
- break;
+
+ // Don't allow certificates from non-whitelisted hosts.
+ return !IsWhitelistedHost(wosign::kDafsa, arraysize(wosign::kDafsa),
+ hostname);
}
}
return false;
}
-void SetCertificateWhitelistForTesting(const PublicKeyWhitelist* whitelist,
- size_t whitelist_size) {
- if (whitelist == nullptr || whitelist_size == 0) {
- g_whitelist = kBuiltinWhitelist;
- g_whitelist_size = kBuiltinWhitelistSize;
- return;
+bool IsWhitelistedHost(const unsigned char* graph,
+ size_t graph_length,
+ base::StringPiece host) {
+ if (host.empty())
+ return false;
+
+ size_t end = host.length();
+
+ // Skip trailing '.', if any.
+ if (host[end - 1] == '.') {
+ --end;
+ }
+
+ // Reverse through each of the domain components, trying to see if the
+ // domain is on the whitelist. For example, the string
+ // "www.domain.example.com" would be processed by first searching
+ // for "com", then "example.com", then "domain.example.com". The
+ // loop will terminate when there are no more distinct label separators,
+ // and thus the final check for "www.domain.example.com".
+ size_t start = end;
+ while (start != 0 &&
+ (start = host.rfind('.', start - 1)) != base::StringPiece::npos) {
+ const char* domain_str = host.data() + start + 1;
+ size_t domain_length = end - start - 1;
+ if (domain_length == 0)
+ return false;
+ if (LookupStringInFixedSet(graph, graph_length, domain_str,
+ domain_length) != kDafsaNotFound) {
+ return true;
+ }
}
- g_whitelist = whitelist;
- g_whitelist_size = whitelist_size;
+ return LookupStringInFixedSet(graph, graph_length, host.data(), end) !=
+ kDafsaNotFound;
}
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.h b/chromium/net/cert/cert_verify_proc_whitelist.h
index 47ce9831848..2c7dfd5bda1 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.h
+++ b/chromium/net/cert/cert_verify_proc_whitelist.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/strings/string_piece.h"
#include "crypto/sha2.h"
#include "net/base/hash_value.h"
#include "net/base/net_export.h"
@@ -16,32 +17,26 @@ namespace net {
class X509Certificate;
-// PublicKeyWhitelist contains a SHA-256 SPKI hash and a pointer to an array
-// of SHA-256 certificate hashes that have been publicly disclosed and
-// whitelisted.
-struct PublicKeyWhitelist {
- uint8_t public_key[crypto::kSHA256Length];
- const uint8_t (*whitelist)[crypto::kSHA256Length];
- size_t whitelist_size;
-};
-
// Returns true if |cert| has been issued by a CA that is constrained from
// issuing new certificates and |cert| is not within the whitelist of
// existing certificates. Returns false if |cert| was issued by an
// unconstrained CA or if it was in the whitelist for that
// CA.
// |cert| should be the verified certificate chain, with |public_key_hashes|
-// being the set of hashes of the SPKIs within the verified chain.
+// being the set of hashes of the SPKIs within the verified chain, and
+// |hostname| as the GURL-normalized hostname.
bool NET_EXPORT_PRIVATE
IsNonWhitelistedCertificate(const X509Certificate& cert,
- const HashValueVector& public_key_hashes);
+ const HashValueVector& public_key_hashes,
+ base::StringPiece hostname);
-// Sets the certificate whitelist for testing. Supply nullptr/0 to reset to
-// the built-in whitelist.
-void NET_EXPORT_PRIVATE
-SetCertificateWhitelistForTesting(const PublicKeyWhitelist* whitelist,
- size_t whitelist_size);
+// Returns true if |host| is in (or a subdomain of) a whitelisted host
+// in |graph|, which is a DAFSA constructed by
+// //net/tools/dafsa/make_dafsa.py that is |graph_length| bytes long.
+bool NET_EXPORT_PRIVATE IsWhitelistedHost(const unsigned char* graph,
+ size_t graph_length,
+ base::StringPiece host);
} // namespace net
-#endif // NET_CERT_CERT_VERIFY_PROC_WHITELIST
+#endif // NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
diff --git a/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc b/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
index 791957315a6..1ad6a1c5316 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
@@ -14,177 +14,16 @@ namespace net {
namespace {
-HashValue GetTestHashValue(uint8_t label, HashValueTag tag) {
- HashValue hash_value(tag);
- memset(hash_value.data(), label, hash_value.size());
- return hash_value;
-}
-
-HashValueVector GetFakeHashValues() {
- HashValueVector public_key_hashes;
-
- // Fake "root" hash
- public_key_hashes.push_back(GetTestHashValue(0x00, HASH_VALUE_SHA256));
- public_key_hashes.push_back(GetTestHashValue(0x01, HASH_VALUE_SHA1));
- // Fake "intermediate" hash
- public_key_hashes.push_back(GetTestHashValue(0x02, HASH_VALUE_SHA256));
- public_key_hashes.push_back(GetTestHashValue(0x03, HASH_VALUE_SHA1));
- // Fake "leaf" hash
- public_key_hashes.push_back(GetTestHashValue(0x04, HASH_VALUE_SHA256));
- public_key_hashes.push_back(GetTestHashValue(0x05, HASH_VALUE_SHA1));
-
- return public_key_hashes;
-}
-
-// The SHA-256 hash of the leaf cert "ok_cert.pem"; obtainable either
-// via X509Certificate::CalculateFingerprint256 or
-// openssl x509 -inform pem -in ok_cert.pem -outform der | openssl
-// dgst -sha256 -c
-const uint8_t kWhitelistCerts[][crypto::kSHA256Length] = {
- /* clang-format off */
- { 0xf4, 0x42, 0xdd, 0x66, 0xfa, 0x10, 0x70, 0x65,
- 0xd1, 0x7e, 0xd9, 0xbb, 0x7c, 0xa9, 0x3c, 0x79,
- 0x63, 0xbe, 0x01, 0xa7, 0x54, 0x18, 0xab, 0x2f,
- 0xc3, 0x9a, 0x14, 0x53, 0xc3, 0x83, 0xa0, 0x5a },
- /* clang-format on */
-};
-
-TEST(CertVerifyProcWhitelistTest, AcceptsWhitelistedEEByRoot) {
- scoped_refptr<X509Certificate> cert =
- ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
- ASSERT_TRUE(cert);
-
- // clang-format off
- const PublicKeyWhitelist kWhitelist[] = {
- { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- kWhitelistCerts, arraysize(kWhitelistCerts)
- },
- };
- // clang-format on
-
- SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
- HashValueVector public_key_hashes = GetFakeHashValues();
-
- // Should return false, indicating this cert is acceptable because of
- // it being whitelisted.
- EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
- SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, AcceptsWhitelistedEEByIntermediate) {
- scoped_refptr<X509Certificate> cert =
- ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
- ASSERT_TRUE(cert);
-
- // clang-format off
- const PublicKeyWhitelist kWhitelist[] = {
- { { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
- kWhitelistCerts, arraysize(kWhitelistCerts)
- },
- };
- // clang-format on
-
- SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
- HashValueVector public_key_hashes = GetFakeHashValues();
-
- // Should return false, indicating this cert is acceptable because of
- // it being whitelisted.
- EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
- SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, RejectsNonWhitelistedEE) {
- scoped_refptr<X509Certificate> cert =
- ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
- ASSERT_TRUE(cert);
-
- // clang-format off
- const PublicKeyWhitelist kWhitelist[] = {
- { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- kWhitelistCerts, arraysize(kWhitelistCerts)
- },
- };
- // clang-format on
-
- SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
- HashValueVector public_key_hashes = GetFakeHashValues();
-
- // Should return true, indicating this certificate chains to a constrained
- // root and is not whitelisted.
- EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
- SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, RejectsNonWhitelistedEEByIntermediate) {
- scoped_refptr<X509Certificate> cert =
- ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
- ASSERT_TRUE(cert);
-
- // clang-format off
- const PublicKeyWhitelist kWhitelist[] = {
- { { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
- kWhitelistCerts, arraysize(kWhitelistCerts)
- },
- };
- // clang-format on
-
- SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
- HashValueVector public_key_hashes = GetFakeHashValues();
-
- // Should return true, indicating this certificate chains to a constrained
- // root and is not whitelisted.
- EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
- SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, AcceptsUnconstrainedLeaf) {
- scoped_refptr<X509Certificate> cert =
- ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
- ASSERT_TRUE(cert);
-
- // clang-format off
- const PublicKeyWhitelist kWhitelist[] = {
- { { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
- kWhitelistCerts, arraysize(kWhitelistCerts)
- },
- };
- // clang-format on
-
- SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
- HashValueVector public_key_hashes = GetFakeHashValues();
-
- // Should return false, because the chain (as indicated by
- // public_key_hashes) is not constrained.
- EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
- SetCertificateWhitelistForTesting(nullptr, 0);
-}
+namespace test1 {
+#include "net/cert/cert_verify_proc_whitelist_unittest1-inc.cc"
+} // namespace test
TEST(CertVerifyProcWhitelistTest, HandlesWosignCerts) {
+ // The domain must be in the whitelist from
+ // //net/data/ssl/wosign/wosign_domains.gperf
+ const char kWhitelistedDomain[] = "005.tv";
+ const char kNonWhitelistedDomain[] = "006.tv";
+
scoped_refptr<X509Certificate> cert =
ImportCertFromFile(GetTestCertsDirectory(), "wosign_before_oct_21.pem");
ASSERT_TRUE(cert);
@@ -195,12 +34,68 @@ TEST(CertVerifyProcWhitelistTest, HandlesWosignCerts) {
0x95, 0xa5, 0x99, 0x68, 0xce, 0xf2, 0x34, 0x77, 0x37, 0x79, 0xdf,
0x51, 0x81, 0xcf, 0x10, 0xfa, 0x64, 0x75, 0x34, 0xbb, 0x65}});
- EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
+ // Domains on the whitelist are allowed, as long as their certificates were
+ // pre-existing before Oct 21, 2016.
+ EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kWhitelistedDomain));
+ // Domains not on the whitelist are not allowed, regardless of the validity
+ // period of the certificate.
+ EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kNonWhitelistedDomain));
cert = ImportCertFromFile(GetTestCertsDirectory(), "wosign_after_oct_21.pem");
ASSERT_TRUE(cert);
- EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
+ // No new certificates (after Oct 21, 2016) are all allowed, regardless
+ // of the domain.
+ EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kWhitelistedDomain));
+ EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kNonWhitelistedDomain));
+
+ // Certificates that aren't issued by WoSign are allowed, regardless of
+ // domain.
+ public_key_hashes[0].data()[0] = 0x14;
+ EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kWhitelistedDomain));
+ EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes,
+ kNonWhitelistedDomain));
+}
+
+TEST(CertVerifyProcWhitelistTest, IsWhitelistedHost) {
+ const unsigned char* graph = test1::kDafsa;
+ size_t graph_size = arraysize(test1::kDafsa);
+
+ // Test malformed inputs.
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, ""));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "."));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, ".."));
+
+ // Make sure that TLDs aren't accepted just because a subdomain is.
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "com"));
+
+ // Test various forms of domain names that GURL will accept for entries in
+ // the graph.
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, "example.com"));
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, "subdomain.example.com"));
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, ".subdomain.example.com"));
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, "example.com."));
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, ".example.com."));
+ EXPECT_TRUE(IsWhitelistedHost(graph, graph_size, "www.example.bar.jp"));
+
+ // Test various prefix/suffices of entries in the graph, but that aren't
+ // themselves domain matches.
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "anotherexample.com"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "bar.jp"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "example.bar.jp.junk"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "foo.example.bar.jp.junk"));
+
+ // Test various forms of domain names that GURL will accept for entries not
+ // in the graph.
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "domain.com"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "example..com"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "www.co.uk"));
+ EXPECT_FALSE(IsWhitelistedHost(graph, graph_size, "www..co.uk"));
}
} // namespace
diff --git a/chromium/net/cert/cert_verify_proc_whitelist_unittest1.gperf b/chromium/net/cert/cert_verify_proc_whitelist_unittest1.gperf
new file mode 100644
index 00000000000..cfe582aa6f7
--- /dev/null
+++ b/chromium/net/cert/cert_verify_proc_whitelist_unittest1.gperf
@@ -0,0 +1,9 @@
+%{
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+%}
+%%
+example.com, 0
+example.bar.jp, 0
+%%
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index a13117a7a8e..373b43cbe8e 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -363,27 +363,6 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context,
} else {
verified_chain.push_back(cert);
}
-
- const char* algorithm = cert->pCertInfo->SignatureAlgorithm.pszObjId;
- if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) {
- // md5WithRSAEncryption: 1.2.840.113549.1.1.4
- verify_result->has_md5 = true;
- } else if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) {
- // md2WithRSAEncryption: 1.2.840.113549.1.1.2
- verify_result->has_md2 = true;
- } else if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) {
- // md4WithRSAEncryption: 1.2.840.113549.1.1.3
- verify_result->has_md4 = true;
- } else if (strcmp(algorithm, szOID_RSA_SHA1RSA) == 0 ||
- strcmp(algorithm, szOID_X957_SHA1DSA) == 0 ||
- strcmp(algorithm, szOID_ECDSA_SHA1) == 0) {
- // sha1WithRSAEncryption: 1.2.840.113549.1.1.5
- // id-dsa-with-sha1: 1.2.840.10040.4.3
- // ecdsa-with-SHA1: 1.2.840.10045.4.1
- verify_result->has_sha1 = true;
- if (i == 0)
- verify_result->has_sha1_leaf = true;
- }
}
if (verified_cert) {
diff --git a/chromium/net/cert/cert_verify_result.cc b/chromium/net/cert/cert_verify_result.cc
index b1054e4ced3..4b605165d60 100644
--- a/chromium/net/cert/cert_verify_result.cc
+++ b/chromium/net/cert/cert_verify_result.cc
@@ -36,7 +36,8 @@ void CertVerifyResult::Reset() {
}
bool CertVerifyResult::operator==(const CertVerifyResult& other) const {
- return verified_cert->Equals(other.verified_cert.get()) &&
+ return (!!verified_cert == !!other.verified_cert) &&
+ (!verified_cert || verified_cert->Equals(other.verified_cert.get())) &&
std::tie(cert_status, has_md2, has_md4, has_md5, has_sha1,
has_sha1_leaf, public_key_hashes, is_issued_by_known_root,
is_issued_by_additional_trust_anchor,
diff --git a/chromium/net/cert/cert_verify_result.h b/chromium/net/cert/cert_verify_result.h
index 29c0675af3f..176c4ca50ed 100644
--- a/chromium/net/cert/cert_verify_result.h
+++ b/chromium/net/cert/cert_verify_result.h
@@ -28,12 +28,22 @@ class NET_EXPORT CertVerifyResult {
bool operator==(const CertVerifyResult& other) const;
- // The certificate and chain that was constructed during verification.
- // Note that the though the verified certificate will match the originally
- // supplied certificate, the intermediate certificates stored within may
- // be substantially different. In the event of a verification failure, this
- // will contain the chain as supplied by the server. This may be NULL if
- // running within the sandbox.
+ // The certificate chain that was constructed during verification.
+ //
+ // Note: Although |verified_cert| will match the originally supplied
+ // certificate to be validated, the results of GetIntermediateCertificates()
+ // may be substantially different, both in order and in content, then the
+ // originally supplied intermediates.
+ //
+ // In the event of validation failures, this may contain the originally
+ // supplied certificate chain or a partially constructed path, depending on
+ // the implementation.
+ //
+ // In the event of validation success, the trust anchor will be
+ // |verified_cert->GetIntermediateCertificates().back()| if
+ // there was a certificate chain to the trust anchor, and will
+ // be |verified_cert->os_cert_handle()| if the certificate was
+ // the trust anchor.
scoped_refptr<X509Certificate> verified_cert;
// Bitmask of CERT_STATUS_* from net/cert/cert_status_flags.h. Note that
@@ -42,7 +52,8 @@ class NET_EXPORT CertVerifyResult {
// chain.
CertStatus cert_status;
- // Properties of the certificate chain.
+ // Hash algorithms used by the certificate chain, excluding the trust
+ // anchor.
bool has_md2;
bool has_md4;
bool has_md5;
diff --git a/chromium/net/cert/crl_set_storage.cc b/chromium/net/cert/crl_set_storage.cc
index a4e3fd122cd..007cf3c1f47 100644
--- a/chromium/net/cert/crl_set_storage.cc
+++ b/chromium/net/cert/crl_set_storage.cc
@@ -14,6 +14,7 @@
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "crypto/sha2.h"
+#include "net/base/trace_constants.h"
#include "third_party/zlib/zlib.h"
namespace net {
@@ -132,7 +133,7 @@ static base::DictionaryValue* ReadHeader(base::StringPiece* data) {
if (header.get() == NULL)
return NULL;
- if (!header->IsType(base::Value::TYPE_DICTIONARY))
+ if (!header->IsType(base::Value::Type::DICTIONARY))
return NULL;
return static_cast<base::DictionaryValue*>(header.release());
}
@@ -294,7 +295,7 @@ static bool ReadDeltaCRL(base::StringPiece* data,
// static
bool CRLSetStorage::Parse(base::StringPiece data,
scoped_refptr<CRLSet>* out_crl_set) {
- TRACE_EVENT0("net", "CRLSetStorage::Parse");
+ TRACE_EVENT0(kNetTracingCategory, "CRLSetStorage::Parse");
// Other parts of Chrome assume that we're little endian, so we don't lose
// anything by doing this.
#if defined(__BYTE_ORDER)
diff --git a/chromium/net/cert/ct_known_logs.cc b/chromium/net/cert/ct_known_logs.cc
index a65988971ed..cca1fbefcef 100644
--- a/chromium/net/cert/ct_known_logs.cc
+++ b/chromium/net/cert/ct_known_logs.cc
@@ -92,4 +92,3 @@ bool IsLogDisqualified(base::StringPiece log_id,
} // namespace ct
} // namespace net
-
diff --git a/chromium/net/cert/ct_known_logs_static-inc.h b/chromium/net/cert/ct_known_logs_static-inc.h
index 7ead66cc559..87961b92403 100644
--- a/chromium/net/cert/ct_known_logs_static-inc.h
+++ b/chromium/net/cert/ct_known_logs_static-inc.h
@@ -4,21 +4,21 @@
struct CTLogInfo {
// The DER-encoded SubjectPublicKeyInfo for the log.
- const char* const log_key;
+ const char* log_key;
// The length, in bytes, of |log_key|.
- const size_t log_key_length;
+ size_t log_key_length;
// The user-friendly log name.
// Note: This will not be translated.
- const char* const log_name;
+ const char* log_name;
// The HTTPS API endpoint for the log.
// Note: Trailing slashes should be included.
- const char* const log_url;
+ const char* log_url;
// The DNS API endpoint for the log.
// This is used as the parent domain for all queries about the log.
// If empty, CT DNS queries are not supported for the log. This will prevent
// retrieval of inclusion proofs over DNS for SCTs from the log.
// https://github.com/google/certificate-transparency-rfcs/blob/master/dns/draft-ct-over-dns.md.
- const char* const log_dns_domain;
+ const char* log_dns_domain;
};
// The set of all presently-qualifying CT logs.
diff --git a/chromium/net/cert/ct_log_response_parser.cc b/chromium/net/cert/ct_log_response_parser.cc
index 5baf1b33534..b6067d14f38 100644
--- a/chromium/net/cert/ct_log_response_parser.cc
+++ b/chromium/net/cert/ct_log_response_parser.cc
@@ -4,10 +4,11 @@
#include "net/cert/ct_log_response_parser.h"
+#include <memory>
+
#include "base/base64.h"
#include "base/json/json_value_converter.h"
#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -105,7 +106,7 @@ bool IsJsonSTHStructurallyValid(const JsonSignedTreeHead& sth) {
// Structure for making JSON decoding easier. The string fields
// are base64-encoded so will require further decoding.
struct JsonConsistencyProof {
- ScopedVector<std::string> proof_nodes;
+ std::vector<std::unique_ptr<std::string>> proof_nodes;
static void RegisterJSONConverter(
base::JSONValueConverter<JsonConsistencyProof>* converter);
@@ -170,7 +171,7 @@ bool FillConsistencyProof(const base::Value& json_consistency_proof,
}
consistency_proof->reserve(parsed_proof.proof_nodes.size());
- for (std::string* proof_node : parsed_proof.proof_nodes) {
+ for (const auto& proof_node : parsed_proof.proof_nodes) {
consistency_proof->push_back(*proof_node);
}
diff --git a/chromium/net/cert/ct_log_response_parser_unittest.cc b/chromium/net/cert/ct_log_response_parser_unittest.cc
index 110a432aaa4..11006ec5ece 100644
--- a/chromium/net/cert/ct_log_response_parser_unittest.cc
+++ b/chromium/net/cert/ct_log_response_parser_unittest.cc
@@ -9,7 +9,6 @@
#include "base/base64.h"
#include "base/json/json_reader.h"
-#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/cert/ct_serialization.h"
diff --git a/chromium/net/cert/ct_log_verifier_util.h b/chromium/net/cert/ct_log_verifier_util.h
index 9894afe59ea..2e62d1a7a3d 100644
--- a/chromium/net/cert/ct_log_verifier_util.h
+++ b/chromium/net/cert/ct_log_verifier_util.h
@@ -27,4 +27,4 @@ NET_EXPORT std::string HashNodes(const std::string& lh, const std::string& rh);
} // namespace net
-#endif
+#endif // NET_CERT_CT_LOG_VERIFIER_UTIL_H_
diff --git a/chromium/net/cert/ct_objects_extractor.cc b/chromium/net/cert/ct_objects_extractor.cc
index 4f451fdd1f2..1a6e6e4772d 100644
--- a/chromium/net/cert/ct_objects_extractor.cc
+++ b/chromium/net/cert/ct_objects_extractor.cc
@@ -252,7 +252,7 @@ bool GetX509LogEntry(X509Certificate::OSCertHandle leaf, LogEntry* result) {
bool ExtractSCTListFromOCSPResponse(X509Certificate::OSCertHandle issuer,
const std::string& cert_serial_number,
- const std::string& ocsp_response,
+ base::StringPiece ocsp_response,
std::string* sct_list) {
// The input is an OCSPResponse. See RFC2560, section 4.2.1. The SCT list is
// in the extensions field of the SingleResponse which matches the input
diff --git a/chromium/net/cert/ct_objects_extractor.h b/chromium/net/cert/ct_objects_extractor.h
index d8fc5f95e52..d5deb5b607e 100644
--- a/chromium/net/cert/ct_objects_extractor.h
+++ b/chromium/net/cert/ct_objects_extractor.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/cert/x509_certificate.h"
@@ -54,7 +55,7 @@ NET_EXPORT_PRIVATE bool GetX509LogEntry(X509Certificate::OSCertHandle leaf,
NET_EXPORT_PRIVATE bool ExtractSCTListFromOCSPResponse(
X509Certificate::OSCertHandle issuer,
const std::string& cert_serial_number,
- const std::string& ocsp_response,
+ base::StringPiece ocsp_response,
std::string* sct_list);
} // namespace ct
diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc
index 7efec352535..8f8896938cd 100644
--- a/chromium/net/cert/ct_objects_extractor_unittest.cc
+++ b/chromium/net/cert/ct_objects_extractor_unittest.cc
@@ -44,8 +44,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
std::vector<base::StringPiece> parsed_scts;
base::StringPiece sct_list_sp(sct_list);
// Make sure the SCT list can be decoded properly
- EXPECT_TRUE(DecodeSCTList(&sct_list_sp, &parsed_scts));
-
+ EXPECT_TRUE(DecodeSCTList(sct_list_sp, &parsed_scts));
EXPECT_TRUE(DecodeSignedCertificateTimestamp(&parsed_scts[0], sct));
}
diff --git a/chromium/net/cert/ct_policy_enforcer.h b/chromium/net/cert/ct_policy_enforcer.h
index c732cee6ff4..7111970e29d 100644
--- a/chromium/net/cert/ct_policy_enforcer.h
+++ b/chromium/net/cert/ct_policy_enforcer.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_CT_POLICY_ENFORCER_H
-#define NET_CERT_CT_POLICY_ENFORCER_H
+#ifndef NET_CERT_CT_POLICY_ENFORCER_H_
+#define NET_CERT_CT_POLICY_ENFORCER_H_
#include <stddef.h>
#include <vector>
@@ -105,4 +105,4 @@ class NET_EXPORT CTPolicyEnforcer {
} // namespace net
-#endif // NET_CERT_CT_POLICY_ENFORCER_H
+#endif // NET_CERT_CT_POLICY_ENFORCER_H_
diff --git a/chromium/net/cert/ct_policy_enforcer_unittest.cc b/chromium/net/cert/ct_policy_enforcer_unittest.cc
index 59544094c29..f30411c338b 100644
--- a/chromium/net/cert/ct_policy_enforcer_unittest.cc
+++ b/chromium/net/cert/ct_policy_enforcer_unittest.cc
@@ -85,11 +85,11 @@ class CTPolicyEnforcerTest : public ::testing::Test {
sct->log_id = std::string(crypto::kSHA256Length, static_cast<char>(i));
if (timestamp_past_enforcement_date) {
- sct->timestamp =
- base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0});
+ EXPECT_TRUE(base::Time::FromUTCExploded({2015, 8, 0, 15, 0, 0, 0, 0},
+ &sct->timestamp));
} else {
- sct->timestamp =
- base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0});
+ EXPECT_TRUE(base::Time::FromUTCExploded({2015, 6, 0, 15, 0, 0, 0, 0},
+ &sct->timestamp));
}
verified_scts->push_back(sct);
@@ -111,10 +111,11 @@ class CTPolicyEnforcerTest : public ::testing::Test {
sct->origin = desired_origin;
sct->log_id = std::string(kCertlyLogID, crypto::kSHA256Length);
if (timestamp_after_disqualification_date) {
- sct->timestamp =
- base::Time::FromUTCExploded({2016, 4, 0, 16, 0, 0, 0, 0});
+ EXPECT_TRUE(base::Time::FromUTCExploded({2016, 4, 0, 16, 0, 0, 0, 0},
+ &sct->timestamp));
} else {
- sct->timestamp = base::Time::FromUTCExploded({2016, 4, 0, 1, 0, 0, 0, 0});
+ EXPECT_TRUE(base::Time::FromUTCExploded({2016, 4, 0, 1, 0, 0, 0, 0},
+ &sct->timestamp));
}
verified_scts->push_back(sct);
@@ -130,6 +131,14 @@ class CTPolicyEnforcerTest : public ::testing::Test {
verified_scts);
}
+ base::Time CreateTime(const base::Time::Exploded& exploded) {
+ base::Time result;
+ if (!base::Time::FromUTCExploded(exploded, &result)) {
+ ADD_FAILURE() << "Failed FromUTCExploded";
+ }
+ return result;
+ }
+
protected:
std::unique_ptr<CTPolicyEnforcer> policy_enforcer_;
scoped_refptr<X509Certificate> chain_;
@@ -137,8 +146,15 @@ class CTPolicyEnforcerTest : public ::testing::Test {
std::string non_google_log_id_;
};
+#if defined(OS_ANDROID)
+#define MAYBE_DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle \
+ DISABLED_DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle
+#else
+#define MAYBE_DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle \
+ DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle
+#endif
TEST_F(CTPolicyEnforcerTest,
- DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle) {
+ MAYBE_DoesNotConformToCTEVPolicyNotEnoughDiverseSCTsAllGoogle) {
ct::SCTList scts;
std::vector<std::string> desired_log_ids(2, google_log_id_);
@@ -443,38 +459,48 @@ TEST_F(CTPolicyEnforcerTest,
ASSERT_TRUE(private_key);
// Test multiple validity periods
+ base::Time time_2015_3_0_25_11_25_0_0 =
+ CreateTime({2015, 3, 0, 25, 11, 25, 0, 0});
+
+ base::Time time_2016_6_0_6_11_25_0_0 =
+ CreateTime({2016, 6, 0, 6, 11, 25, 0, 0});
+
+ base::Time time_2016_6_0_25_11_25_0_0 =
+ CreateTime({2016, 6, 0, 25, 11, 25, 0, 0});
+
+ base::Time time_2016_6_0_27_11_25_0_0 =
+ CreateTime({2016, 6, 0, 27, 11, 25, 0, 0});
+
+ base::Time time_2017_6_0_25_11_25_0_0 =
+ CreateTime({2017, 6, 0, 25, 11, 25, 0, 0});
+
+ base::Time time_2017_6_0_28_11_25_0_0 =
+ CreateTime({2017, 6, 0, 28, 11, 25, 0, 0});
+
+ base::Time time_2018_6_0_25_11_25_0_0 =
+ CreateTime({2018, 6, 0, 25, 11, 25, 0, 0});
+
+ base::Time time_2018_6_0_27_11_25_0_0 =
+ CreateTime({2018, 6, 0, 27, 11, 25, 0, 0});
+
const struct TestData {
base::Time validity_start;
base::Time validity_end;
size_t scts_required;
} kTestData[] = {{// Cert valid for 14 months, needs 2 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2016, 6, 0, 6, 11, 25, 0, 0}),
- 2},
+ time_2015_3_0_25_11_25_0_0, time_2016_6_0_6_11_25_0_0, 2},
{// Cert valid for exactly 15 months, needs 3 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2016, 6, 0, 25, 11, 25, 0, 0}),
- 3},
+ time_2015_3_0_25_11_25_0_0, time_2016_6_0_25_11_25_0_0, 3},
{// Cert valid for over 15 months, needs 3 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2016, 6, 0, 27, 11, 25, 0, 0}),
- 3},
+ time_2015_3_0_25_11_25_0_0, time_2016_6_0_27_11_25_0_0, 3},
{// Cert valid for exactly 27 months, needs 3 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2017, 6, 0, 25, 11, 25, 0, 0}),
- 3},
+ time_2015_3_0_25_11_25_0_0, time_2017_6_0_25_11_25_0_0, 3},
{// Cert valid for over 27 months, needs 4 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2017, 6, 0, 28, 11, 25, 0, 0}),
- 4},
+ time_2015_3_0_25_11_25_0_0, time_2017_6_0_28_11_25_0_0, 4},
{// Cert valid for exactly 39 months, needs 4 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2018, 6, 0, 25, 11, 25, 0, 0}),
- 4},
+ time_2015_3_0_25_11_25_0_0, time_2018_6_0_25_11_25_0_0, 4},
{// Cert valid for over 39 months, needs 5 SCTs.
- base::Time::FromUTCExploded({2015, 3, 0, 25, 11, 25, 0, 0}),
- base::Time::FromUTCExploded({2018, 6, 0, 27, 11, 25, 0, 0}),
- 5}};
+ time_2015_3_0_25_11_25_0_0, time_2018_6_0_27_11_25_0_0, 5}};
for (size_t i = 0; i < arraysize(kTestData); ++i) {
SCOPED_TRACE(i);
diff --git a/chromium/net/cert/ct_policy_status.h b/chromium/net/cert/ct_policy_status.h
index cc38585d6fa..c86e68100ed 100644
--- a/chromium/net/cert/ct_policy_status.h
+++ b/chromium/net/cert/ct_policy_status.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_CT_POLICY_STATUS_H
-#define NET_CERT_CT_POLICY_STATUS_H
+#ifndef NET_CERT_CT_POLICY_STATUS_H_
+#define NET_CERT_CT_POLICY_STATUS_H_
namespace net {
@@ -54,4 +54,4 @@ enum class EVPolicyCompliance {
} // namespace net
-#endif // NET_CERT_CT_POLICY_STATUS_H
+#endif // NET_CERT_CT_POLICY_STATUS_H_
diff --git a/chromium/net/cert/ct_serialization.cc b/chromium/net/cert/ct_serialization.cc
index 60d94263423..64a6ff5c5d0 100644
--- a/chromium/net/cert/ct_serialization.cc
+++ b/chromium/net/cert/ct_serialization.cc
@@ -383,15 +383,15 @@ void EncodeTreeHeadSignature(const SignedTreeHead& signed_tree_head,
output);
}
-bool DecodeSCTList(base::StringPiece* input,
+bool DecodeSCTList(base::StringPiece input,
std::vector<base::StringPiece>* output) {
std::vector<base::StringPiece> result;
- if (!ReadList(kSCTListLengthBytes, kSerializedSCTLengthBytes,
- input, &result)) {
+ if (!ReadList(kSCTListLengthBytes, kSerializedSCTLengthBytes, &input,
+ &result)) {
return false;
}
- if (!input->empty() || result.empty())
+ if (!input.empty() || result.empty())
return false;
output->swap(result);
return true;
diff --git a/chromium/net/cert/ct_serialization.h b/chromium/net/cert/ct_serialization.h
index 269892d3512..b5b3d77d69d 100644
--- a/chromium/net/cert/ct_serialization.h
+++ b/chromium/net/cert/ct_serialization.h
@@ -75,7 +75,7 @@ NET_EXPORT_PRIVATE void EncodeTreeHeadSignature(
// Returns true if the list could be read and decoded successfully, false
// otherwise (note that the validity of each individual SCT should be checked
// separately).
-NET_EXPORT_PRIVATE bool DecodeSCTList(base::StringPiece* input,
+NET_EXPORT_PRIVATE bool DecodeSCTList(base::StringPiece input,
std::vector<base::StringPiece>* output);
// Decodes a single SCT from |input| to |output|.
diff --git a/chromium/net/cert/ct_serialization_unittest.cc b/chromium/net/cert/ct_serialization_unittest.cc
index 6056ea3bcf1..6ddb329b7c4 100644
--- a/chromium/net/cert/ct_serialization_unittest.cc
+++ b/chromium/net/cert/ct_serialization_unittest.cc
@@ -141,7 +141,7 @@ TEST_F(CtSerializationTest, DecodesSCTList) {
base::StringPiece encoded("\x0\xa\x0\x3\x61\x62\x63\x0\x3\x64\x65\x66", 12);
std::vector<base::StringPiece> decoded;
- ASSERT_TRUE(ct::DecodeSCTList(&encoded, &decoded));
+ ASSERT_TRUE(ct::DecodeSCTList(encoded, &decoded));
ASSERT_STREQ("abc", decoded[0].data());
ASSERT_STREQ("def", decoded[1].data());
}
@@ -151,7 +151,7 @@ TEST_F(CtSerializationTest, FailsDecodingInvalidSCTList) {
base::StringPiece encoded("\x0\xa\x0\x3\x61\x62\x63\x0\x5\x64\x65\x66", 12);
std::vector<base::StringPiece> decoded;
- ASSERT_FALSE(ct::DecodeSCTList(&encoded, &decoded));
+ ASSERT_FALSE(ct::DecodeSCTList(encoded, &decoded));
}
TEST_F(CtSerializationTest, DecodesSignedCertificateTimestamp) {
@@ -259,4 +259,3 @@ TEST_F(CtSerializationTest, EncodesValidSignedTreeHead) {
}
} // namespace net
-
diff --git a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
index 1930ba892ce..d92f028897f 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -10,7 +10,6 @@
#include "base/base64.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "net/cert/ct_sct_to_string.h"
#include "net/cert/signed_certificate_timestamp.h"
@@ -22,10 +21,9 @@ namespace {
// Base64 encode the given |value| string and put it in |dict| with the
// description |key|.
-void SetBinaryData(
- const char* key,
- const std::string& value,
- base::DictionaryValue* dict) {
+void SetBinaryData(const char* key,
+ base::StringPiece value,
+ base::DictionaryValue* dict) {
std::string b64_value;
base::Base64Encode(value, &b64_value);
@@ -85,15 +83,15 @@ std::unique_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
}
std::unique_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
- const std::string* embedded_scts,
- const std::string* sct_list_from_ocsp,
- const std::string* sct_list_from_tls_extension,
+ base::StringPiece embedded_scts,
+ base::StringPiece sct_list_from_ocsp,
+ base::StringPiece sct_list_from_tls_extension,
NetLogCaptureMode capture_mode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- SetBinaryData("embedded_scts", *embedded_scts, dict.get());
- SetBinaryData("scts_from_ocsp_response", *sct_list_from_ocsp, dict.get());
- SetBinaryData("scts_from_tls_extension", *sct_list_from_tls_extension,
+ SetBinaryData("embedded_scts", embedded_scts, dict.get());
+ SetBinaryData("scts_from_ocsp_response", sct_list_from_ocsp, dict.get());
+ SetBinaryData("scts_from_tls_extension", sct_list_from_tls_extension,
dict.get());
return std::move(dict);
diff --git a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h
index 373a7525337..c2149cdb578 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h
@@ -6,8 +6,8 @@
#define NET_CERT_CT_SIGNED_CERTIFICATE_TIMESTAMP_LOG_PARAM_H_
#include <memory>
-#include <string>
+#include "base/strings/string_piece.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
namespace base {
@@ -31,9 +31,9 @@ std::unique_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
// See the documentation for SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED
// in net/log/net_log_event_type_list.h
std::unique_ptr<base::Value> NetLogRawSignedCertificateTimestampCallback(
- const std::string* embedded_scts,
- const std::string* sct_list_from_ocsp,
- const std::string* sct_list_from_tls_extension,
+ base::StringPiece embedded_scts,
+ base::StringPiece sct_list_from_ocsp,
+ base::StringPiece sct_list_from_tls_extension,
NetLogCaptureMode capture_mode);
} // namespace net
diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h
index b65a1334b48..b5b1c79045f 100644
--- a/chromium/net/cert/ct_verifier.h
+++ b/chromium/net/cert/ct_verifier.h
@@ -5,14 +5,12 @@
#ifndef NET_CERT_CT_VERIFIER_H_
#define NET_CERT_CT_VERIFIER_H_
-#include <string>
-
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
namespace net {
-class CTLogVerifier;
class NetLogWithSource;
class X509Certificate;
@@ -45,13 +43,13 @@ class NET_EXPORT CTVerifier {
// (embedding, TLS extension or OCSP stapling). If no stapled OCSP response
// is available, |stapled_ocsp_response| should be an empty string. If no SCT
// TLS extension was negotiated, |sct_list_from_tls_extension| should be an
- // empty string. |result| will be filled with the SCTs present, divided into
- // categories based on the verification result.
- virtual int Verify(X509Certificate* cert,
- const std::string& stapled_ocsp_response,
- const std::string& sct_list_from_tls_extension,
- SignedCertificateTimestampAndStatusList* output_scts,
- const NetLogWithSource& net_log) = 0;
+ // empty string. |output_scts| will be cleared and filled with the SCTs
+ // present, if any, along with their verification results.
+ virtual void Verify(X509Certificate* cert,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
+ SignedCertificateTimestampAndStatusList* output_scts,
+ const NetLogWithSource& net_log) = 0;
// Registers |observer| to receive notifications of validated SCTs. Does not
// take ownership of the observer as the observer may be performing
diff --git a/chromium/net/cert/do_nothing_ct_verifier.cc b/chromium/net/cert/do_nothing_ct_verifier.cc
new file mode 100644
index 00000000000..0429d86e765
--- /dev/null
+++ b/chromium/net/cert/do_nothing_ct_verifier.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/do_nothing_ct_verifier.h"
+
+#include "net/base/net_errors.h"
+
+namespace net {
+
+DoNothingCTVerifier::DoNothingCTVerifier() = default;
+DoNothingCTVerifier::~DoNothingCTVerifier() = default;
+
+void DoNothingCTVerifier::Verify(
+ X509Certificate* cert,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
+ SignedCertificateTimestampAndStatusList* output_scts,
+ const NetLogWithSource& net_log) {
+ output_scts->clear();
+}
+
+void DoNothingCTVerifier::SetObserver(Observer* observer) {}
+
+} // namespace net
diff --git a/chromium/net/cert/do_nothing_ct_verifier.h b/chromium/net/cert/do_nothing_ct_verifier.h
new file mode 100644
index 00000000000..025ffd11be8
--- /dev/null
+++ b/chromium/net/cert/do_nothing_ct_verifier.h
@@ -0,0 +1,67 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_DO_NOTHING_CT_VERIFIER_H_
+#define NET_CERT_DO_NOTHING_CT_VERIFIER_H_
+
+#include "base/macros.h"
+#include "net/base/net_export.h"
+#include "net/cert/ct_verifier.h"
+
+namespace net {
+
+// An implementation of CTVerifier that does not validate SCTs.
+//
+// SECURITY NOTE:
+// As Certificate Transparency is an essential part in safeguarding TLS
+// connections, disabling Certificate Transparency enforcement is a decision
+// that should not be taken lightly, and it should be made an explicit
+// decision rather than a potentially accidental decision (such as allowing
+// for a nullptr instance). By checking Certificate Transparency information,
+// typically via a net::MultiLogCTVerifier, and enforcing policies related
+// to Certificate Transparency provided by a net::CTPolicyEnforcer, developers
+// can help protect their users by ensuring that misissued TLS certificates
+// are detected.
+//
+// However, not every consumer of TLS certificates is using the Web PKI. For
+// example, they may be using connections authenticated out of band, or may
+// be using private or local PKIs for which Certificate Transparency is not
+// relevant. Alternatively, much like how a robust and secure TLS client
+// requires a regularly updated root certificate store, a robust and secure
+// Certificate Transparency client requires regular updates. However, since
+// some clients may not support regular updates, it may be intentional to
+// disable Certificate Transparency and choose a less-secure default
+// behavior.
+//
+// Consumers of this class should generally try to get a security or design
+// to discuss the type of net::X509Certificates they will be validating,
+// and determine whether or not Certificate Transparency is right for the
+// particular use case.
+//
+// Because of the complex nuances related to security tradeoffs, it is
+// expected that classes which expect a CTVerifier will require one to be
+// supplied, forcing the caller to make an intentional and explicit decision
+// about the appropriate security policy, rather than leaving it ambiguous,
+// such as via a nullptr. This class is intended to indicate an intentional
+// consideration of CT, and a decision to not support it.
+class NET_EXPORT DoNothingCTVerifier : public CTVerifier {
+ public:
+ DoNothingCTVerifier();
+ ~DoNothingCTVerifier() override;
+
+ void Verify(X509Certificate* cert,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
+ SignedCertificateTimestampAndStatusList* output_scts,
+ const NetLogWithSource& net_log) override;
+
+ void SetObserver(Observer* observer) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DoNothingCTVerifier);
+};
+
+} // namespace net
+
+#endif // NET_CERT_DO_NOTHING_CT_VERIFIER_H_
diff --git a/chromium/net/cert/ev_root_ca_metadata.cc b/chromium/net/cert/ev_root_ca_metadata.cc
index 1370f1726c4..a7e85ec8059 100644
--- a/chromium/net/cert/ev_root_ca_metadata.cc
+++ b/chromium/net/cert/ev_root_ca_metadata.cc
@@ -41,7 +41,7 @@ struct EVMetadata {
SHA1HashValue fingerprint;
// The EV policy OIDs of the root CA.
- const char policy_oids[kMaxOIDsPerCA][kMaxOIDLength];
+ char policy_oids[kMaxOIDsPerCA][kMaxOIDLength];
};
static const EVMetadata ev_root_ca_metadata[] = {
@@ -114,6 +114,34 @@ static const EVMetadata ev_root_ca_metadata[] = {
0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb}},
{"1.3.6.1.4.1.34697.2.4", ""},
},
+ // Amazon Root CA 1
+ // https://good.sca1a.amazontrust.com/
+ {
+ {{0x8d, 0xa7, 0xf9, 0x65, 0xec, 0x5e, 0xfc, 0x37, 0x91, 0x0f,
+ 0x1c, 0x6e, 0x59, 0xfd, 0xc1, 0xcc, 0x6a, 0x6e, 0xde, 0x16}},
+ {"2.23.140.1.1", ""},
+ },
+ // Amazon Root CA 2
+ // https://good.sca2a.amazontrust.com/
+ {
+ {{0x5a, 0x8c, 0xef, 0x45, 0xd7, 0xa6, 0x98, 0x59, 0x76, 0x7a,
+ 0x8c, 0x8b, 0x44, 0x96, 0xb5, 0x78, 0xcf, 0x47, 0x4b, 0x1a}},
+ {"2.23.140.1.1", ""},
+ },
+ // Amazon Root CA 3
+ // https://good.sca3a.amazontrust.com/
+ {
+ {{0x0d, 0x44, 0xdd, 0x8c, 0x3c, 0x8c, 0x1a, 0x1a, 0x58, 0x75,
+ 0x64, 0x81, 0xe9, 0x0f, 0x2e, 0x2a, 0xff, 0xb3, 0xd2, 0x6e}},
+ {"2.23.140.1.1", ""},
+ },
+ // Amazon Root CA 4
+ // https://good.sca4a.amazontrust.com/
+ {
+ {{0xf6, 0x10, 0x84, 0x07, 0xd6, 0xf8, 0xbb, 0x67, 0x98, 0x0c,
+ 0xc2, 0xe2, 0x44, 0xc2, 0xeb, 0xae, 0x1c, 0xef, 0x63, 0xbe}},
+ {"2.23.140.1.1", ""},
+ },
// Autoridad de Certificacion Firmaprofesional CIF A62634068
// https://publifirma.firmaprofesional.com/
{{{0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f,
@@ -168,6 +196,13 @@ static const EVMetadata ev_root_ca_metadata[] = {
0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e}},
{"1.2.616.1.113527.2.5.1.1", ""},
},
+ // CFCA EV ROOT
+ // https://www.erenepu.com/
+ {
+ {{0xe2, 0xb8, 0x29, 0x4b, 0x55, 0x84, 0xab, 0x6b, 0x58, 0xc2,
+ 0x90, 0x46, 0x6c, 0xac, 0x3f, 0xb8, 0x39, 0x8f, 0x84, 0x83}},
+ {"2.16.156.112554.3", ""},
+ },
// China Internet Network Information Center EV Certificates Root
// https://evdemo.cnnic.cn/
{
@@ -239,6 +274,13 @@ static const EVMetadata ev_root_ca_metadata[] = {
0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9}},
{"2.16.840.1.114028.10.1.2", ""},
},
+ // Entrust Root Certification Authority – G2
+ // https://validg2.entrust.net
+ {
+ {{0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06,
+ 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4}},
+ {"2.16.840.1.114028.10.1.2", ""},
+ },
// Equifax Secure Certificate Authority (GeoTrust)
// https://www.geotrust.com/
{
@@ -343,6 +385,13 @@ static const EVMetadata ev_root_ca_metadata[] = {
0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd}},
{"1.3.6.1.4.1.14777.6.1.1", "1.3.6.1.4.1.14777.6.1.2"},
},
+ // LuxTrust Global Root 2
+ // https://ltsslca5.trustme.lu/
+ {
+ {{0x1e, 0x0e, 0x56, 0x19, 0x0a, 0xd1, 0x8b, 0x25, 0x98, 0xb2,
+ 0x04, 0x44, 0xff, 0x66, 0x8a, 0x04, 0x17, 0x99, 0x5f, 0x3f}},
+ {"1.3.171.1.1.10.5.2", ""},
+ },
// Network Solutions Certificate Authority
// https://www.networksolutions.com/website-packages/index.jsp
{
@@ -358,6 +407,13 @@ static const EVMetadata ev_root_ca_metadata[] = {
0xc0, 0x71, 0xf8, 0xf7, 0x33, 0xb1, 0x83, 0x85, 0x63, 0x32}},
{"1.3.6.1.4.1.782.1.2.1.8.1", ""},
},
+ // OISTE WISeKey Global Root GB CA
+ // https://goodevssl.wisekey.com
+ {
+ {{0x0f, 0xf9, 0x40, 0x76, 0x18, 0xd3, 0xd7, 0x6a, 0x4b, 0x98,
+ 0xf0, 0xa8, 0x35, 0x9e, 0x0c, 0xfd, 0x27, 0xac, 0xcc, 0xed}},
+ {"2.16.756.5.14.7.4.8", ""},
+ },
// QuoVadis Root CA 2
// https://www.quovadis.bm/
{
@@ -440,7 +496,7 @@ static const EVMetadata ev_root_ca_metadata[] = {
{
{{0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f,
0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f}},
- {"2.16.840.1.114414.1.7.24.3", ""},
+ {"2.16.840.1.114414.1.7.24.3", "2.23.140.1.1"},
},
// SwissSign Gold CA - G2
// https://testevg2.swisssign.net/
diff --git a/chromium/net/cert/internal/cert_errors.h b/chromium/net/cert/internal/cert_errors.h
index a9579ce0c31..cd713ed42ec 100644
--- a/chromium/net/cert/internal/cert_errors.h
+++ b/chromium/net/cert/internal/cert_errors.h
@@ -75,7 +75,6 @@ namespace net {
class CertErrorParams;
class CertErrorScoper;
-class ParsedCertificate;
// The type of a particular CertErrorNode.
enum class CertErrorNodeType {
diff --git a/chromium/net/cert/internal/cert_issuer_source.h b/chromium/net/cert/internal/cert_issuer_source.h
index 1ffc3b3a9f9..c38b61d2546 100644
--- a/chromium/net/cert/internal/cert_issuer_source.h
+++ b/chromium/net/cert/internal/cert_issuer_source.h
@@ -8,9 +8,7 @@
#include <memory>
#include <vector>
-#include "base/callback.h"
#include "net/base/net_export.h"
-#include "net/cert/internal/completion_status.h"
#include "net/cert/internal/parsed_certificate.h"
namespace net {
@@ -30,27 +28,19 @@ class NET_EXPORT CertIssuerSource {
// Destruction of the Request cancels it.
virtual ~Request() = default;
- // Retrieves the next issuer.
+ // Retrieves issuers and appends them to |issuers|.
//
- // If one is available it will be stored in |out_cert| and SYNC will be
- // returned. GetNext should be called again to retrieve any remaining
- // issuers.
+ // GetNext should be called again to retrieve any remaining issuers.
//
- // If no issuers are currently available, |out_cert| will be cleared and the
- // return value will indicate if the Request is exhausted. If the return
- // value is ASYNC, the |issuers_callback| that was passed to
- // AsyncGetIssuersOf will be called again (unless the Request is destroyed
- // first). If the return value is SYNC, the Request is complete and the
- // |issuers_callback| will not be called again.
- virtual CompletionStatus GetNext(
- scoped_refptr<ParsedCertificate>* out_cert) = 0;
+ // If no issuers are left then |issuers| will not be modified. This
+ // indicates that the issuers have been exhausted and GetNext() should
+ // not be called again.
+ virtual void GetNext(ParsedCertificateList* issuers) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Request);
};
- using IssuerCallback = base::Callback<void(Request*)>;
-
virtual ~CertIssuerSource() = default;
// Finds certificates whose Subject matches |cert|'s Issuer.
@@ -61,18 +51,13 @@ class NET_EXPORT CertIssuerSource {
ParsedCertificateList* issuers) = 0;
// Finds certificates whose Subject matches |cert|'s Issuer.
- // If an async callback will be made |*out_req| is filled with a Request
- // object which may be destroyed to cancel the callback. If the implementation
- // does not support asynchronous lookups or can determine synchronously that
- // it would return no results, |*out_req| will be set to nullptr.
+ // If the implementation does not support asynchronous lookups or can
+ // determine synchronously that it would return no results, |*out_req|
+ // will be set to nullptr.
//
- // When matches are available or the request is complete, |issuers_callback|
- // will be called with a pointer to the same Request. The Request::GetNext
- // method may then be used to iterate through the retrieved issuers. Note that
- // |issuers_callback| may be called multiple times. See the documentation for
- // Request::GetNext for more details.
+ // Otherwise a request is started and saved to |out_req|. The results can be
+ // read through the Request interface.
virtual void AsyncGetIssuersOf(const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
std::unique_ptr<Request>* out_req) = 0;
};
diff --git a/chromium/net/cert/internal/cert_issuer_source_aia.cc b/chromium/net/cert/internal/cert_issuer_source_aia.cc
index a6fb1b703d1..6e1290ab26d 100644
--- a/chromium/net/cert/internal/cert_issuer_source_aia.cc
+++ b/chromium/net/cert/internal/cert_issuer_source_aia.cc
@@ -20,94 +20,82 @@ const int kMaxFetchesPerCert = 5;
class AiaRequest : public CertIssuerSource::Request {
public:
- explicit AiaRequest(const CertIssuerSource::IssuerCallback& issuers_callback);
+ AiaRequest() {}
~AiaRequest() override;
// CertIssuerSource::Request implementation.
- CompletionStatus GetNext(scoped_refptr<ParsedCertificate>* out_cert) override;
+ void GetNext(ParsedCertificateList* issuers) override;
void AddCertFetcherRequest(
std::unique_ptr<CertNetFetcher::Request> cert_fetcher_request);
- void OnFetchCompleted(Error error, const std::vector<uint8_t>& fetched_bytes);
+ bool AddCompletedFetchToResults(Error error,
+ std::vector<uint8_t> fetched_bytes,
+ ParsedCertificateList* results);
private:
- bool HasNext() const { return current_result_ < results_.size(); }
-
- CertIssuerSource::IssuerCallback issuers_callback_;
std::vector<std::unique_ptr<CertNetFetcher::Request>> cert_fetcher_requests_;
- size_t pending_requests_ = 0;
- ParsedCertificateList results_;
- size_t current_result_ = 0;
+ size_t current_request_ = 0;
DISALLOW_COPY_AND_ASSIGN(AiaRequest);
};
-AiaRequest::AiaRequest(const CertIssuerSource::IssuerCallback& issuers_callback)
- : issuers_callback_(issuers_callback) {}
-
AiaRequest::~AiaRequest() = default;
-CompletionStatus AiaRequest::GetNext(
- scoped_refptr<ParsedCertificate>* out_cert) {
- if (HasNext()) {
- *out_cert = std::move(results_[current_result_++]);
- return CompletionStatus::SYNC;
+void AiaRequest::GetNext(ParsedCertificateList* out_certs) {
+ // TODO(eroman): Rather than blocking in FIFO order, select the one that
+ // completes first.
+ while (current_request_ < cert_fetcher_requests_.size()) {
+ Error error;
+ std::vector<uint8_t> bytes;
+ auto req = std::move(cert_fetcher_requests_[current_request_++]);
+ req->WaitForResult(&error, &bytes);
+
+ if (AddCompletedFetchToResults(error, std::move(bytes), out_certs))
+ return;
}
- *out_cert = nullptr;
- if (pending_requests_)
- return CompletionStatus::ASYNC;
- return CompletionStatus::SYNC;
}
void AiaRequest::AddCertFetcherRequest(
std::unique_ptr<CertNetFetcher::Request> cert_fetcher_request) {
DCHECK(cert_fetcher_request);
cert_fetcher_requests_.push_back(std::move(cert_fetcher_request));
- pending_requests_++;
}
-void AiaRequest::OnFetchCompleted(Error error,
- const std::vector<uint8_t>& fetched_bytes) {
- DCHECK_GT(pending_requests_, 0U);
- pending_requests_--;
- bool client_waiting_for_callback = !HasNext();
+bool AiaRequest::AddCompletedFetchToResults(Error error,
+ std::vector<uint8_t> fetched_bytes,
+ ParsedCertificateList* results) {
if (error != OK) {
// TODO(mattm): propagate error info.
LOG(ERROR) << "AiaRequest::OnFetchCompleted got error " << error;
- } else {
- // RFC 5280 section 4.2.2.1:
- //
- // Conforming applications that support HTTP or FTP for accessing
- // certificates MUST be able to accept individual DER encoded
- // certificates and SHOULD be able to accept "certs-only" CMS messages.
- //
- // TODO(mattm): Is supporting CMS message format important?
- //
- // TODO(mattm): Avoid copying bytes. Change the CertNetFetcher and
- // ParsedCertificate interface to allow passing through ownership of the
- // bytes.
- CertErrors errors;
- if (!ParsedCertificate::CreateAndAddToVector(fetched_bytes.data(),
- fetched_bytes.size(), {},
- &results_, &errors)) {
- // TODO(crbug.com/634443): propagate error info.
- LOG(ERROR) << "Error parsing cert retrieved from AIA:\n"
- << errors.ToDebugString();
- }
+ return false;
}
- // If the client is waiting for results, need to run callback if:
- // * Some are available now.
- // * The last fetch finished, even with no results. (Client needs to know to
- // stop waiting.)
- if (client_waiting_for_callback && (HasNext() || pending_requests_ == 0))
- issuers_callback_.Run(this);
+ // RFC 5280 section 4.2.2.1:
+ //
+ // Conforming applications that support HTTP or FTP for accessing
+ // certificates MUST be able to accept individual DER encoded
+ // certificates and SHOULD be able to accept "certs-only" CMS messages.
+ //
+ // TODO(mattm): Is supporting CMS message format important?
+ //
+ // TODO(eroman): Avoid copying bytes in the certificate?
+ CertErrors errors;
+ if (!ParsedCertificate::CreateAndAddToVector(
+ fetched_bytes.data(), fetched_bytes.size(), {}, results, &errors)) {
+ // TODO(crbug.com/634443): propagate error info.
+ LOG(ERROR) << "Error parsing cert retrieved from AIA:\n"
+ << errors.ToDebugString();
+ return false;
+ }
+
+ return true;
}
} // namespace
-CertIssuerSourceAia::CertIssuerSourceAia(CertNetFetcher* cert_fetcher)
- : cert_fetcher_(cert_fetcher) {}
+CertIssuerSourceAia::CertIssuerSourceAia(
+ scoped_refptr<CertNetFetcher> cert_fetcher)
+ : cert_fetcher_(std::move(cert_fetcher)) {}
CertIssuerSourceAia::~CertIssuerSourceAia() = default;
@@ -116,10 +104,8 @@ void CertIssuerSourceAia::SyncGetIssuersOf(const ParsedCertificate* cert,
// CertIssuerSourceAia never returns synchronous results.
}
-void CertIssuerSourceAia::AsyncGetIssuersOf(
- const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
- std::unique_ptr<Request>* out_req) {
+void CertIssuerSourceAia::AsyncGetIssuersOf(const ParsedCertificate* cert,
+ std::unique_ptr<Request>* out_req) {
out_req->reset();
if (!cert->has_authority_info_access())
@@ -152,16 +138,14 @@ void CertIssuerSourceAia::AsyncGetIssuersOf(
if (urls.empty())
return;
- std::unique_ptr<AiaRequest> aia_request(new AiaRequest(issuers_callback));
+ std::unique_ptr<AiaRequest> aia_request(new AiaRequest());
for (const auto& url : urls) {
// TODO(mattm): add synchronous failure mode to FetchCaIssuers interface so
// that this doesn't need to wait for async callback just to tell that an
// URL has an unsupported scheme?
aia_request->AddCertFetcherRequest(cert_fetcher_->FetchCaIssuers(
- url, kTimeoutMilliseconds, kMaxResponseBytes,
- base::Bind(&AiaRequest::OnFetchCompleted,
- base::Unretained(aia_request.get()))));
+ url, kTimeoutMilliseconds, kMaxResponseBytes));
}
*out_req = std::move(aia_request);
diff --git a/chromium/net/cert/internal/cert_issuer_source_aia.h b/chromium/net/cert/internal/cert_issuer_source_aia.h
index 73c8177bce0..3e62c95a085 100644
--- a/chromium/net/cert/internal/cert_issuer_source_aia.h
+++ b/chromium/net/cert/internal/cert_issuer_source_aia.h
@@ -16,21 +16,20 @@ class CertNetFetcher;
class NET_EXPORT CertIssuerSourceAia : public CertIssuerSource {
public:
// Creates CertIssuerSource that will use |cert_fetcher| to retrieve issuers
- // using AuthorityInfoAccess URIs. |cert_fetcher| must outlive the
- // CertIssuerSourceAia. CertIssuerSourceAia must be created and used only on
- // a single thread, which is the thread |cert_fetcher| will be operated from.
- explicit CertIssuerSourceAia(CertNetFetcher* cert_fetcher);
+ // using AuthorityInfoAccess URIs. CertIssuerSourceAia must be created and
+ // used only on a single thread, which is the thread |cert_fetcher| will be
+ // operated from.
+ explicit CertIssuerSourceAia(scoped_refptr<CertNetFetcher> cert_fetcher);
~CertIssuerSourceAia() override;
// CertIssuerSource implementation:
void SyncGetIssuersOf(const ParsedCertificate* cert,
ParsedCertificateList* issuers) override;
void AsyncGetIssuersOf(const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
std::unique_ptr<Request>* out_req) override;
private:
- CertNetFetcher* cert_fetcher_;
+ scoped_refptr<CertNetFetcher> cert_fetcher_;
DISALLOW_COPY_AND_ASSIGN(CertIssuerSourceAia);
};
diff --git a/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc b/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc
index b0f1aa72d28..f81c33d76f3 100644
--- a/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc
+++ b/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc
@@ -5,6 +5,7 @@
#include "net/cert/internal/cert_issuer_source_aia.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "net/cert/cert_net_fetcher.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parsed_certificate.h"
@@ -17,8 +18,11 @@ namespace net {
namespace {
+using ::testing::ByMove;
using ::testing::Mock;
+using ::testing::Return;
using ::testing::StrictMock;
+using ::testing::_;
::testing::AssertionResult ReadTestPem(const std::string& file_name,
const std::string& block_name,
@@ -56,112 +60,59 @@ std::vector<uint8_t> CertDataVector(const ParsedCertificate* cert) {
return data;
}
-// Tracks a CertNetFetcher::Request that will be returned to the
-// CertIssuerSourceAia. Allows the tests to tell if the Request is still alive
-// or was deleted(cancelled) by the CertIssuerSourceAia. If the Request is still
-// alive, the test can get the FetchCallback to simulate the Request completing.
-class RequestManager {
+// MockCertNetFetcher is an implementation of CertNetFetcher for testing.
+class MockCertNetFetcher : public CertNetFetcher {
public:
- class Request : public CertNetFetcher::Request {
- public:
- Request(RequestManager* manager,
- const CertNetFetcher::FetchCallback& callback)
- : manager_(manager), callback_(callback) {}
- ~Request() override { manager_->RequestWasDestroyed(); }
-
- CertNetFetcher::FetchCallback get_callback() const { return callback_; }
-
- private:
- RequestManager* manager_;
- CertNetFetcher::FetchCallback callback_;
- };
-
- ~RequestManager() { CHECK(!request_); }
-
- std::unique_ptr<Request> CreateRequest(
- const CertNetFetcher::FetchCallback& callback) {
- EXPECT_FALSE(request_);
- std::unique_ptr<Request> request(new Request(this, callback));
- request_ = request.get();
- return request;
- }
-
- bool is_request_alive() const { return request_; }
-
- CertNetFetcher::FetchCallback get_callback() const {
- CHECK(is_request_alive());
- return request_->get_callback();
- }
-
- private:
- void RequestWasDestroyed() {
- EXPECT_TRUE(request_);
- request_ = nullptr;
- }
-
- Request* request_;
+ MockCertNetFetcher() {}
+ MOCK_METHOD0(Shutdown, void());
+ MOCK_METHOD3(FetchCaIssuers,
+ std::unique_ptr<Request>(const GURL& url,
+ int timeout_milliseconds,
+ int max_response_bytes));
+ MOCK_METHOD3(FetchCrl,
+ std::unique_ptr<Request>(const GURL& url,
+ int timeout_milliseconds,
+ int max_response_bytes));
+
+ MOCK_METHOD3(FetchOcsp,
+ std::unique_ptr<Request>(const GURL& url,
+ int timeout_milliseconds,
+ int max_response_bytes));
+
+ protected:
+ ~MockCertNetFetcher() override {}
};
-// MockCertNetFetcherImpl is an implementation of CertNetFetcher for testing.
-class MockCertNetFetcherImpl : public CertNetFetcher {
+// MockCertNetFetcherRequest gives back the indicated error and bytes.
+class MockCertNetFetcherRequest : public CertNetFetcher::Request {
public:
- MockCertNetFetcherImpl() = default;
- ~MockCertNetFetcherImpl() override = default;
-
- RequestManager* GetRequestManagerForURL(const GURL& url) {
- auto it = request_map_.find(url);
- if (it == request_map_.end())
- return nullptr;
- return it->second.get();
- }
-
- WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCaIssuers(
- const GURL& url,
- int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) override {
- EXPECT_TRUE(request_map_.find(url) == request_map_.end());
-
- std::unique_ptr<RequestManager> request_manager(new RequestManager());
-
- std::unique_ptr<Request> request = request_manager->CreateRequest(callback);
-
- request_map_[url] = std::move(request_manager);
-
- return request;
- }
-
- WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCrl(
- const GURL& url,
- int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) override {
- NOTREACHED();
- return nullptr;
- }
-
- WARN_UNUSED_RESULT std::unique_ptr<Request> FetchOcsp(
- const GURL& url,
- int timeout_milliseconds,
- int max_response_bytes,
- const FetchCallback& callback) override {
- NOTREACHED();
- return nullptr;
+ MockCertNetFetcherRequest(Error error, std::vector<uint8_t> bytes)
+ : error_(error), bytes_(std::move(bytes)) {}
+
+ void WaitForResult(Error* error, std::vector<uint8_t>* bytes) override {
+ DCHECK(!did_consume_result_);
+ *error = error_;
+ *bytes = std::move(bytes_);
+ did_consume_result_ = true;
}
private:
- std::map<GURL, std::unique_ptr<RequestManager>> request_map_;
-
- DISALLOW_COPY_AND_ASSIGN(MockCertNetFetcherImpl);
+ Error error_;
+ std::vector<uint8_t> bytes_;
+ bool did_consume_result_ = false;
};
-class MockIssuerCallback {
- public:
- MOCK_METHOD1(Callback, void(CertIssuerSource::Request*));
-};
+// Creates a CertNetFetcher::Request that completes with an error.
+std::unique_ptr<CertNetFetcher::Request> CreateMockRequest(Error error) {
+ return base::MakeUnique<MockCertNetFetcherRequest>(error,
+ std::vector<uint8_t>());
+}
-void NotCalled(CertIssuerSource::Request* request) {
- ADD_FAILURE() << "NotCalled was called";
+// Creates a CertNetFetcher::Request that completes with the specified error
+// code and bytes.
+std::unique_ptr<CertNetFetcher::Request> CreateMockRequest(
+ const std::vector<uint8_t>& bytes) {
+ return base::MakeUnique<MockCertNetFetcherRequest>(OK, bytes);
}
// CertIssuerSourceAia does not return results for SyncGetIssuersOf.
@@ -169,8 +120,9 @@ TEST(CertIssuerSourceAiaTest, NoSyncResults) {
scoped_refptr<ParsedCertificate> cert;
ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ // No methods on |mock_fetcher| should be called.
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
ParsedCertificateList issuers;
aia_source.SyncGetIssuersOf(cert.get(), &issuers);
EXPECT_EQ(0U, issuers.size());
@@ -182,10 +134,11 @@ TEST(CertIssuerSourceAiaTest, NoAia) {
scoped_refptr<ParsedCertificate> cert;
ASSERT_TRUE(ReadTestCert("target_no_aia.pem", &cert));
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ // No methods on |mock_fetcher| should be called.
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> request;
- aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request);
+ aia_source.AsyncGetIssuersOf(cert.get(), &request);
EXPECT_EQ(nullptr, request);
}
@@ -198,32 +151,19 @@ TEST(CertIssuerSourceAiaTest, FileAia) {
scoped_refptr<ParsedCertificate> cert;
ASSERT_TRUE(ReadTestCert("target_file_aia.pem", &cert));
- StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+ EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
+ .WillOnce(Return(ByMove(CreateMockRequest(ERR_DISALLOWED_URL_SCHEME))));
+
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
- aia_source.AsyncGetIssuersOf(cert.get(),
- base::Bind(&MockIssuerCallback::Callback,
- base::Unretained(&mock_callback)),
- &cert_source_request);
+ aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
ASSERT_NE(nullptr, cert_source_request);
- RequestManager* req_manager =
- mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null"));
- ASSERT_TRUE(req_manager);
- ASSERT_TRUE(req_manager->is_request_alive());
-
- EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
- // CertNetFetcher rejects the URL scheme.
- req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME,
- std::vector<uint8_t>());
- Mock::VerifyAndClearExpectations(&mock_callback);
-
// No results.
- scoped_refptr<ParsedCertificate> result_cert;
- CompletionStatus status = cert_source_request->GetNext(&result_cert);
- EXPECT_EQ(CompletionStatus::SYNC, status);
- EXPECT_FALSE(result_cert.get());
+ ParsedCertificateList result_certs;
+ cert_source_request->GetNext(&result_certs);
+ EXPECT_TRUE(result_certs.empty());
}
// If the AuthorityInfoAccess extension contains an invalid URL,
@@ -232,10 +172,10 @@ TEST(CertIssuerSourceAiaTest, OneInvalidURL) {
scoped_refptr<ParsedCertificate> cert;
ASSERT_TRUE(ReadTestCert("target_invalid_url_aia.pem", &cert));
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> request;
- aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request);
+ aia_source.AsyncGetIssuersOf(cert.get(), &request);
EXPECT_EQ(nullptr, request);
}
@@ -246,38 +186,26 @@ TEST(CertIssuerSourceAiaTest, OneAia) {
scoped_refptr<ParsedCertificate> intermediate_cert;
ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
- StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
- std::unique_ptr<CertIssuerSource::Request> cert_source_request;
- aia_source.AsyncGetIssuersOf(cert.get(),
- base::Bind(&MockIssuerCallback::Callback,
- base::Unretained(&mock_callback)),
- &cert_source_request);
- ASSERT_NE(nullptr, cert_source_request);
-
- RequestManager* req_manager =
- mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
- ASSERT_TRUE(req_manager);
- ASSERT_TRUE(req_manager->is_request_alive());
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
- EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
- req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
- Mock::VerifyAndClearExpectations(&mock_callback);
+ EXPECT_CALL(*mock_fetcher,
+ FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
+ .WillOnce(Return(
+ ByMove(CreateMockRequest(CertDataVector(intermediate_cert.get())))));
- scoped_refptr<ParsedCertificate> result_cert;
- CompletionStatus status = cert_source_request->GetNext(&result_cert);
- EXPECT_EQ(CompletionStatus::SYNC, status);
- ASSERT_TRUE(result_cert.get());
- ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
+ CertIssuerSourceAia aia_source(mock_fetcher);
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request;
+ aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
+ ASSERT_NE(nullptr, cert_source_request);
- status = cert_source_request->GetNext(&result_cert);
- EXPECT_EQ(CompletionStatus::SYNC, status);
- EXPECT_FALSE(result_cert.get());
+ ParsedCertificateList result_certs;
+ cert_source_request->GetNext(&result_certs);
+ ASSERT_EQ(1u, result_certs.size());
+ ASSERT_EQ(result_certs.front()->der_cert(), intermediate_cert->der_cert());
- EXPECT_TRUE(req_manager->is_request_alive());
- cert_source_request.reset();
- EXPECT_FALSE(req_manager->is_request_alive());
+ result_certs.clear();
+ cert_source_request->GetNext(&result_certs);
+ EXPECT_TRUE(result_certs.empty());
}
// AuthorityInfoAccess with two URIs, one a FILE, the other a HTTP.
@@ -290,52 +218,32 @@ TEST(CertIssuerSourceAiaTest, OneFileOneHttpAia) {
scoped_refptr<ParsedCertificate> intermediate_cert;
ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
- StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
- std::unique_ptr<CertIssuerSource::Request> cert_source_request;
- aia_source.AsyncGetIssuersOf(cert.get(),
- base::Bind(&MockIssuerCallback::Callback,
- base::Unretained(&mock_callback)),
- &cert_source_request);
- ASSERT_NE(nullptr, cert_source_request);
-
- RequestManager* req_manager =
- mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null"));
- ASSERT_TRUE(req_manager);
- ASSERT_TRUE(req_manager->is_request_alive());
+ auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
- RequestManager* req_manager2 =
- mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
- ASSERT_TRUE(req_manager2);
- ASSERT_TRUE(req_manager2->is_request_alive());
+ EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
+ .WillOnce(Return(ByMove(CreateMockRequest(ERR_DISALLOWED_URL_SCHEME))));
- // Request for file URL completes with disallowed scheme failure. Callback is
- // NOT called.
- req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME,
- std::vector<uint8_t>());
- Mock::VerifyAndClearExpectations(&mock_callback);
-
- // Request for I2.foo completes. Callback should be called now.
- EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
- req_manager2->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
- Mock::VerifyAndClearExpectations(&mock_callback);
+ EXPECT_CALL(*mock_fetcher,
+ FetchCaIssuers(GURL("http://url-for-aia2/I2.foo"), _, _))
+ .WillOnce(Return(
+ ByMove(CreateMockRequest(CertDataVector(intermediate_cert.get())))));
- scoped_refptr<ParsedCertificate> result_cert;
- CompletionStatus status = cert_source_request->GetNext(&result_cert);
- EXPECT_EQ(CompletionStatus::SYNC, status);
- ASSERT_TRUE(result_cert.get());
- ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
+ CertIssuerSourceAia aia_source(mock_fetcher);
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request;
+ aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
+ ASSERT_NE(nullptr, cert_source_request);
- status = cert_source_request->GetNext(&result_cert);
- EXPECT_EQ(CompletionStatus::SYNC, status);
- EXPECT_FALSE(result_cert.get());
+ ParsedCertificateList result_certs;
+ cert_source_request->GetNext(&result_certs);
+ ASSERT_EQ(1u, result_certs.size());
+ ASSERT_EQ(result_certs.front()->der_cert(), intermediate_cert->der_cert());
- EXPECT_TRUE(req_manager2->is_request_alive());
- cert_source_request.reset();
- EXPECT_FALSE(req_manager2->is_request_alive());
+ cert_source_request->GetNext(&result_certs);
+ EXPECT_EQ(1u, result_certs.size());
}
+// TODO(eroman): Re-enable these tests!
+#if 0
// AuthorityInfoAccess with two URIs, one is invalid, the other HTTP.
TEST(CertIssuerSourceAiaTest, OneInvalidOneHttpAia) {
scoped_refptr<ParsedCertificate> cert;
@@ -344,8 +252,9 @@ TEST(CertIssuerSourceAiaTest, OneInvalidOneHttpAia) {
ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -389,8 +298,9 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeries) {
ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -465,8 +375,9 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedBeforeGetNext) {
ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -537,8 +448,9 @@ TEST(CertIssuerSourceAiaTest, AiaRequestCompletesDuringGetNextSequence) {
ASSERT_TRUE(ReadTestCert("i3.pem", &intermediate_cert3));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -613,8 +525,9 @@ TEST(CertIssuerSourceAiaTest, OneAiaHttpError) {
ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -647,8 +560,9 @@ TEST(CertIssuerSourceAiaTest, OneAiaParseError) {
ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -682,8 +596,9 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeriesFirstFails) {
ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -736,8 +651,9 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeriesSecondFails) {
ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -794,8 +710,9 @@ TEST(CertIssuerSourceAiaTest, CertSourceRequestCancelled) {
ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -830,8 +747,9 @@ TEST(CertIssuerSourceAiaTest, TwoAiaOneCompletedThenRequestCancelled) {
ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -881,8 +799,9 @@ TEST(CertIssuerSourceAiaTest, MaxFetchesPerCert) {
ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert));
StrictMock<MockIssuerCallback> mock_callback;
- StrictMock<MockCertNetFetcherImpl> mock_fetcher;
- CertIssuerSourceAia aia_source(&mock_fetcher);
+ scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+ new StrictMock<MockCertNetFetcherImpl>());
+ CertIssuerSourceAia aia_source(mock_fetcher);
std::unique_ptr<CertIssuerSource::Request> cert_source_request;
aia_source.AsyncGetIssuersOf(cert.get(),
base::Bind(&MockIssuerCallback::Callback,
@@ -920,6 +839,8 @@ TEST(CertIssuerSourceAiaTest, MaxFetchesPerCert) {
mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia6/I6.foo")));
}
+#endif
+
} // namespace
} // namespace net
diff --git a/chromium/net/cert/internal/cert_issuer_source_nss.cc b/chromium/net/cert/internal/cert_issuer_source_nss.cc
new file mode 100644
index 00000000000..418efe3ada6
--- /dev/null
+++ b/chromium/net/cert/internal/cert_issuer_source_nss.cc
@@ -0,0 +1,62 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/cert_issuer_source_nss.h"
+
+#include <cert.h>
+#include <certdb.h>
+
+#include "crypto/nss_util.h"
+#include "net/cert/internal/cert_errors.h"
+#include "net/cert/internal/parsed_certificate.h"
+
+namespace net {
+
+CertIssuerSourceNSS::CertIssuerSourceNSS() = default;
+CertIssuerSourceNSS::~CertIssuerSourceNSS() = default;
+
+void CertIssuerSourceNSS::SyncGetIssuersOf(const ParsedCertificate* cert,
+ ParsedCertificateList* issuers) {
+ crypto::EnsureNSSInit();
+
+ SECItem name;
+ // Use the original issuer value instead of the normalized version. NSS does a
+ // less extensive normalization in its Name comparisons, so our normalized
+ // version may not match the unnormalized version.
+ name.len = cert->tbs().issuer_tlv.Length();
+ name.data = const_cast<uint8_t*>(cert->tbs().issuer_tlv.UnsafeData());
+ // |validOnly| in CERT_CreateSubjectCertList controls whether to return only
+ // certs that are valid at |sorttime|. Including expired certs could lead to
+ // more useful error messages in the case where a valid path can't be found,
+ // so request all matches.
+ CERTCertList* found_certs = CERT_CreateSubjectCertList(
+ nullptr /* certList */, CERT_GetDefaultCertDB(), &name,
+ PR_Now() /* sorttime */, PR_FALSE /* validOnly */);
+ if (!found_certs)
+ return;
+
+ for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs);
+ !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) {
+ CertErrors errors;
+ scoped_refptr<ParsedCertificate> issuer_cert = ParsedCertificate::Create(
+ node->cert->derCert.data, node->cert->derCert.len, {}, &errors);
+ if (!issuer_cert) {
+ // TODO(crbug.com/634443): return errors better.
+ LOG(ERROR) << "Error parsing issuer certificate:\n"
+ << errors.ToDebugString();
+ continue;
+ }
+
+ issuers->push_back(std::move(issuer_cert));
+ }
+ CERT_DestroyCertList(found_certs);
+}
+
+void CertIssuerSourceNSS::AsyncGetIssuersOf(const ParsedCertificate* cert,
+ std::unique_ptr<Request>* out_req) {
+ // CertIssuerSourceNSS never returns asynchronous results.
+ out_req->reset();
+}
+
+} // namespace net
diff --git a/chromium/net/cert/internal/cert_issuer_source_nss.h b/chromium/net/cert/internal/cert_issuer_source_nss.h
new file mode 100644
index 00000000000..1621b3b0457
--- /dev/null
+++ b/chromium/net/cert/internal/cert_issuer_source_nss.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_NSS_H_
+#define NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_NSS_H_
+
+#include "net/base/net_export.h"
+#include "net/cert/internal/cert_issuer_source.h"
+
+namespace net {
+
+// Returns issuers from NSS. Always returns results synchronously.
+// This will return any matches from NSS, possibly including trust anchors,
+// blacklisted/distrusted certs, and temporary/cached certs. In the current
+// implementation, trust is checked in a separate stage of path building, so
+// including trusted certs here doesn't cause any issues. In particular, a trust
+// anchor being returned here indicates the path ending in that trust anchor
+// must already have been tested and failed to verify, and now the pathbuilder
+// is trying to find a different path through that certificate. Including
+// distrusted certs is desirable so that those paths can be built (and then fail
+// to verify), leading to a better error message.
+class NET_EXPORT CertIssuerSourceNSS : public CertIssuerSource {
+ public:
+ CertIssuerSourceNSS();
+ ~CertIssuerSourceNSS() override;
+
+ // CertIssuerSource implementation:
+ void SyncGetIssuersOf(const ParsedCertificate* cert,
+ ParsedCertificateList* issuers) override;
+ void AsyncGetIssuersOf(const ParsedCertificate* cert,
+ std::unique_ptr<Request>* out_req) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CertIssuerSourceNSS);
+};
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_NSS_H_
diff --git a/chromium/net/cert/internal/cert_issuer_source_nss_unittest.cc b/chromium/net/cert/internal/cert_issuer_source_nss_unittest.cc
new file mode 100644
index 00000000000..1653998aa24
--- /dev/null
+++ b/chromium/net/cert/internal/cert_issuer_source_nss_unittest.cc
@@ -0,0 +1,62 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/cert_issuer_source_nss.h"
+
+#include <cert.h>
+#include <certdb.h>
+
+#include "base/strings/string_number_conversions.h"
+#include "crypto/scoped_test_nss_db.h"
+#include "net/cert/internal/cert_issuer_source_sync_unittest.h"
+#include "net/cert/scoped_nss_types.h"
+#include "net/cert/x509_certificate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+class CertIssuerSourceNSSTestDelegate {
+ public:
+ void AddCert(scoped_refptr<ParsedCertificate> cert) {
+ ASSERT_TRUE(test_nssdb_.is_open());
+ std::string nickname = GetUniqueNickname();
+ ScopedCERTCertificate nss_cert(
+ X509Certificate::CreateOSCertHandleFromBytesWithNickname(
+ cert->der_cert().AsStringPiece().data(), cert->der_cert().Length(),
+ nickname.c_str()));
+ ASSERT_TRUE(nss_cert);
+ SECStatus srv =
+ PK11_ImportCert(test_nssdb_.slot(), nss_cert.get(), CK_INVALID_HANDLE,
+ nickname.c_str(), PR_FALSE /* includeTrust (unused) */);
+ ASSERT_EQ(SECSuccess, srv);
+ }
+
+ CertIssuerSource& source() { return cert_issuer_source_nss_; }
+
+ protected:
+ std::string GetUniqueNickname() {
+ return "cert_issuer_source_nss_unittest" +
+ base::UintToString(nickname_counter_++);
+ }
+
+ crypto::ScopedTestNSSDB test_nssdb_;
+ CertIssuerSourceNSS cert_issuer_source_nss_;
+ unsigned int nickname_counter_ = 0;
+};
+
+INSTANTIATE_TYPED_TEST_CASE_P(CertIssuerSourceNSSTest,
+ CertIssuerSourceSyncTest,
+ CertIssuerSourceNSSTestDelegate);
+
+// NSS doesn't normalize UTF8String values, so use the not-normalized version of
+// those tests.
+INSTANTIATE_TYPED_TEST_CASE_P(CertIssuerSourceNSSNotNormalizedTest,
+ CertIssuerSourceSyncNotNormalizedTest,
+ CertIssuerSourceNSSTestDelegate);
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/cert/internal/cert_issuer_source_static.cc b/chromium/net/cert/internal/cert_issuer_source_static.cc
index d8a42a3f30e..e6ddb27b39f 100644
--- a/chromium/net/cert/internal/cert_issuer_source_static.cc
+++ b/chromium/net/cert/internal/cert_issuer_source_static.cc
@@ -24,7 +24,6 @@ void CertIssuerSourceStatic::SyncGetIssuersOf(const ParsedCertificate* cert,
void CertIssuerSourceStatic::AsyncGetIssuersOf(
const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
std::unique_ptr<Request>* out_req) {
// CertIssuerSourceStatic never returns asynchronous results.
out_req->reset();
diff --git a/chromium/net/cert/internal/cert_issuer_source_static.h b/chromium/net/cert/internal/cert_issuer_source_static.h
index 143e97d660b..4f9240b6e94 100644
--- a/chromium/net/cert/internal/cert_issuer_source_static.h
+++ b/chromium/net/cert/internal/cert_issuer_source_static.h
@@ -27,7 +27,6 @@ class NET_EXPORT CertIssuerSourceStatic : public CertIssuerSource {
void SyncGetIssuersOf(const ParsedCertificate* cert,
ParsedCertificateList* issuers) override;
void AsyncGetIssuersOf(const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
std::unique_ptr<Request>* out_req) override;
private:
diff --git a/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc b/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc
index 949035c0eb1..627757f6c6d 100644
--- a/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc
+++ b/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc
@@ -4,142 +4,33 @@
#include "net/cert/internal/cert_issuer_source_static.h"
-#include "base/bind.h"
-#include "net/cert/internal/cert_errors.h"
+#include "net/cert/internal/cert_issuer_source_sync_unittest.h"
#include "net/cert/internal/parsed_certificate.h"
-#include "net/cert/internal/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
-void NotCalled(CertIssuerSource::Request* req) {
- ADD_FAILURE() << "NotCalled was called";
-}
-
-::testing::AssertionResult ReadTestPem(const std::string& file_name,
- const std::string& block_name,
- std::string* result) {
- const PemBlockMapping mappings[] = {
- {block_name.c_str(), result},
- };
-
- return ReadTestDataFromPemFile(file_name, mappings);
-}
-
-::testing::AssertionResult ReadTestCert(
- const std::string& file_name,
- scoped_refptr<ParsedCertificate>* result) {
- std::string der;
- ::testing::AssertionResult r =
- ReadTestPem("net/data/cert_issuer_source_static_unittest/" + file_name,
- "CERTIFICATE", &der);
- if (!r)
- return r;
- CertErrors errors;
- *result = ParsedCertificate::Create(der, {}, &errors);
- if (!*result) {
- return ::testing::AssertionFailure()
- << "ParsedCertificate::Create() failed:\n"
- << errors.ToDebugString();
- }
- return ::testing::AssertionSuccess();
-}
-
-class CertIssuerSourceStaticTest : public ::testing::Test {
+class CertIssuerSourceStaticTestDelegate {
public:
- void SetUp() override {
- ASSERT_TRUE(ReadTestCert("root.pem", &root_));
- ASSERT_TRUE(ReadTestCert("i1_1.pem", &i1_1_));
- ASSERT_TRUE(ReadTestCert("i1_2.pem", &i1_2_));
- ASSERT_TRUE(ReadTestCert("i2.pem", &i2_));
- ASSERT_TRUE(ReadTestCert("c1.pem", &c1_));
- ASSERT_TRUE(ReadTestCert("c2.pem", &c2_));
- ASSERT_TRUE(ReadTestCert("d.pem", &d_));
+ void AddCert(scoped_refptr<ParsedCertificate> cert) {
+ source_.AddCert(std::move(cert));
}
- void AddAllCerts(CertIssuerSourceStatic* source) {
- source->AddCert(root_);
- source->AddCert(i1_1_);
- source->AddCert(i1_2_);
- source->AddCert(i2_);
- source->AddCert(c1_);
- source->AddCert(c2_);
- source->AddCert(d_);
- }
+ CertIssuerSource& source() { return source_; }
protected:
- scoped_refptr<ParsedCertificate> root_;
- scoped_refptr<ParsedCertificate> i1_1_;
- scoped_refptr<ParsedCertificate> i1_2_;
- scoped_refptr<ParsedCertificate> i2_;
- scoped_refptr<ParsedCertificate> c1_;
- scoped_refptr<ParsedCertificate> c2_;
- scoped_refptr<ParsedCertificate> d_;
+ CertIssuerSourceStatic source_;
};
-TEST_F(CertIssuerSourceStaticTest, NoMatch) {
- CertIssuerSourceStatic source;
- source.AddCert(root_);
-
- ParsedCertificateList issuers;
- source.SyncGetIssuersOf(c1_.get(), &issuers);
- ASSERT_EQ(0U, issuers.size());
-}
-
-TEST_F(CertIssuerSourceStaticTest, OneMatch) {
- CertIssuerSourceStatic source;
- AddAllCerts(&source);
-
- ParsedCertificateList issuers;
- source.SyncGetIssuersOf(i1_1_.get(), &issuers);
- ASSERT_EQ(1U, issuers.size());
- EXPECT_TRUE(issuers[0] == root_);
-
- issuers.clear();
- source.SyncGetIssuersOf(d_.get(), &issuers);
- ASSERT_EQ(1U, issuers.size());
- EXPECT_TRUE(issuers[0] == i2_);
-}
-
-TEST_F(CertIssuerSourceStaticTest, MultipleMatches) {
- CertIssuerSourceStatic source;
- AddAllCerts(&source);
-
- ParsedCertificateList issuers;
- source.SyncGetIssuersOf(c1_.get(), &issuers);
-
- ASSERT_EQ(2U, issuers.size());
- EXPECT_TRUE(std::find(issuers.begin(), issuers.end(), i1_1_) !=
- issuers.end());
- EXPECT_TRUE(std::find(issuers.begin(), issuers.end(), i1_2_) !=
- issuers.end());
-}
-
-// Searching for the issuer of a self-issued cert returns the same cert if it
-// happens to be in the CertIssuerSourceStatic.
-// Conceptually this makes sense, though probably not very useful in practice.
-// Doesn't hurt anything though.
-TEST_F(CertIssuerSourceStaticTest, SelfIssued) {
- CertIssuerSourceStatic source;
- AddAllCerts(&source);
-
- ParsedCertificateList issuers;
- source.SyncGetIssuersOf(root_.get(), &issuers);
-
- ASSERT_EQ(1U, issuers.size());
- EXPECT_TRUE(issuers[0] == root_);
-}
+INSTANTIATE_TYPED_TEST_CASE_P(CertIssuerSourceStaticTest,
+ CertIssuerSourceSyncTest,
+ CertIssuerSourceStaticTestDelegate);
-// CertIssuerSourceStatic never returns results asynchronously.
-TEST_F(CertIssuerSourceStaticTest, IsNotAsync) {
- CertIssuerSourceStatic source;
- source.AddCert(i1_1_);
- std::unique_ptr<CertIssuerSource::Request> request;
- source.AsyncGetIssuersOf(c1_.get(), base::Bind(&NotCalled), &request);
- EXPECT_EQ(nullptr, request);
-}
+INSTANTIATE_TYPED_TEST_CASE_P(CertIssuerSourceStaticNormalizationTest,
+ CertIssuerSourceSyncNormalizationTest,
+ CertIssuerSourceStaticTestDelegate);
} // namespace
diff --git a/chromium/net/cert/internal/cert_issuer_source_sync_unittest.h b/chromium/net/cert/internal/cert_issuer_source_sync_unittest.h
new file mode 100644
index 00000000000..6b36b2fe28f
--- /dev/null
+++ b/chromium/net/cert/internal/cert_issuer_source_sync_unittest.h
@@ -0,0 +1,210 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
+#define NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
+
+#include "net/cert/internal/cert_errors.h"
+#include "net/cert/internal/cert_issuer_source.h"
+#include "net/cert/internal/test_helpers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+::testing::AssertionResult ReadTestPem(const std::string& file_name,
+ const std::string& block_name,
+ std::string* result) {
+ const PemBlockMapping mappings[] = {
+ {block_name.c_str(), result},
+ };
+
+ return ReadTestDataFromPemFile(file_name, mappings);
+}
+
+::testing::AssertionResult ReadTestCert(
+ const std::string& file_name,
+ scoped_refptr<ParsedCertificate>* result) {
+ std::string der;
+ ::testing::AssertionResult r =
+ ReadTestPem("net/data/cert_issuer_source_static_unittest/" + file_name,
+ "CERTIFICATE", &der);
+ if (!r)
+ return r;
+ CertErrors errors;
+ *result = ParsedCertificate::Create(der, {}, &errors);
+ if (!*result) {
+ return ::testing::AssertionFailure()
+ << "ParsedCertificate::Create() failed:\n"
+ << errors.ToDebugString();
+ }
+ return ::testing::AssertionSuccess();
+}
+
+} // namespace
+
+template <typename TestDelegate>
+class CertIssuerSourceSyncTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ ASSERT_TRUE(ReadTestCert("root.pem", &root_));
+ ASSERT_TRUE(ReadTestCert("i1_1.pem", &i1_1_));
+ ASSERT_TRUE(ReadTestCert("i1_2.pem", &i1_2_));
+ ASSERT_TRUE(ReadTestCert("i2.pem", &i2_));
+ ASSERT_TRUE(ReadTestCert("i3_1.pem", &i3_1_));
+ ASSERT_TRUE(ReadTestCert("i3_2.pem", &i3_2_));
+ ASSERT_TRUE(ReadTestCert("c1.pem", &c1_));
+ ASSERT_TRUE(ReadTestCert("c2.pem", &c2_));
+ ASSERT_TRUE(ReadTestCert("d.pem", &d_));
+ ASSERT_TRUE(ReadTestCert("e1.pem", &e1_));
+ ASSERT_TRUE(ReadTestCert("e2.pem", &e2_));
+ }
+
+ void AddCert(scoped_refptr<ParsedCertificate> cert) {
+ delegate_.AddCert(std::move(cert));
+ }
+
+ void AddAllCerts() {
+ AddCert(root_);
+ AddCert(i1_1_);
+ AddCert(i1_2_);
+ AddCert(i2_);
+ AddCert(i3_1_);
+ AddCert(i3_2_);
+ AddCert(c1_);
+ AddCert(c2_);
+ AddCert(d_);
+ AddCert(e1_);
+ AddCert(e2_);
+ }
+
+ CertIssuerSource& source() { return delegate_.source(); }
+
+ protected:
+ bool IssuersMatch(scoped_refptr<ParsedCertificate> cert,
+ ParsedCertificateList expected_matches) {
+ ParsedCertificateList matches;
+ source().SyncGetIssuersOf(cert.get(), &matches);
+
+ std::vector<der::Input> der_result_matches;
+ for (const auto& it : matches)
+ der_result_matches.push_back(it->der_cert());
+ std::sort(der_result_matches.begin(), der_result_matches.end());
+
+ std::vector<der::Input> der_expected_matches;
+ for (const auto& it : expected_matches)
+ der_expected_matches.push_back(it->der_cert());
+ std::sort(der_expected_matches.begin(), der_expected_matches.end());
+
+ if (der_expected_matches == der_result_matches)
+ return true;
+
+ // Print some extra information for debugging.
+ EXPECT_EQ(der_expected_matches, der_result_matches);
+ return false;
+ }
+
+ TestDelegate delegate_;
+ scoped_refptr<ParsedCertificate> root_;
+ scoped_refptr<ParsedCertificate> i1_1_;
+ scoped_refptr<ParsedCertificate> i1_2_;
+ scoped_refptr<ParsedCertificate> i2_;
+ scoped_refptr<ParsedCertificate> i3_1_;
+ scoped_refptr<ParsedCertificate> i3_2_;
+ scoped_refptr<ParsedCertificate> c1_;
+ scoped_refptr<ParsedCertificate> c2_;
+ scoped_refptr<ParsedCertificate> d_;
+ scoped_refptr<ParsedCertificate> e1_;
+ scoped_refptr<ParsedCertificate> e2_;
+};
+
+TYPED_TEST_CASE_P(CertIssuerSourceSyncTest);
+
+TYPED_TEST_P(CertIssuerSourceSyncTest, NoMatch) {
+ this->AddCert(this->root_);
+
+ EXPECT_TRUE(this->IssuersMatch(this->c1_, ParsedCertificateList()));
+}
+
+TYPED_TEST_P(CertIssuerSourceSyncTest, OneMatch) {
+ this->AddAllCerts();
+
+ EXPECT_TRUE(this->IssuersMatch(this->i1_1_, {this->root_}));
+ EXPECT_TRUE(this->IssuersMatch(this->d_, {this->i2_}));
+}
+
+TYPED_TEST_P(CertIssuerSourceSyncTest, MultipleMatches) {
+ this->AddAllCerts();
+
+ EXPECT_TRUE(this->IssuersMatch(this->e1_, {this->i3_1_, this->i3_2_}));
+ EXPECT_TRUE(this->IssuersMatch(this->e2_, {this->i3_1_, this->i3_2_}));
+}
+
+// Searching for the issuer of a self-issued cert returns the same cert if it
+// happens to be in the CertIssuerSourceStatic.
+// Conceptually this makes sense, though probably not very useful in practice.
+// Doesn't hurt anything though.
+TYPED_TEST_P(CertIssuerSourceSyncTest, SelfIssued) {
+ this->AddAllCerts();
+
+ EXPECT_TRUE(this->IssuersMatch(this->root_, {this->root_}));
+}
+
+// CertIssuerSourceStatic never returns results asynchronously.
+TYPED_TEST_P(CertIssuerSourceSyncTest, IsNotAsync) {
+ this->AddCert(this->i1_1_);
+ std::unique_ptr<CertIssuerSource::Request> request;
+ this->source().AsyncGetIssuersOf(this->c1_.get(), &request);
+ EXPECT_EQ(nullptr, request);
+}
+
+// These are all the tests that should have the same result with or without
+// normalization.
+REGISTER_TYPED_TEST_CASE_P(CertIssuerSourceSyncTest,
+ NoMatch,
+ OneMatch,
+ MultipleMatches,
+ SelfIssued,
+ IsNotAsync);
+
+template <typename TestDelegate>
+class CertIssuerSourceSyncNormalizationTest
+ : public CertIssuerSourceSyncTest<TestDelegate> {};
+TYPED_TEST_CASE_P(CertIssuerSourceSyncNormalizationTest);
+
+TYPED_TEST_P(CertIssuerSourceSyncNormalizationTest,
+ MultipleMatchesAfterNormalization) {
+ this->AddAllCerts();
+
+ EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_, this->i1_2_}));
+ EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_1_, this->i1_2_}));
+}
+
+// These tests require (utf8) normalization.
+REGISTER_TYPED_TEST_CASE_P(CertIssuerSourceSyncNormalizationTest,
+ MultipleMatchesAfterNormalization);
+
+template <typename TestDelegate>
+class CertIssuerSourceSyncNotNormalizedTest
+ : public CertIssuerSourceSyncTest<TestDelegate> {};
+TYPED_TEST_CASE_P(CertIssuerSourceSyncNotNormalizedTest);
+
+TYPED_TEST_P(CertIssuerSourceSyncNotNormalizedTest,
+ OneMatchWithoutNormalization) {
+ this->AddAllCerts();
+
+ // Without normalization c1 and c2 should at least be able to find their
+ // exact matching issuer. (c1 should match i1_1, and c2 should match i1_2.)
+ EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_}));
+ EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_2_}));
+}
+
+// These tests are for implementations which do not do utf8 normalization.
+REGISTER_TYPED_TEST_CASE_P(CertIssuerSourceSyncNotNormalizedTest,
+ OneMatchWithoutNormalization);
+
+} // namespace net
+
+#endif // NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
diff --git a/chromium/net/cert/internal/completion_status.h b/chromium/net/cert/internal/completion_status.h
deleted file mode 100644
index 69126cd6010..00000000000
--- a/chromium/net/cert/internal/completion_status.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_INTERNAL_COMPLETION_STATUS_H_
-#define NET_CERT_INTERNAL_COMPLETION_STATUS_H_
-
-namespace net {
-
-enum class CompletionStatus {
- SYNC,
- ASYNC,
-};
-
-} // namespace net
-
-#endif // NET_CERT_INTERNAL_COMPLETION_STATUS_H_
diff --git a/chromium/net/cert/internal/name_constraints.cc b/chromium/net/cert/internal/name_constraints.cc
index 162569f964c..0ed685101e9 100644
--- a/chromium/net/cert/internal/name_constraints.cc
+++ b/chromium/net/cert/internal/name_constraints.cc
@@ -87,6 +87,11 @@ bool DNSNameMatches(base::StringPiece name,
// Exact match.
if (name.size() == dns_constraint.size())
return true;
+ // If dNSName constraint starts with a dot, only subdomains should match.
+ // (e.g., "foo.bar.com" matches constraint ".bar.com", but "bar.com" doesn't.)
+ // RFC 5280 is ambiguous, but this matches the behavior of other platforms.
+ if (!dns_constraint.empty() && dns_constraint[0] == '.')
+ dns_constraint.remove_prefix(1);
// Subtree match.
if (name.size() > dns_constraint.size() &&
name[name.size() - dns_constraint.size() - 1] == '.') {
diff --git a/chromium/net/cert/internal/name_constraints_unittest.cc b/chromium/net/cert/internal/name_constraints_unittest.cc
index f1dd470d093..150d851c491 100644
--- a/chromium/net/cert/internal/name_constraints_unittest.cc
+++ b/chromium/net/cert/internal/name_constraints_unittest.cc
@@ -186,7 +186,7 @@ TEST_P(ParseNameConstraints,
EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.foo.bar.com"));
}
-TEST_P(ParseNameConstraints, DNSNamesWithLeadingDot) {
+TEST_P(ParseNameConstraints, DNSNamesPermittedWithLeadingDot) {
std::string a;
ASSERT_TRUE(
LoadTestNameConstraint("dnsname-permitted_with_leading_dot.pem", &a));
@@ -194,13 +194,44 @@ TEST_P(ParseNameConstraints, DNSNamesWithLeadingDot) {
NameConstraints::Create(der::Input(&a), is_critical()));
ASSERT_TRUE(name_constraints);
- // dNSName constraints should be specified as a host. A dNSName constraint
- // with a leading "." doesn't make sense, though some certs include it
- // (probably confusing it with the rules for uniformResourceIdentifier
- // constraints). It should not match anything.
+ // A permitted dNSName constraint of ".bar.com" should only match subdomains
+ // of .bar.com, but not bar.com itself.
EXPECT_FALSE(name_constraints->IsPermittedDNSName("com"));
EXPECT_FALSE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foobar.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("*.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesExcludedWithLeadingDot) {
+ std::string a;
+ ASSERT_TRUE(
+ LoadTestNameConstraint("dnsname-excluded_with_leading_dot.pem", &a));
+ std::unique_ptr<NameConstraints> name_constraints(
+ NameConstraints::Create(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // An excluded dNSName constraint of ".bar.com" should only match subdomains
+ // of .bar.com, but not bar.com itself.
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("bar.com"));
+ EXPECT_TRUE(name_constraints->IsPermittedDNSName("foobar.com"));
EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.bar.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.bar.com"));
+}
+
+TEST_P(ParseNameConstraints, DNSNamesPermittedTwoDot) {
+ std::string a;
+ ASSERT_TRUE(LoadTestNameConstraint("dnsname-permitted_two_dot.pem", &a));
+ std::unique_ptr<NameConstraints> name_constraints(
+ NameConstraints::Create(der::Input(&a), is_critical()));
+ ASSERT_TRUE(name_constraints);
+
+ // A dNSName constraint of ".." isn't meaningful. Shouldn't match anything.
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("com."));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("foo.com"));
+ EXPECT_FALSE(name_constraints->IsPermittedDNSName("*.com"));
}
TEST_P(ParseNameConstraints, DNSNamesExcludeOnly) {
diff --git a/chromium/net/cert/internal/nist_pkits_unittest.h b/chromium/net/cert/internal/nist_pkits_unittest.h
index 47fd46274d6..6a454020ffb 100644
--- a/chromium/net/cert/internal/nist_pkits_unittest.h
+++ b/chromium/net/cert/internal/nist_pkits_unittest.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H
-#define NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H
+#ifndef NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_
+#define NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_
#include "net/cert/internal/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,4 +33,4 @@ class PkitsTest : public ::testing::Test {
// Inline the generated test code:
#include "net/third_party/nist-pkits/pkits_testcases-inl.h"
-#endif // NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H
+#endif // NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_
diff --git a/chromium/net/cert/internal/parse_certificate_unittest.cc b/chromium/net/cert/internal/parse_certificate_unittest.cc
index 08c37944cea..a54d895acba 100644
--- a/chromium/net/cert/internal/parse_certificate_unittest.cc
+++ b/chromium/net/cert/internal/parse_certificate_unittest.cc
@@ -6,10 +6,6 @@
#include "base/strings/stringprintf.h"
#include "net/cert/internal/cert_errors.h"
-// TODO(eroman): These tests should be moved into
-// parsed_certificate_unittest.cc; this include dependency should
-// go.
-#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/internal/test_helpers.h"
#include "net/der/input.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -79,37 +75,6 @@ void RunCertificateTest(const std::string& file_name) {
}
}
-// Reads and parses a certificate from the PEM file |file_name|.
-//
-// Returns nullptr if the certificate parsing failed, and verifies that any
-// errors match the ERRORS block in the .pem file.
-scoped_refptr<ParsedCertificate> ParseCertificateFromFile(
- const std::string& file_name) {
- std::string data;
- std::string expected_errors;
-
- // Read the certificate data and error expectations from a single PEM file.
- const PemBlockMapping mappings[] = {
- {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/},
- };
- std::string test_file_path = GetFilePath(file_name);
- EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));
-
- CertErrors errors;
- scoped_refptr<ParsedCertificate> cert =
- ParsedCertificate::Create(data, {}, &errors);
-
- EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: "
- << test_file_path;
-
- // TODO(crbug.com/634443): Every parse failure being tested should emit error
- // information.
- // if (!cert)
- // EXPECT_FALSE(errors.empty());
-
- return cert;
-}
-
// Tests parsing a Certificate.
TEST(ParseCertificateTest, Version3) {
RunCertificateTest("cert_version3.pem");
@@ -362,255 +327,6 @@ TEST(ParseTbsCertificateTest, ValidityRelaxed) {
RunTbsCertificateTest("tbs_validity_relaxed.pem");
}
-der::Input DavidBenOid() {
- // This OID corresponds with
- // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
- static const uint8_t kOid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
- 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
- return der::Input(kOid);
-}
-
-// Parses an Extension whose critical field is true (255).
-TEST(ParseCertificateTest, ExtensionCritical) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("extension_critical.pem");
- ASSERT_TRUE(cert);
-
- const uint8_t kExpectedValue[] = {0x30, 0x00};
-
- auto it = cert->unparsed_extensions().find(DavidBenOid());
- ASSERT_NE(cert->unparsed_extensions().end(), it);
- const auto& extension = it->second;
-
- EXPECT_TRUE(extension.critical);
- EXPECT_EQ(DavidBenOid(), extension.oid);
- EXPECT_EQ(der::Input(kExpectedValue), extension.value);
-}
-
-// Parses an Extension whose critical field is false (omitted).
-TEST(ParseCertificateTest, ExtensionNotCritical) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("extension_not_critical.pem");
- ASSERT_TRUE(cert);
-
- const uint8_t kExpectedValue[] = {0x30, 0x00};
-
- auto it = cert->unparsed_extensions().find(DavidBenOid());
- ASSERT_NE(cert->unparsed_extensions().end(), it);
- const auto& extension = it->second;
-
- EXPECT_FALSE(extension.critical);
- EXPECT_EQ(DavidBenOid(), extension.oid);
- EXPECT_EQ(der::Input(kExpectedValue), extension.value);
-}
-
-// Parses an Extension whose critical field is 0. This is in one sense FALSE,
-// however because critical has DEFAULT of false this is in fact invalid
-// DER-encoding.
-TEST(ParseCertificateTest, ExtensionCritical0) {
- ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem"));
-}
-
-// Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN
-// values must an octet of either all zero bits, or all 1 bits, so this is not
-// valid.
-TEST(ParseCertificateTest, ExtensionCritical3) {
- ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem"));
-}
-
-// Parses an Extensions that is an empty sequence.
-TEST(ParseCertificateTest, ExtensionsEmptySequence) {
- ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem"));
-}
-
-// Parses an Extensions that is not a sequence.
-TEST(ParseCertificateTest, ExtensionsNotSequence) {
- ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem"));
-}
-
-// Parses an Extensions that has data after the sequence.
-TEST(ParseCertificateTest, ExtensionsDataAfterSequence) {
- ASSERT_FALSE(ParseCertificateFromFile("extensions_data_after_sequence.pem"));
-}
-
-// Parses an Extensions that contains duplicated key usages.
-TEST(ParseCertificateTest, ExtensionsDuplicateKeyUsage) {
- ASSERT_FALSE(ParseCertificateFromFile("extensions_duplicate_key_usage.pem"));
-}
-
-// Parses an Extensions that contains an extended key usages.
-TEST(ParseCertificateTest, ExtendedKeyUsage) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("extended_key_usage.pem");
- ASSERT_TRUE(cert);
-
- const auto& extensions = cert->unparsed_extensions();
- ASSERT_EQ(3u, extensions.size());
-
- auto iter = extensions.find(ExtKeyUsageOid());
- ASSERT_TRUE(iter != extensions.end());
- EXPECT_FALSE(iter->second.critical);
- EXPECT_EQ(45u, iter->second.value.Length());
-}
-
-// Parses an Extensions that contains a key usage.
-TEST(ParseCertificateTest, KeyUsage) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("key_usage.pem");
- ASSERT_TRUE(cert);
-
- ASSERT_TRUE(cert->has_key_usage());
-
- EXPECT_EQ(5u, cert->key_usage().unused_bits());
- const uint8_t kExpectedBytes[] = {0xA0};
- EXPECT_EQ(der::Input(kExpectedBytes), cert->key_usage().bytes());
-
- EXPECT_TRUE(cert->key_usage().AssertsBit(0));
- EXPECT_FALSE(cert->key_usage().AssertsBit(1));
- EXPECT_TRUE(cert->key_usage().AssertsBit(2));
-}
-
-// Parses an Extensions that contains a policies extension.
-TEST(ParseCertificateTest, Policies) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("policies.pem");
- ASSERT_TRUE(cert);
-
- const auto& extensions = cert->unparsed_extensions();
- ASSERT_EQ(3u, extensions.size());
-
- auto iter = extensions.find(CertificatePoliciesOid());
- ASSERT_TRUE(iter != extensions.end());
- EXPECT_FALSE(iter->second.critical);
- EXPECT_EQ(95u, iter->second.value.Length());
-}
-
-// Parses an Extensions that contains a subjectaltname extension.
-TEST(ParseCertificateTest, SubjectAltName) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("subject_alt_name.pem");
- ASSERT_TRUE(cert);
-
- ASSERT_TRUE(cert->has_subject_alt_names());
-}
-
-// Parses an Extensions that contains multiple extensions, sourced from a
-// real-world certificate.
-TEST(ParseCertificateTest, ExtensionsReal) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("extensions_real.pem");
- ASSERT_TRUE(cert);
-
- const auto& extensions = cert->unparsed_extensions();
- ASSERT_EQ(4u, extensions.size());
-
- EXPECT_TRUE(cert->has_key_usage());
- EXPECT_TRUE(cert->has_basic_constraints());
-
- auto iter = extensions.find(CertificatePoliciesOid());
- ASSERT_TRUE(iter != extensions.end());
- EXPECT_FALSE(iter->second.critical);
- EXPECT_EQ(16u, iter->second.value.Length());
-
- // TODO(eroman): Verify the other 4 extensions' values.
-}
-
-// Parses a BasicConstraints with no CA or pathlen.
-TEST(ParseCertificateTest, BasicConstraintsNotCa) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_not_ca.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_FALSE(cert->basic_constraints().is_ca);
- EXPECT_FALSE(cert->basic_constraints().has_path_len);
-}
-
-// Parses a BasicConstraints with CA but no pathlen.
-TEST(ParseCertificateTest, BasicConstraintsCaNoPath) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_ca_no_path.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_TRUE(cert->basic_constraints().is_ca);
- EXPECT_FALSE(cert->basic_constraints().has_path_len);
-}
-
-// Parses a BasicConstraints with CA and pathlen of 9.
-TEST(ParseCertificateTest, BasicConstraintsCaPath9) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_ca_path_9.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_TRUE(cert->basic_constraints().is_ca);
- EXPECT_TRUE(cert->basic_constraints().has_path_len);
- EXPECT_EQ(9u, cert->basic_constraints().path_len);
-}
-
-// Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size).
-TEST(ParseCertificateTest, BasicConstraintsPathlen255) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_pathlen_255.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_TRUE(cert->basic_constraints().is_ca);
- EXPECT_TRUE(cert->basic_constraints().has_path_len);
- EXPECT_EQ(255, cert->basic_constraints().path_len);
-}
-
-// Parses a BasicConstraints with CA and pathlen of 256 (too large).
-TEST(ParseCertificateTest, BasicConstraintsPathlen256) {
- ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_pathlen_256.pem"));
-}
-
-// Parses a BasicConstraints with CA and a negative pathlen.
-TEST(ParseCertificateTest, BasicConstraintsNegativePath) {
- ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_negative_path.pem"));
-}
-
-// Parses a BasicConstraints with CA and pathlen that is very large (and
-// couldn't fit in a 64-bit integer).
-TEST(ParseCertificateTest, BasicConstraintsPathTooLarge) {
- ASSERT_FALSE(
- ParseCertificateFromFile("basic_constraints_path_too_large.pem"));
-}
-
-// Parses a BasicConstraints with CA explicitly set to false. This violates
-// DER-encoding rules, however is commonly used, so it is accepted.
-TEST(ParseCertificateTest, BasicConstraintsCaFalse) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_ca_false.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_FALSE(cert->basic_constraints().is_ca);
- EXPECT_FALSE(cert->basic_constraints().has_path_len);
-}
-
-// Parses a BasicConstraints with CA set to true and an unexpected NULL at
-// the end.
-TEST(ParseCertificateTest, BasicConstraintsUnconsumedData) {
- ASSERT_FALSE(
- ParseCertificateFromFile("basic_constraints_unconsumed_data.pem"));
-}
-
-// Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1.
-// This is valid DER for the ASN.1, however is not valid when interpreting the
-// BasicConstraints at a higher level.
-TEST(ParseCertificateTest, BasicConstraintsPathLenButNotCa) {
- scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem");
- ASSERT_TRUE(cert);
-
- EXPECT_TRUE(cert->has_basic_constraints());
- EXPECT_FALSE(cert->basic_constraints().is_ca);
- EXPECT_TRUE(cert->basic_constraints().has_path_len);
- EXPECT_EQ(1u, cert->basic_constraints().path_len);
-}
-
// Parses a KeyUsage with a single 0 bit.
TEST(ParseKeyUsageTest, OneBitAllZeros) {
const uint8_t der[] = {
diff --git a/chromium/net/cert/internal/parse_ocsp.cc b/chromium/net/cert/internal/parse_ocsp.cc
index 2f734102270..0e13fc3d09a 100644
--- a/chromium/net/cert/internal/parse_ocsp.cc
+++ b/chromium/net/cert/internal/parse_ocsp.cc
@@ -5,6 +5,7 @@
#include <algorithm>
#include "base/sha1.h"
+#include "base/time/time.h"
#include "crypto/sha2.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parse_ocsp.h"
diff --git a/chromium/net/cert/internal/parsed_certificate_unittest.cc b/chromium/net/cert/internal/parsed_certificate_unittest.cc
new file mode 100644
index 00000000000..ab1d4a0f91c
--- /dev/null
+++ b/chromium/net/cert/internal/parsed_certificate_unittest.cc
@@ -0,0 +1,303 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/parsed_certificate.h"
+
+#include "net/cert/internal/cert_errors.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/test_helpers.h"
+#include "net/der/input.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+std::string GetFilePath(const std::string& file_name) {
+ return std::string("net/data/parse_certificate_unittest/") + file_name;
+}
+
+// Reads and parses a certificate from the PEM file |file_name|.
+//
+// Returns nullptr if the certificate parsing failed, and verifies that any
+// errors match the ERRORS block in the .pem file.
+scoped_refptr<ParsedCertificate> ParseCertificateFromFile(
+ const std::string& file_name) {
+ std::string data;
+ std::string expected_errors;
+
+ // Read the certificate data and error expectations from a single PEM file.
+ const PemBlockMapping mappings[] = {
+ {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/},
+ };
+ std::string test_file_path = GetFilePath(file_name);
+ EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));
+
+ CertErrors errors;
+ scoped_refptr<ParsedCertificate> cert =
+ ParsedCertificate::Create(data, {}, &errors);
+
+ EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: "
+ << test_file_path;
+
+ // TODO(crbug.com/634443): Every parse failure being tested should emit error
+ // information.
+ // if (!cert)
+ // EXPECT_FALSE(errors.empty());
+
+ return cert;
+}
+
+der::Input DavidBenOid() {
+ // This OID corresponds with
+ // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
+ static const uint8_t kOid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
+ 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
+ return der::Input(kOid);
+}
+
+// Parses an Extension whose critical field is true (255).
+TEST(ParsedCertificateTest, ExtensionCritical) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("extension_critical.pem");
+ ASSERT_TRUE(cert);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+
+ auto it = cert->unparsed_extensions().find(DavidBenOid());
+ ASSERT_NE(cert->unparsed_extensions().end(), it);
+ const auto& extension = it->second;
+
+ EXPECT_TRUE(extension.critical);
+ EXPECT_EQ(DavidBenOid(), extension.oid);
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is false (omitted).
+TEST(ParsedCertificateTest, ExtensionNotCritical) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("extension_not_critical.pem");
+ ASSERT_TRUE(cert);
+
+ const uint8_t kExpectedValue[] = {0x30, 0x00};
+
+ auto it = cert->unparsed_extensions().find(DavidBenOid());
+ ASSERT_NE(cert->unparsed_extensions().end(), it);
+ const auto& extension = it->second;
+
+ EXPECT_FALSE(extension.critical);
+ EXPECT_EQ(DavidBenOid(), extension.oid);
+ EXPECT_EQ(der::Input(kExpectedValue), extension.value);
+}
+
+// Parses an Extension whose critical field is 0. This is in one sense FALSE,
+// however because critical has DEFAULT of false this is in fact invalid
+// DER-encoding.
+TEST(ParsedCertificateTest, ExtensionCritical0) {
+ ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem"));
+}
+
+// Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN
+// values must an octet of either all zero bits, or all 1 bits, so this is not
+// valid.
+TEST(ParsedCertificateTest, ExtensionCritical3) {
+ ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem"));
+}
+
+// Parses an Extensions that is an empty sequence.
+TEST(ParsedCertificateTest, ExtensionsEmptySequence) {
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem"));
+}
+
+// Parses an Extensions that is not a sequence.
+TEST(ParsedCertificateTest, ExtensionsNotSequence) {
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem"));
+}
+
+// Parses an Extensions that has data after the sequence.
+TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) {
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_data_after_sequence.pem"));
+}
+
+// Parses an Extensions that contains duplicated key usages.
+TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) {
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_duplicate_key_usage.pem"));
+}
+
+// Parses an Extensions that contains an extended key usages.
+TEST(ParsedCertificateTest, ExtendedKeyUsage) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("extended_key_usage.pem");
+ ASSERT_TRUE(cert);
+
+ const auto& extensions = cert->unparsed_extensions();
+ ASSERT_EQ(3u, extensions.size());
+
+ auto iter = extensions.find(ExtKeyUsageOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(45u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a key usage.
+TEST(ParsedCertificateTest, KeyUsage) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("key_usage.pem");
+ ASSERT_TRUE(cert);
+
+ ASSERT_TRUE(cert->has_key_usage());
+
+ EXPECT_EQ(5u, cert->key_usage().unused_bits());
+ const uint8_t kExpectedBytes[] = {0xA0};
+ EXPECT_EQ(der::Input(kExpectedBytes), cert->key_usage().bytes());
+
+ EXPECT_TRUE(cert->key_usage().AssertsBit(0));
+ EXPECT_FALSE(cert->key_usage().AssertsBit(1));
+ EXPECT_TRUE(cert->key_usage().AssertsBit(2));
+}
+
+// Parses an Extensions that contains a policies extension.
+TEST(ParsedCertificateTest, Policies) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("policies.pem");
+ ASSERT_TRUE(cert);
+
+ const auto& extensions = cert->unparsed_extensions();
+ ASSERT_EQ(3u, extensions.size());
+
+ auto iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(95u, iter->second.value.Length());
+}
+
+// Parses an Extensions that contains a subjectaltname extension.
+TEST(ParsedCertificateTest, SubjectAltName) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("subject_alt_name.pem");
+ ASSERT_TRUE(cert);
+
+ ASSERT_TRUE(cert->has_subject_alt_names());
+}
+
+// Parses an Extensions that contains multiple extensions, sourced from a
+// real-world certificate.
+TEST(ParsedCertificateTest, ExtensionsReal) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("extensions_real.pem");
+ ASSERT_TRUE(cert);
+
+ const auto& extensions = cert->unparsed_extensions();
+ ASSERT_EQ(4u, extensions.size());
+
+ EXPECT_TRUE(cert->has_key_usage());
+ EXPECT_TRUE(cert->has_basic_constraints());
+
+ auto iter = extensions.find(CertificatePoliciesOid());
+ ASSERT_TRUE(iter != extensions.end());
+ EXPECT_FALSE(iter->second.critical);
+ EXPECT_EQ(16u, iter->second.value.Length());
+
+ // TODO(eroman): Verify the other 4 extensions' values.
+}
+
+// Parses a BasicConstraints with no CA or pathlen.
+TEST(ParsedCertificateTest, BasicConstraintsNotCa) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_not_ca.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_FALSE(cert->basic_constraints().is_ca);
+ EXPECT_FALSE(cert->basic_constraints().has_path_len);
+}
+
+// Parses a BasicConstraints with CA but no pathlen.
+TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_ca_no_path.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_TRUE(cert->basic_constraints().is_ca);
+ EXPECT_FALSE(cert->basic_constraints().has_path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 9.
+TEST(ParsedCertificateTest, BasicConstraintsCaPath9) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_ca_path_9.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_TRUE(cert->basic_constraints().is_ca);
+ EXPECT_TRUE(cert->basic_constraints().has_path_len);
+ EXPECT_EQ(9u, cert->basic_constraints().path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size).
+TEST(ParsedCertificateTest, BasicConstraintsPathlen255) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_pathlen_255.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_TRUE(cert->basic_constraints().is_ca);
+ EXPECT_TRUE(cert->basic_constraints().has_path_len);
+ EXPECT_EQ(255, cert->basic_constraints().path_len);
+}
+
+// Parses a BasicConstraints with CA and pathlen of 256 (too large).
+TEST(ParsedCertificateTest, BasicConstraintsPathlen256) {
+ ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_pathlen_256.pem"));
+}
+
+// Parses a BasicConstraints with CA and a negative pathlen.
+TEST(ParsedCertificateTest, BasicConstraintsNegativePath) {
+ ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_negative_path.pem"));
+}
+
+// Parses a BasicConstraints with CA and pathlen that is very large (and
+// couldn't fit in a 64-bit integer).
+TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) {
+ ASSERT_FALSE(
+ ParseCertificateFromFile("basic_constraints_path_too_large.pem"));
+}
+
+// Parses a BasicConstraints with CA explicitly set to false. This violates
+// DER-encoding rules, however is commonly used, so it is accepted.
+TEST(ParsedCertificateTest, BasicConstraintsCaFalse) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_ca_false.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_FALSE(cert->basic_constraints().is_ca);
+ EXPECT_FALSE(cert->basic_constraints().has_path_len);
+}
+
+// Parses a BasicConstraints with CA set to true and an unexpected NULL at
+// the end.
+TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) {
+ ASSERT_FALSE(
+ ParseCertificateFromFile("basic_constraints_unconsumed_data.pem"));
+}
+
+// Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1.
+// This is valid DER for the ASN.1, however is not valid when interpreting the
+// BasicConstraints at a higher level.
+TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) {
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(cert->has_basic_constraints());
+ EXPECT_FALSE(cert->basic_constraints().is_ca);
+ EXPECT_TRUE(cert->basic_constraints().has_path_len);
+ EXPECT_EQ(1u, cert->basic_constraints().path_len);
+}
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/cert/internal/path_builder.cc b/chromium/net/cert/internal/path_builder.cc
index 36cd9d45f8d..bb4283eeed6 100644
--- a/chromium/net/cert/internal/path_builder.cc
+++ b/chromium/net/cert/internal/path_builder.cc
@@ -7,7 +7,6 @@
#include <set>
#include <unordered_set>
-#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "net/base/net_errors.h"
@@ -71,24 +70,20 @@ class CertIssuersIter {
CertIssuerSources* cert_issuer_sources,
const TrustStore* trust_store);
- // Gets the next candidate issuer. If an issuer is ready synchronously, SYNC
- // is returned and the cert is stored in |*cert|. If an issuer is not
- // ready, ASYNC is returned and |callback| will be called once |*out_cert| has
- // been set. If |callback| is null, always completes synchronously.
- //
- // In either case, if all issuers have been exhausted, |*out| is cleared.
- CompletionStatus GetNextIssuer(CertificateOrTrustAnchor* out,
- const base::Closure& callback);
+ // Gets the next candidate issuer, or clears |*out| when all issuers have been
+ // exhausted.
+ void GetNextIssuer(CertificateOrTrustAnchor* out);
// Returns the |cert| for which issuers are being retrieved.
const ParsedCertificate* cert() const { return cert_.get(); }
scoped_refptr<ParsedCertificate> reference_cert() const { return cert_; }
private:
+ void AddIssuers(ParsedCertificateList issuers);
void DoAsyncIssuerQuery();
- void GotAsyncAnchors(TrustAnchors anchors);
- void GotAsyncCerts(CertIssuerSource::Request* request);
- void NotifyIfNecessary();
+
+ // Returns true if |issuers_| contains unconsumed certificates.
+ bool HasCurrentIssuer() const { return cur_issuer_ < issuers_.size(); }
scoped_refptr<ParsedCertificate> cert_;
CertIssuerSources* cert_issuer_sources_;
@@ -119,19 +114,12 @@ class CertIssuersIter {
// Tracks which requests have been made yet.
bool did_initial_query_ = false;
bool did_async_issuer_query_ = false;
- // If asynchronous requests were made, how many of them are still outstanding?
- size_t pending_async_results_;
+ // Index into pending_async_requests_ that is the next one to process.
+ size_t cur_async_request_ = 0;
// Owns the Request objects for any asynchronous requests so that they will be
// cancelled if CertIssuersIter is destroyed.
std::vector<std::unique_ptr<CertIssuerSource::Request>>
pending_async_requests_;
- std::unique_ptr<TrustStore::Request> pending_anchor_request_;
-
- // When GetNextIssuer was called and returned asynchronously, |*out_| is
- // where the result will be stored, and |callback_| will be run when the
- // result is ready.
- CertificateOrTrustAnchor* out_;
- base::Closure callback_;
DISALLOW_COPY_AND_ASSIGN(CertIssuersIter);
};
@@ -145,30 +133,15 @@ CertIssuersIter::CertIssuersIter(scoped_refptr<ParsedCertificate> in_cert,
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") created";
}
-CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
- const base::Closure& callback) {
- // Should not be called again while already waiting for an async result.
- DCHECK(callback_.is_null());
-
+void CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out) {
if (!did_initial_query_) {
did_initial_query_ = true;
- trust_store_->FindTrustAnchorsForCert(
- cert_,
- callback.is_null() ? TrustStore::TrustAnchorsCallback()
- : base::Bind(&CertIssuersIter::GotAsyncAnchors,
- base::Unretained(this)),
- &anchors_, &pending_anchor_request_);
+ trust_store_->FindTrustAnchorsForCert(cert_, &anchors_);
for (auto* cert_issuer_source : *cert_issuer_sources_) {
ParsedCertificateList new_issuers;
cert_issuer_source->SyncGetIssuersOf(cert(), &new_issuers);
- for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
- if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
- present_issuers_.end())
- continue;
- present_issuers_.insert(issuer->der_cert().AsStringPiece());
- issuers_.push_back(std::move(issuer));
- }
+ AddIssuers(std::move(new_issuers));
}
DVLOG(1) << anchors_.size() << " sync anchors, " << issuers_.size()
<< " sync issuers";
@@ -186,18 +159,33 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
<< anchors_.size();
// Still have anchors that haven't been returned yet, return one of them.
*out = CertificateOrTrustAnchor(anchors_[cur_anchor_++]);
- return CompletionStatus::SYNC;
+ return;
}
- if (pending_anchor_request_) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") Still waiting for async trust anchor results.";
- out_ = out;
- callback_ = callback;
- return CompletionStatus::ASYNC;
+ // If there aren't any issuers left, block until async results are ready.
+ if (!HasCurrentIssuer()) {
+ if (!did_async_issuer_query_) {
+ // Now issue request(s) for async ones (AIA, etc).
+ DoAsyncIssuerQuery();
+ }
+
+ // TODO(eroman): Rather than blocking on the async requests in FIFO order,
+ // consume in the order they become ready.
+ while (!HasCurrentIssuer() &&
+ cur_async_request_ < pending_async_requests_.size()) {
+ ParsedCertificateList new_issuers;
+ pending_async_requests_[cur_async_request_]->GetNext(&new_issuers);
+ if (new_issuers.empty()) {
+ // Request is exhausted, no more results pending from that
+ // CertIssuerSource.
+ pending_async_requests_[cur_async_request_++].reset();
+ } else {
+ AddIssuers(std::move(new_issuers));
+ }
+ }
}
- if (cur_issuer_ < issuers_.size()) {
+ if (HasCurrentIssuer()) {
DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
<< "): returning issuer " << cur_issuer_ << " of "
<< issuers_.size();
@@ -205,148 +193,40 @@ CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out,
// A reference to the returned issuer is retained, since |present_issuers_|
// points to data owned by it.
*out = CertificateOrTrustAnchor(issuers_[cur_issuer_++]);
- return CompletionStatus::SYNC;
- }
-
- if (did_async_issuer_query_) {
- if (pending_async_results_ == 0) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") Reached the end of all available issuers.";
- // Reached the end of all available issuers.
- *out = CertificateOrTrustAnchor();
- return CompletionStatus::SYNC;
- }
-
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") Still waiting for async results from other "
- "CertIssuerSources.";
- // Still waiting for async results from other CertIssuerSources.
- out_ = out;
- callback_ = callback;
- return CompletionStatus::ASYNC;
+ return;
}
- // Reached the end of synchronously gathered issuers.
- if (callback.is_null()) {
- // Synchronous-only mode, don't try to query async sources.
- *out = CertificateOrTrustAnchor();
- return CompletionStatus::SYNC;
- }
-
- // Now issue request(s) for async ones (AIA, etc).
- DoAsyncIssuerQuery();
+ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
+ << ") Reached the end of all available issuers.";
+ // Reached the end of all available issuers.
+ *out = CertificateOrTrustAnchor();
+}
- if (pending_async_results_ == 0) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") No cert sources have async results.";
- // No cert sources have async results.
- *out = CertificateOrTrustAnchor();
- return CompletionStatus::SYNC;
+void CertIssuersIter::AddIssuers(ParsedCertificateList new_issuers) {
+ for (scoped_refptr<ParsedCertificate>& issuer : new_issuers) {
+ if (present_issuers_.find(issuer->der_cert().AsStringPiece()) !=
+ present_issuers_.end())
+ continue;
+ present_issuers_.insert(issuer->der_cert().AsStringPiece());
+ issuers_.push_back(std::move(issuer));
}
-
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_
- << ")";
- out_ = out;
- callback_ = callback;
- return CompletionStatus::ASYNC;
}
void CertIssuersIter::DoAsyncIssuerQuery() {
DCHECK(!did_async_issuer_query_);
did_async_issuer_query_ = true;
- pending_async_results_ = 0;
+ cur_async_request_ = 0;
for (auto* cert_issuer_source : *cert_issuer_sources_) {
std::unique_ptr<CertIssuerSource::Request> request;
- cert_issuer_source->AsyncGetIssuersOf(
- cert(),
- base::Bind(&CertIssuersIter::GotAsyncCerts, base::Unretained(this)),
- &request);
+ cert_issuer_source->AsyncGetIssuersOf(cert(), &request);
if (request) {
DVLOG(1) << "AsyncGetIssuersOf(" << CertDebugString(cert())
<< ") pending...";
- pending_async_results_++;
pending_async_requests_.push_back(std::move(request));
}
}
}
-void CertIssuersIter::GotAsyncAnchors(TrustAnchors anchors) {
- DVLOG(1) << "CertIssuersIter::GotAsyncAnchors(" << CertDebugString(cert())
- << "): " << anchors.size() << " anchors";
- for (scoped_refptr<TrustAnchor>& anchor : anchors)
- anchors_.push_back(std::move(anchor));
- pending_anchor_request_.reset();
-
- NotifyIfNecessary();
-}
-
-void CertIssuersIter::GotAsyncCerts(CertIssuerSource::Request* request) {
- DVLOG(1) << "CertIssuersIter::GotAsyncCerts(" << CertDebugString(cert())
- << ")";
- while (true) {
- scoped_refptr<ParsedCertificate> cert;
- CompletionStatus status = request->GetNext(&cert);
- if (!cert) {
- if (status == CompletionStatus::SYNC) {
- // Request is exhausted, no more results pending from that
- // CertIssuerSource.
- DCHECK_GT(pending_async_results_, 0U);
- pending_async_results_--;
- }
- break;
- }
- DCHECK_EQ(status, CompletionStatus::SYNC);
- if (present_issuers_.find(cert->der_cert().AsStringPiece()) !=
- present_issuers_.end())
- continue;
- present_issuers_.insert(cert->der_cert().AsStringPiece());
- issuers_.push_back(std::move(cert));
- }
-
- // TODO(mattm): re-sort remaining elements of issuers_ (remaining elements may
- // be more than the ones just inserted, depending on |cur_| value).
-
- NotifyIfNecessary();
-}
-
-void CertIssuersIter::NotifyIfNecessary() {
- // Notify that more results are available, if necessary.
- if (!callback_.is_null()) {
- if (cur_anchor_ < anchors_.size()) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): async returning anchor " << cur_anchor_ << " of "
- << anchors_.size();
- *out_ = CertificateOrTrustAnchor(std::move(anchors_[cur_anchor_++]));
- base::ResetAndReturn(&callback_).Run();
- return;
- }
- if (cur_issuer_ < issuers_.size()) {
- DCHECK(!pending_anchor_request_);
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): async returning issuer " << cur_issuer_ << " of "
- << issuers_.size();
- *out_ = CertificateOrTrustAnchor(std::move(issuers_[cur_issuer_++]));
- base::ResetAndReturn(&callback_).Run();
- return;
- }
-
- if (!did_async_issuer_query_)
- DoAsyncIssuerQuery();
-
- if (pending_async_results_ == 0) {
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): async returning empty result";
- *out_ = CertificateOrTrustAnchor();
- base::ResetAndReturn(&callback_).Run();
- return;
- }
- DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert())
- << "): empty result, but other async results "
- "pending, waiting..";
- }
-}
-
// CertIssuerIterPath tracks which certs are present in the path and prevents
// paths from being built which repeat any certs (including different versions
// of the same cert, based on Subject+SubjectAltName+SPKI).
@@ -446,11 +326,9 @@ class CertPathIter {
// CertPathIter.
void AddCertIssuerSource(CertIssuerSource* cert_issuer_source);
- // Gets the next candidate path. If a path is ready synchronously, SYNC is
- // returned and the path is stored in |*path|. If a path is not ready,
- // ASYNC is returned and |callback| will be called once |*path| has been set.
- // In either case, if all paths have been exhausted, |*path| is cleared.
- CompletionStatus GetNextPath(CertPath* path, const base::Closure& callback);
+ // Gets the next candidate path, or clears |*path| when all paths have been
+ // exhausted.
+ void GetNextPath(CertPath* path);
private:
enum State {
@@ -461,13 +339,9 @@ class CertPathIter {
STATE_BACKTRACK,
};
- CompletionStatus DoLoop(bool allow_async);
-
- CompletionStatus DoGetNextIssuer(bool allow_async);
- CompletionStatus DoGetNextIssuerComplete();
- CompletionStatus DoBackTrack();
-
- void HandleGotNextIssuer(void);
+ void DoGetNextIssuer();
+ void DoGetNextIssuerComplete();
+ void DoBackTrack();
// Stores the next candidate issuer, until it is used during the
// STATE_GET_NEXT_ISSUER_COMPLETE step.
@@ -483,8 +357,6 @@ class CertPathIter {
// The output variable for storing the next candidate path, which the client
// passes in to GetNextPath. Only used for a single path output.
CertPath* out_path_;
- // The callback to be called if an async lookup generated a candidate path.
- base::Closure callback_;
// Current state of the state machine.
State next_state_;
@@ -501,22 +373,10 @@ void CertPathIter::AddCertIssuerSource(CertIssuerSource* cert_issuer_source) {
cert_issuer_sources_.push_back(cert_issuer_source);
}
-CompletionStatus CertPathIter::GetNextPath(CertPath* path,
- const base::Closure& callback) {
+// TODO(eroman): Simplify (doesn't need to use the "DoLoop" pattern).
+void CertPathIter::GetNextPath(CertPath* path) {
out_path_ = path;
out_path_->Clear();
- CompletionStatus rv = DoLoop(!callback.is_null());
- if (rv == CompletionStatus::ASYNC) {
- callback_ = callback;
- } else {
- // Clear the reference to the output parameter as a precaution.
- out_path_ = nullptr;
- }
- return rv;
-}
-
-CompletionStatus CertPathIter::DoLoop(bool allow_async) {
- CompletionStatus result = CompletionStatus::SYNC;
do {
State state = next_state_;
next_state_ = STATE_NONE;
@@ -525,39 +385,32 @@ CompletionStatus CertPathIter::DoLoop(bool allow_async) {
NOTREACHED();
break;
case STATE_GET_NEXT_ISSUER:
- result = DoGetNextIssuer(allow_async);
+ DoGetNextIssuer();
break;
case STATE_GET_NEXT_ISSUER_COMPLETE:
- result = DoGetNextIssuerComplete();
+ DoGetNextIssuerComplete();
break;
case STATE_RETURN_A_PATH:
// If the returned path did not verify, keep looking for other paths
// (the trust root is not part of cur_path_, so don't need to
// backtrack).
next_state_ = STATE_GET_NEXT_ISSUER;
- result = CompletionStatus::SYNC;
break;
case STATE_BACKTRACK:
- result = DoBackTrack();
+ DoBackTrack();
break;
}
- } while (result == CompletionStatus::SYNC && next_state_ != STATE_NONE &&
- next_state_ != STATE_RETURN_A_PATH);
+ } while (next_state_ != STATE_NONE && next_state_ != STATE_RETURN_A_PATH);
- return result;
+ out_path_ = nullptr;
}
-CompletionStatus CertPathIter::DoGetNextIssuer(bool allow_async) {
+void CertPathIter::DoGetNextIssuer() {
next_state_ = STATE_GET_NEXT_ISSUER_COMPLETE;
- CompletionStatus rv = cur_path_.back()->GetNextIssuer(
- &next_issuer_, allow_async
- ? base::Bind(&CertPathIter::HandleGotNextIssuer,
- base::Unretained(this))
- : base::Closure());
- return rv;
+ cur_path_.back()->GetNextIssuer(&next_issuer_);
}
-CompletionStatus CertPathIter::DoGetNextIssuerComplete() {
+void CertPathIter::DoGetNextIssuerComplete() {
// If the issuer is a trust anchor signal readiness.
if (next_issuer_.IsTrustAnchor()) {
DVLOG(1) << "CertPathIter got anchor("
@@ -566,14 +419,14 @@ CompletionStatus CertPathIter::DoGetNextIssuerComplete() {
cur_path_.CopyPath(&out_path_->certs);
out_path_->trust_anchor = std::move(next_issuer_.anchor);
next_issuer_ = CertificateOrTrustAnchor();
- return CompletionStatus::SYNC;
+ return;
}
if (next_issuer_.IsCertificate()) {
// Skip this cert if it is already in the chain.
if (cur_path_.IsPresent(next_issuer_.cert.get())) {
next_state_ = STATE_GET_NEXT_ISSUER;
- return CompletionStatus::SYNC;
+ return;
}
cur_path_.Append(base::MakeUnique<CertIssuersIter>(
@@ -590,10 +443,9 @@ CompletionStatus CertPathIter::DoGetNextIssuerComplete() {
// more for the previous cert.
next_state_ = STATE_BACKTRACK;
}
- return CompletionStatus::SYNC;
}
-CompletionStatus CertPathIter::DoBackTrack() {
+void CertPathIter::DoBackTrack() {
DVLOG(1) << "CertPathIter backtracking...";
cur_path_.Pop();
if (cur_path_.Empty()) {
@@ -603,17 +455,6 @@ CompletionStatus CertPathIter::DoBackTrack() {
// Continue exploring issuers of the previous path.
next_state_ = STATE_GET_NEXT_ISSUER;
}
- return CompletionStatus::SYNC;
-}
-
-void CertPathIter::HandleGotNextIssuer(void) {
- DCHECK(!callback_.is_null());
- CompletionStatus rv = DoLoop(true /* allow_async */);
- if (rv == CompletionStatus::SYNC) {
- // Clear the reference to the output parameter as a precaution.
- out_path_ = nullptr;
- base::ResetAndReturn(&callback_).Run();
- }
}
CertPathBuilder::ResultPath::ResultPath() = default;
@@ -658,19 +499,10 @@ void CertPathBuilder::AddCertIssuerSource(
cert_path_iter_->AddCertIssuerSource(cert_issuer_source);
}
-CompletionStatus CertPathBuilder::Run(const base::Closure& callback) {
+// TODO(eroman): Simplify (doesn't need to use the "DoLoop" pattern).
+void CertPathBuilder::Run() {
DCHECK_EQ(STATE_NONE, next_state_);
next_state_ = STATE_GET_NEXT_PATH;
- CompletionStatus rv = DoLoop(!callback.is_null());
-
- if (rv == CompletionStatus::ASYNC)
- callback_ = callback;
-
- return rv;
-}
-
-CompletionStatus CertPathBuilder::DoLoop(bool allow_async) {
- CompletionStatus result = CompletionStatus::SYNC;
do {
State state = next_state_;
@@ -680,38 +512,25 @@ CompletionStatus CertPathBuilder::DoLoop(bool allow_async) {
NOTREACHED();
break;
case STATE_GET_NEXT_PATH:
- result = DoGetNextPath(allow_async);
+ DoGetNextPath();
break;
case STATE_GET_NEXT_PATH_COMPLETE:
- result = DoGetNextPathComplete();
+ DoGetNextPathComplete();
break;
}
- } while (result == CompletionStatus::SYNC && next_state_ != STATE_NONE);
-
- return result;
+ } while (next_state_ != STATE_NONE);
}
-CompletionStatus CertPathBuilder::DoGetNextPath(bool allow_async) {
+void CertPathBuilder::DoGetNextPath() {
next_state_ = STATE_GET_NEXT_PATH_COMPLETE;
- CompletionStatus rv = cert_path_iter_->GetNextPath(
- &next_path_, allow_async ? base::Bind(&CertPathBuilder::HandleGotNextPath,
- base::Unretained(this))
- : base::Closure());
- return rv;
-}
-
-void CertPathBuilder::HandleGotNextPath() {
- DCHECK(!callback_.is_null());
- CompletionStatus rv = DoLoop(true /* allow_async */);
- if (rv == CompletionStatus::SYNC)
- base::ResetAndReturn(&callback_).Run();
+ cert_path_iter_->GetNextPath(&next_path_);
}
-CompletionStatus CertPathBuilder::DoGetNextPathComplete() {
+void CertPathBuilder::DoGetNextPathComplete() {
if (next_path_.IsEmpty()) {
// No more paths to check, signal completion.
next_state_ = STATE_NONE;
- return CompletionStatus::SYNC;
+ return;
}
// Verify the entire certificate chain.
@@ -729,14 +548,13 @@ CompletionStatus CertPathBuilder::DoGetNextPathComplete() {
// Found a valid path, return immediately.
// TODO(mattm): add debug/test mode that tries all possible paths.
next_state_ = STATE_NONE;
- return CompletionStatus::SYNC;
+ return;
}
// Path did not verify. Try more paths. If there are no more paths, the result
// will be returned next time DoGetNextPathComplete is called with next_path_
// empty.
next_state_ = STATE_GET_NEXT_PATH;
- return CompletionStatus::SYNC;
}
void CertPathBuilder::AddResultPath(std::unique_ptr<ResultPath> result_path) {
diff --git a/chromium/net/cert/internal/path_builder.h b/chromium/net/cert/internal/path_builder.h
index 69784f333b0..ee39ed67ee5 100644
--- a/chromium/net/cert/internal/path_builder.h
+++ b/chromium/net/cert/internal/path_builder.h
@@ -9,11 +9,8 @@
#include <string>
#include <vector>
-#include "base/callback.h"
-#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/cert/internal/cert_errors.h"
-#include "net/cert/internal/completion_status.h"
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/internal/trust_store.h"
#include "net/der/input.h"
@@ -107,6 +104,9 @@ class NET_EXPORT CertPathBuilder {
// TODO(mattm): allow caller specified hook/callback to extend path
// verification.
//
+ // TODO(eroman): The assumption is that |result| is default initialized. Can
+ // probably just internalize |result| into CertPathBuilder.
+ //
// Creates a CertPathBuilder that attempts to find a path from |cert| to a
// trust anchor in |trust_store|, which satisfies |signature_policy| and is
// valid at |time|. Details of attempted path(s) are stored in |*result|.
@@ -129,24 +129,12 @@ class NET_EXPORT CertPathBuilder {
// it is a trust anchor or is directly signed by a trust anchor.)
void AddCertIssuerSource(CertIssuerSource* cert_issuer_source);
- // Begins verification of the target certificate.
- //
- // If the return value is SYNC then the verification is complete and the
- // |result| value can be inspected for the status, and |callback| will not be
- // called.
- // If the return value is ASYNC, the |callback| will be called asynchronously
- // once the verification is complete. |result| should not be examined or
- // modified until the |callback| is run.
- //
- // If |callback| is null, verification always completes synchronously, even if
- // it fails to find a valid path and one could have been found asynchronously.
+ // Executes verification of the target certificate.
//
- // The CertPathBuilder may be deleted while an ASYNC verification is pending,
- // in which case the verification is cancelled, |callback| will not be called,
- // and the output Result will be in an undefined state.
- // It is safe to delete the CertPathBuilder during the |callback|.
- // Run must not be called more than once on each CertPathBuilder instance.
- CompletionStatus Run(const base::Closure& callback);
+ // Upon return results are written to the |result| object passed into the
+ // constructor. Run must not be called more than once on each CertPathBuilder
+ // instance.
+ void Run();
private:
enum State {
@@ -155,16 +143,11 @@ class NET_EXPORT CertPathBuilder {
STATE_GET_NEXT_PATH_COMPLETE,
};
- CompletionStatus DoLoop(bool allow_async);
-
- CompletionStatus DoGetNextPath(bool allow_async);
- void HandleGotNextPath();
- CompletionStatus DoGetNextPathComplete();
+ void DoGetNextPath();
+ void DoGetNextPathComplete();
void AddResultPath(std::unique_ptr<ResultPath> result_path);
- base::Closure callback_;
-
std::unique_ptr<CertPathIter> cert_path_iter_;
const SignaturePolicy* signature_policy_;
const der::GeneralizedTime time_;
diff --git a/chromium/net/cert/internal/path_builder_pkits_unittest.cc b/chromium/net/cert/internal/path_builder_pkits_unittest.cc
index 4039428687e..b362519319d 100644
--- a/chromium/net/cert/internal/path_builder_pkits_unittest.cc
+++ b/chromium/net/cert/internal/path_builder_pkits_unittest.cc
@@ -90,8 +90,7 @@ class PathBuilderPkitsTestDelegate {
&signature_policy, time, &result);
path_builder.AddCertIssuerSource(&cert_issuer_source);
- CompletionStatus rv = path_builder.Run(base::Closure());
- EXPECT_EQ(CompletionStatus::SYNC, rv);
+ path_builder.Run();
return result.HasValidPath();
}
diff --git a/chromium/net/cert/internal/path_builder_unittest.cc b/chromium/net/cert/internal/path_builder_unittest.cc
index 5f0a2eb6234..35fe1542905 100644
--- a/chromium/net/cert/internal/path_builder_unittest.cc
+++ b/chromium/net/cert/internal/path_builder_unittest.cc
@@ -5,18 +5,14 @@
#include "net/cert/internal/path_builder.h"
#include "base/base_paths.h"
-#include "base/cancelable_callback.h"
#include "base/files/file_util.h"
-#include "base/location.h"
#include "base/path_service.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "net/base/test_completion_callback.h"
#include "net/cert/internal/cert_issuer_source_static.h"
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/internal/signature_policy.h"
#include "net/cert/internal/test_helpers.h"
+#include "net/cert/internal/trust_store_collection.h"
#include "net/cert/internal/trust_store_in_memory.h"
-#include "net/cert/internal/trust_store_test_helpers.h"
#include "net/cert/internal/verify_certificate_chain.h"
#include "net/cert/pem_tokenizer.h"
#include "net/der/input.h"
@@ -44,32 +40,17 @@ class AsyncCertIssuerSourceStatic : public CertIssuerSource {
public:
class StaticAsyncRequest : public Request {
public:
- StaticAsyncRequest(const IssuerCallback& issuers_callback,
- ParsedCertificateList&& issuers)
- : cancelable_closure_(base::Bind(&StaticAsyncRequest::RunCallback,
- base::Unretained(this))),
- issuers_callback_(issuers_callback) {
+ StaticAsyncRequest(ParsedCertificateList&& issuers) {
issuers_.swap(issuers);
issuers_iter_ = issuers_.begin();
}
~StaticAsyncRequest() override {}
- CompletionStatus GetNext(
- scoped_refptr<ParsedCertificate>* out_cert) override {
- if (issuers_iter_ == issuers_.end())
- *out_cert = nullptr;
- else
- *out_cert = std::move(*issuers_iter_++);
- return CompletionStatus::SYNC;
+ void GetNext(ParsedCertificateList* out_certs) override {
+ if (issuers_iter_ != issuers_.end())
+ out_certs->push_back(std::move(*issuers_iter_++));
}
- base::Closure callback() { return cancelable_closure_.callback(); }
-
- private:
- void RunCallback() { issuers_callback_.Run(this); }
-
- base::CancelableClosure cancelable_closure_;
- IssuerCallback issuers_callback_;
ParsedCertificateList issuers_;
ParsedCertificateList::iterator issuers_iter_;
@@ -85,14 +66,12 @@ class AsyncCertIssuerSourceStatic : public CertIssuerSource {
void SyncGetIssuersOf(const ParsedCertificate* cert,
ParsedCertificateList* issuers) override {}
void AsyncGetIssuersOf(const ParsedCertificate* cert,
- const IssuerCallback& issuers_callback,
std::unique_ptr<Request>* out_req) override {
num_async_gets_++;
ParsedCertificateList issuers;
static_cert_issuer_source_.SyncGetIssuersOf(cert, &issuers);
std::unique_ptr<StaticAsyncRequest> req(
- new StaticAsyncRequest(issuers_callback, std::move(issuers)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, req->callback());
+ new StaticAsyncRequest(std::move(issuers)));
*out_req = std::move(req);
}
int num_async_gets() const { return num_async_gets_; }
@@ -131,21 +110,6 @@ class AsyncCertIssuerSourceStatic : public CertIssuerSource {
return ::testing::AssertionSuccess();
}
-// Run the path builder, and wait for async completion if necessary. The return
-// value signifies whether the path builder completed synchronously or
-// asynchronously, not that RunPathBuilder itself is asynchronous.
-CompletionStatus RunPathBuilder(CertPathBuilder* path_builder) {
- TestClosure callback;
- CompletionStatus rv = path_builder->Run(callback.closure());
-
- if (rv == CompletionStatus::ASYNC) {
- DVLOG(1) << "waiting for async completion...";
- callback.WaitForResult();
- DVLOG(1) << "async completed.";
- }
- return rv;
-}
-
class PathBuilderMultiRootTest : public ::testing::Test {
public:
PathBuilderMultiRootTest() : signature_policy_(1024) {}
@@ -194,7 +158,7 @@ TEST_F(PathBuilderMultiRootTest, TargetHasNameAndSpkiOfTrustAnchor) {
CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
&result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
const auto& path = result.GetBestValidPath()->path;
@@ -214,7 +178,7 @@ TEST_F(PathBuilderMultiRootTest, TargetWithSameNameAsTrustAnchorFails) {
CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
&result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_FALSE(result.HasValidPath());
}
@@ -245,7 +209,7 @@ TEST_F(PathBuilderMultiRootTest, SelfSignedTrustAnchorSupplementalCert) {
expired_time, &result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_FALSE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
@@ -277,7 +241,7 @@ TEST_F(PathBuilderMultiRootTest, TargetIsSelfSignedTrustAnchor) {
CertPathBuilder path_builder(e_by_e_, &trust_store, &signature_policy_, time_,
&result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
const auto& path = result.GetBestValidPath()->path;
@@ -296,7 +260,7 @@ TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) {
CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
&result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
const auto& path = result.GetBestValidPath()->path;
@@ -325,35 +289,12 @@ TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
path_builder.AddCertIssuerSource(&async_certs);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
EXPECT_EQ(0, async_certs.num_async_gets());
}
-// Test that async cert queries are not made if no callback is provided.
-TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) {
- TrustStoreInMemory trust_store;
- AddTrustedCertificate(e_by_e_, &trust_store);
-
- CertIssuerSourceStatic sync_certs;
- sync_certs.AddCert(f_by_e_);
-
- AsyncCertIssuerSourceStatic async_certs;
- async_certs.AddCert(b_by_f_);
-
- CertPathBuilder::Result result;
- CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
- &result);
- path_builder.AddCertIssuerSource(&async_certs);
- path_builder.AddCertIssuerSource(&sync_certs);
-
- EXPECT_EQ(CompletionStatus::SYNC, path_builder.Run(base::Closure()));
-
- EXPECT_FALSE(result.HasValidPath());
- EXPECT_EQ(0, async_certs.num_async_gets());
-}
-
// If async queries are needed, all async sources will be queried
// simultaneously.
TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
@@ -377,7 +318,7 @@ TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
path_builder.AddCertIssuerSource(&async_certs2);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
EXPECT_EQ(1, async_certs1.num_async_gets());
@@ -402,7 +343,7 @@ TEST_F(PathBuilderMultiRootTest, TestLongChain) {
&result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
@@ -436,7 +377,7 @@ TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
path_builder.AddCertIssuerSource(&sync_certs);
path_builder.AddCertIssuerSource(&async_certs);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
@@ -474,7 +415,7 @@ TEST_F(PathBuilderMultiRootTest, TestCertIssuerOrdering) {
time_, &result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
@@ -558,7 +499,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
&result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
@@ -606,7 +547,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
&result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
@@ -630,141 +571,39 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
}
}
-// If trust anchors are provided both synchronously and asynchronously for the
-// same cert, the synchronously provided ones should be tried first, and
-// pathbuilder should finish synchronously.
-TEST_F(PathBuilderKeyRolloverTest, TestSyncAnchorsPreferred) {
- TrustStoreInMemoryAsync trust_store;
- // Both oldintermediate and newintermediate are trusted, but oldintermediate
- // is returned synchronously and newintermediate asynchronously.
- trust_store.AddSyncTrustAnchor(
- TrustAnchor::CreateFromCertificateNoConstraints(oldintermediate_));
- trust_store.AddAsyncTrustAnchor(
- TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_));
-
- CertPathBuilder::Result result;
- CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
- &result);
-
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
-
- EXPECT_TRUE(result.HasValidPath());
-
- ASSERT_EQ(1U, result.paths.size());
- const auto& path = result.paths[0]->path;
- EXPECT_TRUE(result.paths[0]->valid);
- ASSERT_EQ(1U, path.certs.size());
- EXPECT_EQ(target_, path.certs[0]);
- EXPECT_EQ(oldintermediate_, path.trust_anchor->cert());
-}
-
-// Async trust anchor checks should be done before synchronous issuer checks are
-// considered. (Avoiding creating unnecessarily long paths.)
-//
-// Two valid paths could be built:
-// newintermediate <- newrootrollover <- oldroot
-// newintermediate <- newroot
-// One invalid path could be built:
-// newintermediate <- oldroot
-//
-// First: newintermediate <- oldroot will be tried, since oldroot is
-// available synchronously, but this path will not verify.
-// Second: newintermediate <- newroot should be built, even though
-// newrootrollover issuer is available synchronously and newroot is async. This
-// path should verify and pathbuilder will stop.
-TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsBeforeSyncIssuers) {
- TrustStoreInMemoryAsync trust_store;
- trust_store.AddSyncTrustAnchor(oldroot_);
- trust_store.AddAsyncTrustAnchor(
- TrustAnchor::CreateFromCertificateNoConstraints(newroot_));
-
- CertIssuerSourceStatic sync_certs;
- sync_certs.AddCert(newrootrollover_);
-
- CertPathBuilder::Result result;
- CertPathBuilder path_builder(newintermediate_, &trust_store,
- &signature_policy_, time_, &result);
- path_builder.AddCertIssuerSource(&sync_certs);
-
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
-
- EXPECT_TRUE(result.HasValidPath());
-
- ASSERT_EQ(2U, result.paths.size());
- {
- const auto& path = result.paths[0]->path;
- EXPECT_FALSE(result.paths[0]->valid);
- ASSERT_EQ(1U, path.certs.size());
- EXPECT_EQ(newintermediate_, path.certs[0]);
- EXPECT_EQ(oldroot_, path.trust_anchor);
- }
- {
- const auto& path = result.paths[1]->path;
- EXPECT_TRUE(result.paths[1]->valid);
- ASSERT_EQ(1U, path.certs.size());
- EXPECT_EQ(newintermediate_, path.certs[0]);
- EXPECT_EQ(newroot_, path.trust_anchor->cert());
- }
-}
-
-// If async trust anchor query returned no results, and there are no issuer
+// If trust anchor query returned no results, and there are no issuer
// sources, path building should fail at that point.
-TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsNoMatchAndNoIssuerSources) {
- TrustStoreInMemoryAsync trust_store;
- trust_store.AddAsyncTrustAnchor(
+TEST_F(PathBuilderKeyRolloverTest, TestAnchorsNoMatchAndNoIssuerSources) {
+ TrustStoreInMemory trust_store;
+ trust_store.AddTrustAnchor(
TrustAnchor::CreateFromCertificateNoConstraints(newroot_));
CertPathBuilder::Result result;
CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
&result);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_FALSE(result.HasValidPath());
ASSERT_EQ(0U, result.paths.size());
}
-// Both trust store and issuer source are async. Should successfully build a
-// path.
-TEST_F(PathBuilderKeyRolloverTest, TestAsyncAnchorsAndAsyncIssuers) {
- TrustStoreInMemoryAsync trust_store;
- trust_store.AddAsyncTrustAnchor(
- TrustAnchor::CreateFromCertificateNoConstraints(newroot_));
-
- AsyncCertIssuerSourceStatic async_certs;
- async_certs.AddCert(newintermediate_);
-
- CertPathBuilder::Result result;
- CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
- &result);
- path_builder.AddCertIssuerSource(&async_certs);
-
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
-
- EXPECT_TRUE(result.HasValidPath());
-
- ASSERT_EQ(1U, result.paths.size());
- const auto& path = result.paths[0]->path;
- EXPECT_TRUE(result.paths[0]->valid);
- ASSERT_EQ(2U, path.certs.size());
- EXPECT_EQ(target_, path.certs[0]);
- EXPECT_EQ(newintermediate_, path.certs[1]);
- EXPECT_EQ(newroot_, path.trust_anchor->cert());
-}
-
// Tests that multiple trust root matches on a single path will be considered.
// Both roots have the same subject but different keys. Only one of them will
// verify.
TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
- TrustStoreInMemoryAsync trust_store;
- // Since FindTrustAnchorsByNormalizedName returns newroot synchronously, it
- // should be tried first.
- trust_store.AddSyncTrustAnchor(
+ TrustStoreCollection trust_store_collection;
+ TrustStoreInMemory trust_store1;
+ TrustStoreInMemory trust_store2;
+ trust_store_collection.AddTrustStore(&trust_store1);
+ trust_store_collection.AddTrustStore(&trust_store2);
+ // Add two trust anchors (newroot_ and oldroot_). Path building will attempt
+ // them in this same order, as trust_store1 was added to
+ // trust_store_collection first.
+ trust_store1.AddTrustAnchor(
TrustAnchor::CreateFromCertificateNoConstraints(newroot_));
- // oldroot is returned asynchronously, so it should only be tried after the
- // path built with newroot fails.
- trust_store.AddAsyncTrustAnchor(oldroot_);
+ trust_store2.AddTrustAnchor(oldroot_);
// Only oldintermediate is supplied, so the path with newroot should fail,
// oldroot should succeed.
@@ -772,11 +611,11 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
sync_certs.AddCert(oldintermediate_);
CertPathBuilder::Result result;
- CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
- &result);
+ CertPathBuilder path_builder(target_, &trust_store_collection,
+ &signature_policy_, time_, &result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
@@ -827,7 +666,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
path_builder.AddCertIssuerSource(&sync_certs);
path_builder.AddCertIssuerSource(&async_certs);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
ASSERT_EQ(3U, result.paths.size());
@@ -882,7 +721,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
CertPathBuilder path_builder(newintermediate_, &trust_store,
&signature_policy_, time_, &result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_FALSE(result.HasValidPath());
}
@@ -907,7 +746,7 @@ TEST_F(PathBuilderKeyRolloverTest,
time_, &result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
// This could actually be OK, but CertPathBuilder does not build the
// newroot <- newrootrollover <- oldroot path.
@@ -927,7 +766,7 @@ TEST_F(PathBuilderKeyRolloverTest,
CertPathBuilder path_builder(newroot_, &trust_store, &signature_policy_,
time_, &result);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
ASSERT_TRUE(result.HasValidPath());
@@ -975,7 +814,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediates) {
path_builder.AddCertIssuerSource(&sync_certs2);
path_builder.AddCertIssuerSource(&async_certs);
- EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_TRUE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
@@ -1024,7 +863,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
&result);
path_builder.AddCertIssuerSource(&sync_certs);
- EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
+ path_builder.Run();
EXPECT_FALSE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
@@ -1044,17 +883,15 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
class MockCertIssuerSourceRequest : public CertIssuerSource::Request {
public:
- MOCK_METHOD1(GetNext, CompletionStatus(scoped_refptr<ParsedCertificate>*));
+ MOCK_METHOD1(GetNext, void(ParsedCertificateList*));
};
class MockCertIssuerSource : public CertIssuerSource {
public:
MOCK_METHOD2(SyncGetIssuersOf,
void(const ParsedCertificate*, ParsedCertificateList*));
- MOCK_METHOD3(AsyncGetIssuersOf,
- void(const ParsedCertificate*,
- const IssuerCallback&,
- std::unique_ptr<Request>*));
+ MOCK_METHOD2(AsyncGetIssuersOf,
+ void(const ParsedCertificate*, std::unique_ptr<Request>*));
};
// Helper class to pass the Request to the PathBuilder when it calls
@@ -1065,7 +902,6 @@ class CertIssuerSourceRequestMover {
CertIssuerSourceRequestMover(std::unique_ptr<CertIssuerSource::Request> req)
: request_(std::move(req)) {}
void MoveIt(const ParsedCertificate* cert,
- const CertIssuerSource::IssuerCallback& issuers_callback,
std::unique_ptr<CertIssuerSource::Request>* out_req) {
*out_req = std::move(request_);
}
@@ -1074,10 +910,23 @@ class CertIssuerSourceRequestMover {
std::unique_ptr<CertIssuerSource::Request> request_;
};
+// Functor that when called with a ParsedCertificateList* will append the
+// specified certificate.
+class AppendCertToList {
+ public:
+ explicit AppendCertToList(const scoped_refptr<ParsedCertificate>& cert)
+ : cert_(cert) {}
+
+ void operator()(ParsedCertificateList* out) { out->push_back(cert_); }
+
+ private:
+ scoped_refptr<ParsedCertificate> cert_;
+};
+
// Test that a single CertIssuerSource returning multiple async batches of
// issuers is handled correctly. Due to the StrictMocks, it also tests that path
// builder does not request issuers of certs that it shouldn't.
-TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
+TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncIssuersFromSingleSource) {
StrictMock<MockCertIssuerSource> cert_issuer_source;
// Only newroot is a trusted root.
@@ -1089,7 +938,6 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
&result);
path_builder.AddCertIssuerSource(&cert_issuer_source);
- CertIssuerSource::IssuerCallback target_issuers_callback;
// Create the mock CertIssuerSource::Request...
std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>>
target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>());
@@ -1102,26 +950,15 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
{
::testing::InSequence s;
EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
- EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
- .WillOnce(
- DoAll(SaveArg<1>(&target_issuers_callback),
- Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
+ EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _))
+ .WillOnce(Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt));
}
- TestClosure callback;
- CompletionStatus rv = path_builder.Run(callback.closure());
- ASSERT_EQ(CompletionStatus::ASYNC, rv);
-
- ASSERT_FALSE(target_issuers_callback.is_null());
-
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
-
- // First async batch: return oldintermediate_.
EXPECT_CALL(*target_issuers_req, GetNext(_))
- .WillOnce(DoAll(SetArgPointee<0>(oldintermediate_),
- Return(CompletionStatus::SYNC)))
- .WillOnce(
- DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
+ // First async batch: return oldintermediate_.
+ .WillOnce(Invoke(AppendCertToList(oldintermediate_)))
+ // Second async batch: return newintermediate_.
+ .WillOnce(Invoke(AppendCertToList(newintermediate_)));
{
::testing::InSequence s;
// oldintermediate_ does not create a valid path, so both sync and async
@@ -1129,30 +966,21 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
EXPECT_CALL(cert_issuer_source,
SyncGetIssuersOf(oldintermediate_.get(), _));
EXPECT_CALL(cert_issuer_source,
- AsyncGetIssuersOf(oldintermediate_.get(), _, _));
+ AsyncGetIssuersOf(oldintermediate_.get(), _));
}
- target_issuers_callback.Run(target_issuers_req);
- ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
- // Second async batch: return newintermediate_.
- EXPECT_CALL(*target_issuers_req, GetNext(_))
- .WillOnce(DoAll(SetArgPointee<0>(newintermediate_),
- Return(CompletionStatus::SYNC)))
- .WillOnce(
- DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
// newroot_ is in the trust store, so this path will be completed
// synchronously. AsyncGetIssuersOf will not be called on newintermediate_.
EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediate_.get(), _));
- target_issuers_callback.Run(target_issuers_req);
+
+ // Ensure pathbuilder finished and filled result.
+ path_builder.Run();
+
// Note that VerifyAndClearExpectations(target_issuers_req) is not called
// here. PathBuilder could have destroyed it already, so just let the
// expectations get checked by the destructor.
::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
- // Ensure pathbuilder finished and filled result.
- callback.WaitForResult();
-
EXPECT_TRUE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
@@ -1189,7 +1017,6 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
&result);
path_builder.AddCertIssuerSource(&cert_issuer_source);
- CertIssuerSource::IssuerCallback target_issuers_callback;
// Create the mock CertIssuerSource::Request...
std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>>
target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>());
@@ -1202,26 +1029,22 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
{
::testing::InSequence s;
EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
- EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
- .WillOnce(
- DoAll(SaveArg<1>(&target_issuers_callback),
- Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
+ EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _))
+ .WillOnce(Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt));
}
- TestClosure callback;
- CompletionStatus rv = path_builder.Run(callback.closure());
- ASSERT_EQ(CompletionStatus::ASYNC, rv);
-
- ASSERT_FALSE(target_issuers_callback.is_null());
-
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
+ scoped_refptr<ParsedCertificate> oldintermediate_dupe(
+ ParsedCertificate::Create(oldintermediate_->der_cert().AsStringPiece(),
+ {}, nullptr));
- // First async batch: return oldintermediate_.
EXPECT_CALL(*target_issuers_req, GetNext(_))
- .WillOnce(DoAll(SetArgPointee<0>(oldintermediate_),
- Return(CompletionStatus::SYNC)))
- .WillOnce(
- DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
+ // First async batch: return oldintermediate_.
+ .WillOnce(Invoke(AppendCertToList(oldintermediate_)))
+ // Second async batch: return a different copy of oldintermediate_ again.
+ .WillOnce(Invoke(AppendCertToList(oldintermediate_dupe)))
+ // Third async batch: return newintermediate_.
+ .WillOnce(Invoke(AppendCertToList(newintermediate_)));
+
{
::testing::InSequence s;
// oldintermediate_ does not create a valid path, so both sync and async
@@ -1229,44 +1052,17 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
EXPECT_CALL(cert_issuer_source,
SyncGetIssuersOf(oldintermediate_.get(), _));
EXPECT_CALL(cert_issuer_source,
- AsyncGetIssuersOf(oldintermediate_.get(), _, _));
+ AsyncGetIssuersOf(oldintermediate_.get(), _));
}
- target_issuers_callback.Run(target_issuers_req);
- ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
-
- // Second async batch: return a different copy of oldintermediate_ again.
- scoped_refptr<ParsedCertificate> oldintermediate_dupe(
- ParsedCertificate::Create(oldintermediate_->der_cert().AsStringPiece(),
- {}, nullptr));
- EXPECT_CALL(*target_issuers_req, GetNext(_))
- .WillOnce(DoAll(SetArgPointee<0>(oldintermediate_dupe),
- Return(CompletionStatus::SYNC)))
- .WillOnce(
- DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
- target_issuers_callback.Run(target_issuers_req);
- // oldintermediate was already processed above, it should not generate any
- // more requests.
- ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
- // Third async batch: return newintermediate_.
- EXPECT_CALL(*target_issuers_req, GetNext(_))
- .WillOnce(DoAll(SetArgPointee<0>(newintermediate_),
- Return(CompletionStatus::SYNC)))
- .WillOnce(
- DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
// newroot_ is in the trust store, so this path will be completed
// synchronously. AsyncGetIssuersOf will not be called on newintermediate_.
EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediate_.get(), _));
- target_issuers_callback.Run(target_issuers_req);
- // Note that VerifyAndClearExpectations(target_issuers_req) is not called
- // here. PathBuilder could have destroyed it already, so just let the
- // expectations get checked by the destructor.
- ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
// Ensure pathbuilder finished and filled result.
- callback.WaitForResult();
+ path_builder.Run();
+
+ ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
EXPECT_TRUE(result.HasValidPath());
ASSERT_EQ(2U, result.paths.size());
diff --git a/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc b/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc
index 3bc20ef0819..003157b8dfa 100644
--- a/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc
+++ b/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc
@@ -37,9 +37,7 @@ class PathBuilderDelegate {
time, &result);
path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source);
- CompletionStatus rv = path_builder.Run(base::Closure());
- EXPECT_EQ(CompletionStatus::SYNC, rv);
-
+ path_builder.Run();
EXPECT_EQ(expected_result, result.HasValidPath());
}
};
diff --git a/chromium/net/cert/internal/trust_store.cc b/chromium/net/cert/internal/trust_store.cc
index 07eff04a326..7540cfdab8b 100644
--- a/chromium/net/cert/internal/trust_store.cc
+++ b/chromium/net/cert/internal/trust_store.cc
@@ -36,9 +36,6 @@ TrustAnchor::TrustAnchor(scoped_refptr<ParsedCertificate> cert,
TrustAnchor::~TrustAnchor() = default;
-TrustStore::Request::Request() = default;
-TrustStore::Request::~Request() = default;
-
TrustStore::TrustStore() = default;
TrustStore::~TrustStore() = default;
diff --git a/chromium/net/cert/internal/trust_store.h b/chromium/net/cert/internal/trust_store.h
index 8422fd5c96a..6985301f35c 100644
--- a/chromium/net/cert/internal/trust_store.h
+++ b/chromium/net/cert/internal/trust_store.h
@@ -7,7 +7,6 @@
#include <vector>
-#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/internal/parsed_certificate.h"
@@ -115,35 +114,14 @@ using TrustAnchors = std::vector<scoped_refptr<TrustAnchor>>;
// Interface for finding trust anchors.
class NET_EXPORT TrustStore {
public:
- class NET_EXPORT Request {
- public:
- Request();
- // Destruction of the Request cancels it.
- virtual ~Request();
- };
-
TrustStore();
virtual ~TrustStore();
- using TrustAnchorsCallback = base::Callback<void(TrustAnchors)>;
-
- // Returns the trust anchors that match |cert|'s issuer name in
- // |*synchronous_matches| and/or through |callback|. |cert| and
- // |synchronous_matches| must not be null.
- //
- // If results are available synchronously, they will be appended to
- // |*synchronous_matches|. |*synchronous_matches| will not be modified
- // asynchronously.
- //
- // If |callback| is not null and results may be available asynchronously,
- // |*out_req| will be filled with a Request, and |callback| will be called
- // when results are available. The Request may be destroyed to cancel
- // the callback if it has not occurred yet.
+ // Appends the trust anchors that match |cert|'s issuer name to |*matches|.
+ // |cert| and |matches| must not be null.
virtual void FindTrustAnchorsForCert(
const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const = 0;
+ TrustAnchors* matches) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TrustStore);
diff --git a/chromium/net/cert/internal/trust_store_collection.cc b/chromium/net/cert/internal/trust_store_collection.cc
index dc35306eee2..7e004ae1b72 100644
--- a/chromium/net/cert/internal/trust_store_collection.cc
+++ b/chromium/net/cert/internal/trust_store_collection.cc
@@ -9,29 +9,16 @@ namespace net {
TrustStoreCollection::TrustStoreCollection() = default;
TrustStoreCollection::~TrustStoreCollection() = default;
-void TrustStoreCollection::SetPrimaryTrustStore(TrustStore* store) {
- DCHECK(!primary_store_);
+void TrustStoreCollection::AddTrustStore(TrustStore* store) {
DCHECK(store);
- primary_store_ = store;
-}
-
-void TrustStoreCollection::AddTrustStoreSynchronousOnly(TrustStore* store) {
- DCHECK(store);
- sync_only_stores_.push_back(store);
+ stores_.push_back(store);
}
void TrustStoreCollection::FindTrustAnchorsForCert(
const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const {
- if (primary_store_)
- primary_store_->FindTrustAnchorsForCert(cert, callback, synchronous_matches,
- out_req);
-
- for (auto* store : sync_only_stores_) {
- store->FindTrustAnchorsForCert(cert, TrustAnchorsCallback(),
- synchronous_matches, nullptr);
+ TrustAnchors* matches) const {
+ for (auto* store : stores_) {
+ store->FindTrustAnchorsForCert(cert, matches);
}
}
diff --git a/chromium/net/cert/internal/trust_store_collection.h b/chromium/net/cert/internal/trust_store_collection.h
index ec9d49fd8e2..74ece5f97ba 100644
--- a/chromium/net/cert/internal/trust_store_collection.h
+++ b/chromium/net/cert/internal/trust_store_collection.h
@@ -9,50 +9,28 @@
#include "net/base/net_export.h"
#include "net/cert/internal/trust_store.h"
-namespace base {
-class TaskRunner;
-}
-
namespace net {
// TrustStoreCollection is an implementation of TrustStore which combines the
// results from multiple TrustStores.
//
-// The synchronous matches will be in order from the primary store, and then
-// from the secondary stores in the order they were added to the
-// TrustStoreCollection.
-//
-// Currently only one "primary" store can be added that supports async queries,
-// any number of additional, synchronous-only stores can be used. (The
-// assumption is that the async one would be useful for OS integration, while
-// the sync only stores can be used for supplying additional anchors. If
-// multiple async stores are desired, it might be worth changing the
-// FindTrustAnchorsForCert interface so that it can return async results in
-// multiple batches.)
+// The order of the matches will correspond to a concatenation of matches in
+// the order the stores were added.
class NET_EXPORT TrustStoreCollection : public TrustStore {
public:
TrustStoreCollection();
~TrustStoreCollection() override;
- // Includes results from |store| in the combined output. Both sync and async
- // queries to |store| will be allowed. |store| must outlive the
- // TrustStoreCollection.
- void SetPrimaryTrustStore(TrustStore* store);
-
- // Includes results from |store| in the combined output. |store| will only be
- // queried synchronously. |store| must outlive the TrustStoreCollection.
- void AddTrustStoreSynchronousOnly(TrustStore* store);
+ // Includes results from |store| in the combined output. |store| must
+ // outlive the TrustStoreCollection.
+ void AddTrustStore(TrustStore* store);
// TrustStore implementation:
- void FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const override;
+ void FindTrustAnchorsForCert(const scoped_refptr<ParsedCertificate>& cert,
+ TrustAnchors* matches) const override;
private:
- TrustStore* primary_store_ = nullptr;
- std::vector<TrustStore*> sync_only_stores_;
+ std::vector<TrustStore*> stores_;
DISALLOW_COPY_AND_ASSIGN(TrustStoreCollection);
};
diff --git a/chromium/net/cert/internal/trust_store_collection_unittest.cc b/chromium/net/cert/internal/trust_store_collection_unittest.cc
index a7561d3f782..c9cd85ccab8 100644
--- a/chromium/net/cert/internal/trust_store_collection_unittest.cc
+++ b/chromium/net/cert/internal/trust_store_collection_unittest.cc
@@ -4,33 +4,14 @@
#include "net/cert/internal/trust_store_collection.h"
-#include "base/bind.h"
#include "net/cert/internal/test_helpers.h"
-#include "net/cert/internal/trust_store_test_helpers.h"
-#include "testing/gmock/include/gmock/gmock.h"
+#include "net/cert/internal/trust_store_in_memory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
-using ::testing::_;
-using ::testing::Property;
-using ::testing::StrictMock;
-
-void NotCalled(TrustAnchors anchors) {
- ADD_FAILURE() << "NotCalled was called";
-}
-
-class MockTrustStore : public TrustStore {
- public:
- MOCK_CONST_METHOD4(FindTrustAnchorsForCert,
- void(const scoped_refptr<ParsedCertificate>&,
- const TrustAnchorsCallback&,
- TrustAnchors*,
- std::unique_ptr<Request>*));
-};
-
class TrustStoreCollectionTest : public testing::Test {
public:
void SetUp() override {
@@ -75,155 +56,46 @@ class TrustStoreCollectionTest : public testing::Test {
scoped_refptr<ParsedCertificate> newintermediate_;
};
-// Collection contains no stores, should return no results and complete
-// synchronously.
+// Collection contains no stores, should return no results.
TEST_F(TrustStoreCollectionTest, NoStores) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
+ TrustAnchors matches;
TrustStoreCollection collection;
- collection.FindTrustAnchorsForCert(target_, base::Bind(&NotCalled),
- &sync_matches, &req);
+ collection.FindTrustAnchorsForCert(target_, &matches);
- EXPECT_FALSE(req);
- EXPECT_TRUE(sync_matches.empty());
+ EXPECT_TRUE(matches.empty());
}
-// Collection contains only one synchronous store, should complete
-// synchronously.
-TEST_F(TrustStoreCollectionTest, NoPrimaryStoreOneSyncStore) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
+// Collection contains only one store.
+TEST_F(TrustStoreCollectionTest, OneStore) {
+ TrustAnchors matches;
TrustStoreCollection collection;
TrustStoreInMemory in_memory;
in_memory.AddTrustAnchor(newroot_);
- collection.AddTrustStoreSynchronousOnly(&in_memory);
- collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
- &sync_matches, &req);
-
- EXPECT_FALSE(req);
- ASSERT_EQ(1U, sync_matches.size());
- EXPECT_EQ(newroot_, sync_matches[0]);
-}
-
-// Collection contains two synchronous stores, should complete synchronously.
-TEST_F(TrustStoreCollectionTest, NoPrimaryStoreTwoSyncStores) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
-
- TrustStoreCollection collection;
- TrustStoreInMemory in_memory1;
- TrustStoreInMemory in_memory2;
- in_memory1.AddTrustAnchor(newroot_);
- in_memory2.AddTrustAnchor(oldroot_);
- collection.AddTrustStoreSynchronousOnly(&in_memory1);
- collection.AddTrustStoreSynchronousOnly(&in_memory2);
- collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
- &sync_matches, &req);
-
- EXPECT_FALSE(req);
- ASSERT_EQ(2U, sync_matches.size());
- EXPECT_EQ(newroot_, sync_matches[0]);
- EXPECT_EQ(oldroot_, sync_matches[1]);
-}
-
-// The secondary stores in the collection should not be passed a callback to
-// their FindTrustAnchorsForCert call.
-TEST_F(TrustStoreCollectionTest, SyncStoresAreQueriedSynchronously) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
-
- TrustStoreCollection collection;
- StrictMock<MockTrustStore> store;
- collection.AddTrustStoreSynchronousOnly(&store);
+ collection.AddTrustStore(&in_memory);
+ collection.FindTrustAnchorsForCert(newintermediate_, &matches);
- EXPECT_CALL(
- store,
- FindTrustAnchorsForCert(
- _, Property(&TrustStore::TrustAnchorsCallback::is_null, true), _, _));
-
- collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
- &sync_matches, &req);
-
- EXPECT_FALSE(req);
- EXPECT_TRUE(sync_matches.empty());
+ ASSERT_EQ(1U, matches.size());
+ EXPECT_EQ(newroot_, matches[0]);
}
-// If the primary store completes synchronously, TrustStoreCollection should
-// complete synchronously also.
-TEST_F(TrustStoreCollectionTest, AllStoresAreSynchronous) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
+// Collection contains two stores.
+TEST_F(TrustStoreCollectionTest, TwoStores) {
+ TrustAnchors matches;
TrustStoreCollection collection;
TrustStoreInMemory in_memory1;
TrustStoreInMemory in_memory2;
in_memory1.AddTrustAnchor(newroot_);
in_memory2.AddTrustAnchor(oldroot_);
- collection.SetPrimaryTrustStore(&in_memory1);
- collection.AddTrustStoreSynchronousOnly(&in_memory2);
- collection.FindTrustAnchorsForCert(newintermediate_, base::Bind(&NotCalled),
- &sync_matches, &req);
-
- EXPECT_FALSE(req);
- ASSERT_EQ(2U, sync_matches.size());
- EXPECT_EQ(newroot_, sync_matches[0]);
- EXPECT_EQ(oldroot_, sync_matches[1]);
-}
-
-// Primary store returns results asynchronously. No secondary stores registered.
-TEST_F(TrustStoreCollectionTest, AsyncPrimaryStore) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
-
- TrustStoreInMemoryAsync in_memory_async;
- in_memory_async.AddAsyncTrustAnchor(newroot_);
-
- TrustStoreCollection collection;
- collection.SetPrimaryTrustStore(&in_memory_async);
-
- TrustAnchorResultRecorder anchor_results;
- collection.FindTrustAnchorsForCert(
- newintermediate_, anchor_results.Callback(), &sync_matches, &req);
-
- ASSERT_TRUE(req);
- EXPECT_TRUE(sync_matches.empty());
-
- anchor_results.Run();
- ASSERT_EQ(1U, anchor_results.matches().size());
- EXPECT_EQ(newroot_, anchor_results.matches()[0]);
-}
-
-// Primary store returns results both synchronously and asynchronously, and
-// a secondary store returns results synchronously as well.
-TEST_F(TrustStoreCollectionTest, SyncAndAsyncPrimaryStoreAndSyncStore) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
-
- TrustStoreInMemoryAsync in_memory_async;
- in_memory_async.AddAsyncTrustAnchor(newroot_);
- in_memory_async.AddSyncTrustAnchor(newrootrollover_);
-
- TrustStoreInMemory in_memory;
- in_memory.AddTrustAnchor(oldroot_);
-
- TrustStoreCollection collection;
- collection.SetPrimaryTrustStore(&in_memory_async);
- collection.AddTrustStoreSynchronousOnly(&in_memory);
-
- TrustAnchorResultRecorder anchor_results;
- collection.FindTrustAnchorsForCert(
- newintermediate_, anchor_results.Callback(), &sync_matches, &req);
-
- ASSERT_TRUE(req);
- ASSERT_EQ(2U, sync_matches.size());
- EXPECT_EQ(newrootrollover_, sync_matches[0]);
- EXPECT_EQ(oldroot_, sync_matches[1]);
+ collection.AddTrustStore(&in_memory1);
+ collection.AddTrustStore(&in_memory2);
+ collection.FindTrustAnchorsForCert(newintermediate_, &matches);
- anchor_results.Run();
- ASSERT_EQ(1U, anchor_results.matches().size());
- EXPECT_EQ(newroot_, anchor_results.matches()[0]);
+ ASSERT_EQ(2U, matches.size());
+ EXPECT_EQ(newroot_, matches[0]);
+ EXPECT_EQ(oldroot_, matches[1]);
}
} // namespace
diff --git a/chromium/net/cert/internal/trust_store_in_memory.cc b/chromium/net/cert/internal/trust_store_in_memory.cc
index 4cdab9672d2..3f94b6f0c49 100644
--- a/chromium/net/cert/internal/trust_store_in_memory.cc
+++ b/chromium/net/cert/internal/trust_store_in_memory.cc
@@ -21,12 +21,10 @@ void TrustStoreInMemory::AddTrustAnchor(scoped_refptr<TrustAnchor> anchor) {
void TrustStoreInMemory::FindTrustAnchorsForCert(
const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const {
+ TrustAnchors* matches) const {
auto range = anchors_.equal_range(cert->normalized_issuer().AsStringPiece());
for (auto it = range.first; it != range.second; ++it)
- synchronous_matches->push_back(it->second);
+ matches->push_back(it->second);
}
} // namespace net
diff --git a/chromium/net/cert/internal/trust_store_in_memory.h b/chromium/net/cert/internal/trust_store_in_memory.h
index fea4c87d314..45b5123caf1 100644
--- a/chromium/net/cert/internal/trust_store_in_memory.h
+++ b/chromium/net/cert/internal/trust_store_in_memory.h
@@ -14,10 +14,6 @@
namespace net {
-namespace der {
-class Input;
-}
-
// A very simple implementation of a TrustStore, which contains a set of
// trust anchors.
class NET_EXPORT TrustStoreInMemory : public TrustStore {
@@ -31,11 +27,8 @@ class NET_EXPORT TrustStoreInMemory : public TrustStore {
void AddTrustAnchor(scoped_refptr<TrustAnchor> anchor);
// TrustStore implementation:
- void FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const override;
+ void FindTrustAnchorsForCert(const scoped_refptr<ParsedCertificate>& cert,
+ TrustAnchors* matches) const override;
private:
// Multimap from normalized subject -> TrustAnchor.
diff --git a/chromium/net/cert/internal/trust_store_nss.cc b/chromium/net/cert/internal/trust_store_nss.cc
index 1a01875ecdf..dd214dca4cf 100644
--- a/chromium/net/cert/internal/trust_store_nss.cc
+++ b/chromium/net/cert/internal/trust_store_nss.cc
@@ -7,11 +7,7 @@
#include <cert.h>
#include <certdb.h>
-#include "base/bind.h"
-#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "base/task_runner.h"
#include "crypto/nss_util.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parsed_certificate.h"
@@ -22,13 +18,14 @@
namespace net {
-namespace {
+TrustStoreNSS::TrustStoreNSS(SECTrustType trust_type)
+ : trust_type_(trust_type) {}
-// Get all certs in NSS which have a subject matching |der_name| and which are
-// marked as a trusted CA.
-void GetAnchors(const scoped_refptr<ParsedCertificate>& cert,
- SECTrustType trust_type,
- TrustAnchors* out_anchors) {
+TrustStoreNSS::~TrustStoreNSS() = default;
+
+void TrustStoreNSS::FindTrustAnchorsForCert(
+ const scoped_refptr<ParsedCertificate>& cert,
+ TrustAnchors* out_anchors) const {
crypto::EnsureNSSInit();
SECItem name;
@@ -54,7 +51,7 @@ void GetAnchors(const scoped_refptr<ParsedCertificate>& cert,
// TODO(mattm): handle explicit distrust (blacklisting)?
const int ca_trust = CERTDB_TRUSTED_CA;
- if ((SEC_GET_TRUST_FLAGS(&trust, trust_type) & ca_trust) != ca_trust)
+ if ((SEC_GET_TRUST_FLAGS(&trust, trust_type_) & ca_trust) != ca_trust)
continue;
CertErrors errors;
@@ -73,65 +70,4 @@ void GetAnchors(const scoped_refptr<ParsedCertificate>& cert,
CERT_DestroyCertList(found_certs);
}
-class GetAnchorsRequest : public TrustStore::Request {
- public:
- explicit GetAnchorsRequest(const TrustStore::TrustAnchorsCallback& callback);
- // Destruction of the Request cancels it. GetAnchors will still run, but the
- // callback will not be called since the WeakPtr will be invalidated.
- ~GetAnchorsRequest() override = default;
-
- void Start(const scoped_refptr<ParsedCertificate>& cert,
- SECTrustType trust_type,
- base::TaskRunner* task_runner);
-
- private:
- void HandleGetAnchors(std::unique_ptr<TrustAnchors> anchors);
-
- TrustStore::TrustAnchorsCallback callback_;
- base::WeakPtrFactory<GetAnchorsRequest> weak_ptr_factory_;
-};
-
-GetAnchorsRequest::GetAnchorsRequest(
- const TrustStore::TrustAnchorsCallback& callback)
- : callback_(callback), weak_ptr_factory_(this) {}
-
-void GetAnchorsRequest::Start(const scoped_refptr<ParsedCertificate>& cert,
- SECTrustType trust_type,
- base::TaskRunner* task_runner) {
- auto anchors = base::MakeUnique<TrustAnchors>();
-
- auto* anchors_ptr = anchors.get();
- task_runner->PostTaskAndReply(
- FROM_HERE, base::Bind(&GetAnchors, cert, trust_type, anchors_ptr),
- base::Bind(&GetAnchorsRequest::HandleGetAnchors,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&anchors)));
-}
-
-void GetAnchorsRequest::HandleGetAnchors(
- std::unique_ptr<TrustAnchors> anchors) {
- base::ResetAndReturn(&callback_).Run(std::move(*anchors));
- // |this| may be deleted here.
-}
-
-} // namespace
-
-TrustStoreNSS::TrustStoreNSS(SECTrustType trust_type,
- scoped_refptr<base::TaskRunner> nss_task_runner)
- : trust_type_(trust_type), nss_task_runner_(std::move(nss_task_runner)) {}
-
-TrustStoreNSS::~TrustStoreNSS() = default;
-
-void TrustStoreNSS::FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const {
- if (callback.is_null())
- return;
-
- auto req = base::MakeUnique<GetAnchorsRequest>(callback);
- req->Start(cert, trust_type_, nss_task_runner_.get());
- *out_req = std::move(req);
-}
-
} // namespace net
diff --git a/chromium/net/cert/internal/trust_store_nss.h b/chromium/net/cert/internal/trust_store_nss.h
index d153dbc5fdf..760d49953c2 100644
--- a/chromium/net/cert/internal/trust_store_nss.h
+++ b/chromium/net/cert/internal/trust_store_nss.h
@@ -11,36 +11,23 @@
#include "net/base/net_export.h"
#include "net/cert/internal/trust_store.h"
-namespace base {
-class TaskRunner;
-}
-
namespace net {
// TrustStoreNSS is an implementation of TrustStore which uses NSS to find trust
// anchors for path building.
-// TODO(mattm): also implement CertIssuerSource to return intermediates in NSS
-// DB? Or have a separate CertIssuerSourceNSS for that? (implementing both in
-// the same class could be more efficient with some caching/etc. Need to be
-// careful about caching between different pathbuilder instances though.)
class NET_EXPORT TrustStoreNSS : public TrustStore {
public:
// Creates a TrustStoreNSS which will find anchors that are trusted for
- // |trust_type|. All NSS calls will be done on |nss_task_runner|.
- TrustStoreNSS(SECTrustType trust_type,
- scoped_refptr<base::TaskRunner> nss_task_runner);
+ // |trust_type|.
+ explicit TrustStoreNSS(SECTrustType trust_type);
~TrustStoreNSS() override;
// TrustStore implementation:
- void FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const override;
+ void FindTrustAnchorsForCert(const scoped_refptr<ParsedCertificate>& cert,
+ TrustAnchors* matches) const override;
private:
SECTrustType trust_type_;
- scoped_refptr<base::TaskRunner> nss_task_runner_;
DISALLOW_COPY_AND_ASSIGN(TrustStoreNSS);
};
diff --git a/chromium/net/cert/internal/trust_store_nss_unittest.cc b/chromium/net/cert/internal/trust_store_nss_unittest.cc
index b74c5f97125..f9d1f272d74 100644
--- a/chromium/net/cert/internal/trust_store_nss_unittest.cc
+++ b/chromium/net/cert/internal/trust_store_nss_unittest.cc
@@ -7,14 +7,10 @@
#include <cert.h>
#include <certdb.h>
-#include "base/bind.h"
#include "base/memory/ptr_util.h"
-#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "crypto/scoped_test_nss_db.h"
#include "net/cert/internal/test_helpers.h"
-#include "net/cert/internal/trust_store_test_helpers.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/x509_certificate.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,10 +19,6 @@ namespace net {
namespace {
-void NotCalled(TrustAnchors anchors) {
- ADD_FAILURE() << "NotCalled was called";
-}
-
class TrustStoreNSSTest : public testing::Test {
public:
void SetUp() override {
@@ -61,8 +53,7 @@ class TrustStoreNSSTest : public testing::Test {
ASSERT_TRUE(newroot_);
ASSERT_TRUE(newrootrollover_);
- trust_store_nss_.reset(
- new TrustStoreNSS(trustSSL, base::ThreadTaskRunnerHandle::Get()));
+ trust_store_nss_.reset(new TrustStoreNSS(trustSSL));
}
std::string GetUniqueNickname() {
@@ -112,31 +103,27 @@ class TrustStoreNSSTest : public testing::Test {
}
protected:
- void ExpectTrustStoreContains(tracked_objects::Location loc,
- scoped_refptr<ParsedCertificate> cert,
- TrustAnchors expected_async_matches) {
- SCOPED_TRACE(loc.ToString());
-
- TrustAnchors sync_matches;
- TrustAnchorResultRecorder anchor_results;
- std::unique_ptr<TrustStore::Request> req;
- trust_store_nss_->FindTrustAnchorsForCert(cert, anchor_results.Callback(),
- &sync_matches, &req);
- ASSERT_TRUE(req);
- EXPECT_TRUE(sync_matches.empty());
-
- anchor_results.Run();
+ bool TrustStoreContains(scoped_refptr<ParsedCertificate> cert,
+ TrustAnchors expected_matches) {
+ TrustAnchors matches;
+ trust_store_nss_->FindTrustAnchorsForCert(cert, &matches);
+
std::vector<der::Input> der_result_matches;
- for (const auto& it : anchor_results.matches())
+ for (const auto& it : matches)
der_result_matches.push_back(it->cert()->der_cert());
std::sort(der_result_matches.begin(), der_result_matches.end());
std::vector<der::Input> der_expected_matches;
- for (const auto& it : expected_async_matches)
+ for (const auto& it : expected_matches)
der_expected_matches.push_back(it->cert()->der_cert());
std::sort(der_expected_matches.begin(), der_expected_matches.end());
+ if (der_expected_matches == der_result_matches)
+ return true;
+
+ // Print some extra information for debugging.
EXPECT_EQ(der_expected_matches, der_result_matches);
+ return false;
}
scoped_refptr<TrustAnchor> oldroot_;
@@ -154,19 +141,19 @@ class TrustStoreNSSTest : public testing::Test {
// Without adding any certs to the NSS DB, should get no anchor results for any
// of the test certs.
TEST_F(TrustStoreNSSTest, CertsNotPresent) {
- ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
+ EXPECT_TRUE(TrustStoreContains(target_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newroot_->cert(), TrustAnchors()));
}
// If certs are present in NSS DB but aren't marked as trusted, should get no
// anchor results for any of the test certs.
TEST_F(TrustStoreNSSTest, CertsPresentButNotTrusted) {
AddCertsToNSS();
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(target_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newroot_->cert(), TrustAnchors()));
}
// A self-signed CA certificate is trusted. FindTrustAnchorsForCert should
@@ -175,12 +162,12 @@ TEST_F(TrustStoreNSSTest, CertsPresentButNotTrusted) {
TEST_F(TrustStoreNSSTest, TrustedCA) {
AddCertsToNSS();
TrustCert(newroot_.get());
- ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_});
- ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_});
- ExpectTrustStoreContains(FROM_HERE, newrootrollover_, {newroot_});
- ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_});
- ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), {newroot_});
+ EXPECT_TRUE(TrustStoreContains(target_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, {newroot_}));
+ EXPECT_TRUE(TrustStoreContains(oldintermediate_, {newroot_}));
+ EXPECT_TRUE(TrustStoreContains(newrootrollover_, {newroot_}));
+ EXPECT_TRUE(TrustStoreContains(oldroot_->cert(), {newroot_}));
+ EXPECT_TRUE(TrustStoreContains(newroot_->cert(), {newroot_}));
}
// When an intermediate certificate is trusted, FindTrustAnchorsForCert should
@@ -189,14 +176,14 @@ TEST_F(TrustStoreNSSTest, TrustedCA) {
TEST_F(TrustStoreNSSTest, TrustedIntermediate) {
AddCertsToNSS();
TrustCert(newintermediate_.get());
- ExpectTrustStoreContains(
- FROM_HERE, target_,
- {TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_)});
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, oldintermediate_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newrootrollover_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newroot_->cert(), TrustAnchors());
+ EXPECT_TRUE(TrustStoreContains(
+ target_,
+ {TrustAnchor::CreateFromCertificateNoConstraints(newintermediate_)}));
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(oldintermediate_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newrootrollover_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(oldroot_->cert(), TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newroot_->cert(), TrustAnchors()));
}
// Multiple self-signed CA certificates with the same name are trusted.
@@ -206,41 +193,10 @@ TEST_F(TrustStoreNSSTest, MultipleTrustedCAWithSameSubject) {
AddCertsToNSS();
TrustCert(oldroot_.get());
TrustCert(newroot_.get());
- ExpectTrustStoreContains(FROM_HERE, target_, TrustAnchors());
- ExpectTrustStoreContains(FROM_HERE, newintermediate_, {newroot_, oldroot_});
- ExpectTrustStoreContains(FROM_HERE, oldintermediate_, {newroot_, oldroot_});
- ExpectTrustStoreContains(FROM_HERE, oldroot_->cert(), {newroot_, oldroot_});
-}
-
-// Cancel a FindTrustAnchorsForCert request before it has returned any results.
-// Callback should not be called.
-TEST_F(TrustStoreNSSTest, CancelRequest) {
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
- trust_store_nss_->FindTrustAnchorsForCert(target_, base::Bind(&NotCalled),
- &sync_matches, &req);
- ASSERT_TRUE(req);
- req.reset();
- base::RunLoop().RunUntilIdle();
-}
-
-// Cancel a FindTrustAnchorsForCert request during the callback. Should not
-// crash.
-TEST_F(TrustStoreNSSTest, CancelRequestDuringCallback) {
- AddCertsToNSS();
- TrustCert(newroot_.get());
-
- base::RunLoop run_loop;
- std::unique_ptr<TrustStore::Request> req;
- TrustAnchors sync_matches;
- trust_store_nss_->FindTrustAnchorsForCert(
- newintermediate_,
- base::Bind(&TrustStoreRequestDeleter, &req, run_loop.QuitClosure()),
- &sync_matches, &req);
- ASSERT_TRUE(req);
- run_loop.Run();
- ASSERT_FALSE(req);
- base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(TrustStoreContains(target_, TrustAnchors()));
+ EXPECT_TRUE(TrustStoreContains(newintermediate_, {newroot_, oldroot_}));
+ EXPECT_TRUE(TrustStoreContains(oldintermediate_, {newroot_, oldroot_}));
+ EXPECT_TRUE(TrustStoreContains(oldroot_->cert(), {newroot_, oldroot_}));
}
} // namespace
diff --git a/chromium/net/cert/internal/trust_store_test_helpers.cc b/chromium/net/cert/internal/trust_store_test_helpers.cc
deleted file mode 100644
index 52edc4e61e4..00000000000
--- a/chromium/net/cert/internal/trust_store_test_helpers.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/cert/internal/trust_store_test_helpers.h"
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_task_runner_handle.h"
-
-namespace net {
-
-namespace {
-
-class TrustStoreInMemoryAsyncRequest : public TrustStore::Request {
- public:
- explicit TrustStoreInMemoryAsyncRequest(
- const TrustStore::TrustAnchorsCallback& callback)
- : callback_(callback), weak_ptr_factory_(this) {}
-
- void PostTrustCallback(TrustAnchors anchors) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&TrustStoreInMemoryAsyncRequest::DoTrustCallback,
- weak_ptr_factory_.GetWeakPtr(), std::move(anchors)));
- }
-
- private:
- void DoTrustCallback(TrustAnchors anchors) {
- base::ResetAndReturn(&callback_).Run(std::move(anchors));
- // |this| may be deleted here.
- }
-
- TrustStore::TrustAnchorsCallback callback_;
- base::WeakPtrFactory<TrustStoreInMemoryAsyncRequest> weak_ptr_factory_;
-};
-
-} // namespace
-
-void TrustStoreRequestDeleter(std::unique_ptr<TrustStore::Request>* req_owner,
- const base::Closure& done_callback,
- TrustAnchors anchors) {
- req_owner->reset();
- done_callback.Run();
-}
-
-TrustAnchorResultRecorder::TrustAnchorResultRecorder() = default;
-TrustAnchorResultRecorder::~TrustAnchorResultRecorder() = default;
-
-TrustStore::TrustAnchorsCallback TrustAnchorResultRecorder::Callback() {
- return base::Bind(&TrustAnchorResultRecorder::OnGotAnchors,
- base::Unretained(this));
-}
-
-void TrustAnchorResultRecorder::OnGotAnchors(TrustAnchors anchors) {
- anchors_ = std::move(anchors);
- run_loop_.Quit();
-}
-
-TrustStoreInMemoryAsync::TrustStoreInMemoryAsync() = default;
-TrustStoreInMemoryAsync::~TrustStoreInMemoryAsync() = default;
-
-void TrustStoreInMemoryAsync::AddSyncTrustAnchor(
- scoped_refptr<TrustAnchor> anchor) {
- sync_store_.AddTrustAnchor(std::move(anchor));
-}
-
-void TrustStoreInMemoryAsync::AddAsyncTrustAnchor(
- scoped_refptr<TrustAnchor> anchor) {
- async_store_.AddTrustAnchor(std::move(anchor));
-}
-
-void TrustStoreInMemoryAsync::FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const {
- sync_store_.FindTrustAnchorsForCert(cert, TrustAnchorsCallback(),
- synchronous_matches, nullptr);
- if (!callback.is_null()) {
- TrustAnchors async_matches;
- async_store_.FindTrustAnchorsForCert(cert, TrustAnchorsCallback(),
- &async_matches, nullptr);
-
- std::unique_ptr<TrustStoreInMemoryAsyncRequest> req(
- base::MakeUnique<TrustStoreInMemoryAsyncRequest>(callback));
- req->PostTrustCallback(std::move(async_matches));
-
- *out_req = std::move(req);
- }
-}
-
-} // namespace net
diff --git a/chromium/net/cert/internal/trust_store_test_helpers.h b/chromium/net/cert/internal/trust_store_test_helpers.h
deleted file mode 100644
index 3d1d5a6594c..00000000000
--- a/chromium/net/cert/internal/trust_store_test_helpers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_INTERNAL_TRUST_STORE_TEST_HELPERS_H_
-#define NET_CERT_INTERNAL_TRUST_STORE_TEST_HELPERS_H_
-
-#include "base/callback.h"
-#include "base/run_loop.h"
-#include "net/cert/internal/trust_store.h"
-#include "net/cert/internal/trust_store_in_memory.h"
-
-namespace net {
-
-// Deletes the Request owned by |*req_owner|, then calls done_callback. Intended
-// to be passed as the TrustAnchorsCallback to FindTrustAnchorsForCert to test
-// deleting the Request during the request callback.
-void TrustStoreRequestDeleter(std::unique_ptr<TrustStore::Request>* req_owner,
- const base::Closure& done_callback,
- TrustAnchors anchors);
-
-// Helper to record async results from a FindTrustAnchorsForCert call.
-class TrustAnchorResultRecorder {
- public:
- TrustAnchorResultRecorder();
- ~TrustAnchorResultRecorder();
-
- TrustStore::TrustAnchorsCallback Callback();
-
- void Run() { run_loop_.Run(); }
-
- const TrustAnchors& matches() const { return anchors_; }
-
- private:
- void OnGotAnchors(TrustAnchors anchors);
-
- base::RunLoop run_loop_;
- TrustAnchors anchors_;
-};
-
-// In-memory TrustStore that can return results synchronously, asynchronously,
-// or both.
-class TrustStoreInMemoryAsync : public TrustStore {
- public:
- TrustStoreInMemoryAsync();
- ~TrustStoreInMemoryAsync() override;
-
- // Adds |anchor| to the set of results that will be returned synchronously.
- void AddSyncTrustAnchor(scoped_refptr<TrustAnchor> anchor);
-
- // Adds |anchor| to the set of results that will be returned asynchronously.
- void AddAsyncTrustAnchor(scoped_refptr<TrustAnchor> anchor);
-
- // TrustStore implementation:
- void FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- const TrustAnchorsCallback& callback,
- TrustAnchors* synchronous_matches,
- std::unique_ptr<Request>* out_req) const override;
-
- private:
- TrustStoreInMemory sync_store_;
- TrustStoreInMemory async_store_;
-};
-
-} // namespace net
-
-#endif // NET_CERT_INTERNAL_TRUST_STORE_TEST_HELPERS_H_
diff --git a/chromium/net/cert/internal/verify_certificate_chain.h b/chromium/net/cert/internal/verify_certificate_chain.h
index d1ea57e0575..428bd7b0214 100644
--- a/chromium/net/cert/internal/verify_certificate_chain.h
+++ b/chromium/net/cert/internal/verify_certificate_chain.h
@@ -22,7 +22,6 @@ struct GeneralizedTime;
class SignaturePolicy;
class TrustAnchor;
-class TrustStore;
// VerifyCertificateChain() verifies a certificate path (chain) based on the
// rules in RFC 5280. The caller is responsible for building the path and
diff --git a/chromium/net/cert/internal/verify_signed_data.cc b/chromium/net/cert/internal/verify_signed_data.cc
index 37fc0eb0a9e..8fd045b2a91 100644
--- a/chromium/net/cert/internal/verify_signed_data.cc
+++ b/chromium/net/cert/internal/verify_signed_data.cc
@@ -6,6 +6,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/numerics/safe_math.h"
#include "crypto/openssl_util.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/signature_algorithm.h"
diff --git a/chromium/net/cert/multi_log_ct_verifier.cc b/chromium/net/cert/multi_log_ct_verifier.cc
index 61c07b6d4e5..a372b05c8a9 100644
--- a/chromium/net/cert/multi_log_ct_verifier.cc
+++ b/chromium/net/cert/multi_log_ct_verifier.cc
@@ -81,10 +81,10 @@ void MultiLogCTVerifier::SetObserver(Observer* observer) {
observer_ = observer;
}
-int MultiLogCTVerifier::Verify(
+void MultiLogCTVerifier::Verify(
X509Certificate* cert,
- const std::string& stapled_ocsp_response,
- const std::string& sct_list_from_tls_extension,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
SignedCertificateTimestampAndStatusList* output_scts,
const NetLogWithSource& net_log) {
DCHECK(cert);
@@ -92,8 +92,6 @@ int MultiLogCTVerifier::Verify(
output_scts->clear();
- bool has_verified_scts = false;
-
std::string embedded_scts;
if (!cert->GetIntermediateCertificates().empty() &&
ct::ExtractEmbeddedSCTList(
@@ -101,13 +99,13 @@ int MultiLogCTVerifier::Verify(
&embedded_scts)) {
ct::LogEntry precert_entry;
- has_verified_scts =
- ct::GetPrecertLogEntry(cert->os_cert_handle(),
+ if (ct::GetPrecertLogEntry(cert->os_cert_handle(),
cert->GetIntermediateCertificates().front(),
- &precert_entry) &&
- VerifySCTs(embedded_scts, precert_entry,
- ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert,
- output_scts);
+ &precert_entry)) {
+ VerifySCTs(embedded_scts, precert_entry,
+ ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert,
+ output_scts);
+ }
}
std::string sct_list_from_ocsp;
@@ -121,23 +119,21 @@ int MultiLogCTVerifier::Verify(
// Log to Net Log, after extracting SCTs but before possibly failing on
// X.509 entry creation.
NetLogParametersCallback net_log_callback =
- base::Bind(&NetLogRawSignedCertificateTimestampCallback, &embedded_scts,
- &sct_list_from_ocsp, &sct_list_from_tls_extension);
+ base::Bind(&NetLogRawSignedCertificateTimestampCallback, embedded_scts,
+ sct_list_from_ocsp, sct_list_from_tls_extension);
net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED,
net_log_callback);
ct::LogEntry x509_entry;
if (ct::GetX509LogEntry(cert->os_cert_handle(), &x509_entry)) {
- has_verified_scts |=
- VerifySCTs(sct_list_from_ocsp, x509_entry,
- ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, cert,
- output_scts);
-
- has_verified_scts |=
- VerifySCTs(sct_list_from_tls_extension, x509_entry,
- ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert,
- output_scts);
+ VerifySCTs(sct_list_from_ocsp, x509_entry,
+ ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, cert,
+ output_scts);
+
+ VerifySCTs(sct_list_from_tls_extension, x509_entry,
+ ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert,
+ output_scts);
}
NetLogParametersCallback net_log_checked_callback =
@@ -147,29 +143,22 @@ int MultiLogCTVerifier::Verify(
net_log_checked_callback);
LogNumSCTsToUMA(*output_scts);
-
- if (has_verified_scts)
- return OK;
-
- return ERR_CT_NO_SCTS_VERIFIED_OK;
}
-bool MultiLogCTVerifier::VerifySCTs(
- const std::string& encoded_sct_list,
+void MultiLogCTVerifier::VerifySCTs(
+ base::StringPiece encoded_sct_list,
const ct::LogEntry& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
X509Certificate* cert,
SignedCertificateTimestampAndStatusList* output_scts) {
if (logs_.empty())
- return false;
+ return;
- base::StringPiece temp(encoded_sct_list);
std::vector<base::StringPiece> sct_list;
- if (!ct::DecodeSCTList(&temp, &sct_list))
- return false;
+ if (!ct::DecodeSCTList(encoded_sct_list, &sct_list))
+ return;
- bool verified = false;
for (std::vector<base::StringPiece>::const_iterator it = sct_list.begin();
it != sct_list.end(); ++it) {
base::StringPiece encoded_sct(*it);
@@ -178,15 +167,12 @@ bool MultiLogCTVerifier::VerifySCTs(
scoped_refptr<ct::SignedCertificateTimestamp> decoded_sct;
if (!DecodeSignedCertificateTimestamp(&encoded_sct, &decoded_sct)) {
LogSCTStatusToUMA(ct::SCT_STATUS_NONE);
- // XXX(rsleevi): Should we really just skip over bad SCTs?
continue;
}
decoded_sct->origin = origin;
- verified |= VerifySingleSCT(decoded_sct, expected_entry, cert, output_scts);
+ VerifySingleSCT(decoded_sct, expected_entry, cert, output_scts);
}
-
- return verified;
}
bool MultiLogCTVerifier::VerifySingleSCT(
diff --git a/chromium/net/cert/multi_log_ct_verifier.h b/chromium/net/cert/multi_log_ct_verifier.h
index 05c2c069264..d4cb56fc2ac 100644
--- a/chromium/net/cert/multi_log_ct_verifier.h
+++ b/chromium/net/cert/multi_log_ct_verifier.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/signed_certificate_timestamp.h"
@@ -34,19 +35,19 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers);
// CTVerifier implementation:
- int Verify(X509Certificate* cert,
- const std::string& stapled_ocsp_response,
- const std::string& sct_list_from_tls_extension,
- SignedCertificateTimestampAndStatusList* output_scts,
- const NetLogWithSource& net_log) override;
+ void Verify(X509Certificate* cert,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
+ SignedCertificateTimestampAndStatusList* output_scts,
+ const NetLogWithSource& net_log) override;
void SetObserver(Observer* observer) override;
private:
// Verify a list of SCTs from |encoded_sct_list| over |expected_entry|,
- // placing the verification results in |result|. The SCTs in the list
+ // placing the verification results in |output_scts|. The SCTs in the list
// come from |origin| (as will be indicated in the origin field of each SCT).
- bool VerifySCTs(const std::string& encoded_sct_list,
+ void VerifySCTs(base::StringPiece encoded_sct_list,
const ct::LogEntry& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
X509Certificate* cert,
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index 2efd7012a46..aea27f97195 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -111,34 +111,29 @@ class MultiLogCTVerifierTest : public ::testing::Test {
return true;
}
- bool VerifySinglePrecertificateChain(
- scoped_refptr<X509Certificate> chain,
- const NetLogWithSource& net_log,
- SignedCertificateTimestampAndStatusList* output_scts) {
- return verifier_->Verify(chain.get(), std::string(), std::string(),
- output_scts, net_log) == OK;
- }
-
+ // Returns true is |chain| is a certificate with embedded SCTs that can be
+ // successfully extracted.
bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) {
SignedCertificateTimestampAndStatusList scts;
- TestNetLog test_net_log;
- NetLogWithSource net_log =
- NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB);
-
- return verifier_->Verify(chain.get(), std::string(), std::string(), &scts,
- net_log) == OK;
+ verifier_->Verify(chain.get(), base::StringPiece(), base::StringPiece(),
+ &scts, NetLogWithSource());
+ return !scts.empty();
}
+ // Returns true if |chain| is a certificate with a single embedded SCT that
+ // can be successfully extracted and matched to the test log indicated by
+ // |kLogDescription|.
bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) {
SignedCertificateTimestampAndStatusList scts;
TestNetLog test_net_log;
- NetLogWithSource net_log =
- NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB);
- return (VerifySinglePrecertificateChain(chain, net_log, &scts) &&
- ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) &&
- ct::CheckForSCTOrigin(
- scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
- CheckForEmbeddedSCTInNetLog(test_net_log));
+ NetLogWithSource net_log = NetLogWithSource::Make(
+ &test_net_log, NetLogSourceType::SSL_CONNECT_JOB);
+ verifier_->Verify(chain.get(), base::StringPiece(), base::StringPiece(),
+ &scts, net_log);
+ return ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) &&
+ ct::CheckForSCTOrigin(
+ scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
+ CheckForEmbeddedSCTInNetLog(test_net_log);
}
// Histogram-related helper methods
@@ -212,8 +207,8 @@ TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) {
std::string sct_list = ct::GetSCTListForTesting();
SignedCertificateTimestampAndStatusList scts;
- EXPECT_EQ(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts,
- NetLogWithSource()));
+ verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
+ NetLogWithSource());
ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription));
ASSERT_TRUE(ct::CheckForSCTOrigin(
scts, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
@@ -223,8 +218,8 @@ TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) {
std::string sct_list = ct::GetSCTListWithInvalidSCT();
SignedCertificateTimestampAndStatusList scts;
- EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts,
- NetLogWithSource()));
+ verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
+ NetLogWithSource());
EXPECT_EQ(1U, scts.size());
EXPECT_EQ("", scts[0].sct->log_description);
EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, scts[0].status);
@@ -246,8 +241,8 @@ TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) {
int num_invalid_scts = GetValueFromHistogram(
"Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN);
- EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts,
- NetLogWithSource()));
+ verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
+ NetLogWithSource());
ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram());
ASSERT_EQ(num_invalid_scts + 1,
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index 061ecd973f9..8312d413933 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -24,6 +24,7 @@
#include "base/values.h"
#include "net/base/hash_value.h"
#include "net/base/net_errors.h"
+#include "net/base/trace_constants.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/crl_set.h"
@@ -189,7 +190,7 @@ void DoVerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc,
const CertificateList& additional_trust_anchors,
int* error,
CertVerifyResult* result) {
- TRACE_EVENT0("net", "DoVerifyOnWorkerThread");
+ TRACE_EVENT0(kNetTracingCategory, "DoVerifyOnWorkerThread");
*error = verify_proc->Verify(cert.get(), hostname, ocsp_response, flags,
crl_set.get(), additional_trust_anchors, result);
@@ -308,7 +309,7 @@ class CertVerifierJob {
}
void OnJobCompleted(std::unique_ptr<ResultHelper> verify_result) {
- TRACE_EVENT0("net", "CertVerifierJob::OnJobCompleted");
+ TRACE_EVENT0(kNetTracingCategory, "CertVerifierJob::OnJobCompleted");
std::unique_ptr<CertVerifierJob> keep_alive =
cert_verifier_->RemoveJob(this);
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index 6022984dac6..6b9dfadb7ae 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -25,7 +25,6 @@ namespace net {
class CertVerifierJob;
class CertVerifierRequest;
-class CertVerifierWorker;
class CertVerifyProc;
// MultiThreadedCertVerifier is a CertVerifier implementation that runs
diff --git a/chromium/net/cert/multi_threaded_cert_verifier_unittest.cc b/chromium/net/cert/multi_threaded_cert_verifier_unittest.cc
index 1c1dbe43f31..aecbb51de08 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier_unittest.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier_unittest.cc
@@ -10,7 +10,6 @@
#include "base/debug/leak_annotations.h"
#include "base/files/file_path.h"
#include "base/format_macros.h"
-#include "base/strings/stringprintf.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/cert_verify_proc.h"
diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc
index 6842643d5f6..fc2ae61557a 100644
--- a/chromium/net/cert/nss_cert_database.cc
+++ b/chromium/net/cert/nss_cert_database.cc
@@ -143,16 +143,6 @@ crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const {
return crypto::ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()));
}
-CryptoModule* NSSCertDatabase::GetPublicModule() const {
- crypto::ScopedPK11Slot slot(GetPublicSlot());
- return CryptoModule::CreateFromHandle(slot.get());
-}
-
-CryptoModule* NSSCertDatabase::GetPrivateModule() const {
- crypto::ScopedPK11Slot slot(GetPrivateSlot());
- return CryptoModule::CreateFromHandle(slot.get());
-}
-
void NSSCertDatabase::ListModules(CryptoModuleList* modules,
bool need_rw) const {
modules->clear();
@@ -176,15 +166,15 @@ void NSSCertDatabase::ListModules(CryptoModuleList* modules,
}
}
-int NSSCertDatabase::ImportFromPKCS12(CryptoModule* module,
+int NSSCertDatabase::ImportFromPKCS12(PK11SlotInfo* slot_info,
const std::string& data,
const base::string16& password,
bool is_extractable,
CertificateList* imported_certs) {
DVLOG(1) << __func__ << " "
- << PK11_GetModuleID(module->os_module_handle()) << ":"
- << PK11_GetSlotID(module->os_module_handle());
- int result = psm::nsPKCS12Blob_Import(module->os_module_handle(),
+ << PK11_GetModuleID(slot_info) << ":"
+ << PK11_GetSlotID(slot_info);
+ int result = psm::nsPKCS12Blob_Import(slot_info,
data.data(), data.size(),
password,
is_extractable,
diff --git a/chromium/net/cert/nss_cert_database.h b/chromium/net/cert/nss_cert_database.h
index 2ee859dbb71..18e14768ac0 100644
--- a/chromium/net/cert/nss_cert_database.h
+++ b/chromium/net/cert/nss_cert_database.h
@@ -145,18 +145,6 @@ class NET_EXPORT NSSCertDatabase {
// Can return NULL.
crypto::ScopedPK11Slot GetPrivateSlot() const;
- // Get the default module for public key data.
- // The returned pointer must be stored in a scoped_refptr<CryptoModule>.
- // DEPRECATED: use GetPublicSlot instead.
- // TODO(mattm): remove usage of this method and remove it.
- CryptoModule* GetPublicModule() const;
-
- // Get the default module for private key or mixed private/public key data.
- // The returned pointer must be stored in a scoped_refptr<CryptoModule>.
- // DEPRECATED: use GetPrivateSlot instead.
- // TODO(mattm): remove usage of this method and remove it.
- CryptoModule* GetPrivateModule() const;
-
// Get all modules.
// If |need_rw| is true, only writable modules will be returned.
// TODO(mattm): come up with better alternative to CryptoModuleList.
@@ -168,7 +156,7 @@ class NET_EXPORT NSSCertDatabase {
// Returns OK or a network error code such as ERR_PKCS12_IMPORT_BAD_PASSWORD
// or ERR_PKCS12_IMPORT_ERROR. |imported_certs|, if non-NULL, returns a list
// of certs that were imported.
- int ImportFromPKCS12(CryptoModule* module,
+ int ImportFromPKCS12(PK11SlotInfo* slot_info,
const std::string& data,
const base::string16& password,
bool is_extractable,
diff --git a/chromium/net/cert/nss_cert_database_chromeos.h b/chromium/net/cert/nss_cert_database_chromeos.h
index 4eb27a7fd48..fa440575fb0 100644
--- a/chromium/net/cert/nss_cert_database_chromeos.h
+++ b/chromium/net/cert/nss_cert_database_chromeos.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_NSS_CERT_DATABASE_CHROMEOS_
-#define NET_CERT_NSS_CERT_DATABASE_CHROMEOS_
+#ifndef NET_CERT_NSS_CERT_DATABASE_CHROMEOS_H_
+#define NET_CERT_NSS_CERT_DATABASE_CHROMEOS_H_
#include "base/callback.h"
#include "base/macros.h"
@@ -51,4 +51,4 @@ class NET_EXPORT NSSCertDatabaseChromeOS : public NSSCertDatabase {
} // namespace net
-#endif // NET_CERT_NSS_CERT_DATABASE_CHROMEOS_
+#endif // NET_CERT_NSS_CERT_DATABASE_CHROMEOS_H_
diff --git a/chromium/net/cert/nss_cert_database_unittest.cc b/chromium/net/cert/nss_cert_database_unittest.cc
index 9e20f886def..235ea44cc0d 100644
--- a/chromium/net/cert/nss_cert_database_unittest.cc
+++ b/chromium/net/cert/nss_cert_database_unittest.cc
@@ -68,7 +68,7 @@ class CertDatabaseNSSTest : public testing::Test {
PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */,
crypto::ScopedPK11Slot(
PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */));
- public_module_ = cert_db_->GetPublicModule();
+ public_slot_ = cert_db_->GetPublicSlot();
// Test db should be empty at start of test.
EXPECT_EQ(0U, ListCerts().size());
@@ -82,7 +82,7 @@ class CertDatabaseNSSTest : public testing::Test {
}
protected:
- CryptoModule* GetPublicModule() { return public_module_.get(); }
+ PK11SlotInfo* GetPublicSlot() { return public_slot_.get(); }
static std::string ReadTestFile(const std::string& name) {
std::string result;
@@ -128,7 +128,7 @@ class CertDatabaseNSSTest : public testing::Test {
std::unique_ptr<NSSCertDatabase> cert_db_;
const CertificateList empty_cert_list_;
crypto::ScopedTestNSSDB test_nssdb_;
- scoped_refptr<CryptoModule> public_module_;
+ crypto::ScopedPK11Slot public_slot_;
};
TEST_F(CertDatabaseNSSTest, ListCertsSync) {
@@ -160,7 +160,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) {
std::string pkcs12_data = ReadTestFile("client.p12");
EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
base::string16(),
true, // is_extractable
@@ -174,7 +174,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) {
std::string pkcs12_data = ReadTestFile("client.p12");
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
true, // is_extractable
@@ -199,7 +199,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) {
std::string pkcs12_data = ReadTestFile("client.p12");
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
true, // is_extractable
@@ -209,7 +209,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) {
// NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like
// it's ever used. This test verifies that.
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
true, // is_extractable
@@ -221,7 +221,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) {
std::string pkcs12_data = ReadTestFile("client.p12");
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
false, // is_extractable
@@ -244,7 +244,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) {
TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) {
std::string pkcs12_data = ReadTestFile("client.p12");
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
true, // is_extractable
@@ -256,7 +256,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) {
// Now import a PKCS#12 file with just a certificate but no private key.
pkcs12_data = ReadTestFile("client-nokey.p12");
EXPECT_EQ(OK,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
ASCIIToUTF16("12345"),
false, // is_extractable
@@ -276,7 +276,7 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) {
std::string pkcs12_data = "Foobarbaz";
EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE,
- cert_db_->ImportFromPKCS12(GetPublicModule(),
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
pkcs12_data,
base::string16(),
true, // is_extractable
@@ -286,6 +286,30 @@ TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) {
EXPECT_EQ(0U, ListCerts().size());
}
+TEST_F(CertDatabaseNSSTest, ImportFromPKCS12EmptyPassword) {
+ std::string pkcs12_data = ReadTestFile("client-empty-password.p12");
+
+ EXPECT_EQ(OK,
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
+ pkcs12_data,
+ base::string16(),
+ true, // is_extractable
+ NULL));
+ EXPECT_EQ(1U, ListCerts().size());
+}
+
+TEST_F(CertDatabaseNSSTest, ImportFromPKCS12NullPassword) {
+ std::string pkcs12_data = ReadTestFile("client-null-password.p12");
+
+ EXPECT_EQ(OK,
+ cert_db_->ImportFromPKCS12(GetPublicSlot(),
+ pkcs12_data,
+ base::string16(),
+ true, // is_extractable
+ NULL));
+ EXPECT_EQ(1U, ListCerts().size());
+}
+
TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) {
CertificateList certs = CreateCertificateListFromFile(
GetTestCertsDirectory(), "root_ca_cert.pem",
diff --git a/chromium/net/cert/nss_profile_filter_chromeos.cc b/chromium/net/cert/nss_profile_filter_chromeos.cc
index adb5defb6f8..71eeab20629 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos.cc
@@ -158,4 +158,3 @@ bool NSSProfileFilterChromeOS::ModuleNotAllowedForProfilePredicate::operator()(
}
} // namespace net
-
diff --git a/chromium/net/cert/ocsp_revocation_status.h b/chromium/net/cert/ocsp_revocation_status.h
index 945104f26f6..c20dd2e2c83 100644
--- a/chromium/net/cert/ocsp_revocation_status.h
+++ b/chromium/net/cert/ocsp_revocation_status.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_OCSP_REVOCATION_STATUS_H
-#define NET_CERT_OCSP_REVOCATION_STATUS_H
+#ifndef NET_CERT_OCSP_REVOCATION_STATUS_H_
+#define NET_CERT_OCSP_REVOCATION_STATUS_H_
namespace net {
@@ -15,4 +15,4 @@ enum class OCSPRevocationStatus {
} // namespace net
-#endif // NET_CERT_OCSP_REVOCATION_STATUS_H
+#endif // NET_CERT_OCSP_REVOCATION_STATUS_H_
diff --git a/chromium/net/cert/ocsp_verify_result.h b/chromium/net/cert/ocsp_verify_result.h
index a2b8494b277..3a0bd7c26e3 100644
--- a/chromium/net/cert/ocsp_verify_result.h
+++ b/chromium/net/cert/ocsp_verify_result.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_OCSP_VERIFY_RESULT_H
-#define NET_CERT_OCSP_VERIFY_RESULT_H
+#ifndef NET_CERT_OCSP_VERIFY_RESULT_H_
+#define NET_CERT_OCSP_VERIFY_RESULT_H_
#include <string>
@@ -27,6 +27,9 @@ struct NET_EXPORT OCSPVerifyResult {
bool operator==(const OCSPVerifyResult& other) const;
enum ResponseStatus {
+ // OCSP verification was not checked on this connection.
+ NOT_CHECKED,
+
// No OCSPResponse was stapled.
MISSING,
@@ -56,7 +59,7 @@ struct NET_EXPORT OCSPVerifyResult {
};
- ResponseStatus response_status = MISSING;
+ ResponseStatus response_status = NOT_CHECKED;
// The strictest CertStatus matching the certificate (REVOKED > UNKNOWN >
// GOOD). Only valid if |response_status| = PROVIDED.
@@ -65,4 +68,4 @@ struct NET_EXPORT OCSPVerifyResult {
} // namespace net
-#endif // NET_CERT_OCSP_VERIFY_RESULT_H
+#endif // NET_CERT_OCSP_VERIFY_RESULT_H_
diff --git a/chromium/net/cert/signed_tree_head.h b/chromium/net/cert/signed_tree_head.h
index 2d65192fc54..2b97f744506 100644
--- a/chromium/net/cert/signed_tree_head.h
+++ b/chromium/net/cert/signed_tree_head.h
@@ -61,4 +61,4 @@ NET_EXPORT bool operator!=(const SignedTreeHead& lhs,
} // namespace net
-#endif
+#endif // NET_CERT_SIGNED_TREE_HEAD_H_
diff --git a/chromium/net/cert/test_keychain_search_list_mac.h b/chromium/net/cert/test_keychain_search_list_mac.h
index d0faffdbf54..4ae25729c93 100644
--- a/chromium/net/cert/test_keychain_search_list_mac.h
+++ b/chromium/net/cert/test_keychain_search_list_mac.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_CERT_KEYCHAIN_SEARCH_LIST_MAC_H_
-#define NET_CERT_KEYCHAIN_SEARCH_LIST_MAC_H_
+#ifndef NET_CERT_TEST_KEYCHAIN_SEARCH_LIST_MAC_H_
+#define NET_CERT_TEST_KEYCHAIN_SEARCH_LIST_MAC_H_
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
@@ -43,4 +43,4 @@ class NET_EXPORT TestKeychainSearchList {
} // namespace net
-#endif // NET_CERT_KEYCHAIN_SEARCH_LIST_MAC_H_
+#endif // NET_CERT_TEST_KEYCHAIN_SEARCH_LIST_MAC_H_
diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h
index a77f0bf5f1d..53dd5f59106 100644
--- a/chromium/net/cert/test_root_certs.h
+++ b/chromium/net/cert/test_root_certs.h
@@ -150,7 +150,7 @@ class NET_EXPORT TestRootCerts {
class NET_EXPORT_PRIVATE ScopedTestRoot {
public:
ScopedTestRoot();
- // Creates a ScopedTestRoot that will adds|cert| to the TestRootCerts store.
+ // Creates a ScopedTestRoot that will add |cert| to the TestRootCerts store.
explicit ScopedTestRoot(X509Certificate* cert);
~ScopedTestRoot();
diff --git a/chromium/net/cert/x509_cert_types.cc b/chromium/net/cert/x509_cert_types.cc
index e2ffb3d1b05..eec184a10f4 100644
--- a/chromium/net/cert/x509_cert_types.cc
+++ b/chromium/net/cert/x509_cert_types.cc
@@ -71,13 +71,9 @@ bool ParseCertificateDate(const base::StringPiece& raw_date,
if (valid && year_length == 2)
exploded.year += exploded.year < 50 ? 2000 : 1900;
- valid &= exploded.HasValidValues();
-
if (!valid)
return false;
-
- *time = base::Time::FromUTCExploded(exploded);
- return true;
+ return base::Time::FromUTCExploded(exploded, time);
}
} // namespace net
diff --git a/chromium/net/cert/x509_cert_types.h b/chromium/net/cert/x509_cert_types.h
index d2a55fe4b54..acb5b4fa3d5 100644
--- a/chromium/net/cert/x509_cert_types.h
+++ b/chromium/net/cert/x509_cert_types.h
@@ -30,8 +30,6 @@ class Time;
namespace net {
-class X509Certificate;
-
// CertPrincipal represents the issuer or subject field of an X.509 certificate.
struct NET_EXPORT CertPrincipal {
CertPrincipal();
diff --git a/chromium/net/cert/x509_cert_types_unittest.cc b/chromium/net/cert/x509_cert_types_unittest.cc
index 50275f0eb01..cc9d88fbe9f 100644
--- a/chromium/net/cert/x509_cert_types_unittest.cc
+++ b/chromium/net/cert/x509_cert_types_unittest.cc
@@ -182,18 +182,21 @@ const struct CertDateTestData {
"20120101123000Z",
true,
{2012, 1, 0, 1, 12, 30, 0}},
+ // test 31st of April
+ {CERT_DATE_FORMAT_GENERALIZED_TIME, "20160431121000Z", false, {0}},
+ // test 31st of February
+ {CERT_DATE_FORMAT_GENERALIZED_TIME, "20160231121000Z", false, {0}},
};
// GTest pretty printer.
void PrintTo(const CertDateTestData& data, std::ostream* os) {
+ base::Time out_time;
+ bool result = base::Time::FromUTCExploded(data.expected_result, &out_time);
*os << " format: " << data.format
<< "; date string: " << base::StringPiece(data.date_string)
- << "; valid: " << data.is_valid
- << "; expected date: "
- << (data.is_valid ?
- base::Time::FromUTCExploded(data.expected_result)
- .ToInternalValue() :
- 0U);
+ << "; valid: " << data.is_valid << "; expected date: "
+ << (data.is_valid ? out_time.ToInternalValue() : 0U)
+ << "; FromUTCExploded conversion result: " << result;
}
class X509CertTypesDateTest : public testing::TestWithParam<CertDateTestData> {
@@ -202,24 +205,30 @@ class X509CertTypesDateTest : public testing::TestWithParam<CertDateTestData> {
void SetUp() override { test_data_ = GetParam(); }
protected:
- CertDateTestData test_data_;
+ CertDateTestData test_data_;
};
TEST_P(X509CertTypesDateTest, Parse) {
base::Time parsed_date;
bool parsed = ParseCertificateDate(
test_data_.date_string, test_data_.format, &parsed_date);
- EXPECT_EQ(test_data_.is_valid, parsed);
+ if (!parsed && test_data_.is_valid &&
+ test_data_.expected_result.year >= 2038 && sizeof(time_t) == 4) {
+ // Some of the valid test data will fail on 32-bit POSIX systems
+ return;
+ }
+
if (!test_data_.is_valid)
return;
- // Convert the expected value to a base::Time(). This ensures that systems
+ // Convert the expected value to a base::Time(). This ensures that
// systems that only support 32-bit times will pass the tests, by ensuring at
- // least that the times have the same truncating behaviour.
+ // least that the times have the same truncating behavior.
// Note: Compared as internal values so that mismatches can be cleanly
- // printed by GTest (eg: without PrintTo overrides).
- EXPECT_EQ(base::Time::FromUTCExploded(test_data_.expected_result)
- .ToInternalValue(),
- parsed_date.ToInternalValue());
+ // printed by GTest (e.g.: without PrintTo overrides).
+ base::Time out_time;
+ EXPECT_TRUE(
+ base::Time::FromUTCExploded(test_data_.expected_result, &out_time));
+ EXPECT_EQ(out_time.ToInternalValue(), parsed_date.ToInternalValue());
}
INSTANTIATE_TEST_CASE_P(,
X509CertTypesDateTest,
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index 7f23e7bf1d4..0d6fe95f134 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -25,6 +25,7 @@
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
#include "crypto/secure_hash.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/url_util.h"
@@ -235,6 +236,8 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromHandle(
// static
scoped_refptr<X509Certificate> X509Certificate::CreateFromDERCertChain(
const std::vector<base::StringPiece>& der_certs) {
+ TRACE_EVENT0("io", "X509Certificate::CreateFromDERCertChain");
+
// TODO(cbentzel): Remove ScopedTracker below once crbug.com/424386 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
diff --git a/chromium/net/cert/x509_certificate.h b/chromium/net/cert/x509_certificate.h
index dde8ae0ad4e..0aff1be6100 100644
--- a/chromium/net/cert/x509_certificate.h
+++ b/chromium/net/cert/x509_certificate.h
@@ -42,8 +42,7 @@ class PickleIterator;
namespace net {
-class CRLSet;
-class CertVerifyResult;
+class X509Certificate;
typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
@@ -81,6 +80,14 @@ class NET_EXPORT X509Certificate
kPublicKeyTypeECDH
};
+ enum SignatureHashAlgorithm {
+ kSignatureHashAlgorithmMd2,
+ kSignatureHashAlgorithmMd4,
+ kSignatureHashAlgorithmMd5,
+ kSignatureHashAlgorithmSha1,
+ kSignatureHashAlgorithmOther,
+ };
+
enum Format {
// The data contains a single DER-encoded certificate, or a PEM-encoded
// DER certificate with the PEM encoding block name of "CERTIFICATE".
@@ -146,20 +153,8 @@ class NET_EXPORT X509Certificate
size_t length);
#if defined(USE_NSS_CERTS)
- // Create an X509Certificate from the DER-encoded representation.
- // |nickname| can be NULL if an auto-generated nickname is desired.
- // Returns NULL on failure.
- //
- // This function differs from CreateFromBytes in that it takes a
- // nickname that will be used when the certificate is imported into PKCS#11.
- static scoped_refptr<X509Certificate> CreateFromBytesWithNickname(
- const char* data,
- size_t length,
- const char* nickname);
-
// The default nickname of the certificate, based on the certificate type
- // passed in. If this object was created using CreateFromBytesWithNickname,
- // then this will return the nickname specified upon creation.
+ // passed in.
std::string GetDefaultNickname(CertType type) const;
#endif
@@ -328,6 +323,15 @@ class NET_EXPORT X509Certificate
size_t* size_bits,
PublicKeyType* type);
+ // Returns the digest algorithm used in |cert_handle|'s signature.
+ // If the digest algorithm cannot be determined, or if it is not one
+ // of the explicitly enumerated values, kSignatureHashAlgorithmOther
+ // will be returned.
+ // NOTE: No validation of the signature is performed, and thus invalid
+ // signatures may result in seemingly meaningful values.
+ static SignatureHashAlgorithm GetSignatureHashAlgorithm(
+ OSCertHandle cert_handle);
+
// Returns the OSCertHandle of this object. Because of caching, this may
// differ from the OSCertHandle originally supplied during initialization.
// Note: On Windows, CryptoAPI may return unexpected results if this handle
@@ -462,14 +466,6 @@ class NET_EXPORT X509Certificate
// that may be needed for chain building.
OSCertHandles intermediate_ca_certs_;
-#if defined(USE_NSS_CERTS)
- // This stores any default nickname that has been set on the certificate
- // at creation time with CreateFromBytesWithNickname.
- // If this is empty, then GetDefaultNickname will return a generated name
- // based on the type of the certificate.
- std::string default_nickname_;
-#endif
-
DISALLOW_COPY_AND_ASSIGN(X509Certificate);
};
diff --git a/chromium/net/cert/x509_certificate_ios.cc b/chromium/net/cert/x509_certificate_ios.cc
index 737970768fb..18ce828df72 100644
--- a/chromium/net/cert/x509_certificate_ios.cc
+++ b/chromium/net/cert/x509_certificate_ios.cc
@@ -358,6 +358,29 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
*size_bits = EVP_PKEY_bits(key);
}
+// static
+X509Certificate::SignatureHashAlgorithm
+X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
+ bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(cert_handle);
+ if (!cert)
+ return kSignatureHashAlgorithmOther;
+
+ // TODO(eroman): This duplicates code with x509_certificate_openssl.cc
+ int sig_alg = OBJ_obj2nid(cert->sig_alg->algorithm);
+ if (sig_alg == NID_md2WithRSAEncryption)
+ return kSignatureHashAlgorithmMd2;
+ if (sig_alg == NID_md4WithRSAEncryption)
+ return kSignatureHashAlgorithmMd4;
+ if (sig_alg == NID_md5WithRSAEncryption || sig_alg == NID_md5WithRSA)
+ return kSignatureHashAlgorithmMd5;
+ if (sig_alg == NID_sha1WithRSAEncryption || sig_alg == NID_dsaWithSHA ||
+ sig_alg == NID_dsaWithSHA1 || sig_alg == NID_dsaWithSHA1_2 ||
+ sig_alg == NID_sha1WithRSA || sig_alg == NID_ecdsa_with_SHA1) {
+ return kSignatureHashAlgorithmSha1;
+ }
+ return kSignatureHashAlgorithmOther;
+}
+
bool X509Certificate::SupportsSSLClientAuth() const {
return false;
}
diff --git a/chromium/net/cert/x509_certificate_known_roots_win.h b/chromium/net/cert/x509_certificate_known_roots_win.h
index eea3a6875ff..43ce812de9e 100644
--- a/chromium/net/cert/x509_certificate_known_roots_win.h
+++ b/chromium/net/cert/x509_certificate_known_roots_win.h
@@ -16,7 +16,7 @@
//
// Note that these *are not* trust anchors for Chromium. They are only used to
// distinguish `real' root CAs from roots that were user-installed.
-static uint8_t kKnownRootCertSHA256Hashes[][32] = {
+static const uint8_t kKnownRootCertSHA256Hashes[][32] = {
// C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate
// Authority
{0x00, 0x16, 0x86, 0xCD, 0x18, 0x1F, 0x83, 0xA1, 0xB1, 0x21, 0x7D, 0x30,
diff --git a/chromium/net/cert/x509_certificate_mac.cc b/chromium/net/cert/x509_certificate_mac.cc
index 8e6ecf9fb42..6283d3658d2 100644
--- a/chromium/net/cert/x509_certificate_mac.cc
+++ b/chromium/net/cert/x509_certificate_mac.cc
@@ -518,6 +518,43 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
}
}
+X509Certificate::SignatureHashAlgorithm
+X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
+ x509_util::CSSMCachedCertificate cached_cert;
+ OSStatus status = cached_cert.Init(cert_handle);
+ if (status)
+ return kSignatureHashAlgorithmOther;
+
+ x509_util::CSSMFieldValue signature_field;
+ status =
+ cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field);
+ if (status || !signature_field.field())
+ return kSignatureHashAlgorithmOther;
+
+ const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm =
+ signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>();
+ if (!sig_algorithm)
+ return kSignatureHashAlgorithmOther;
+
+ const CSSM_OID* alg_oid = &sig_algorithm->algorithm;
+ if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA))
+ return kSignatureHashAlgorithmMd2;
+ if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA))
+ return kSignatureHashAlgorithmMd4;
+ if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA))
+ return kSignatureHashAlgorithmMd5;
+ if (CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) ||
+ CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
+ CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
+ CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
+ CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
+ CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
+ return kSignatureHashAlgorithmSha1;
+ }
+
+ return kSignatureHashAlgorithmOther;
+}
+
// static
bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
x509_util::CSSMCachedCertificate cached_cert;
diff --git a/chromium/net/cert/x509_certificate_net_log_param.h b/chromium/net/cert/x509_certificate_net_log_param.h
index 01b46f95b15..a6721ab4782 100644
--- a/chromium/net/cert/x509_certificate_net_log_param.h
+++ b/chromium/net/cert/x509_certificate_net_log_param.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_BASE_X509_CERT_NET_LOG_PARAM_H_
-#define NET_BASE_X509_CERT_NET_LOG_PARAM_H_
+#ifndef NET_CERT_X509_CERTIFICATE_NET_LOG_PARAM_H_
+#define NET_CERT_X509_CERTIFICATE_NET_LOG_PARAM_H_
#include <memory>
@@ -23,4 +23,4 @@ std::unique_ptr<base::Value> NetLogX509CertificateCallback(
} // namespace net
-#endif // NET_BASE_X509_CERT_NET_LOG_PARAM_H_
+#endif // NET_CERT_X509_CERTIFICATE_NET_LOG_PARAM_H_
diff --git a/chromium/net/cert/x509_certificate_nss.cc b/chromium/net/cert/x509_certificate_nss.cc
index abb6f20462e..2f2f9772662 100644
--- a/chromium/net/cert/x509_certificate_nss.cc
+++ b/chromium/net/cert/x509_certificate_nss.cc
@@ -36,31 +36,7 @@ void X509Certificate::Initialize() {
serial_number_ = x509_util::ParseSerialNumber(cert_handle_);
}
-// static
-scoped_refptr<X509Certificate> X509Certificate::CreateFromBytesWithNickname(
- const char* data,
- size_t length,
- const char* nickname) {
- OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data,
- length,
- nickname);
- if (!cert_handle)
- return NULL;
-
- scoped_refptr<X509Certificate> cert =
- CreateFromHandle(cert_handle, OSCertHandles());
- FreeOSCertHandle(cert_handle);
-
- if (nickname)
- cert->default_nickname_ = nickname;
-
- return cert;
-}
-
std::string X509Certificate::GetDefaultNickname(CertType type) const {
- if (!default_nickname_.empty())
- return default_nickname_;
-
std::string result;
if (type == USER_CERT && cert_handle_->slot) {
// Find the private key for this certificate and see if it has a
@@ -263,6 +239,28 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
}
// static
+X509Certificate::SignatureHashAlgorithm
+X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
+ SECAlgorithmID& signature = cert_handle->signature;
+ SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm);
+ switch (oid_tag) {
+ case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+ return kSignatureHashAlgorithmMd5;
+ case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
+ return kSignatureHashAlgorithmMd2;
+ case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
+ return kSignatureHashAlgorithmMd4;
+ case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+ case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
+ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+ case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
+ return kSignatureHashAlgorithmSha1;
+ default:
+ return kSignatureHashAlgorithmOther;
+ }
+}
+
+// static
bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert_handle));
if (!public_key.get())
diff --git a/chromium/net/cert/x509_certificate_openssl.cc b/chromium/net/cert/x509_certificate_openssl.cc
index 30d9598a50a..730eef0d6ac 100644
--- a/chromium/net/cert/x509_certificate_openssl.cc
+++ b/chromium/net/cert/x509_certificate_openssl.cc
@@ -377,6 +377,24 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
}
}
+// static
+X509Certificate::SignatureHashAlgorithm
+X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
+ int sig_alg = OBJ_obj2nid(cert_handle->sig_alg->algorithm);
+ if (sig_alg == NID_md2WithRSAEncryption)
+ return kSignatureHashAlgorithmMd2;
+ if (sig_alg == NID_md4WithRSAEncryption)
+ return kSignatureHashAlgorithmMd4;
+ if (sig_alg == NID_md5WithRSAEncryption || sig_alg == NID_md5WithRSA)
+ return kSignatureHashAlgorithmMd5;
+ if (sig_alg == NID_sha1WithRSAEncryption || sig_alg == NID_dsaWithSHA ||
+ sig_alg == NID_dsaWithSHA1 || sig_alg == NID_dsaWithSHA1_2 ||
+ sig_alg == NID_sha1WithRSA || sig_alg == NID_ecdsa_with_SHA1) {
+ return kSignatureHashAlgorithmSha1;
+ }
+ return kSignatureHashAlgorithmOther;
+}
+
bool X509Certificate::IsIssuedByEncoded(
const std::vector<std::string>& valid_issuers) {
if (valid_issuers.empty())
diff --git a/chromium/net/cert/x509_certificate_win.cc b/chromium/net/cert/x509_certificate_win.cc
index c67011e06b9..ef3d040e5df 100644
--- a/chromium/net/cert/x509_certificate_win.cc
+++ b/chromium/net/cert/x509_certificate_win.cc
@@ -421,6 +421,33 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
}
}
+X509Certificate::SignatureHashAlgorithm
+X509Certificate::GetSignatureHashAlgorithm(OSCertHandle cert_handle) {
+ const char* algorithm = cert_handle->pCertInfo->SignatureAlgorithm.pszObjId;
+ if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) {
+ // md5WithRSAEncryption: 1.2.840.113549.1.1.4
+ return kSignatureHashAlgorithmMd5;
+ }
+ if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) {
+ // md2WithRSAEncryption: 1.2.840.113549.1.1.2
+ return kSignatureHashAlgorithmMd2;
+ }
+ if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) {
+ // md4WithRSAEncryption: 1.2.840.113549.1.1.3
+ return kSignatureHashAlgorithmMd4;
+ }
+ if (strcmp(algorithm, szOID_RSA_SHA1RSA) == 0 ||
+ strcmp(algorithm, szOID_X957_SHA1DSA) == 0 ||
+ strcmp(algorithm, szOID_ECDSA_SHA1) == 0) {
+ // sha1WithRSAEncryption: 1.2.840.113549.1.1.5
+ // id-dsa-with-sha1: 1.2.840.10040.4.3
+ // ecdsa-with-SHA1: 1.2.840.10045.4.1
+ return kSignatureHashAlgorithmSha1;
+ }
+
+ return kSignatureHashAlgorithmOther;
+}
+
bool X509Certificate::IsIssuedByEncoded(
const std::vector<std::string>& valid_issuers) {
diff --git a/chromium/net/cert/x509_util.cc b/chromium/net/cert/x509_util.cc
index 35913c19d2b..a5d583d0eb1 100644
--- a/chromium/net/cert/x509_util.cc
+++ b/chromium/net/cert/x509_util.cc
@@ -112,7 +112,7 @@ bool CreateKeyAndSelfSignedCert(const std::string& subject,
not_valid_after,
der_cert);
if (success)
- key->reset(new_key.release());
+ *key = std::move(new_key);
return success;
}
diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h
index 07f4e21b1d3..e29219d3eca 100644
--- a/chromium/net/cert/x509_util.h
+++ b/chromium/net/cert/x509_util.h
@@ -17,7 +17,6 @@
#include "net/base/net_export.h"
namespace crypto {
-class ECPrivateKey;
class RSAPrivateKey;
}