summaryrefslogtreecommitdiff
path: root/chromium/net/cert
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-08 10:28:10 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-20 13:40:30 +0000
commite733310db58160074f574c429d48f8308c0afe17 (patch)
treef8aef4b7e62a69928dbcf880620eece20f98c6df /chromium/net/cert
parent2f583e4aec1ae3a86fa047829c96b310dc12ecdf (diff)
downloadqtwebengine-chromium-e733310db58160074f574c429d48f8308c0afe17.tar.gz
BASELINE: Update Chromium to 56.0.2924.122
Change-Id: I4e04de8f47e47e501c46ed934c76a431c6337ced Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/cert')
-rw-r--r--chromium/net/cert/asn1_util.cc147
-rw-r--r--chromium/net/cert/asn1_util.h7
-rw-r--r--chromium/net/cert/caching_cert_verifier.cc2
-rw-r--r--chromium/net/cert/caching_cert_verifier.h2
-rw-r--r--chromium/net/cert/cert_database.cc15
-rw-r--r--chromium/net/cert/cert_database.h29
-rw-r--r--chromium/net/cert/cert_database_android.cc28
-rw-r--r--chromium/net/cert/cert_database_ios.cc12
-rw-r--r--chromium/net/cert/cert_database_mac.cc43
-rw-r--r--chromium/net/cert/cert_database_nss.cc49
-rw-r--r--chromium/net/cert/cert_database_openssl.cc41
-rw-r--r--chromium/net/cert/cert_database_win.cc43
-rw-r--r--chromium/net/cert/cert_verifier.cc3
-rw-r--r--chromium/net/cert/cert_verify_proc.cc89
-rw-r--r--chromium/net/cert/cert_verify_proc.h7
-rw-r--r--chromium/net/cert/cert_verify_proc_android.cc3
-rw-r--r--chromium/net/cert/cert_verify_proc_ios.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc_openssl.cc17
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc316
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist.cc368
-rw-r--r--chromium/net/cert/cert_verify_proc_whitelist_unittest.cc19
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc113
-rw-r--r--chromium/net/cert/ct_log_verifier.cc63
-rw-r--r--chromium/net/cert/ct_log_verifier.h13
-rw-r--r--chromium/net/cert/ct_log_verifier_unittest.cc743
-rw-r--r--chromium/net/cert/ct_objects_extractor.cc33
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc5
-rw-r--r--chromium/net/cert/ct_signed_certificate_timestamp_log_param.h8
-rw-r--r--chromium/net/cert/ct_verifier.h8
-rw-r--r--chromium/net/cert/internal/signature_policy.cc3
-rw-r--r--chromium/net/cert/internal/verify_name_match.cc12
-rw-r--r--chromium/net/cert/internal/verify_name_match_fuzzer.cc8
-rw-r--r--chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc8
-rw-r--r--chromium/net/cert/internal/verify_signed_data.cc33
-rw-r--r--chromium/net/cert/internal/verify_signed_data_unittest.cc3
-rw-r--r--chromium/net/cert/jwk_serializer.cc24
-rw-r--r--chromium/net/cert/merkle_audit_proof.cc3
-rw-r--r--chromium/net/cert/merkle_audit_proof.h8
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.cc58
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.h6
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc54
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc27
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h12
-rw-r--r--chromium/net/cert/nss_cert_database.cc51
-rw-r--r--chromium/net/cert/nss_cert_database.h15
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos_unittest.cc13
-rw-r--r--chromium/net/cert/sth_distributor.cc3
-rw-r--r--chromium/net/cert/test_root_certs.h36
-rw-r--r--chromium/net/cert/test_root_certs_nss.cc40
-rw-r--r--chromium/net/cert/test_root_certs_openssl.cc5
-rw-r--r--chromium/net/cert/x509_certificate.cc2
-rw-r--r--chromium/net/cert/x509_certificate_ios.cc35
-rw-r--r--chromium/net/cert/x509_certificate_openssl.cc38
-rw-r--r--chromium/net/cert/x509_certificate_unittest.cc26
-rw-r--r--chromium/net/cert/x509_certificate_win.cc3
-rw-r--r--chromium/net/cert/x509_util_openssl.cc70
-rw-r--r--chromium/net/cert/x509_util_openssl.h5
57 files changed, 1545 insertions, 1284 deletions
diff --git a/chromium/net/cert/asn1_util.cc b/chromium/net/cert/asn1_util.cc
index 6b0b71d9024..97e12dfc45a 100644
--- a/chromium/net/cert/asn1_util.cc
+++ b/chromium/net/cert/asn1_util.cc
@@ -70,6 +70,75 @@ bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
return true;
}
+// Parses input |in| which should point to the beginning of a
+// Certificate. If parsing fails, this function returns false, with
+// |*extensions_present| and |*extensions_parser| left in an undefined
+// state. If parsing succeeds and extensions are present, this function
+// sets |*extensions_present| to true and sets |*extensions_parser|
+// ready to parse the Extensions. If extensions are not present, it sets
+// |*extensions_present| to false and |*extensions_parser| is left in an
+// undefined state.
+bool SeekToExtensions(der::Input in,
+ bool* extensions_present,
+ der::Parser* extensions_parser) {
+ bool present;
+ der::Parser tbs_cert_parser;
+ if (!SeekToSPKI(in, &tbs_cert_parser))
+ return false;
+
+ // From RFC 5280, section 4.1
+ // TBSCertificate ::= SEQUENCE {
+ // ...
+ // subjectPublicKeyInfo SubjectPublicKeyInfo,
+ // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
+ // extensions [3] EXPLICIT Extensions OPTIONAL }
+
+ // subjectPublicKeyInfo
+ if (!tbs_cert_parser.SkipTag(der::kSequence))
+ return false;
+ // issuerUniqueID
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 1, &present)) {
+ return false;
+ }
+ // subjectUniqueID
+ if (!tbs_cert_parser.SkipOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 2, &present)) {
+ return false;
+ }
+
+ der::Input extensions;
+ if (!tbs_cert_parser.ReadOptionalTag(
+ der::kTagConstructed | der::kTagContextSpecific | 3, &extensions,
+ &present)) {
+ return false;
+ }
+
+ if (!present) {
+ *extensions_present = false;
+ return true;
+ }
+
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING }
+
+ // |extensions| was EXPLICITly tagged, so we still need to remove the
+ // ASN.1 SEQUENCE header.
+ der::Parser explicit_extensions_parser(extensions);
+ if (!explicit_extensions_parser.ReadSequence(extensions_parser))
+ return false;
+
+ if (explicit_extensions_parser.HasMore())
+ return false;
+
+ *extensions_present = true;
+ return true;
+}
+
} // namespace
bool ExtractSPKIFromDERCert(base::StringPiece cert,
@@ -118,60 +187,14 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
std::vector<base::StringPiece>* urls_out) {
urls_out->clear();
std::vector<base::StringPiece> tmp_urls_out;
-
bool present;
- der::Parser tbs_cert_parser;
- if (!SeekToSPKI(der::Input(cert), &tbs_cert_parser))
- return false;
-
- // From RFC 5280, section 4.1
- // TBSCertificate ::= SEQUENCE {
- // ...
- // subjectPublicKeyInfo SubjectPublicKeyInfo,
- // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- // extensions [3] EXPLICIT Extensions OPTIONAL }
-
- // subjectPublicKeyInfo
- if (!tbs_cert_parser.SkipTag(der::kSequence))
- return false;
- // issuerUniqueID
- if (!tbs_cert_parser.SkipOptionalTag(
- der::kTagConstructed | der::kTagContextSpecific | 1, &present)) {
- return false;
- }
- // subjectUniqueID
- if (!tbs_cert_parser.SkipOptionalTag(
- der::kTagConstructed | der::kTagContextSpecific | 2, &present)) {
- return false;
- }
-
- der::Input extensions;
- if (!tbs_cert_parser.ReadOptionalTag(
- der::kTagConstructed | der::kTagContextSpecific | 3, &extensions,
- &present)) {
+ der::Parser extensions_parser;
+ if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser))
return false;
- }
if (!present)
return true;
- // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
- // Extension ::= SEQUENCE {
- // extnID OBJECT IDENTIFIER,
- // critical BOOLEAN DEFAULT FALSE,
- // extnValue OCTET STRING }
-
- // |extensions| was EXPLICITly tagged, so we still need to remove the
- // ASN.1 SEQUENCE header.
- der::Parser explicit_extensions_parser(extensions);
- der::Parser extensions_parser;
- if (!explicit_extensions_parser.ReadSequence(&extensions_parser))
- return false;
-
- if (explicit_extensions_parser.HasMore())
- return false;
-
while (extensions_parser.HasMore()) {
der::Parser extension_parser;
if (!extensions_parser.ReadSequence(&extension_parser))
@@ -289,6 +312,34 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert,
return true;
}
+bool HasTLSFeatureExtension(base::StringPiece cert) {
+ bool present;
+ der::Parser extensions_parser;
+ if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser))
+ return false;
+ if (!present)
+ return false;
+
+ while (extensions_parser.HasMore()) {
+ der::Parser extension_parser;
+ if (!extensions_parser.ReadSequence(&extension_parser))
+ return false;
+
+ der::Input oid;
+ if (!extension_parser.ReadTag(der::kOid, &oid))
+ return false;
+
+ // kTLSFeatureExtensionOID is the DER encoding of the OID for the
+ // X.509 TLS Feature Extension.
+ static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x01, 0x18};
+ if (oid == der::Input(kTLSFeatureExtensionOID))
+ return true;
+ }
+
+ return false;
+}
+
} // namespace asn1
} // namespace net
diff --git a/chromium/net/cert/asn1_util.h b/chromium/net/cert/asn1_util.h
index 23bc2d2cf90..fb64bfbb58b 100644
--- a/chromium/net/cert/asn1_util.h
+++ b/chromium/net/cert/asn1_util.h
@@ -43,6 +43,13 @@ NET_EXPORT_PRIVATE bool ExtractCRLURLsFromDERCert(
base::StringPiece cert,
std::vector<base::StringPiece>* urls_out);
+// HasTLSFeatureExtension parses the DER encoded certificate in |cert|
+// and extracts the TLS feature extension
+// (https://tools.ietf.org/html/rfc7633) if present. Returns true if the
+// TLS feature extension was present, and false if the extension was not
+// present or if there was a parsing failure.
+NET_EXPORT_PRIVATE bool HasTLSFeatureExtension(base::StringPiece cert);
+
} // namespace asn1
} // namespace net
diff --git a/chromium/net/cert/caching_cert_verifier.cc b/chromium/net/cert/caching_cert_verifier.cc
index 43515f8d4b5..342adf80ea2 100644
--- a/chromium/net/cert/caching_cert_verifier.cc
+++ b/chromium/net/cert/caching_cert_verifier.cc
@@ -198,7 +198,7 @@ void CachingCertVerifier::VisitEntries(CacheVisitor* visitor) const {
}
}
-void CachingCertVerifier::OnCACertChanged(const X509Certificate* cert) {
+void CachingCertVerifier::OnCertDBChanged(const X509Certificate* cert) {
ClearCache();
}
diff --git a/chromium/net/cert/caching_cert_verifier.h b/chromium/net/cert/caching_cert_verifier.h
index e10d6db0ed2..57a61428d47 100644
--- a/chromium/net/cert/caching_cert_verifier.h
+++ b/chromium/net/cert/caching_cert_verifier.h
@@ -144,7 +144,7 @@ class NET_EXPORT CachingCertVerifier : public CertVerifier,
int error);
// CertDatabase::Observer methods:
- void OnCACertChanged(const X509Certificate* cert) override;
+ void OnCertDBChanged(const X509Certificate* cert) override;
// For unit testing.
void ClearCache();
diff --git a/chromium/net/cert/cert_database.cc b/chromium/net/cert/cert_database.cc
index 3d423b0c4f4..d2ef9ffdf4a 100644
--- a/chromium/net/cert/cert_database.cc
+++ b/chromium/net/cert/cert_database.cc
@@ -25,19 +25,8 @@ void CertDatabase::RemoveObserver(Observer* observer) {
observer_list_->RemoveObserver(observer);
}
-void CertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCertAdded,
- base::RetainedRef(cert));
-}
-
-void CertDatabase::NotifyObserversOfCertRemoved(const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCertRemoved,
- base::RetainedRef(cert));
-}
-
-void CertDatabase::NotifyObserversOfCACertChanged(
- const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCACertChanged,
+void CertDatabase::NotifyObserversCertDBChanged(const X509Certificate* cert) {
+ observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged,
base::RetainedRef(cert));
}
diff --git a/chromium/net/cert/cert_database.h b/chromium/net/cert/cert_database.h
index 873a7c7c9cb..819716a9596 100644
--- a/chromium/net/cert/cert_database.h
+++ b/chromium/net/cert/cert_database.h
@@ -39,17 +39,11 @@ class NET_EXPORT CertDatabase {
public:
virtual ~Observer() {}
- // Will be called when a new certificate is added. If the imported cert can
- // be determined, |cert| will be non-NULL, but if not, or if multiple
- // certificates were imported, |cert| may be NULL.
- virtual void OnCertAdded(const X509Certificate* cert) {}
-
- // Will be called when a certificate is removed.
- virtual void OnCertRemoved(const X509Certificate* cert) {}
-
- // Will be called when a CA certificate was added, removed, or its trust
- // changed. This can also mean that a client certificate's trust changed.
- virtual void OnCACertChanged(const X509Certificate* cert) {}
+ // Called whenever the Cert Database is known to have changed.
+ // Typically, this will be in response to a CA certificate being added,
+ // removed, or its trust changed, but may also signal on client
+ // certificate events when they can be reliably detected.
+ virtual void OnCertDBChanged(const X509Certificate* cert) {}
protected:
Observer() {}
@@ -61,15 +55,6 @@ class NET_EXPORT CertDatabase {
// Returns the CertDatabase singleton.
static CertDatabase* GetInstance();
- // Check whether this is a valid user cert that we have the private key for.
- // Returns OK or a network error code such as ERR_CERT_CONTAINS_ERRORS.
- int CheckUserCert(X509Certificate* cert);
-
- // Store user (client) certificate. Assumes CheckUserCert has already passed.
- // Returns OK, or ERR_ADD_USER_CERT_FAILED if there was a problem saving to
- // the platform cert database, or possibly other network error codes.
- int AddUserCert(X509Certificate* cert);
-
// Registers |observer| to receive notifications of certificate changes. The
// thread on which this is called is the thread on which |observer| will be
// called back with notifications.
@@ -101,9 +86,7 @@ class NET_EXPORT CertDatabase {
// Synthetically injects notifications to all observers. In general, this
// should only be called by the creator of the CertDatabase. Used to inject
// notifcations from other DB interfaces.
- void NotifyObserversOfCertAdded(const X509Certificate* cert);
- void NotifyObserversOfCertRemoved(const X509Certificate* cert);
- void NotifyObserversOfCACertChanged(const X509Certificate* cert);
+ void NotifyObserversCertDBChanged(const X509Certificate* cert);
private:
friend struct base::DefaultSingletonTraits<CertDatabase>;
diff --git a/chromium/net/cert/cert_database_android.cc b/chromium/net/cert/cert_database_android.cc
index 89a1a44a54b..b3a75b09ac3 100644
--- a/chromium/net/cert/cert_database_android.cc
+++ b/chromium/net/cert/cert_database_android.cc
@@ -17,38 +17,18 @@ CertDatabase::CertDatabase()
CertDatabase::~CertDatabase() {}
-int CertDatabase::CheckUserCert(X509Certificate* cert) {
- // NOTE: This method shall never be called on Android.
- //
- // On other platforms, it is only used by the SSLAddCertHandler class
- // to handle veritication and installation of downloaded certificates.
- //
- // On Android, the certificate data is passed directly to the system's
- // CertInstaller activity, which handles verification, naming,
- // installation and UI (for success/failure).
- NOTIMPLEMENTED();
- return ERR_NOT_IMPLEMENTED;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert) {
- // This method is only used by the content SSLAddCertHandler which is
- // never used on Android.
- NOTIMPLEMENTED();
- return ERR_NOT_IMPLEMENTED;
-}
-
void CertDatabase::OnAndroidKeyStoreChanged() {
- NotifyObserversOfCertAdded(NULL);
+ NotifyObserversCertDBChanged(NULL);
// Dump the OpenSSLClientKeyStore to drop references to now disconnected
// PrivateKeys stored in the in-memory key store. Note: this assumes that
// every SSLClientAuthCache is dumped as part of notifying
- // OnCertAdded. Otherwise client auth decisions will be silently converted to
- // no-certificate decisions. See https://crbug.com/382696
+ // OnCertDBChanged. Otherwise client auth decisions will be silently converted
+ // to no-certificate decisions. See https://crbug.com/382696
OpenSSLClientKeyStore::GetInstance()->Flush();
}
void CertDatabase::OnAndroidKeyChainChanged() {
- observer_list_->Notify(FROM_HERE, &Observer::OnCACertChanged, nullptr);
+ observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged, nullptr);
}
} // namespace net
diff --git a/chromium/net/cert/cert_database_ios.cc b/chromium/net/cert/cert_database_ios.cc
index 87dfd39843e..c426ee9f21c 100644
--- a/chromium/net/cert/cert_database_ios.cc
+++ b/chromium/net/cert/cert_database_ios.cc
@@ -16,16 +16,4 @@ CertDatabase::CertDatabase()
CertDatabase::~CertDatabase() {}
-int CertDatabase::CheckUserCert(X509Certificate* cert_obj) {
- // iOS doesn't handle user certificates.
- NOTREACHED();
- return OK;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
- // iOS doesn't handle user certificates.
- NOTREACHED();
- return OK;
-}
-
} // namespace net
diff --git a/chromium/net/cert/cert_database_mac.cc b/chromium/net/cert/cert_database_mac.cc
index 42e54c1c973..34088e2f6aa 100644
--- a/chromium/net/cert/cert_database_mac.cc
+++ b/chromium/net/cert/cert_database_mac.cc
@@ -104,7 +104,7 @@ OSStatus CertDatabase::Notifier::KeychainCallback(
switch (keychain_event) {
case kSecKeychainListChangedEvent:
case kSecTrustSettingsChangedEvent:
- that->cert_db_->NotifyObserversOfCACertChanged(NULL);
+ that->cert_db_->NotifyObserversCertDBChanged(NULL);
break;
default:
@@ -132,45 +132,4 @@ CertDatabase::~CertDatabase() {
notifier_.release()->Shutdown();
}
-int CertDatabase::CheckUserCert(X509Certificate* cert) {
- if (!cert)
- return ERR_CERT_INVALID;
- if (cert->HasExpired())
- return ERR_CERT_DATE_INVALID;
-
- // Verify the Keychain already has the corresponding private key:
- SecIdentityRef identity = NULL;
- OSStatus err = SecIdentityCreateWithCertificate(NULL, cert->os_cert_handle(),
- &identity);
- if (err == errSecItemNotFound)
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- if (err != noErr || !identity) {
- // TODO(snej): Map the error code more intelligently.
- return ERR_CERT_INVALID;
- }
-
- CFRelease(identity);
- return OK;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert) {
- OSStatus err;
- {
- base::AutoLock locked(crypto::GetMacSecurityServicesLock());
- err = SecCertificateAddToKeychain(cert->os_cert_handle(), NULL);
- }
- switch (err) {
- case noErr:
- CertDatabase::NotifyObserversOfCertAdded(cert);
- // Fall through.
- case errSecDuplicateItem:
- return OK;
- default:
- OSSTATUS_LOG(ERROR, err) << "CertDatabase failed to add cert to keychain";
- // TODO(snej): Map the error code more intelligently.
- return ERR_ADD_USER_CERT_FAILED;
- }
-}
-
} // namespace net
diff --git a/chromium/net/cert/cert_database_nss.cc b/chromium/net/cert/cert_database_nss.cc
index 2073de1890b..cd71820d1de 100644
--- a/chromium/net/cert/cert_database_nss.cc
+++ b/chromium/net/cert/cert_database_nss.cc
@@ -4,23 +4,8 @@
#include "net/cert/cert_database.h"
-#include <cert.h>
-#include <pk11pub.h>
-#include <secmod.h>
-
-#include <vector>
-
-#include "base/logging.h"
#include "base/observer_list_threadsafe.h"
#include "crypto/nss_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "net/base/net_errors.h"
-#include "net/cert/x509_certificate.h"
-#include "net/cert/x509_util_nss.h"
-#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
-
-// PSM = Mozilla's Personal Security Manager.
-namespace psm = mozilla_security_manager;
namespace net {
@@ -31,38 +16,4 @@ CertDatabase::CertDatabase()
CertDatabase::~CertDatabase() {}
-int CertDatabase::CheckUserCert(X509Certificate* cert_obj) {
- if (!cert_obj)
- return ERR_CERT_INVALID;
- if (cert_obj->HasExpired())
- return ERR_CERT_DATE_INVALID;
-
- // Check if the private key corresponding to the certificate exist
- // We shouldn't accept any random client certificate sent by a CA.
-
- // Note: The NSS source documentation wrongly suggests that this
- // also imports the certificate if the private key exists. This
- // doesn't seem to be the case.
-
- CERTCertificate* cert = cert_obj->os_cert_handle();
- PK11SlotInfo* slot = PK11_KeyForCertExists(cert, NULL, NULL);
- if (!slot)
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- PK11_FreeSlot(slot);
-
- return OK;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert_obj) {
- CertificateList cert_list;
- cert_list.push_back(cert_obj);
- int result = psm::ImportUserCert(cert_list);
-
- if (result == OK)
- NotifyObserversOfCertAdded(NULL);
-
- return result;
-}
-
} // namespace net
diff --git a/chromium/net/cert/cert_database_openssl.cc b/chromium/net/cert/cert_database_openssl.cc
index a59c2eb0c43..35048d04ff6 100644
--- a/chromium/net/cert/cert_database_openssl.cc
+++ b/chromium/net/cert/cert_database_openssl.cc
@@ -4,15 +4,7 @@
#include "net/cert/cert_database.h"
-#include <openssl/x509.h>
-
-#include "base/logging.h"
#include "base/observer_list_threadsafe.h"
-#include "crypto/scoped_openssl_types.h"
-#include "net/base/crypto_module.h"
-#include "net/base/net_errors.h"
-#include "net/base/openssl_private_key_store.h"
-#include "net/cert/x509_certificate.h"
namespace net {
@@ -22,37 +14,4 @@ CertDatabase::CertDatabase()
CertDatabase::~CertDatabase() {}
-// This method is used to check a client certificate before trying to
-// install it on the system, which will happen later by calling
-// AddUserCert() below.
-//
-// On the Linux/OpenSSL build, there is simply no system keystore, but
-// OpenSSLPrivateKeyStore() implements a small in-memory store for
-// (public/private) key pairs generated through keygen.
-//
-// Try to check for a private key in the in-memory store to check
-// for the case when the browser is trying to install a server-generated
-// certificate from a <keygen> exchange.
-int CertDatabase::CheckUserCert(X509Certificate* cert) {
- if (!cert)
- return ERR_CERT_INVALID;
- if (cert->HasExpired())
- return ERR_CERT_DATE_INVALID;
-
- // X509_PUBKEY_get() transfers ownership, not X509_get_X509_PUBKEY()
- crypto::ScopedEVP_PKEY public_key(
- X509_PUBKEY_get(X509_get_X509_PUBKEY(cert->os_cert_handle())));
-
- if (!OpenSSLPrivateKeyStore::HasPrivateKey(public_key.get()))
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- return OK;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert) {
- // There is no certificate store on the Linux/OpenSSL build.
- NOTIMPLEMENTED();
- return ERR_NOT_IMPLEMENTED;
-}
-
} // namespace net
diff --git a/chromium/net/cert/cert_database_win.cc b/chromium/net/cert/cert_database_win.cc
index bda2ef02a49..32c9168ab98 100644
--- a/chromium/net/cert/cert_database_win.cc
+++ b/chromium/net/cert/cert_database_win.cc
@@ -4,12 +4,7 @@
#include "net/cert/cert_database.h"
-#include <windows.h>
-
#include "base/observer_list_threadsafe.h"
-#include "crypto/wincrypt_shim.h"
-#include "net/base/net_errors.h"
-#include "net/cert/x509_certificate.h"
namespace net {
@@ -19,42 +14,4 @@ CertDatabase::CertDatabase()
CertDatabase::~CertDatabase() {}
-int CertDatabase::CheckUserCert(X509Certificate* cert) {
- if (!cert)
- return ERR_CERT_INVALID;
- if (cert->HasExpired())
- return ERR_CERT_DATE_INVALID;
-
- // TODO(rsleevi): Should CRYPT_FIND_SILENT_KEYSET_FLAG be specified? A UI
- // may be shown here / this call may block.
- if (!CryptFindCertificateKeyProvInfo(cert->os_cert_handle(), 0, NULL))
- return ERR_NO_PRIVATE_KEY_FOR_CERT;
-
- return OK;
-}
-
-int CertDatabase::AddUserCert(X509Certificate* cert) {
- // TODO(rsleevi): Would it be more appropriate to have the CertDatabase take
- // construction parameters (Keychain filepath on Mac OS X, PKCS #11 slot on
- // NSS, and Store Type / Path) here? For now, certs will be stashed into the
- // user's personal store, which will not automatically mark them as trusted,
- // but will allow them to be used for client auth.
- HCERTSTORE cert_db = CertOpenSystemStore(NULL, L"MY");
- if (!cert_db)
- return ERR_ADD_USER_CERT_FAILED;
-
- BOOL added = CertAddCertificateContextToStore(cert_db,
- cert->os_cert_handle(),
- CERT_STORE_ADD_USE_EXISTING,
- NULL);
-
- CertCloseStore(cert_db, 0);
-
- if (!added)
- return ERR_ADD_USER_CERT_FAILED;
-
- NotifyObserversOfCertAdded(cert);
- return OK;
-}
-
} // namespace net
diff --git a/chromium/net/cert/cert_verifier.cc b/chromium/net/cert/cert_verifier.cc
index 3aea1be694a..c471fa92161 100644
--- a/chromium/net/cert/cert_verifier.cc
+++ b/chromium/net/cert/cert_verifier.cc
@@ -4,8 +4,6 @@
#include "net/cert/cert_verifier.h"
-#include <openssl/sha.h>
-
#include <algorithm>
#include <memory>
@@ -13,6 +11,7 @@
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "net/cert/cert_verify_proc.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
#if defined(OS_NACL)
#include "base/logging.h"
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index 8fdd93cbb1b..413abb4b2fb 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -18,6 +18,7 @@
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/url_util.h"
+#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_proc_whitelist.h"
@@ -40,6 +41,7 @@
#elif defined(OS_MACOSX)
#include "net/cert/cert_verify_proc_mac.h"
#elif defined(OS_WIN)
+#include "base/win/windows_version.h"
#include "net/cert/cert_verify_proc_win.h"
#else
#error Implement certificate verification.
@@ -309,6 +311,34 @@ void CheckOCSP(const std::string& raw_response,
}
}
+// Records histograms indicating whether the certificate |cert|, which
+// is assumed to have been validated chaining to a private root,
+// contains the TLS Feature Extension (https://tools.ietf.org/html/rfc7633) and
+// has valid OCSP information stapled.
+void RecordTLSFeatureExtensionWithPrivateRoot(
+ X509Certificate* cert,
+ const OCSPVerifyResult& ocsp_result) {
+ std::string cert_der;
+ if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &cert_der))
+ return;
+
+ // This checks only for the presence of the TLS Feature Extension, but
+ // does not check the feature list, and in particular does not verify that
+ // its value is 'status_request' or 'status_request2'. In practice the
+ // only use of the TLS feature extension is for OCSP stapling, so
+ // don't bother to check the value.
+ bool has_extension = asn1::HasTLSFeatureExtension(cert_der);
+
+ UMA_HISTOGRAM_BOOLEAN("Net.Certificate.TLSFeatureExtensionWithPrivateRoot",
+ has_extension);
+ if (!has_extension)
+ return;
+
+ UMA_HISTOGRAM_BOOLEAN(
+ "Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP",
+ (ocsp_result.response_status != OCSPVerifyResult::MISSING));
+}
+
// Comparison functor used for binary searching whether a given HashValue,
// which MUST be a SHA-256 hash, is contained with an array of SHA-256
// hashes.
@@ -328,6 +358,17 @@ struct HashToArrayComparator {
}
};
+bool AreSHA1IntermediatesAllowed() {
+#if defined(OS_WIN)
+ // TODO(rsleevi): Remove this once https://crbug.com/588789 is resolved
+ // for Windows 7/2008 users.
+ // Note: This must be kept in sync with cert_verify_proc_unittest.cc
+ return base::win::GetVersion() < base::win::VERSION_WIN8;
+#else
+ return false;
+#endif
+};
+
} // namespace
// static
@@ -349,7 +390,8 @@ CertVerifyProc* CertVerifyProc::CreateDefault() {
#endif
}
-CertVerifyProc::CertVerifyProc() {}
+CertVerifyProc::CertVerifyProc()
+ : sha1_legacy_mode_enabled(base::FeatureList::IsEnabled(kSHA1LegacyMode)) {}
CertVerifyProc::~CertVerifyProc() {}
@@ -444,8 +486,20 @@ int CertVerifyProc::Verify(X509Certificate* cert,
// TODO(mattm): apply the SHA-1 deprecation check to all certs unless
// CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS flag is present.
if (verify_result->has_md5 ||
- (verify_result->has_sha1_leaf && verify_result->is_issued_by_known_root &&
- IsPastSHA1DeprecationDate(*cert))) {
+ // 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)))) {
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
@@ -472,6 +526,11 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
+ // Record a histogram for the presence of the TLS feature extension in
+ // a certificate chaining to a private root.
+ if (rv == OK && !verify_result->is_issued_by_known_root)
+ RecordTLSFeatureExtensionWithPrivateRoot(cert, verify_result->ocsp_result);
+
return rv;
}
@@ -531,13 +590,11 @@ static bool CheckNameConstraints(const std::vector<std::string>& dns_names,
if (host_info.IsIPAddress())
continue;
- const size_t registry_len = registry_controlled_domains::GetRegistryLength(
- dns_name,
- registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
- registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
// If the name is not in a known TLD, ignore it. This permits internal
// names.
- if (registry_len == 0)
+ if (!registry_controlled_domains::HostHasRegistryControlledDomain(
+ dns_name, registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
+ registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES))
continue;
for (size_t j = 0; domains[j][0]; ++j) {
@@ -693,12 +750,12 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
if (exploded_expiry.day_of_month > exploded_start.day_of_month)
++month_diff;
- static const base::Time time_2012_07_01 =
- base::Time::FromUTCExploded({2012, 7, 0, 1, 0, 0, 0, 0});
- static const base::Time time_2015_04_01 =
- base::Time::FromUTCExploded({2015, 4, 0, 1, 0, 0, 0, 0});
- static const base::Time time_2019_07_01 =
- base::Time::FromUTCExploded({2019, 7, 0, 1, 0, 0, 0, 0});
+ const base::Time time_2012_07_01 =
+ base::Time::FromInternalValue(12985574400000000);
+ const base::Time time_2015_04_01 =
+ base::Time::FromInternalValue(13072320000000000);
+ const base::Time time_2019_07_01 =
+ base::Time::FromInternalValue(13206412800000000);
// For certificates issued before the BRs took effect.
if (start < time_2012_07_01 && (month_diff > 120 || expiry > time_2019_07_01))
@@ -715,4 +772,8 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
return false;
}
+// static
+const base::Feature CertVerifyProc::kSHA1LegacyMode{
+ "SHA1LegacyMode", base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc.h b/chromium/net/cert/cert_verify_proc.h
index 629fde8bf38..352610f22e5 100644
--- a/chromium/net/cert/cert_verify_proc.h
+++ b/chromium/net/cert/cert_verify_proc.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/feature_list.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -83,6 +84,8 @@ class NET_EXPORT CertVerifyProc
friend class base::RefCountedThreadSafe<CertVerifyProc>;
FRIEND_TEST_ALL_PREFIXES(CertVerifyProcTest, DigiNotarCerts);
FRIEND_TEST_ALL_PREFIXES(CertVerifyProcTest, TestHasTooLongValidity);
+ FRIEND_TEST_ALL_PREFIXES(CertVerifyProcTest,
+ VerifyRejectsSHA1AfterDeprecationLegacyMode);
// Performs the actual verification using the desired underlying
// cryptographic library. On entry, |verify_result->verified_cert|
@@ -124,6 +127,10 @@ class NET_EXPORT CertVerifyProc
// (i.e. by 1 July 2019).
static bool HasTooLongValidity(const X509Certificate& cert);
+ // Emergency kill-switch for SHA-1 deprecation. Disabled by default.
+ static const base::Feature kSHA1LegacyMode;
+ const bool sha1_legacy_mode_enabled;
+
DISALLOW_COPY_AND_ASSIGN(CertVerifyProc);
};
diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc
index 3825b20a475..2cb12f75c23 100644
--- a/chromium/net/cert/cert_verify_proc_android.cc
+++ b/chromium/net/cert/cert_verify_proc_android.cc
@@ -4,8 +4,6 @@
#include "net/cert/cert_verify_proc_android.h"
-#include <openssl/x509v3.h>
-
#include <string>
#include <vector>
@@ -20,6 +18,7 @@
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
namespace net {
diff --git a/chromium/net/cert/cert_verify_proc_ios.cc b/chromium/net/cert/cert_verify_proc_ios.cc
index 73f8a150481..2ab30ed07e4 100644
--- a/chromium/net/cert/cert_verify_proc_ios.cc
+++ b/chromium/net/cert/cert_verify_proc_ios.cc
@@ -125,7 +125,7 @@ void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
if (!X509Certificate::GetDEREncoded(chain_cert, &der_bytes))
return;
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_bytes.data());
- ScopedX509 x509_cert(d2i_X509(NULL, &bytes, der_bytes.size()));
+ bssl::UniquePtr<X509> x509_cert(d2i_X509(NULL, &bytes, der_bytes.size()));
base::StringPiece spki_bytes;
if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
diff --git a/chromium/net/cert/cert_verify_proc_openssl.cc b/chromium/net/cert/cert_verify_proc_openssl.cc
index 824a95cdc45..988bdec1e2e 100644
--- a/chromium/net/cert/cert_verify_proc_openssl.cc
+++ b/chromium/net/cert/cert_verify_proc_openssl.cc
@@ -4,15 +4,12 @@
#include "net/cert/cert_verify_proc_openssl.h"
-#include <openssl/x509v3.h>
-
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/sha1.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "crypto/sha2.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
@@ -21,6 +18,7 @@
#include "net/cert/cert_verify_result.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
namespace net {
@@ -90,11 +88,9 @@ CertStatus MapCertErrorToCertStatus(int err) {
}
}
-// sk_X509_free is a function-style macro, so can't be used as a template
-// param directly.
-void sk_X509_free_fn(STACK_OF(X509)* st) {
- sk_X509_free(st);
-}
+struct ShallowX509StackDeleter {
+ void operator()(STACK_OF(X509) * st) const { sk_X509_free(st); }
+};
void GetCertChainInfo(X509_STORE_CTX* store_ctx,
CertVerifyResult* verify_result) {
@@ -211,10 +207,9 @@ int CertVerifyProcOpenSSL::VerifyInternal(
verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
}
- crypto::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(
- X509_STORE_CTX_new());
+ bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
- crypto::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(
+ std::unique_ptr<STACK_OF(X509), ShallowX509StackDeleter> intermediates(
sk_X509_new_null());
if (!intermediates.get())
return ERR_OUT_OF_MEMORY;
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index ee6a9b14f55..862f7c8690c 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -13,6 +13,8 @@
#include "base/macros.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
+#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "crypto/sha2.h"
#include "net/base/net_errors.h"
@@ -39,6 +41,10 @@
#include "net/cert/test_keychain_search_list_mac.h"
#endif
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
using net::test::IsError;
using net::test::IsOk;
@@ -48,6 +54,11 @@ namespace net {
namespace {
+const char kTLSFeatureExtensionHistogram[] =
+ "Net.Certificate.TLSFeatureExtensionWithPrivateRoot";
+const char kTLSFeatureExtensionOCSPHistogram[] =
+ "Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP";
+
// Mock CertVerifyProc that sets the CertVerifyResult to a given value for
// all certificates that are Verify()'d
class MockCertVerifyProc : public CertVerifyProc {
@@ -164,6 +175,17 @@ class CertVerifyProcTest : public testing::Test {
additional_trust_anchors, verify_result);
}
+ int VerifyWithOCSPResponse(X509Certificate* cert,
+ const std::string& hostname,
+ const std::string& ocsp_response,
+ int flags,
+ CRLSet* crl_set,
+ const CertificateList& additional_trust_anchors,
+ CertVerifyResult* verify_result) {
+ return verify_proc_->Verify(cert, hostname, ocsp_response, flags, crl_set,
+ additional_trust_anchors, verify_result);
+ }
+
const CertificateList empty_cert_list_;
scoped_refptr<CertVerifyProc> verify_proc_;
};
@@ -854,10 +876,18 @@ TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
}
-// Test that a SHA-1 certificate from a publicly trusted CA issued after
-// 1 January 2016 is rejected, but those issued before that date, or with
-// SHA-1 in the intermediate, is not rejected.
-TEST_F(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecation) {
+// While all SHA-1 certificates should be rejected, in the event that there
+// emerges some unexpected bug, test that the 'legacy' behaviour works
+// correctly - rejecting all SHA-1 certificates from publicly trusted CAs
+// 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);
+
CertVerifyResult dummy_result;
CertVerifyResult verify_result;
int error = 0;
@@ -1495,6 +1525,131 @@ TEST_F(CertVerifyProcTest, MacSystemRootCertificateKeychainLocation) {
}
#endif
+bool AreSHA1IntermediatesAllowed() {
+#if defined(OS_WIN)
+ // TODO(rsleevi): Remove this once https://crbug.com/588789 is resolved
+ // for Windows 7/2008 users.
+ // Note: This must be kept in sync with cert_verify_proc.cc
+ return base::win::GetVersion() < base::win::VERSION_WIN8;
+#else
+ return false;
+#endif
+}
+
+TEST_F(CertVerifyProcTest, RejectsMD2) {
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_md2 = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ 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_INVALID));
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
+}
+
+TEST_F(CertVerifyProcTest, RejectsMD4) {
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_md4 = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ 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_INVALID));
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
+}
+
+TEST_F(CertVerifyProcTest, RejectsMD5) {
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_md5 = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ 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_WEAK_SIGNATURE_ALGORITHM);
+}
+
+TEST_F(CertVerifyProcTest, RejectsPublicSHA1Leaves) {
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_sha1 = true;
+ result.has_sha1_leaf = true;
+ result.is_issued_by_known_root = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ 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_WEAK_SIGNATURE_ALGORITHM);
+}
+
+TEST_F(CertVerifyProcTest, RejectsPublicSHA1IntermediatesUnlessAllowed) {
+ scoped_refptr<X509Certificate> cert(ImportCertFromFile(
+ GetTestCertsDirectory(), "39_months_after_2015_04.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_sha1 = true;
+ result.has_sha1_leaf = false;
+ result.is_issued_by_known_root = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error = Verify(cert.get(), "127.0.0.1", flags, nullptr /* crl_set */,
+ empty_cert_list_, &verify_result);
+ if (AreSHA1IntermediatesAllowed()) {
+ EXPECT_THAT(error, IsOk());
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+ } else {
+ EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
+ EXPECT_TRUE(verify_result.cert_status &
+ CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
+ }
+}
+
+TEST_F(CertVerifyProcTest, AcceptsPrivateSHA1) {
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+ result.has_sha1 = true;
+ result.has_sha1_leaf = true;
+ result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ 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, IsOk());
+ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
+}
+
enum ExpectedAlgorithms {
EXPECT_MD2 = 1 << 0,
EXPECT_MD4 = 1 << 1,
@@ -1529,7 +1684,10 @@ class CertVerifyProcWeakDigestTest
virtual ~CertVerifyProcWeakDigestTest() {}
};
-TEST_P(CertVerifyProcWeakDigestTest, Verify) {
+// 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_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
WeakDigestTestData data = GetParam();
base::FilePath certs_dir = GetTestCertsDirectory();
@@ -1537,16 +1695,16 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
if (data.root_cert_filename) {
scoped_refptr<X509Certificate> root_cert =
ImportCertFromFile(certs_dir, data.root_cert_filename);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
+ ASSERT_TRUE(root_cert);
test_root.Reset(root_cert.get());
}
scoped_refptr<X509Certificate> intermediate_cert =
ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert.get());
+ ASSERT_TRUE(intermediate_cert);
scoped_refptr<X509Certificate> ee_cert =
ImportCertFromFile(certs_dir, data.ee_cert_filename);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert.get());
+ ASSERT_TRUE(ee_cert);
X509Certificate::OSCertHandles intermediates;
intermediates.push_back(intermediate_cert->os_cert_handle());
@@ -1554,53 +1712,18 @@ TEST_P(CertVerifyProcWeakDigestTest, Verify) {
scoped_refptr<X509Certificate> ee_chain =
X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
intermediates);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain.get());
+ ASSERT_TRUE(ee_chain);
int flags = 0;
CertVerifyResult verify_result;
- int rv = Verify(ee_chain.get(),
- "127.0.0.1",
- flags,
- NULL,
- empty_cert_list_,
- &verify_result);
+ Verify(ee_chain.get(), "127.0.0.1", flags, NULL, 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);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1);
EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1_LEAF),
verify_result.has_sha1_leaf);
-
- EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
-
- // Ensure that MD4 and MD2 are tagged as invalid.
- if (data.expected_algorithms & (EXPECT_MD2 | EXPECT_MD4)) {
- EXPECT_EQ(CERT_STATUS_INVALID,
- verify_result.cert_status & CERT_STATUS_INVALID);
- }
-
- // Ensure that MD5 is flagged as weak.
- if (data.expected_algorithms & EXPECT_MD5) {
- EXPECT_EQ(
- CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
- verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
- }
-
- // If a root cert is present, then check that the chain was rejected if any
- // weak algorithms are present. This is only checked when a root cert is
- // present because the error reported for incomplete chains with weak
- // algorithms depends on which implementation was used to validate (NSS,
- // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
- // present (MD2, MD4, MD5).
- if (data.root_cert_filename) {
- if (data.expected_algorithms & (EXPECT_MD2 | EXPECT_MD4)) {
- EXPECT_THAT(rv, IsError(ERR_CERT_INVALID));
- } else if (data.expected_algorithms & EXPECT_MD5) {
- EXPECT_THAT(rv, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
- } else {
- EXPECT_THAT(rv, IsOk());
- }
- }
}
// Unlike TEST/TEST_F, which are macros that expand to further macros,
@@ -1844,4 +1967,105 @@ TEST_F(CertVerifyProcTest, LargeKey) {
}
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+// Tests that CertVerifyProc records a histogram correctly when a
+// certificate chaining to a private root contains the TLS feature
+// extension and does not have a stapled OCSP response.
+TEST_F(CertVerifyProcTest, HasTLSFeatureExtensionUMA) {
+ base::HistogramTester histograms;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
+ ASSERT_TRUE(cert);
+ CertVerifyResult result;
+ result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
+ histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1);
+ histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, false, 1);
+}
+
+// Tests that CertVerifyProc records a histogram correctly when a
+// certificate chaining to a private root contains the TLS feature
+// extension and does have a stapled OCSP response.
+TEST_F(CertVerifyProcTest, HasTLSFeatureExtensionWithStapleUMA) {
+ base::HistogramTester histograms;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
+ ASSERT_TRUE(cert);
+ CertVerifyResult result;
+ result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error =
+ VerifyWithOCSPResponse(cert.get(), "127.0.0.1", "dummy response", flags,
+ NULL, empty_cert_list_, &verify_result);
+ EXPECT_EQ(OK, error);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
+ histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1);
+ histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, true, 1);
+}
+
+// Tests that CertVerifyProc records a histogram correctly when a
+// certificate chaining to a private root does not contain the TLS feature
+// extension.
+TEST_F(CertVerifyProcTest, DoesNotHaveTLSFeatureExtensionUMA) {
+ base::HistogramTester histograms;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(cert);
+ CertVerifyResult result;
+ result.is_issued_by_known_root = false;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
+ histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, false, 1);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
+}
+
+// Tests that CertVerifyProc does not record a histogram when a
+// certificate contains the TLS feature extension but chains to a public
+// root.
+TEST_F(CertVerifyProcTest, HasTLSFeatureExtensionWithPublicRootUMA) {
+ base::HistogramTester histograms;
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
+ ASSERT_TRUE(cert);
+ CertVerifyResult result;
+ result.is_issued_by_known_root = true;
+ verify_proc_ = new MockCertVerifyProc(result);
+
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
+ &verify_result);
+ EXPECT_EQ(OK, error);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
+ histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
+}
+
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc_whitelist.cc b/chromium/net/cert/cert_verify_proc_whitelist.cc
index 8b412e447fa..5c53a77a36c 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist.cc
@@ -13,11 +13,43 @@ namespace net {
namespace {
// clang-format off
+// SHA-256 hashes of the subjectPublicKeyInfos of root certificates owned
+// or operated by WoSign, including that of StartCom. For the certificates,
+// see //net/data/ssl/wosign.
+const uint8_t kWosignKeys[][crypto::kSHA256Length] = {
+ { 0x15, 0x28, 0x39, 0x7d, 0xa2, 0x12, 0x89, 0x0a,
+ 0x83, 0x0b, 0x0b, 0x95, 0xa5, 0x99, 0x68, 0xce,
+ 0xf2, 0x34, 0x77, 0x37, 0x79, 0xdf, 0x51, 0x81,
+ 0xcf, 0x10, 0xfa, 0x64, 0x75, 0x34, 0xbb, 0x65 },
+ { 0x38, 0x1a, 0x3f, 0xc7, 0xa8, 0xb0, 0x82, 0xfa,
+ 0x28, 0x61, 0x3a, 0x4d, 0x07, 0xf2, 0xc7, 0x55,
+ 0x3f, 0x4e, 0x19, 0x18, 0xee, 0x07, 0xca, 0xa9,
+ 0xe8, 0xb7, 0xce, 0xde, 0x5a, 0x9c, 0xa0, 0x6a },
+ { 0x7a, 0xed, 0xdd, 0xf3, 0x6b, 0x18, 0xf8, 0xac,
+ 0xb7, 0x37, 0x9f, 0xe1, 0xce, 0x18, 0x32, 0x12,
+ 0xb2, 0x35, 0x0d, 0x07, 0x88, 0xab, 0xe0, 0xe8,
+ 0x24, 0x57, 0xbe, 0x9b, 0xad, 0xad, 0x6d, 0x54 },
+ { 0x9d, 0x98, 0xa1, 0xfb, 0x60, 0x53, 0x8c, 0x4c,
+ 0xc4, 0x85, 0x7f, 0xf1, 0xa8, 0xc8, 0x03, 0x4f,
+ 0xaf, 0x6f, 0xc5, 0x92, 0x09, 0x3f, 0x61, 0x99,
+ 0x94, 0xb2, 0xc8, 0x13, 0xd2, 0x50, 0xb8, 0x64 },
+ { 0xd6, 0xa1, 0x84, 0x43, 0xd3, 0x48, 0xdb, 0x99,
+ 0x4f, 0x93, 0x4c, 0xcd, 0x8e, 0x63, 0x5d, 0x83,
+ 0x3a, 0x27, 0xac, 0x1e, 0x56, 0xf8, 0xaf, 0xaf,
+ 0x7c, 0x97, 0xcb, 0x4f, 0x43, 0xea, 0xb6, 0x8b },
+ { 0xdb, 0x15, 0xc0, 0x06, 0x2b, 0x52, 0x0f, 0x31,
+ 0x8a, 0x19, 0xda, 0xcf, 0xec, 0xd6, 0x4f, 0x9e,
+ 0x7a, 0x3f, 0xbe, 0x60, 0x9f, 0xd5, 0x86, 0x79,
+ 0x6f, 0x20, 0xae, 0x02, 0x8e, 0x8e, 0x30, 0x58 },
+ { 0xe4, 0x2f, 0x24, 0xbd, 0x4d, 0x37, 0xf4, 0xaa,
+ 0x2e, 0x56, 0xb9, 0x79, 0xd8, 0x3d, 0x1e, 0x65,
+ 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, 0x87, 0x75, 0xb8, 0xea, 0xd0, 0xfe, 0x16,
- 0x26, 0x9c, 0x9a, 0x9a, 0xb2, 0x83, 0x39, 0x55,
- 0x49, 0xca, 0x67, 0xc2, 0xa3, 0xaa, 0xe8, 0x2f,
- 0x1a, 0x6b, 0x4d, 0x3a, 0xbc, 0xca, 0xdc, 0x27 },
{ 0x00, 0xc5, 0x9f, 0x5e, 0xf3, 0xb4, 0x6d, 0xbc,
0xa0, 0xa8, 0xbb, 0xa5, 0x0a, 0x72, 0xd4, 0xe1,
0x83, 0x9a, 0x94, 0xfb, 0x1a, 0x58, 0x5a, 0xd7,
@@ -42,14 +74,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xff, 0xde, 0x35, 0xe0, 0xd1, 0x28, 0xb7, 0x99,
0x92, 0x2b, 0xa9, 0x37, 0xa2, 0xe8, 0x65, 0x84,
0x36, 0x62, 0xf1, 0xf4, 0x50, 0x02, 0xb8, 0x2d },
- { 0x04, 0x18, 0xd5, 0x3e, 0xbc, 0x8e, 0x71, 0x41,
- 0x25, 0x1b, 0x4d, 0xc8, 0xfa, 0x7b, 0x2b, 0xd8,
- 0xfd, 0x3a, 0x1c, 0x65, 0x2a, 0xa1, 0x16, 0xe7,
- 0xfc, 0x70, 0x0b, 0x2a, 0xb5, 0x1a, 0x2a, 0x1a },
- { 0x06, 0xd4, 0x08, 0xff, 0xa9, 0x93, 0xaf, 0x04,
- 0x45, 0x9c, 0x45, 0x67, 0x1a, 0xab, 0xd8, 0x7e,
- 0xf9, 0x2b, 0x85, 0x6b, 0x1b, 0x42, 0xc6, 0x7e,
- 0x00, 0x5e, 0xb4, 0xd2, 0x71, 0x58, 0xa8, 0x42 },
{ 0x07, 0x19, 0x4f, 0x47, 0xf4, 0xce, 0xd0, 0x96,
0xd1, 0x06, 0x8d, 0x34, 0x49, 0x3b, 0x67, 0x37,
0x14, 0x45, 0x16, 0x93, 0xa6, 0xa2, 0x71, 0x2f,
@@ -58,14 +82,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe2, 0xc1, 0x78, 0x71, 0xaa, 0xb6, 0xe4, 0x00,
0xb3, 0xfd, 0xbc, 0xdc, 0xf3, 0x91, 0x46, 0xa0,
0x89, 0x37, 0xf9, 0xac, 0x06, 0xa1, 0xb8, 0xbd },
- { 0x07, 0xa9, 0x5c, 0x81, 0xed, 0x15, 0x9e, 0x44,
- 0xa0, 0x41, 0x2b, 0xde, 0xb1, 0x31, 0xa1, 0x1f,
- 0x26, 0xe3, 0x4e, 0x51, 0x67, 0xec, 0xf2, 0x11,
- 0x78, 0xf3, 0xef, 0xbf, 0xb3, 0xa2, 0xbb, 0x72 },
- { 0x07, 0xe9, 0x60, 0x9e, 0x05, 0xdc, 0x0a, 0x1e,
- 0x52, 0x15, 0x06, 0x49, 0xeb, 0xf4, 0x1f, 0x6d,
- 0xe3, 0x86, 0x7c, 0x9c, 0x25, 0xfe, 0x17, 0x7b,
- 0xab, 0xcf, 0xd9, 0xb3, 0x70, 0x46, 0x13, 0x8b },
{ 0x08, 0x21, 0x0a, 0xc3, 0xa2, 0x95, 0x56, 0xf6,
0x8d, 0x33, 0xb4, 0x40, 0x87, 0x9c, 0x54, 0x63,
0x64, 0x04, 0xe9, 0x7c, 0x4d, 0x9f, 0x97, 0x82,
@@ -78,10 +94,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0xa2, 0xc1, 0x4e, 0x5d, 0x62, 0xc3, 0x4a,
- 0xa7, 0x06, 0xff, 0xab, 0xd2, 0x1e, 0x7a, 0xd2,
- 0x25, 0xf6, 0x25, 0xf7, 0x1f, 0xf8, 0x9d, 0xb3,
- 0x9b, 0x32, 0x2a, 0xcb, 0x0c, 0x84, 0x57, 0x4f },
{ 0x09, 0xeb, 0xdd, 0x1b, 0x7f, 0xfa, 0x4e, 0xd7,
0x4b, 0xeb, 0xae, 0x96, 0xba, 0x10, 0x65, 0xdc,
0x7d, 0xa1, 0xc5, 0xd3, 0x18, 0x3c, 0xc5, 0x94,
@@ -118,10 +130,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x66, 0x45, 0x6b, 0x0b, 0xf4, 0xaa, 0x54,
- 0x16, 0xe4, 0x4d, 0x9f, 0xdb, 0x40, 0x38, 0x3d,
- 0x34, 0x3d, 0x7b, 0x3f, 0x6a, 0xfe, 0x69, 0xaa,
- 0x08, 0x95, 0xbb, 0x1a, 0xb5, 0xe0, 0x61, 0xa0 },
{ 0x0d, 0x71, 0xc8, 0xca, 0x16, 0x56, 0x59, 0xef,
0xaf, 0x69, 0x65, 0x29, 0x28, 0x9a, 0xae, 0x25,
0xd9, 0xc4, 0x2a, 0x1b, 0xbb, 0x03, 0x5a, 0x2b,
@@ -186,10 +194,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x77, 0x3e, 0xe9, 0xe9, 0x35, 0x6b, 0x88,
- 0x11, 0xd6, 0x56, 0x79, 0x9c, 0x53, 0x16, 0x0b,
- 0x61, 0x73, 0xfa, 0x8a, 0x81, 0x47, 0x97, 0xdb,
- 0xcd, 0x55, 0xb2, 0x27, 0x38, 0x70, 0x60, 0x3e },
{ 0x19, 0xff, 0xe6, 0xc6, 0x7a, 0x35, 0x86, 0xfc,
0x48, 0x6c, 0xe2, 0x07, 0xfa, 0x2a, 0xf6, 0x62,
0xf5, 0x50, 0xfc, 0x51, 0x2f, 0xdd, 0x78, 0x17,
@@ -242,10 +246,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x09, 0xf3, 0x10, 0x7d, 0x97, 0xf8, 0x70,
- 0x48, 0x70, 0x8e, 0xc8, 0x7c, 0xa2, 0xdc, 0x31,
- 0x8b, 0x2f, 0x2b, 0x57, 0x47, 0xc3, 0x38, 0xbd,
- 0x9c, 0x6d, 0xbc, 0xd6, 0x0f, 0xd6, 0xbe, 0xa2 },
{ 0x21, 0x78, 0xe8, 0x28, 0x3a, 0x73, 0x39, 0x6e,
0x08, 0xc0, 0xa1, 0x1a, 0x88, 0x72, 0xfa, 0x4a,
0x9f, 0xcc, 0x05, 0x67, 0x0c, 0xee, 0xff, 0xb8,
@@ -310,10 +310,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xca, 0x55, 0xb2, 0xe1, 0x63, 0xfd, 0xbb, 0xbc,
0x9d, 0x74, 0xb4, 0xe5, 0xf3, 0x7b, 0x7d, 0xbd,
0x13, 0xc9, 0x4e, 0x85, 0x8d, 0x40, 0xda, 0xd0 },
- { 0x2b, 0xf1, 0xe3, 0xf0, 0x37, 0x5a, 0x9a, 0x21,
- 0xc0, 0x7a, 0x92, 0x18, 0x04, 0x2f, 0x18, 0x77,
- 0x3f, 0x43, 0xea, 0xb0, 0xf5, 0xc0, 0x00, 0x26,
- 0x45, 0x40, 0x48, 0x2f, 0x04, 0xae, 0x18, 0xef },
{ 0x2c, 0x82, 0x47, 0x4f, 0x0e, 0xf6, 0xcb, 0x65,
0x0a, 0x13, 0xef, 0x20, 0x99, 0x6e, 0x65, 0x7b,
0x67, 0x24, 0xf0, 0xa0, 0xd5, 0xee, 0x24, 0x6d,
@@ -342,10 +338,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0xcb, 0x41, 0x11, 0xfb, 0x10, 0x08, 0x6f,
- 0xc6, 0xa4, 0x1f, 0x04, 0xb7, 0xe9, 0xd4, 0xcf,
- 0x66, 0x10, 0xbb, 0x06, 0x59, 0xd8, 0xe2, 0xac,
- 0x80, 0x4f, 0xc8, 0x96, 0xb0, 0x25, 0x42, 0xbb },
{ 0x30, 0xe0, 0x69, 0x80, 0x9c, 0x79, 0x90, 0xf0,
0xb5, 0xf2, 0x66, 0xe8, 0x94, 0x59, 0x96, 0x42,
0xe8, 0x53, 0x50, 0xab, 0x82, 0x81, 0x05, 0x34,
@@ -378,14 +370,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xc8, 0x68, 0x5e, 0xea, 0xac, 0x57, 0x87, 0x2d,
0x3b, 0x47, 0xe6, 0x02, 0xf4, 0x97, 0xe9, 0xf0,
0x28, 0x54, 0x12, 0x32, 0x59, 0xfb, 0xe1, 0x69 },
- { 0x35, 0x98, 0x10, 0xff, 0xfe, 0xd1, 0x3a, 0x2c,
- 0x25, 0xcd, 0x91, 0xfc, 0xf0, 0x85, 0x59, 0x33,
- 0xc9, 0x94, 0xa9, 0xdf, 0xc9, 0x39, 0x2d, 0x97,
- 0x07, 0xc3, 0xc0, 0xe7, 0x30, 0x0f, 0x90, 0x8d },
- { 0x35, 0xdf, 0x79, 0x2b, 0x10, 0x0a, 0x79, 0xa6,
- 0x5c, 0x44, 0x87, 0x04, 0x30, 0x9d, 0xd6, 0x4b,
- 0x54, 0x39, 0x4e, 0xba, 0xe8, 0xc4, 0x8c, 0x3b,
- 0xd5, 0xde, 0xe9, 0xcc, 0x68, 0x7d, 0x60, 0x34 },
{ 0x36, 0x45, 0xef, 0x7f, 0x5d, 0x15, 0xa5, 0x46,
0x7e, 0x85, 0x30, 0x7d, 0xda, 0x15, 0xcb, 0xbb,
0x55, 0xb7, 0x30, 0xae, 0xf8, 0xef, 0x9c, 0x71,
@@ -410,18 +394,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x7b, 0xa8, 0x8a, 0x05, 0xda, 0xfd, 0x7d,
- 0x58, 0xfa, 0xcf, 0x45, 0x60, 0xa6, 0x88, 0xab,
- 0xee, 0xd2, 0x13, 0xe0, 0xf8, 0x8c, 0x76, 0xb6,
- 0x2a, 0xb2, 0xfd, 0xe3, 0x67, 0xc3, 0x2d, 0x32 },
{ 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 },
- { 0x39, 0xff, 0x6e, 0x31, 0x69, 0x9f, 0x5d, 0x68,
- 0x92, 0x97, 0x6d, 0x11, 0xdd, 0xbb, 0x14, 0x24,
- 0xed, 0x0c, 0xec, 0x48, 0x36, 0x3e, 0x94, 0xea,
- 0xe3, 0xcd, 0x5f, 0x4c, 0xaf, 0x1c, 0xbd, 0x2f },
{ 0x3a, 0xcf, 0x85, 0x3c, 0x4e, 0x45, 0x02, 0xbd,
0x82, 0xd5, 0x85, 0xd5, 0xe0, 0x82, 0xc4, 0xb3,
0xad, 0x03, 0xcd, 0xb6, 0xb5, 0x05, 0xca, 0x80,
@@ -434,10 +410,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x6e, 0x3b, 0xb7, 0x00, 0x04, 0xbd, 0x78,
- 0xc9, 0x69, 0xa7, 0xfb, 0xd5, 0x11, 0x33, 0xa2,
- 0xb3, 0xc4, 0xdf, 0xb6, 0xba, 0x38, 0x5d, 0xce,
- 0x3f, 0xb8, 0x4d, 0x73, 0x6b, 0xea, 0xb1, 0xd9 },
{ 0x3b, 0xaa, 0x31, 0x31, 0x70, 0x68, 0xac, 0xe0,
0x89, 0xae, 0xb4, 0xa8, 0x8d, 0x7e, 0xde, 0xbe,
0x94, 0xab, 0x4a, 0xce, 0x46, 0xbb, 0xd2, 0x68,
@@ -474,10 +446,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x29, 0x96, 0x5a, 0x27, 0xc1, 0x6c, 0x2f, 0xed,
0x28, 0xd9, 0xb9, 0x14, 0x0e, 0x4f, 0xb5, 0x5b,
0x37, 0x22, 0x4c, 0x67, 0xb2, 0xa0, 0x55, 0x1f },
- { 0x3f, 0xb6, 0xc4, 0x03, 0x19, 0x63, 0xb9, 0x67,
- 0x28, 0xbf, 0x93, 0x8d, 0x9b, 0x59, 0xc9, 0x05,
- 0x43, 0xa9, 0xa6, 0x3e, 0xa3, 0x9c, 0xd2, 0x76,
- 0x14, 0xf2, 0x41, 0x28, 0xa9, 0x64, 0xef, 0x84 },
{ 0x40, 0x58, 0xec, 0x4a, 0x7a, 0x7b, 0xa0, 0xb8,
0x65, 0xa7, 0x39, 0xa0, 0x0c, 0x85, 0xf3, 0x44,
0x58, 0x79, 0xd6, 0x5e, 0x1d, 0x42, 0x2e, 0xed,
@@ -502,10 +470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xd1, 0xdb, 0xd3, 0x3d, 0x8d, 0x16, 0x34, 0xc4,
0xfa, 0xfe, 0xb6, 0xf8, 0x05, 0xf1, 0xcc, 0xb5,
0x34, 0xac, 0xb7, 0x2a, 0xed, 0xa2, 0xcd, 0x0a },
- { 0x43, 0x13, 0x91, 0xe1, 0x14, 0x14, 0xec, 0x0c,
- 0x5c, 0xf5, 0xe7, 0xb3, 0x9c, 0x65, 0xfe, 0xdb,
- 0x2e, 0xc8, 0x8c, 0x54, 0x48, 0xbf, 0x35, 0xee,
- 0x17, 0x0d, 0xc3, 0xb5, 0xe1, 0x7e, 0xd0, 0x88 },
{ 0x44, 0x12, 0x63, 0x80, 0xa0, 0x73, 0xfe, 0xa1,
0xa2, 0x00, 0x4f, 0x71, 0x1d, 0xf2, 0xca, 0x47,
0xc2, 0xc4, 0xb4, 0xff, 0x64, 0x4e, 0x76, 0xaf,
@@ -546,26 +510,14 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x21, 0xfe, 0xf9, 0x3d, 0x26, 0x0c, 0x24, 0x8c,
0xe3, 0xbe, 0x98, 0x62, 0x68, 0x68, 0xe7, 0x5a,
0x3f, 0x63, 0x34, 0xbb, 0x7d, 0xc1, 0x81, 0xec },
- { 0x4a, 0xcf, 0x9d, 0xa9, 0x05, 0x2f, 0x0b, 0x8c,
- 0xff, 0xf7, 0x37, 0xcd, 0xa3, 0x39, 0x11, 0xc2,
- 0x9e, 0xfc, 0xbf, 0xfd, 0x4b, 0xf4, 0xb7, 0x24,
- 0x83, 0xfa, 0xa7, 0xc7, 0x45, 0x1d, 0xfd, 0x42 },
{ 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, 0x35, 0x02, 0xff, 0xad, 0x64, 0x16, 0x39,
- 0x4f, 0x2f, 0x78, 0x47, 0x76, 0x13, 0x39, 0x69,
- 0xa5, 0x5c, 0xa8, 0xf3, 0x9f, 0x78, 0x3c, 0x26,
- 0x0f, 0xfe, 0xdb, 0xa8, 0xfc, 0xe4, 0x19, 0x70 },
{ 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 },
- { 0x4b, 0x92, 0xdc, 0xfd, 0x0e, 0xda, 0x00, 0x5d,
- 0x9a, 0x37, 0x3d, 0x91, 0xa6, 0x1f, 0x23, 0x12,
- 0x9d, 0x7b, 0x85, 0x3d, 0x79, 0x52, 0x87, 0xc9,
- 0x5c, 0x7e, 0x17, 0x24, 0xa9, 0x1c, 0x53, 0xb3 },
{ 0x4c, 0xd0, 0xd6, 0x7e, 0xcc, 0x3b, 0x01, 0xc8,
0xc2, 0x63, 0x4e, 0x7a, 0x73, 0x76, 0x12, 0xf6,
0x3a, 0x17, 0xff, 0x51, 0x0a, 0x77, 0xa8, 0x04,
@@ -582,10 +534,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x15, 0xb9, 0xc9, 0x92, 0xc8, 0x87, 0xc2,
- 0x4c, 0x99, 0x15, 0x38, 0xdd, 0xd5, 0x1d, 0x01,
- 0x49, 0xcd, 0x9f, 0xf3, 0x60, 0x49, 0xf3, 0xd8,
- 0xa0, 0xb2, 0xd2, 0x92, 0x23, 0xf7, 0x91, 0x38 },
{ 0x50, 0xf4, 0x78, 0x1e, 0xb1, 0xc1, 0x46, 0x70,
0xd9, 0xa5, 0x52, 0xc3, 0x49, 0x5f, 0xb9, 0xf6,
0xae, 0x86, 0x8a, 0xb1, 0xc9, 0xd9, 0x83, 0xe0,
@@ -622,10 +570,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x0c, 0x45, 0xd6, 0xe2, 0x55, 0x8e, 0x7c,
- 0x7d, 0xa8, 0x19, 0xa5, 0x99, 0xd5, 0xb1, 0x6f,
- 0x0e, 0x18, 0x79, 0xf0, 0xcb, 0x58, 0x31, 0xdf,
- 0xdb, 0x9a, 0xb2, 0xff, 0x6e, 0x8e, 0x4b, 0xa0 },
{ 0x58, 0x1a, 0xde, 0x64, 0x84, 0x95, 0xb4, 0xb1,
0x62, 0x9c, 0x3c, 0x7c, 0x78, 0xef, 0xbe, 0xf2,
0x75, 0x06, 0x56, 0x65, 0xb2, 0x41, 0x1c, 0x0e,
@@ -654,10 +598,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa9, 0x38, 0x1a, 0x5c, 0xd8, 0x7b, 0x80, 0xd1,
0x10, 0xf2, 0x6e, 0xe8, 0x39, 0x27, 0x1b, 0xc2,
0x70, 0x60, 0x8f, 0xd1, 0x43, 0x7f, 0x55, 0xb0 },
- { 0x5b, 0x29, 0x3d, 0x30, 0x9f, 0x64, 0x24, 0xbc,
- 0x26, 0x4f, 0x4b, 0xb0, 0x18, 0xae, 0xf5, 0x0e,
- 0x63, 0xe3, 0x37, 0xd1, 0x4d, 0xf0, 0x64, 0xc5,
- 0x7a, 0x23, 0x52, 0x83, 0x42, 0x16, 0x1c, 0x68 },
{ 0x5c, 0x7f, 0xf0, 0x55, 0xc2, 0xfd, 0x03, 0x3f,
0x34, 0xc4, 0xc4, 0xf7, 0xc4, 0xfb, 0x7d, 0xda,
0xaa, 0xfb, 0x43, 0x56, 0xc5, 0x60, 0xc9, 0x9e,
@@ -670,10 +610,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xac, 0xb5, 0x4f, 0x66, 0xa9, 0xb7, 0x78, 0x55,
0x69, 0x6e, 0xce, 0x16, 0x7f, 0xe6, 0xc6, 0x0a,
0x05, 0x16, 0x8b, 0xe4, 0x39, 0x19, 0xc8, 0x0f },
- { 0x5e, 0x23, 0xdb, 0xd4, 0xd0, 0xc9, 0xbf, 0xb1,
- 0x5f, 0x61, 0x6a, 0x95, 0x17, 0xa1, 0x30, 0xd8,
- 0x66, 0xa8, 0xcb, 0x0b, 0x18, 0x96, 0x3d, 0x54,
- 0xe7, 0xed, 0xae, 0xe2, 0x61, 0xcb, 0x1c, 0x19 },
{ 0x5f, 0x8b, 0x88, 0x8e, 0xe9, 0x6c, 0x0c, 0x0f,
0x5a, 0x91, 0x72, 0x90, 0xac, 0xa6, 0x5a, 0xfd,
0x6e, 0xbd, 0xae, 0x05, 0xa0, 0x2a, 0xaf, 0x04,
@@ -706,10 +642,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xde, 0x0b, 0x41, 0x28, 0x5d, 0x9a, 0x13, 0x3f,
0xa7, 0xf5, 0x70, 0xa3, 0xc8, 0x13, 0x55, 0x79,
0xb8, 0x60, 0x19, 0x9d, 0x0a, 0x51, 0x45, 0x7c },
- { 0x67, 0xcf, 0x34, 0x6c, 0xf2, 0x46, 0x77, 0x1b,
- 0x3f, 0x5f, 0x3e, 0x51, 0xcd, 0x75, 0x4e, 0x10,
- 0x93, 0x27, 0x3d, 0x35, 0x69, 0x88, 0x80, 0x84,
- 0x26, 0xf5, 0xdd, 0x2e, 0xd4, 0x8b, 0xbf, 0x49 },
{ 0x69, 0x01, 0x4b, 0xbc, 0x84, 0x29, 0xd8, 0x5f,
0x41, 0xc2, 0x22, 0xd9, 0x7f, 0x7e, 0xd5, 0x35,
0xcf, 0x81, 0x23, 0x9a, 0xf2, 0x7a, 0xcc, 0x88,
@@ -730,10 +662,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x72, 0x94, 0x87, 0xc9, 0x02, 0x5d, 0x18,
- 0x10, 0x51, 0x29, 0xfa, 0x0b, 0xa2, 0x94, 0x4d,
- 0xa8, 0x6a, 0xf1, 0xdb, 0x2d, 0x03, 0x4b, 0xe2,
- 0xbb, 0x73, 0x64, 0x50, 0x0c, 0x05, 0xa6, 0xde },
{ 0x6c, 0x8f, 0xd1, 0xe6, 0xe1, 0x1b, 0xaf, 0xa6,
0x17, 0x78, 0x13, 0xa0, 0x44, 0x40, 0xb1, 0xb9,
0x6a, 0x1c, 0xdb, 0x7c, 0x2d, 0x70, 0x3f, 0x55,
@@ -746,14 +674,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x14, 0xca, 0x72, 0x70, 0x3f, 0x64, 0x46, 0x9b,
0x98, 0x58, 0xfc, 0x39, 0x96, 0x4b, 0x4c, 0x03,
0x93, 0xb3, 0x7d, 0xde, 0xab, 0x8b, 0x19, 0x75 },
- { 0x6d, 0x4e, 0xd4, 0x29, 0x38, 0x15, 0x90, 0xbd,
- 0x3c, 0x6b, 0x7c, 0xb7, 0xe4, 0xe4, 0x25, 0xc8,
- 0xe2, 0x1f, 0x79, 0xff, 0x4d, 0x40, 0x00, 0xb9,
- 0x65, 0x3f, 0xa1, 0x27, 0xe1, 0x41, 0xd3, 0x50 },
- { 0x6d, 0xc9, 0x87, 0x5c, 0xd3, 0x46, 0xa2, 0x2b,
- 0x47, 0xb2, 0x80, 0xb1, 0xb1, 0x45, 0x0d, 0x87,
- 0x8e, 0x09, 0x8b, 0xb2, 0xe2, 0xa9, 0xe3, 0xc2,
- 0x5c, 0xc7, 0x6a, 0xff, 0x93, 0xc0, 0xbe, 0xab },
{ 0x6e, 0x1a, 0x88, 0x63, 0xf2, 0x93, 0x4b, 0x39,
0x01, 0x23, 0x7e, 0x84, 0xd0, 0x76, 0x27, 0x04,
0x23, 0x06, 0x78, 0x7f, 0x2d, 0xe0, 0x66, 0x30,
@@ -770,22 +690,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x73, 0xab, 0x5e, 0xea, 0x4e, 0xc2, 0xf4, 0x84,
0xce, 0x91, 0xd1, 0x0e, 0x31, 0x34, 0x5f, 0x15,
0xa7, 0x6a, 0x84, 0x85, 0xb8, 0xff, 0xfb, 0x7e },
- { 0x6f, 0xdc, 0x18, 0xd6, 0x55, 0x14, 0xdd, 0xce,
- 0xf0, 0x2f, 0xea, 0x81, 0x7a, 0x1b, 0x70, 0x84,
- 0x71, 0x95, 0xff, 0x5c, 0x07, 0xb1, 0x3d, 0x6a,
- 0x97, 0x1e, 0x0e, 0x77, 0x4b, 0x44, 0x10, 0xa0 },
{ 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 },
- { 0x70, 0xe0, 0xb7, 0xf5, 0xc7, 0xa3, 0xd1, 0xf3,
- 0x96, 0x85, 0x84, 0x5d, 0x94, 0xfc, 0x9e, 0x77,
- 0x7c, 0x12, 0x69, 0xcf, 0x15, 0x31, 0x68, 0x51,
- 0x98, 0x3d, 0x60, 0x58, 0x76, 0x1c, 0xf0, 0x63 },
- { 0x71, 0x1e, 0xf0, 0x96, 0x33, 0x43, 0x8a, 0xc5,
- 0xbe, 0x9d, 0xa8, 0x12, 0x2e, 0x7a, 0xcf, 0x0e,
- 0xa2, 0x68, 0xb8, 0x72, 0xad, 0xdc, 0x3e, 0xe8,
- 0x37, 0x2b, 0x91, 0x6d, 0x60, 0x65, 0xcf, 0xa8 },
{ 0x72, 0x1b, 0x1f, 0x92, 0x9d, 0xa7, 0xea, 0xf8,
0x96, 0x24, 0x64, 0x7b, 0xa3, 0xcc, 0x4e, 0x1e,
0xd1, 0x57, 0x54, 0xab, 0x83, 0x6e, 0x33, 0x58,
@@ -802,10 +710,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x54, 0x0f, 0xa5, 0x0a, 0x36, 0x2e, 0x68,
- 0x6d, 0x99, 0x17, 0x98, 0x18, 0x35, 0x09, 0x83,
- 0x6c, 0x95, 0xa3, 0xfb, 0x04, 0x58, 0x00, 0x22,
- 0xf9, 0x68, 0x58, 0x4f, 0x8a, 0xcf, 0x60, 0x1f },
{ 0x74, 0x8e, 0xbb, 0x72, 0xd1, 0x02, 0x04, 0xf4,
0x04, 0x10, 0xbe, 0x70, 0x80, 0xbf, 0xe7, 0xee,
0x63, 0x1f, 0xc0, 0x4d, 0x1f, 0xdb, 0x50, 0x72,
@@ -818,10 +722,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xa2, 0xa2, 0xab, 0x2a, 0x4e, 0x85, 0x49, 0x83,
0xc5, 0xfd, 0xe6, 0x73, 0xce, 0x8e, 0xb1, 0x71,
0x23, 0x49, 0x48, 0x64, 0x86, 0x7a, 0x98, 0xb1 },
- { 0x77, 0xdd, 0xc8, 0x1b, 0xd2, 0x8b, 0x9d, 0x46,
- 0x1e, 0x7d, 0x3c, 0xd4, 0xa8, 0x12, 0x2a, 0xa9,
- 0x8a, 0x24, 0x60, 0xfb, 0xa0, 0x8f, 0x1b, 0x7b,
- 0xac, 0xb6, 0x6c, 0x92, 0xd7, 0x99, 0x1c, 0xcc },
{ 0x78, 0x0c, 0x33, 0xfe, 0x95, 0x4c, 0xc4, 0xdb,
0x39, 0x04, 0xd7, 0x6a, 0x68, 0x58, 0xbc, 0xd1,
0x01, 0x7f, 0x52, 0xda, 0x59, 0x9d, 0x36, 0xda,
@@ -830,18 +730,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x44, 0x5a, 0x43, 0x7b, 0xbe, 0xb4, 0xa5,
- 0x59, 0xc8, 0x1c, 0x8e, 0x57, 0xbb, 0xfb, 0x18,
- 0x66, 0xe2, 0xe2, 0xbf, 0x6e, 0x70, 0xa5, 0x63,
- 0x22, 0x1b, 0x62, 0x7b, 0x71, 0x7d, 0xe6, 0xb1 },
{ 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 },
- { 0x79, 0xa8, 0xfc, 0x72, 0x70, 0xb2, 0xe5, 0xf3,
- 0x35, 0x6b, 0x09, 0xc6, 0xb8, 0x64, 0xfc, 0x92,
- 0xe5, 0xfb, 0xc9, 0xe6, 0x9b, 0xec, 0x93, 0xa4,
- 0xe3, 0x3b, 0x8d, 0xf5, 0x75, 0x60, 0x17, 0xbe },
{ 0x7b, 0xfe, 0x47, 0xae, 0xba, 0x8b, 0x0a, 0x3a,
0x94, 0x5a, 0x88, 0xd8, 0xef, 0x18, 0x91, 0xc9,
0x89, 0x97, 0x8a, 0xbf, 0x12, 0x2e, 0xc5, 0xe0,
@@ -954,10 +846,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x76, 0x88, 0xdc, 0x6e, 0x9f, 0xe3, 0xdb,
- 0x05, 0x05, 0x7f, 0xc6, 0x38, 0xeb, 0x8b, 0x29,
- 0x4c, 0x3d, 0x8e, 0x0a, 0xae, 0x17, 0x51, 0xf7,
- 0x58, 0xf6, 0x36, 0x70, 0x37, 0x2e, 0x66, 0x6d },
{ 0x88, 0x8d, 0x6d, 0x77, 0xd8, 0x1c, 0x62, 0x91,
0xcb, 0x84, 0xd9, 0xd6, 0x56, 0x27, 0x82, 0xfd,
0x2e, 0xb3, 0x42, 0x5d, 0x49, 0x1e, 0x68, 0x74,
@@ -1026,10 +914,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0xb3, 0xa1, 0x85, 0x36, 0x86, 0xaf, 0xeb,
- 0x15, 0x4a, 0xef, 0x7e, 0x84, 0x0d, 0x38, 0x04,
- 0x4e, 0x7d, 0x7f, 0x6d, 0xc4, 0xce, 0x82, 0x8c,
- 0xe3, 0x97, 0x55, 0xac, 0x88, 0xe4, 0x2e, 0x07 },
{ 0x90, 0xe2, 0x51, 0x86, 0x7f, 0x6b, 0x0c, 0x14,
0xbd, 0x9b, 0x51, 0x0c, 0xfd, 0xa8, 0x48, 0x49,
0x72, 0xfd, 0xf0, 0xe0, 0x6d, 0xc1, 0x1f, 0x5d,
@@ -1038,10 +922,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe1, 0x9d, 0x17, 0xdb, 0xbe, 0x6e, 0x7c, 0x82,
0x31, 0x86, 0x9c, 0xa7, 0xf6, 0xe3, 0x07, 0xa2,
0xc2, 0xcc, 0x54, 0x77, 0x8d, 0x4a, 0x89, 0xb3 },
- { 0x91, 0xc7, 0x6e, 0xf8, 0xc7, 0x05, 0x3b, 0x2a,
- 0x27, 0x0b, 0x97, 0x19, 0x78, 0x3c, 0x85, 0x10,
- 0xa2, 0x89, 0x0a, 0x48, 0x40, 0x18, 0x63, 0x72,
- 0x6e, 0x23, 0x3a, 0x82, 0xbf, 0x9a, 0x0b, 0xcf },
{ 0x92, 0x3f, 0x0f, 0x8c, 0x40, 0x5a, 0x02, 0xe6,
0x82, 0xc4, 0xb4, 0x66, 0x5a, 0x7e, 0xe7, 0x16,
0xaa, 0x57, 0xe0, 0xa5, 0x86, 0xc2, 0x4a, 0x16,
@@ -1050,10 +930,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x07, 0xe9, 0x40, 0x7f, 0x7f, 0xff, 0x6a, 0x64,
0x63, 0x5d, 0x7c, 0xe9, 0x06, 0x66, 0xd4, 0x29,
0x94, 0x09, 0x7a, 0xf4, 0x0c, 0x31, 0x36, 0xfb },
- { 0x93, 0x8a, 0xe3, 0xe7, 0x15, 0x48, 0xa9, 0xc3,
- 0x14, 0x27, 0xcb, 0xa7, 0x40, 0xbe, 0x2e, 0xb9,
- 0x26, 0x88, 0x68, 0xbd, 0xac, 0xc1, 0xda, 0xa8,
- 0x67, 0x02, 0xfa, 0xb7, 0x93, 0x70, 0xb8, 0xf9 },
{ 0x94, 0xdc, 0x80, 0x07, 0x49, 0x1d, 0xa8, 0xbf,
0xb7, 0x39, 0x14, 0xad, 0xce, 0xf7, 0x1a, 0x12,
0x41, 0x58, 0xba, 0xd1, 0x7b, 0xa8, 0x8f, 0xa9,
@@ -1082,30 +958,14 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xb1, 0xad, 0xa6, 0x09, 0xe2, 0x00, 0x95, 0xfb,
0xc3, 0x3a, 0x6b, 0xbc, 0x6a, 0x21, 0xd8, 0x0a,
0x4e, 0xcb, 0x27, 0x3c, 0x60, 0xac, 0x2a, 0xc7 },
- { 0x97, 0xe2, 0x11, 0x70, 0x95, 0x44, 0x9c, 0xdf,
- 0xc0, 0xa8, 0x3e, 0xd4, 0x9e, 0x65, 0x0a, 0xdf,
- 0xd9, 0xbc, 0x0b, 0x3c, 0x50, 0x04, 0x9d, 0x7b,
- 0x93, 0x24, 0x5a, 0xcc, 0x3a, 0x0c, 0x16, 0xaf },
- { 0x98, 0xb5, 0x92, 0x4e, 0x06, 0xcd, 0xea, 0x1b,
- 0xa1, 0x7f, 0xdb, 0x1b, 0x13, 0x97, 0x90, 0x24,
- 0xb1, 0xc2, 0x5b, 0x0a, 0x69, 0x0c, 0xfe, 0x87,
- 0x8d, 0x4c, 0xb4, 0x07, 0x76, 0xb9, 0x6f, 0xb0 },
{ 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 },
- { 0x99, 0xb4, 0x6c, 0x68, 0x90, 0x62, 0x37, 0x40,
- 0x23, 0xdb, 0x68, 0x19, 0xf8, 0x89, 0xd3, 0xc1,
- 0xbb, 0x8a, 0x83, 0x8c, 0x6b, 0x51, 0x7e, 0x32,
- 0x7e, 0xd9, 0x1c, 0x6c, 0x96, 0x2d, 0x06, 0x49 },
{ 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, 0x5f, 0xab, 0xe5, 0x8a, 0x1e, 0xae, 0x4b,
- 0x20, 0xba, 0xb3, 0xa7, 0xeb, 0x5e, 0x42, 0xa2,
- 0xda, 0x83, 0x11, 0x59, 0x25, 0x7d, 0xd4, 0xe3,
- 0x55, 0x2e, 0xc6, 0xf7, 0xd2, 0x67, 0xfa, 0xba },
{ 0x9a, 0xae, 0x9d, 0x45, 0xaa, 0x04, 0x03, 0x06,
0x4b, 0xc5, 0xa7, 0x4d, 0xd0, 0x32, 0x5d, 0xa4,
0x1e, 0x12, 0xcf, 0x58, 0x6c, 0x46, 0x2e, 0xe0,
@@ -1118,14 +978,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xbc, 0x8a, 0x77, 0x53, 0x12, 0x57, 0x2a, 0xb2,
0x79, 0x21, 0x6d, 0x55, 0x6d, 0xa7, 0x4a, 0xc2,
0xa7, 0xc0, 0x41, 0xe8, 0xce, 0xb0, 0xbe, 0x0a },
- { 0x9c, 0xca, 0x23, 0x7c, 0xdf, 0xca, 0x2c, 0x72,
- 0xc6, 0x09, 0x25, 0x4a, 0x72, 0x57, 0xfe, 0xd5,
- 0x3a, 0xf1, 0x44, 0xab, 0xc2, 0x5e, 0xcd, 0x8e,
- 0xf7, 0x01, 0x30, 0x8c, 0xb1, 0x3c, 0xf7, 0x69 },
- { 0x9d, 0x32, 0x0d, 0x7b, 0x3d, 0x46, 0x34, 0x5f,
- 0x0f, 0x2d, 0xec, 0xb7, 0x62, 0xa4, 0x81, 0x7b,
- 0x26, 0xa9, 0xa7, 0xcf, 0xe8, 0x71, 0xb1, 0x3e,
- 0x84, 0xe7, 0xec, 0x81, 0x0a, 0xae, 0xb6, 0x2c },
{ 0x9d, 0x6b, 0xdf, 0xcf, 0x0c, 0xbf, 0xfe, 0xea,
0x3b, 0x1a, 0xc7, 0xe9, 0x63, 0xcb, 0xb5, 0xf2,
0x7f, 0xbd, 0xa8, 0x9d, 0x27, 0x77, 0xf6, 0x0e,
@@ -1166,10 +1018,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x02, 0x57, 0x46, 0x34, 0xde, 0x70, 0x7d, 0x2f,
0x92, 0xf4, 0xd0, 0xcb, 0x90, 0xcd, 0xb6, 0x1d,
0xd1, 0x95, 0x8b, 0xcf, 0x0c, 0x55, 0x20, 0x86 },
- { 0xa5, 0x67, 0x98, 0x6c, 0xe0, 0xe3, 0x36, 0xf8,
- 0x4f, 0xdc, 0x08, 0x15, 0xb8, 0x6e, 0xa3, 0x03,
- 0x34, 0x3c, 0xf8, 0xc1, 0x0f, 0x37, 0x27, 0x83,
- 0x27, 0x14, 0x86, 0xb9, 0xc9, 0x3b, 0x63, 0x67 },
{ 0xa6, 0x62, 0xfc, 0x81, 0xc9, 0x09, 0x34, 0xb9,
0xb4, 0xd6, 0x30, 0xb5, 0xd8, 0x2e, 0x86, 0xf2,
0x36, 0x3e, 0xc1, 0x5c, 0xcf, 0xcd, 0xaf, 0xa7,
@@ -1198,10 +1046,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x56, 0x21, 0x2d, 0xb3, 0xab, 0x34, 0x89, 0x6e,
0x91, 0x70, 0x93, 0x11, 0x3e, 0x47, 0xca, 0x35,
0x96, 0x2e, 0xac, 0xca, 0x9c, 0xb3, 0x86, 0xf0 },
- { 0xa9, 0x71, 0x2f, 0x85, 0xed, 0x2e, 0x25, 0xad,
- 0xa5, 0x7d, 0xc1, 0xf0, 0xf8, 0x6d, 0xe1, 0x07,
- 0xb5, 0xe2, 0xf0, 0x36, 0x09, 0x53, 0xf1, 0xed,
- 0x12, 0x5e, 0x37, 0x07, 0x59, 0x47, 0x1d, 0x09 },
{ 0xaa, 0x4b, 0xb3, 0x6f, 0x51, 0xd3, 0xc5, 0x33,
0xb5, 0x27, 0x23, 0xcf, 0x66, 0xa5, 0xa9, 0x9f,
0xc1, 0x2f, 0x11, 0xd4, 0xcc, 0x12, 0x87, 0x56,
@@ -1226,10 +1070,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x8a, 0x54, 0xca, 0xb5, 0x4a, 0x96, 0xe9, 0x66,
0x6e, 0x72, 0xa8, 0x20, 0x22, 0x44, 0xef, 0x3d,
0x7c, 0xa9, 0x34, 0xdf, 0xcc, 0x24, 0xfc, 0xa7 },
- { 0xac, 0x7c, 0x14, 0xb9, 0x56, 0x8f, 0x92, 0x07,
- 0x5a, 0xd4, 0xa3, 0xba, 0x3d, 0x4b, 0x01, 0x84,
- 0x91, 0xf3, 0x66, 0x1a, 0x37, 0x9b, 0x3d, 0xfe,
- 0xdd, 0x6f, 0xd3, 0xc3, 0x2e, 0xfa, 0x84, 0x7d },
{ 0xad, 0x69, 0x54, 0x5f, 0x9f, 0x85, 0x25, 0x5f,
0xe4, 0x16, 0x51, 0x3d, 0x94, 0xdb, 0x31, 0x50,
0x5f, 0x38, 0x4b, 0x52, 0x3c, 0x2c, 0xa2, 0x6e,
@@ -1238,18 +1078,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xe8, 0x54, 0xb5, 0x15, 0x50, 0xea, 0x44, 0x4f,
0xa3, 0xb8, 0xbb, 0x50, 0xae, 0x93, 0x74, 0x01,
0x3c, 0xfe, 0xf3, 0x88, 0x73, 0x5d, 0x0b, 0xd3 },
- { 0xae, 0x4d, 0xf3, 0x97, 0x9b, 0x74, 0x27, 0x34,
- 0xa3, 0x39, 0xc4, 0x70, 0x1d, 0x5e, 0x13, 0x21,
- 0x26, 0x3f, 0xf4, 0x4e, 0x67, 0x56, 0x49, 0x05,
- 0xf4, 0x9e, 0x25, 0x34, 0x62, 0xb8, 0x02, 0x25 },
{ 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, 0x6a, 0x9d, 0x88, 0xad, 0xe1, 0x24, 0xdb,
- 0xf9, 0x50, 0xb2, 0xc4, 0x27, 0xbc, 0x40, 0x19,
- 0x63, 0xb9, 0x61, 0x25, 0xc0, 0xa2, 0xae, 0xbb,
- 0x7f, 0xb3, 0xf9, 0x8e, 0x48, 0x7a, 0x7f, 0xa6 },
{ 0xaf, 0x6b, 0x80, 0x51, 0x47, 0x14, 0x0a, 0x0e,
0x41, 0x81, 0xd8, 0x6a, 0x7e, 0x8f, 0x07, 0x69,
0xb6, 0x1d, 0x46, 0xd7, 0xb6, 0xfa, 0xc6, 0xe6,
@@ -1274,22 +1106,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0xe6, 0x42, 0x06, 0x6e, 0x41, 0x78, 0x67,
- 0xd9, 0x0f, 0xb9, 0xb2, 0xba, 0x15, 0x41, 0x98,
- 0xa5, 0xc5, 0xf6, 0xcc, 0x82, 0x9b, 0x51, 0x39,
- 0xdf, 0xd6, 0x91, 0xe5, 0x1a, 0xd3, 0x74, 0xad },
{ 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 },
- { 0xb4, 0xd4, 0x67, 0xfc, 0x5e, 0x97, 0xdb, 0x25,
- 0xa1, 0xfd, 0xb0, 0x06, 0xd2, 0x77, 0x66, 0xb9,
- 0x99, 0x5b, 0xb9, 0xc7, 0x7b, 0x66, 0x43, 0x97,
- 0x08, 0xa4, 0x59, 0xb0, 0x43, 0xd0, 0x33, 0x24 },
- { 0xb4, 0xed, 0xcd, 0x6f, 0x8a, 0x01, 0x82, 0xb7,
- 0x17, 0xf0, 0x6f, 0xe1, 0xd7, 0xac, 0x9c, 0x62,
- 0x33, 0xd4, 0x38, 0x22, 0xe9, 0xfd, 0x14, 0xdb,
- 0x98, 0xf7, 0xf8, 0x4e, 0x32, 0x79, 0x6d, 0x08 },
{ 0xb5, 0xe5, 0xdc, 0xde, 0xcb, 0x8d, 0xeb, 0x27,
0x13, 0x4f, 0x02, 0xa5, 0x18, 0x79, 0x43, 0x16,
0xf0, 0x8f, 0xaf, 0x9c, 0x2b, 0x1f, 0xda, 0xd6,
@@ -1298,10 +1118,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x1f, 0x29, 0x1e, 0x6e, 0xc6, 0xbd, 0x6c,
- 0x4f, 0x2b, 0x81, 0xf7, 0xf7, 0x21, 0x06, 0x73,
- 0xe9, 0x73, 0x08, 0xaf, 0xf1, 0x24, 0x3f, 0x26,
- 0x99, 0x5a, 0x25, 0xfa, 0x23, 0x0c, 0xfe, 0x4c },
{ 0xb7, 0xa2, 0xae, 0x06, 0x06, 0xaa, 0x2c, 0xfb,
0x27, 0x01, 0xb3, 0xb2, 0x77, 0xf4, 0xd7, 0x12,
0x54, 0x70, 0x48, 0x7e, 0xfd, 0x94, 0x05, 0x85,
@@ -1310,10 +1126,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0xef, 0x73, 0xde, 0x4b, 0x74, 0xf2, 0x83, 0xc4,
0x2b, 0x2c, 0xcb, 0x1c, 0xa3, 0x7c, 0x5b, 0x30,
0xaa, 0xd6, 0x55, 0xa7, 0x40, 0x1a, 0x3d, 0x2f },
- { 0xb8, 0x8c, 0xe8, 0x1a, 0x7b, 0x4b, 0x62, 0x65,
- 0x71, 0x0f, 0x38, 0xd0, 0xca, 0x3e, 0x01, 0xff,
- 0xab, 0xde, 0x0f, 0xc2, 0x48, 0x3e, 0x21, 0xb8,
- 0xf1, 0xa5, 0xff, 0x48, 0x3b, 0x2d, 0x60, 0xce },
{ 0xb9, 0x8d, 0x83, 0x38, 0x55, 0xc3, 0x67, 0x88,
0x62, 0xb6, 0x2f, 0x36, 0x50, 0xdb, 0x00, 0xa3,
0x45, 0xf4, 0x6a, 0x0e, 0x8e, 0x01, 0x1a, 0x20,
@@ -1442,10 +1254,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x43, 0x10, 0x03, 0xbb, 0xea, 0xb5, 0x8e,
- 0x35, 0x2f, 0xde, 0xb4, 0x5b, 0x7f, 0xcf, 0x15,
- 0xc7, 0x3f, 0x07, 0x34, 0xa0, 0x7d, 0x6c, 0xbd,
- 0xf6, 0x32, 0x92, 0x92, 0xeb, 0x81, 0x2c, 0x93 },
{ 0xc9, 0x72, 0xf4, 0xf9, 0x6e, 0x71, 0x33, 0xe1,
0x6e, 0x55, 0x57, 0xa0, 0x57, 0xb1, 0xd4, 0x2b,
0xa9, 0x2d, 0x98, 0x5c, 0xae, 0xe7, 0x3c, 0xaf,
@@ -1470,10 +1278,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x2a, 0x70, 0x6f, 0xe6, 0x8f, 0x5d, 0x17,
- 0xf4, 0xab, 0xaf, 0x60, 0x86, 0xe5, 0xbd, 0x97,
- 0xae, 0x35, 0xeb, 0x35, 0x9f, 0x75, 0xc0, 0x92,
- 0xbb, 0xa4, 0x93, 0xfe, 0x11, 0xf2, 0x69, 0xfd },
{ 0xcc, 0x30, 0xd8, 0x19, 0xde, 0x54, 0x05, 0xf6,
0x49, 0xc8, 0xb7, 0xa8, 0x14, 0x8f, 0x26, 0xd7,
0x71, 0x08, 0x3e, 0xc5, 0x18, 0xf9, 0xb6, 0x6f,
@@ -1554,14 +1358,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x1a, 0xf6, 0x6b, 0xfa, 0x8f, 0x90, 0xd1, 0x41,
0xe9, 0x93, 0xf0, 0x00, 0x21, 0x33, 0xf2, 0x8d,
0xe9, 0x7f, 0x56, 0x4a, 0x1d, 0x60, 0x4e, 0xcc },
- { 0xd9, 0x7f, 0x55, 0xb9, 0x57, 0x9b, 0x05, 0xae,
- 0x4a, 0x3e, 0xd7, 0xfc, 0x55, 0x8c, 0x58, 0x45,
- 0x64, 0x51, 0x60, 0xda, 0xb3, 0x53, 0x85, 0xc1,
- 0x38, 0xbc, 0x89, 0x9c, 0x4d, 0xad, 0x8b, 0x36 },
- { 0xd9, 0xe8, 0xcc, 0xda, 0x78, 0xfb, 0x8d, 0x5d,
- 0xbc, 0xe6, 0x94, 0x15, 0x57, 0x61, 0xf4, 0xd0,
- 0x2c, 0x30, 0xcc, 0x8d, 0x7a, 0xea, 0x0e, 0x11,
- 0x88, 0x2d, 0x79, 0x37, 0x6c, 0x72, 0x90, 0xff },
{ 0xda, 0xdf, 0x97, 0x13, 0x34, 0x14, 0xad, 0x51,
0x3f, 0xc7, 0x50, 0x14, 0xe9, 0x56, 0x65, 0xda,
0xd7, 0x76, 0xb1, 0x50, 0x4b, 0x15, 0x67, 0x43,
@@ -1570,10 +1366,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x64, 0x8d, 0x0e, 0xd8, 0x9b, 0x5d, 0xe0, 0xee,
0x93, 0x1f, 0x1b, 0x33, 0x84, 0x78, 0xab, 0xf5,
0x69, 0x29, 0xa9, 0x4d, 0x3b, 0xd6, 0x1d, 0x46 },
- { 0xdc, 0xb2, 0x1d, 0xef, 0x3c, 0x26, 0x0b, 0x20,
- 0x50, 0xf3, 0x4c, 0x5f, 0x51, 0xbe, 0x30, 0x9c,
- 0x3c, 0x76, 0x36, 0x30, 0x6d, 0x51, 0xb9, 0xbe,
- 0x43, 0xd8, 0x9d, 0xe0, 0x8f, 0x60, 0xd9, 0x4a },
{ 0xde, 0xcd, 0xb9, 0xfc, 0x1d, 0xde, 0xc9, 0x7e,
0x09, 0xc3, 0x02, 0x6a, 0xce, 0xb7, 0x6b, 0xda,
0xe9, 0xde, 0xb6, 0x62, 0x75, 0x1d, 0xda, 0x34,
@@ -1638,18 +1430,10 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x89, 0x0b, 0xc1, 0xf9, 0xfa, 0x00, 0xd8, 0x09,
0x0b, 0x5a, 0xc9, 0x82, 0x5e, 0xa9, 0xd2, 0xfd,
0xf7, 0x7c, 0xa4, 0xda, 0xe9, 0x44, 0x51, 0xb2 },
- { 0xe7, 0x5d, 0x32, 0x90, 0xa6, 0x9a, 0xb5, 0x96,
- 0xee, 0x17, 0x9d, 0xc1, 0x34, 0xaa, 0x07, 0x1e,
- 0x69, 0xfd, 0x98, 0x25, 0xfc, 0x06, 0x2e, 0x33,
- 0x8b, 0xa2, 0x23, 0x5e, 0xe3, 0x25, 0x56, 0xd2 },
{ 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 },
- { 0xe8, 0x21, 0x3c, 0x45, 0x51, 0x81, 0x61, 0xbc,
- 0x36, 0x37, 0x3d, 0xcd, 0x2d, 0x4b, 0x21, 0xb7,
- 0x6a, 0x7c, 0x06, 0x6d, 0xf5, 0x52, 0x6e, 0x88,
- 0x8b, 0x6e, 0xed, 0x09, 0xa9, 0xee, 0xd0, 0x62 },
{ 0xe9, 0xd4, 0x98, 0x51, 0xbf, 0x78, 0x37, 0x6d,
0x54, 0x08, 0x2d, 0x1e, 0xb8, 0x2b, 0xd2, 0xdc,
0x96, 0x82, 0x07, 0x09, 0xb7, 0x77, 0x2d, 0x3f,
@@ -1686,10 +1470,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x1a, 0x2f, 0xa9, 0x58, 0x37, 0x5e, 0x11,
- 0x06, 0xe2, 0xc9, 0x05, 0xed, 0x8a, 0x26, 0x4f,
- 0x28, 0x19, 0xcb, 0xb5, 0x26, 0x11, 0x8d, 0x30,
- 0x68, 0x9d, 0x17, 0x90, 0x42, 0x9a, 0x46, 0xa1 },
{ 0xee, 0x34, 0xe1, 0xa1, 0x9b, 0xc8, 0x89, 0xf8,
0x5f, 0x7f, 0x0f, 0x5b, 0xf8, 0x72, 0xb1, 0xac,
0x56, 0x5e, 0xc6, 0xf1, 0x9d, 0xb5, 0x17, 0xba,
@@ -1706,14 +1486,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0x11, 0xad, 0x9e, 0xdd, 0x4f, 0xe7, 0x18,
- 0x8d, 0x77, 0x2e, 0xba, 0xfa, 0x5b, 0xf5, 0x32,
- 0x92, 0x47, 0x77, 0x88, 0xdc, 0x12, 0x80, 0x32,
- 0x76, 0xb0, 0x00, 0xc4, 0x41, 0x91, 0x03, 0xf0 },
- { 0xf0, 0x2f, 0x9d, 0xa4, 0x5d, 0x9e, 0xb9, 0x86,
- 0x19, 0x4e, 0x06, 0xf5, 0xe6, 0x18, 0x95, 0x45,
- 0x12, 0xc9, 0x02, 0x6e, 0x7c, 0xa7, 0xb5, 0x1e,
- 0x66, 0x5d, 0xb6, 0xad, 0xba, 0xc1, 0xf6, 0x00 },
{ 0xf0, 0x6b, 0x35, 0x95, 0x36, 0xd1, 0x34, 0x32,
0x8b, 0x36, 0x00, 0x4d, 0xa9, 0xa9, 0x19, 0x0c,
0x3a, 0x76, 0x69, 0xe8, 0x27, 0x8d, 0xb9, 0xf7,
@@ -1742,14 +1514,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
0x35, 0xe8, 0x25, 0x67, 0xa6, 0xe2, 0x36, 0x75,
0x03, 0x94, 0xc1, 0x19, 0x14, 0x09, 0x87, 0x0c,
0x6f, 0xbe, 0x95, 0x2d, 0x08, 0xa3, 0x3a, 0xba },
- { 0xf6, 0x6e, 0xdf, 0xf6, 0xa3, 0x94, 0xc6, 0x6d,
- 0xf5, 0xbf, 0x9f, 0xe7, 0x84, 0xe6, 0x31, 0xf7,
- 0x9a, 0xf3, 0x9c, 0xb1, 0x4f, 0x3a, 0xc5, 0x16,
- 0x11, 0xf6, 0xfe, 0x1d, 0x9d, 0x1e, 0x1c, 0xe9 },
- { 0xf6, 0xaa, 0xef, 0x12, 0xfc, 0x25, 0x2d, 0xd9,
- 0xe7, 0xf7, 0x75, 0x2c, 0x2f, 0x74, 0x5d, 0x59,
- 0xd6, 0x37, 0x57, 0xc6, 0xcc, 0x14, 0xd2, 0x25,
- 0x3a, 0x64, 0x7c, 0xd1, 0x81, 0x49, 0x39, 0x93 },
{ 0xf8, 0x64, 0x44, 0x3e, 0x2f, 0x63, 0x9e, 0x7c,
0xff, 0xd2, 0x42, 0x21, 0xf6, 0x1b, 0xbf, 0xf0,
0x7c, 0xce, 0x5c, 0x61, 0xdd, 0xb1, 0x68, 0xb3,
@@ -1770,10 +1534,6 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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, 0xdd, 0x65, 0xd5, 0x6e, 0x48, 0x0c, 0xd2,
- 0x53, 0x1b, 0xab, 0xfb, 0x98, 0xad, 0x6e, 0x35,
- 0x22, 0x1e, 0xb9, 0x8a, 0xe4, 0x63, 0x2c, 0x43,
- 0x12, 0xdb, 0x75, 0x17, 0xb1, 0x36, 0x54, 0x72 },
{ 0xfb, 0xed, 0xd3, 0x88, 0x89, 0xf0, 0xb4, 0x1f,
0x73, 0x4d, 0xe2, 0xf4, 0xc9, 0xd6, 0xf2, 0x7c,
0x8d, 0x4a, 0xa9, 0xab, 0x73, 0x64, 0x91, 0xe1,
@@ -1831,11 +1591,9 @@ const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
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] = {
- { 0x9f, 0xfa, 0x4e, 0xf4, 0xfc, 0xf2, 0xcf, 0xd1,
- 0xb2, 0x7c, 0x6a, 0x62, 0xe3, 0xc4, 0x23, 0x5b,
- 0xd8, 0x3c, 0xc5, 0xe0, 0x06, 0xe9, 0x2a, 0x55,
- 0xe4, 0xa9, 0x86, 0xe6, 0x30, 0x53, 0x57, 0xe3 },
{ 0xb5, 0xef, 0x42, 0xc4, 0xbc, 0xed, 0xf1, 0x7b,
0xec, 0xc7, 0x5b, 0xf4, 0x63, 0x66, 0x49, 0xce,
0xbf, 0xf8, 0x71, 0x1b, 0xce, 0xff, 0xfa, 0x69,
@@ -1844,10 +1602,6 @@ const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
0x4b, 0xcf, 0x60, 0xf2, 0x38, 0x21, 0xac, 0x6c,
0x58, 0x19, 0x73, 0x51, 0xea, 0xcf, 0xa5, 0x57,
0x4c, 0xf0, 0x41, 0xb4, 0xce, 0x6b, 0x84, 0x04 },
- { 0xba, 0xcf, 0x5e, 0x99, 0xf5, 0x7f, 0x78, 0xcc,
- 0x32, 0xf2, 0xaf, 0x8d, 0x4e, 0x80, 0x6a, 0x0a,
- 0x36, 0xce, 0x9b, 0x42, 0xe9, 0xc7, 0x5c, 0x54,
- 0x8d, 0xed, 0x55, 0xd2, 0x48, 0x62, 0xca, 0x17 },
{ 0xdf, 0x69, 0xf9, 0x6a, 0x85, 0x67, 0x8f, 0x6c,
0xaf, 0x3f, 0xde, 0x25, 0xec, 0xfb, 0x5d, 0xf4,
0x74, 0x70, 0x87, 0xc2, 0xaf, 0x3b, 0x00, 0x65,
@@ -1884,36 +1638,54 @@ 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 CompareHashValueToRawHash(const void* key, const void* element) {
+// 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.
+int CompareHashValueToRawHash(const void* key, const void* element) {
+ const HashValue* search_key = reinterpret_cast<const HashValue*>(key);
+ return memcmp(search_key->data(), element, search_key->size());
+}
+
} // namespace
bool IsNonWhitelistedCertificate(const X509Certificate& cert,
const HashValueVector& public_key_hashes) {
- if (g_whitelist_size == 0)
- return false;
- for (size_t i = 0; i < g_whitelist_size; ++i) {
- for (const auto& hash : public_key_hashes) {
- if (hash.tag != HASH_VALUE_SHA256)
- continue;
+ // 2016-10-21 00:00:00 UTC
+ const base::Time last_wosign_cert =
+ base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1477008000);
+
+ 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;
}
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, CompareHashValueToRawHash);
+ void* result = bsearch(
+ &leaf_hash, g_whitelist[i].whitelist, g_whitelist[i].whitelist_size,
+ crypto::kSHA256Length, CompareSHA256HashValueToRawHash);
if (result == nullptr)
- return true;
- return false;
+ return true; // Hash was not found on the public key whitelist.
+ break;
}
}
return false;
diff --git a/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc b/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
index dea54129ba8..791957315a6 100644
--- a/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_whitelist_unittest.cc
@@ -184,6 +184,25 @@ TEST(CertVerifyProcWhitelistTest, AcceptsUnconstrainedLeaf) {
SetCertificateWhitelistForTesting(nullptr, 0);
}
+TEST(CertVerifyProcWhitelistTest, HandlesWosignCerts) {
+ scoped_refptr<X509Certificate> cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "wosign_before_oct_21.pem");
+ ASSERT_TRUE(cert);
+
+ HashValueVector public_key_hashes;
+ public_key_hashes.emplace_back(SHA256HashValue{
+ {0x15, 0x28, 0x39, 0x7d, 0xa2, 0x12, 0x89, 0x0a, 0x83, 0x0b, 0x0b,
+ 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));
+
+ cert = ImportCertFromFile(GetTestCertsDirectory(), "wosign_after_oct_21.pem");
+ ASSERT_TRUE(cert);
+
+ EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index a2647969d80..a13117a7a8e 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/memory/free_deleter.h"
+#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -78,6 +79,8 @@ int MapSecurityError(SECURITY_STATUS err) {
return ERR_CERT_COMMON_NAME_INVALID;
case SEC_E_UNTRUSTED_ROOT: // Schannel
case CERT_E_UNTRUSTEDROOT: // CryptoAPI
+ case TRUST_E_CERT_SIGNATURE: // CryptoAPI. Caused by weak crypto or bad
+ // signatures, but not differentiable.
return ERR_CERT_AUTHORITY_INVALID;
case SEC_E_CERT_EXPIRED: // Schannel
case CERT_E_EXPIRED: // CryptoAPI
@@ -283,8 +286,44 @@ bool IsIssuedByKnownRoot(PCCERT_CHAIN_CONTEXT chain_context) {
PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext;
SHA256HashValue hash = X509Certificate::CalculateFingerprint256(cert);
- return IsSHA256HashInSortedArray(hash, &kKnownRootCertSHA256Hashes[0][0],
- sizeof(kKnownRootCertSHA256Hashes));
+ bool is_builtin =
+ IsSHA256HashInSortedArray(hash, &kKnownRootCertSHA256Hashes[0][0],
+ sizeof(kKnownRootCertSHA256Hashes));
+
+ // Test to see if the use of a built-in set of known roots on Windows can be
+ // replaced with using AuthRoot's SHA-256 property. On any system other than
+ // a fresh RTM with no AuthRoot updates, this property should always exist for
+ // roots delivered via AuthRoot.stl, but should not exist on any manually or
+ // administratively deployed roots.
+ BYTE hash_prop[32] = {0};
+ DWORD size = sizeof(hash_prop);
+ bool found_property =
+ CertGetCertificateContextProperty(
+ cert, CERT_AUTH_ROOT_SHA256_HASH_PROP_ID, &hash_prop, &size) &&
+ size == sizeof(hash_prop);
+
+ enum BuiltinStatus {
+ BUILT_IN_PROPERTY_NOT_FOUND_BUILTIN_NOT_SET = 0,
+ BUILT_IN_PROPERTY_NOT_FOUND_BUILTIN_SET = 1,
+ BUILT_IN_PROPERTY_FOUND_BUILTIN_NOT_SET = 2,
+ BUILT_IN_PROPERTY_FOUND_BUILTIN_SET = 3,
+ BUILT_IN_MAX_VALUE,
+ } status;
+ if (!found_property && !is_builtin) {
+ status = BUILT_IN_PROPERTY_NOT_FOUND_BUILTIN_NOT_SET;
+ } else if (!found_property && is_builtin) {
+ status = BUILT_IN_PROPERTY_NOT_FOUND_BUILTIN_SET;
+ } else if (found_property && !is_builtin) {
+ status = BUILT_IN_PROPERTY_FOUND_BUILTIN_NOT_SET;
+ } else if (found_property && is_builtin) {
+ status = BUILT_IN_PROPERTY_FOUND_BUILTIN_SET;
+ } else {
+ status = BUILT_IN_MAX_VALUE;
+ }
+ UMA_HISTOGRAM_ENUMERATION("Net.SSL_AuthRootConsistency", status,
+ BUILT_IN_MAX_VALUE);
+
+ return is_builtin;
}
// Saves some information about the certificate chain |chain_context| in
@@ -974,16 +1013,68 @@ int CertVerifyProcWin::VerifyInternal(
CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, &ocsp_response_blob);
}
+ CERT_STRONG_SIGN_SERIALIZED_INFO strong_signed_info;
+ memset(&strong_signed_info, 0, sizeof(strong_signed_info));
+ strong_signed_info.dwFlags = 0; // Don't check OCSP or CRL signatures.
+
+ // Note that the following two configurations result in disabling support for
+ // any CNG-added algorithms, which may result in some disruption for internal
+ // PKI operations that use national forms of crypto (e.g. GOST). However, the
+ // fallback mechanism for this (to support SHA-1 chains) will re-enable them,
+ // so they should continue to work - just with added latency.
+ wchar_t hash_algs[] =
+ L"RSA/SHA256;RSA/SHA384;RSA/SHA512;"
+ L"ECDSA/SHA256;ECDSA/SHA384;ECDSA/SHA512";
+ strong_signed_info.pwszCNGSignHashAlgids = hash_algs;
+
+ // RSA-1024 bit support is intentionally enabled here. More investigation is
+ // needed to determine if setting CERT_STRONG_SIGN_DISABLE_END_CHECK_FLAG in
+ // the dwStrongSignFlags of |chain_para| would allow the ability to disable
+ // support for intermediates/roots < 2048-bits, while still ensuring that
+ // end-entity certs signed with SHA-1 are flagged/rejected.
+ wchar_t key_sizes[] = L"RSA/1024;ECDSA/256";
+ strong_signed_info.pwszCNGPubKeyMinBitLengths = key_sizes;
+
+ CERT_STRONG_SIGN_PARA strong_sign_params;
+ memset(&strong_sign_params, 0, sizeof(strong_sign_params));
+ strong_sign_params.cbSize = sizeof(strong_sign_params);
+ strong_sign_params.dwInfoChoice = CERT_STRONG_SIGN_SERIALIZED_INFO_CHOICE;
+ strong_sign_params.pSerializedInfo = &strong_signed_info;
+
+ chain_para.dwStrongSignFlags = 0;
+ chain_para.pStrongSignPara = &strong_sign_params;
+
PCCERT_CHAIN_CONTEXT chain_context = nullptr;
- if (!CertGetCertificateChain(
- chain_engine,
- cert_list.get(),
- NULL, // current system time
- cert_list->hCertStore,
- &chain_para,
- chain_flags,
- NULL, // reserved
- &chain_context)) {
+
+ // First, try to verify with strong signing enabled. If this fails, or if the
+ // chain is rejected, then clear it from |chain_para| so that all subsequent
+ // calls will use the fallback path.
+ BOOL chain_result =
+ CertGetCertificateChain(chain_engine, cert_list.get(),
+ NULL, // current system time
+ cert_list->hCertStore, &chain_para, chain_flags,
+ NULL, // reserved
+ &chain_context);
+ if (chain_result && chain_context &&
+ (chain_context->TrustStatus.dwErrorStatus &
+ (CERT_TRUST_HAS_WEAK_SIGNATURE | CERT_TRUST_IS_NOT_SIGNATURE_VALID))) {
+ // The attempt to verify with strong-sign (only SHA-2) failed, so fall back
+ // to disabling it. This will allow SHA-1 chains to be returned, which will
+ // then be subsequently signalled as weak if necessary.
+ CertFreeCertificateChain(chain_context);
+ chain_context = nullptr;
+
+ chain_para.pStrongSignPara = nullptr;
+ chain_para.dwStrongSignFlags = 0;
+ chain_result =
+ CertGetCertificateChain(chain_engine, cert_list.get(),
+ NULL, // current system time
+ cert_list->hCertStore, &chain_para, chain_flags,
+ NULL, // reserved
+ &chain_context);
+ }
+
+ if (!chain_result) {
verify_result->cert_status |= CERT_STATUS_INVALID;
return MapSecurityError(GetLastError());
}
diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc
index 04eb2f15a12..2af57306d2c 100644
--- a/chromium/net/cert/ct_log_verifier.cc
+++ b/chromium/net/cert/ct_log_verifier.cc
@@ -5,17 +5,19 @@
#include "net/cert/ct_log_verifier.h"
#include <string.h>
-#include <openssl/bytestring.h>
-#include <openssl/evp.h>
+
+#include <vector>
#include "base/logging.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "crypto/sha2.h"
#include "net/cert/ct_log_verifier_util.h"
#include "net/cert/ct_serialization.h"
+#include "net/cert/merkle_audit_proof.h"
#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_tree_head.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
namespace net {
@@ -243,6 +245,61 @@ bool CTLogVerifier::VerifyConsistencyProof(
return fr == old_tree_hash && sr == new_tree_hash && sn == 0;
}
+bool CTLogVerifier::VerifyAuditProof(const ct::MerkleAuditProof& proof,
+ const std::string& root_hash,
+ const std::string& leaf_hash) const {
+ // Implements the algorithm described in
+ // https://tools.ietf.org/html/draft-ietf-trans-rfc6962-bis-19#section-10.4.1
+ //
+ // It maintains a hash |r|, initialized to |leaf_hash|, and hashes nodes from
+ // |proof| into it. The proof is then valid if |r| is |root_hash|, proving
+ // that |root_hash| includes |leaf_hash|.
+
+ // 1. Compare "leaf_index" against "tree_size". If "leaf_index" is
+ // greater than or equal to "tree_size" fail the proof verification.
+ if (proof.leaf_index >= proof.tree_size)
+ return false;
+
+ // 2. Set "fn" to "leaf_index" and "sn" to "tree_size - 1".
+ uint64_t fn = proof.leaf_index;
+ uint64_t sn = proof.tree_size - 1;
+ // 3. Set "r" to "hash".
+ std::string r = leaf_hash;
+
+ // 4. For each value "p" in the "inclusion_path" array:
+ for (const std::string& p : proof.nodes) {
+ // If "sn" is 0, stop the iteration and fail the proof verification.
+ if (sn == 0)
+ return false;
+
+ // If "LSB(fn)" is set, or if "fn" is equal to "sn", then:
+ if ((fn & 1) || fn == sn) {
+ // 1. Set "r" to "HASH(0x01 || p || r)"
+ r = ct::internal::HashNodes(p, r);
+
+ // 2. If "LSB(fn)" is not set, then right-shift both "fn" and "sn"
+ // equally until either "LSB(fn)" is set or "fn" is "0".
+ while (!(fn & 1) && fn != 0) {
+ fn >>= 1;
+ sn >>= 1;
+ }
+ } else { // Otherwise:
+ // Set "r" to "HASH(0x01 || r || p)"
+ r = ct::internal::HashNodes(r, p);
+ }
+
+ // Finally, right-shift both "fn" and "sn" one time.
+ fn >>= 1;
+ sn >>= 1;
+ }
+
+ // 5. Compare "sn" to 0. Compare "r" against the "root_hash". If "sn"
+ // is equal to 0, and "r" and the "root_hash" are equal, then the
+ // log has proven the inclusion of "hash". Otherwise, fail the
+ // proof verification.
+ return sn == 0 && r == root_hash;
+}
+
CTLogVerifier::~CTLogVerifier() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
diff --git a/chromium/net/cert/ct_log_verifier.h b/chromium/net/cert/ct_log_verifier.h
index e9ba307c3e9..6e3b938eb0b 100644
--- a/chromium/net/cert/ct_log_verifier.h
+++ b/chromium/net/cert/ct_log_verifier.h
@@ -21,10 +21,9 @@ typedef struct evp_pkey_st EVP_PKEY;
namespace net {
namespace ct {
-
-struct SignedTreeHead;
+struct MerkleAuditProof;
struct MerkleConsistencyProof;
-
+struct SignedTreeHead;
} // namespace ct
// Class for verifying signatures of a single Certificate Transparency
@@ -76,6 +75,14 @@ class NET_EXPORT CTLogVerifier
const std::string& old_tree_hash,
const std::string& new_tree_hash) const;
+ // Verifies that |proof| is a valid audit proof (RFC 6962, Section 2.1.1) for
+ // this log, and which proves that the certificate represented by |leaf_hash|
+ // has been incorporated into the Merkle tree represented by |root_hash|.
+ // Returns true if verification succeeds, false otherwise.
+ bool VerifyAuditProof(const ct::MerkleAuditProof& proof,
+ const std::string& root_hash,
+ const std::string& leaf_hash) const;
+
private:
FRIEND_TEST_ALL_PREFIXES(CTLogVerifierTest, VerifySignature);
friend class base::RefCountedThreadSafe<CTLogVerifier>;
diff --git a/chromium/net/cert/ct_log_verifier_unittest.cc b/chromium/net/cert/ct_log_verifier_unittest.cc
index 91ddbc737e3..9067cb6e394 100644
--- a/chromium/net/cert/ct_log_verifier_unittest.cc
+++ b/chromium/net/cert/ct_log_verifier_unittest.cc
@@ -10,11 +10,13 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "crypto/secure_hash.h"
#include "net/base/hash_value.h"
#include "net/cert/ct_log_verifier_util.h"
+#include "net/cert/merkle_audit_proof.h"
#include "net/cert/merkle_consistency_proof.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_tree_head.h"
@@ -27,37 +29,45 @@ namespace {
// Calculate the power of two nearest to, but less than, |n|.
// |n| must be at least 2.
-uint64_t CalculateNearestPowerOfTwo(uint64_t n) {
+size_t CalculateNearestPowerOfTwo(size_t n) {
DCHECK_GT(n, 1u);
- uint64_t ret = UINT64_C(1) << 63;
+ size_t ret = size_t(1) << (sizeof(size_t) * 8 - 1);
while (ret >= n)
ret >>= 1;
return ret;
}
-// A single consistency proof. Contains the old and new tree sizes
-// (snapshot1 and snapshot2), the length of the proof (proof_length) and
-// at most 3 proof nodes (all test proofs will be for a tree of size 8).
-struct ProofTestVector {
- uint64_t snapshot1;
- uint64_t snapshot2;
- size_t proof_length;
- const char* const proof[3];
-};
-
// All test data replicated from
// https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc
-// A hash of the empty string.
-const uint8_t kSHA256EmptyTreeHash[32] = {
+
+// The SHA-256 hash of an empty Merkle tree.
+const uint8_t kEmptyTreeHash[32] = {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
-// Root hashes from building the sample tree of size 8 leaf-by-leaf.
-// The first entry is the root at size 0, the last is the root at size 8.
-const char* const kSHA256Roots[8] = {
+std::string GetEmptyTreeHash() {
+ return std::string(std::begin(kEmptyTreeHash), std::end(kEmptyTreeHash));
+}
+
+// SHA-256 Merkle leaf hashes for the sample tree that all of the other test
+// data relates to (8 leaves).
+const char* const kLeafHashes[8] = {
+ "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d",
+ "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7",
+ "0298d122906dcfc10892cb53a73992fc5b9f493ea4c9badb27b791b4127a7fe7",
+ "07506a85fd9dd2f120eb694f86011e5bb4662e5c415a62917033d4a9624487e7",
+ "bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b",
+ "4271a26be0d8a84f0bd54c8c302e7cb3a3b5d1fa6780a40bcce2873477dab658",
+ "b08693ec2e721597130641e8211e7eedccb4c26413963eee6c1e2ed16ffb1a5f",
+ "46f6ffadd3d06a09ff3c5860d2755c8b9819db7df44251788c7d8e3180de8eb1"};
+
+// SHA-256 Merkle root hashes from building the sample tree leaf-by-leaf.
+// The first entry is the root when the tree contains 1 leaf, and the last is
+// the root when the tree contains all 8 leaves.
+const char* const kRootHashes[8] = {
"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d",
"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125",
"aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77",
@@ -67,9 +77,18 @@ const char* const kSHA256Roots[8] = {
"ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c",
"5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328"};
-// A collection of consistency proofs between various sub-trees of the tree
-// defined by |kSHA256Roots|.
-const ProofTestVector kSHA256Proofs[4] = {
+// A single consistency proof. Contains at most 3 proof nodes (all test proofs
+// will be for a tree of size 8).
+struct ConsistencyProofTestVector {
+ size_t old_tree_size;
+ size_t new_tree_size;
+ size_t proof_length;
+ const char* const proof[3];
+};
+
+// A collection of consistency proofs between various sub-trees of the sample
+// tree.
+const ConsistencyProofTestVector kConsistencyProofs[] = {
// Empty consistency proof between trees of the same size (1).
{1, 1, 0, {"", "", ""}},
// Consistency proof between tree of size 1 and tree of size 8, with 3
@@ -96,6 +115,43 @@ const ProofTestVector kSHA256Proofs[4] = {
{"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e",
"bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b", ""}}};
+// A single audit proof. Contains at most 3 proof nodes (all test proofs will be
+// for a tree of size 8).
+struct AuditProofTestVector {
+ size_t leaf;
+ size_t tree_size;
+ size_t proof_length;
+ const char* const proof[3];
+};
+
+// A collection of audit proofs for various leaves and sub-trees of the tree
+// defined by |kRootHashes|.
+const AuditProofTestVector kAuditProofs[] = {
+ {0, 1, 0, {"", "", ""}},
+ {0,
+ 8,
+ 3,
+ {"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7",
+ "5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e",
+ "6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4"}},
+ {5,
+ 8,
+ 3,
+ {"bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b",
+ "ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0",
+ "d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7"}},
+ {2,
+ 3,
+ 1,
+ {"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", "",
+ ""}},
+ {1,
+ 5,
+ 3,
+ {"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d",
+ "5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e",
+ "bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b"}}};
+
// Decodes a hexadecimal string into the binary data it represents.
std::string HexToBytes(const std::string& hex_data) {
std::vector<uint8_t> output;
@@ -105,131 +161,232 @@ std::string HexToBytes(const std::string& hex_data) {
return result;
}
-std::string GetEmptyTreeHash() {
- return std::string(std::begin(kSHA256EmptyTreeHash),
- std::end(kSHA256EmptyTreeHash));
+// Constructs a consistency/audit proof from a test vector.
+// This is templated so that it can be used with both ConsistencyProofTestVector
+// and AuditProofTestVector.
+template <typename TestVectorType>
+std::vector<std::string> GetProof(const TestVectorType& test_vector) {
+ std::vector<std::string> proof(test_vector.proof_length);
+ std::transform(test_vector.proof,
+ test_vector.proof + test_vector.proof_length, proof.begin(),
+ &HexToBytes);
+
+ return proof;
}
-// Creates a ct::MerkleConsistencyProof and returns the result of
-// calling log->VerifyConsistencyProof with that proof and snapshots.
-bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log,
- uint64_t old_tree_size,
+// Creates a ct::MerkleConsistencyProof from its arguments and returns the
+// result of passing this to log.VerifyConsistencyProof().
+bool VerifyConsistencyProof(const CTLogVerifier& log,
+ size_t old_tree_size,
const std::string& old_tree_root,
- uint64_t new_tree_size,
+ size_t new_tree_size,
const std::string& new_tree_root,
const std::vector<std::string>& proof) {
- return log->VerifyConsistencyProof(
- ct::MerkleConsistencyProof(log->key_id(), proof, old_tree_size,
+ return log.VerifyConsistencyProof(
+ ct::MerkleConsistencyProof(log.key_id(), proof, old_tree_size,
new_tree_size),
old_tree_root, new_tree_root);
}
+// Creates a ct::MerkleAuditProof from its arguments and returns the result of
+// passing this to log.VerifyAuditProof().
+bool VerifyAuditProof(const CTLogVerifier& log,
+ size_t leaf,
+ size_t tree_size,
+ const std::vector<std::string>& proof,
+ const std::string& tree_root,
+ const std::string& leaf_hash) {
+ return log.VerifyAuditProof(ct::MerkleAuditProof(leaf, tree_size, proof),
+ tree_root, leaf_hash);
+}
+
class CTLogVerifierTest : public ::testing::Test {
public:
- CTLogVerifierTest() {}
-
void SetUp() override {
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
"https://ct.example.com", "ct.example.com");
ASSERT_TRUE(log_);
- ASSERT_EQ(ct::GetTestPublicKeyId(), log_->key_id());
- ASSERT_EQ("ct.example.com", log_->dns_domain());
+ EXPECT_EQ(ct::GetTestPublicKeyId(), log_->key_id());
+ EXPECT_EQ("ct.example.com", log_->dns_domain());
}
- // Given a consistency proof between two snapshots of the tree, asserts that
- // it verifies and no other combination of snapshots and proof nodes verifies.
- void VerifierConsistencyCheck(int snapshot1,
- int snapshot2,
- const std::string& root1,
- const std::string& root2,
- const std::vector<std::string>& proof) {
- // Verify the original consistency proof.
- EXPECT_TRUE(
- VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, root2, proof))
- << " " << snapshot1 << " " << snapshot2;
-
- if (proof.empty()) {
- // For simplicity test only non-trivial proofs that have root1 != root2
- // snapshot1 != 0 and snapshot1 != snapshot2.
- return;
- }
+ protected:
+ scoped_refptr<const CTLogVerifier> log_;
+};
- // Wrong snapshot index: The proof checking code should not accept
- // as a valid proof a proof for a tree size different than the original
- // size it was produced for.
- // Test that this is not the case for off-by-one changes.
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 - 1, root1, snapshot2,
- root2, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 + 1, root1, snapshot2,
- root2, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1 ^ 2, root1, snapshot2,
- root2, proof));
-
- // Test that the proof is not accepted for trees with wrong tree height.
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 * 2,
- root2, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2 / 2,
- root2, proof));
-
- // Test that providing the wrong input root fails checking an
- // otherwise-valid proof.
- const std::string wrong_root("WrongRoot");
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- wrong_root, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, wrong_root, snapshot2,
- root2, proof));
- // Test that swapping roots fails checking an otherwise-valid proof (that
- // the right root is used for each calculation).
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root2, snapshot2,
- root1, proof));
-
- // Variations of wrong proofs, all of which should be rejected.
- std::vector<std::string> wrong_proof;
- // Empty proof.
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
-
- // Modify a single element in the proof.
- for (size_t j = 0; j < proof.size(); ++j) {
- wrong_proof = proof;
- wrong_proof[j] = GetEmptyTreeHash();
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
- }
+// Given an audit proof for a leaf in a Merkle tree, asserts that it verifies
+// and no other combination of leaves, tree sizes and proof nodes verifies.
+void CheckVerifyAuditProof(const CTLogVerifier& log,
+ size_t leaf,
+ size_t tree_size,
+ const std::vector<std::string>& proof,
+ const std::string& root_hash,
+ const std::string& leaf_hash) {
+ EXPECT_TRUE(
+ VerifyAuditProof(log, leaf, tree_size, proof, root_hash, leaf_hash))
+ << "proof for leaf " << leaf << " did not pass verification";
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf - 1, tree_size, proof, root_hash, leaf_hash))
+ << "proof passed verification with wrong leaf index";
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf + 1, tree_size, proof, root_hash, leaf_hash))
+ << "proof passed verification with wrong leaf index";
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf ^ 2, tree_size, proof, root_hash, leaf_hash))
+ << "proof passed verification with wrong leaf index";
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size * 2, proof, root_hash, leaf_hash))
+ << "proof passed verification with wrong tree height";
+ EXPECT_FALSE(VerifyAuditProof(log, leaf / 2, tree_size / 2, proof, root_hash,
+ leaf_hash))
+ << "proof passed verification with wrong leaf index and tree height";
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size / 2, proof, root_hash, leaf_hash))
+ << "proof passed verification with wrong tree height";
+ EXPECT_FALSE(VerifyAuditProof(log, leaf, tree_size, proof, GetEmptyTreeHash(),
+ leaf_hash))
+ << "proof passed verification with wrong root hash";
- // Add garbage at the end of the proof.
+ std::vector<std::string> wrong_proof;
+
+ // Modify a single element on the proof.
+ for (size_t j = 0; j < proof.size(); ++j) {
wrong_proof = proof;
- wrong_proof.push_back(std::string());
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
- wrong_proof.pop_back();
+ wrong_proof[j] = GetEmptyTreeHash();
+ EXPECT_FALSE(VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash,
+ leaf_hash))
+ << "proof passed verification with one wrong node (node " << j << ")";
+ }
- wrong_proof.push_back(proof.back());
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
- wrong_proof.pop_back();
+ wrong_proof = proof;
+ wrong_proof.push_back(std::string());
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash))
+ << "proof passed verification with an empty node appended";
+
+ wrong_proof.back() = root_hash;
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash))
+ << "proof passed verification with an incorrect node appended";
+ wrong_proof.pop_back();
- // Remove a node from the end.
+ if (!wrong_proof.empty()) {
wrong_proof.pop_back();
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
-
- // Add garbage in the beginning of the proof.
- wrong_proof.clear();
- wrong_proof.push_back(std::string());
- wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end());
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
-
- wrong_proof[0] = proof[0];
- EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2,
- root2, wrong_proof));
+ EXPECT_FALSE(VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash,
+ leaf_hash))
+ << "proof passed verification with the last node missing";
}
- protected:
- scoped_refptr<const CTLogVerifier> log_;
-};
+ wrong_proof.clear();
+ wrong_proof.push_back(std::string());
+ wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end());
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash))
+ << "proof passed verification with an empty node prepended";
+
+ wrong_proof[0] = root_hash;
+ EXPECT_FALSE(
+ VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash))
+ << "proof passed verification with an incorrect node prepended";
+}
+
+// Given a consistency proof between two snapshots of the tree, asserts that it
+// verifies and no other combination of tree sizes and proof nodes verifies.
+void CheckVerifyConsistencyProof(const CTLogVerifier& log,
+ int old_tree_size,
+ int new_tree_size,
+ const std::string& old_root,
+ const std::string& new_root,
+ const std::vector<std::string>& proof) {
+ // Verify the original consistency proof.
+ EXPECT_TRUE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, proof))
+ << "proof between trees of size " << old_tree_size << " and "
+ << new_tree_size << " did not pass verification";
+
+ if (proof.empty()) {
+ // For simplicity test only non-trivial proofs that have old_root !=
+ // new_root
+ // old_tree_size != 0 and old_tree_size != new_tree_size.
+ return;
+ }
+
+ // Wrong tree size: The proof checking code should not accept as a valid proof
+ // a proof for a tree size different than the original size it was produced
+ // for. Test that this is not the case for off-by-one changes.
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size - 1, old_root,
+ new_tree_size, new_root, proof))
+ << "proof passed verification with old tree size - 1";
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size + 1, old_root,
+ new_tree_size, new_root, proof))
+ << "proof passed verification with old tree size + 1";
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size ^ 2, old_root,
+ new_tree_size, new_root, proof))
+ << "proof passed verification with old tree size ^ 2";
+
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size * 2, new_root, proof))
+ << "proof passed verification with new tree height + 1";
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size / 2, new_root, proof))
+ << "proof passed verification with new tree height - 1";
+
+ const std::string wrong_root("WrongRoot");
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, wrong_root, proof))
+ << "proof passed verification with wrong old root";
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, wrong_root,
+ new_tree_size, new_root, proof))
+ << "proof passed verification with wrong new root";
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, new_root,
+ new_tree_size, old_root, proof))
+ << "proof passed verification with old and new root swapped";
+
+ // Variations of wrong proofs, all of which should be rejected.
+ std::vector<std::string> wrong_proof;
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "empty proof passed verification";
+
+ // Modify a single element in the proof.
+ for (size_t j = 0; j < proof.size(); ++j) {
+ wrong_proof = proof;
+ wrong_proof[j] = GetEmptyTreeHash();
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with incorrect node (node " << j << ")";
+ }
+
+ wrong_proof = proof;
+ wrong_proof.push_back(std::string());
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with empty node appended";
+
+ wrong_proof.back() = proof.back();
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with last node duplicated";
+ wrong_proof.pop_back();
+
+ wrong_proof.pop_back();
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with last node missing";
+
+ wrong_proof.clear();
+ wrong_proof.push_back(std::string());
+ wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end());
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with empty node prepended";
+
+ wrong_proof[0] = proof[0];
+ EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root,
+ new_tree_size, new_root, wrong_proof))
+ << "proof passed verification with first node duplicated";
+}
TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
ct::LogEntry cert_entry;
@@ -315,33 +472,38 @@ TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_EmptyProof) {
std::vector<std::string> empty_proof;
- std::string root1(GetEmptyTreeHash()), root2(GetEmptyTreeHash());
+ std::string old_root(GetEmptyTreeHash()), new_root(GetEmptyTreeHash());
- // Snapshots that are always consistent, because they are either
- // from an empty tree to a non-empty one or for trees of the same
- // size.
- EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 0, root2, empty_proof));
- EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 1, root2, empty_proof));
- EXPECT_TRUE(VerifyConsistencyProof(log_, 1, root1, 1, root2, empty_proof));
+ // Tree snapshots that are always consistent, because the proofs are either
+ // from an empty tree to a non-empty one or for trees of the same size.
+ EXPECT_TRUE(
+ VerifyConsistencyProof(*log_, 0, old_root, 0, new_root, empty_proof));
+ EXPECT_TRUE(
+ VerifyConsistencyProof(*log_, 0, old_root, 1, new_root, empty_proof));
+ EXPECT_TRUE(
+ VerifyConsistencyProof(*log_, 1, old_root, 1, new_root, empty_proof));
// Invalid consistency proofs.
// Time travel to the past.
- EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 0, root2, empty_proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, 2, root1, 1, root2, empty_proof));
+ EXPECT_FALSE(
+ VerifyConsistencyProof(*log_, 1, old_root, 0, new_root, empty_proof));
+ EXPECT_FALSE(
+ VerifyConsistencyProof(*log_, 2, old_root, 1, new_root, empty_proof));
// Proof between two trees of different size can never be empty.
- EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 2, root2, empty_proof));
+ EXPECT_FALSE(
+ VerifyConsistencyProof(*log_, 1, old_root, 2, new_root, empty_proof));
}
TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_MismatchingRoots) {
+ const std::string old_root(GetEmptyTreeHash());
+ std::string new_root;
std::vector<std::string> empty_proof;
- std::string root2;
- const std::string empty_tree_hash(GetEmptyTreeHash());
// Roots don't match.
EXPECT_FALSE(
- VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, root2, empty_proof));
+ VerifyConsistencyProof(*log_, 0, old_root, 0, new_root, empty_proof));
EXPECT_FALSE(
- VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, root2, empty_proof));
+ VerifyConsistencyProof(*log_, 1, old_root, 1, new_root, empty_proof));
}
TEST_F(CTLogVerifierTest,
@@ -355,155 +517,244 @@ TEST_F(CTLogVerifierTest,
// but the proof is not empty (the verification code should not accept
// proofs with redundant nodes in this case).
proof.push_back(empty_tree_hash);
- EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 0,
+ EXPECT_FALSE(VerifyConsistencyProof(*log_, 0, empty_tree_hash, 0,
empty_tree_hash, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 1,
+ EXPECT_FALSE(VerifyConsistencyProof(*log_, 0, empty_tree_hash, 1,
empty_tree_hash, proof));
- EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1,
+ EXPECT_FALSE(VerifyConsistencyProof(*log_, 1, empty_tree_hash, 1,
empty_tree_hash, proof));
}
-TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) {
+class CTLogVerifierConsistencyProofTest
+ : public CTLogVerifierTest,
+ public ::testing::WithParamInterface<size_t /* proof index */> {};
+
+// Checks that a sample set of valid consistency proofs verify successfully.
+TEST_P(CTLogVerifierConsistencyProofTest, VerifiesValidConsistencyProof) {
+ const ConsistencyProofTestVector& test_vector =
+ kConsistencyProofs[GetParam()];
+ const std::vector<std::string> proof = GetProof(test_vector);
+
+ const char* const old_root = kRootHashes[test_vector.old_tree_size - 1];
+ const char* const new_root = kRootHashes[test_vector.new_tree_size - 1];
+ CheckVerifyConsistencyProof(*log_, test_vector.old_tree_size,
+ test_vector.new_tree_size, HexToBytes(old_root),
+ HexToBytes(new_root), proof);
+}
+
+INSTANTIATE_TEST_CASE_P(KnownGoodProofs,
+ CTLogVerifierConsistencyProofTest,
+ ::testing::Range(size_t(0),
+ arraysize(kConsistencyProofs)));
+
+class CTLogVerifierAuditProofTest
+ : public CTLogVerifierTest,
+ public ::testing::WithParamInterface<size_t /* proof index */> {};
+
+// Checks that a sample set of valid audit proofs verify successfully.
+TEST_P(CTLogVerifierAuditProofTest, VerifiesValidAuditProofs) {
+ const AuditProofTestVector& test_vector = kAuditProofs[GetParam()];
+ const std::vector<std::string> proof = GetProof(test_vector);
+
+ const char* const root_hash = kRootHashes[test_vector.tree_size - 1];
+ CheckVerifyAuditProof(*log_, test_vector.leaf, test_vector.tree_size, proof,
+ HexToBytes(root_hash),
+ HexToBytes(kLeafHashes[test_vector.leaf]));
+}
+
+INSTANTIATE_TEST_CASE_P(KnownGoodProofs,
+ CTLogVerifierAuditProofTest,
+ ::testing::Range(size_t(0), arraysize(kAuditProofs)));
+
+TEST_F(CTLogVerifierTest, VerifiesAuditProofEdgeCases_InvalidLeafIndex) {
std::vector<std::string> proof;
- std::string root1, root2;
-
- // Known good proofs.
- for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) {
- SCOPED_TRACE(i);
- proof.clear();
- for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) {
- const char* const v = kSHA256Proofs[i].proof[j];
- proof.push_back(HexToBytes(v));
- }
- const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1;
- const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2;
- const char* const old_root = kSHA256Roots[snapshot1 - 1];
- const char* const new_root = kSHA256Roots[snapshot2 - 1];
- VerifierConsistencyCheck(snapshot1, snapshot2, HexToBytes(old_root),
- HexToBytes(new_root), proof);
- }
+ EXPECT_FALSE(
+ VerifyAuditProof(*log_, 1, 0, proof, std::string(), std::string()));
+ EXPECT_FALSE(
+ VerifyAuditProof(*log_, 2, 1, proof, std::string(), std::string()));
+
+ const std::string empty_hash = GetEmptyTreeHash();
+ EXPECT_FALSE(VerifyAuditProof(*log_, 1, 0, proof, empty_hash, std::string()));
+ EXPECT_FALSE(VerifyAuditProof(*log_, 2, 1, proof, empty_hash, std::string()));
}
-const char kLeafPrefix[] = {'\x00'};
+// Functions that implement algorithms from RFC6962 necessary for constructing
+// Merkle trees and proofs. This allows tests to generate a variety of trees
+// for exhaustive testing.
+namespace rfc6962 {
-// Reference implementation of RFC6962.
-// This allows generation of arbitrary-sized Merkle trees and consistency
-// proofs between them for testing the consistency proof validation
-// code.
-class TreeHasher {
- public:
- static std::string HashLeaf(const std::string& leaf) {
- SHA256HashValue sha256;
- memset(sha256.data, 0, sizeof(sha256.data));
-
- std::unique_ptr<crypto::SecureHash> hash(
- crypto::SecureHash::Create(crypto::SecureHash::SHA256));
- hash->Update(kLeafPrefix, 1);
- hash->Update(leaf.data(), leaf.size());
- hash->Finish(sha256.data, sizeof(sha256.data));
-
- return std::string(reinterpret_cast<const char*>(sha256.data),
- sizeof(sha256.data));
- }
-};
+// Calculates the hash of a leaf in a Merkle tree, given its content.
+// See RFC6962, section 2.1.
+std::string HashLeaf(const std::string& leaf) {
+ const char kLeafPrefix[] = {'\x00'};
+
+ SHA256HashValue sha256;
+ memset(sha256.data, 0, sizeof(sha256.data));
-// Reference implementation of Merkle hash, for cross-checking.
-// Recursively calculates the hash of the root given the leaf data
-// specified in |inputs|.
-std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) {
- if (!input_size)
+ std::unique_ptr<crypto::SecureHash> hash(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+ hash->Update(kLeafPrefix, 1);
+ hash->Update(leaf.data(), leaf.size());
+ hash->Finish(sha256.data, sizeof(sha256.data));
+
+ return std::string(reinterpret_cast<const char*>(sha256.data),
+ sizeof(sha256.data));
+}
+
+// Calculates the root hash of a Merkle tree, given its leaf data and size.
+// See RFC6962, section 2.1.
+std::string HashTree(std::string leaves[], size_t tree_size) {
+ if (tree_size == 0)
return GetEmptyTreeHash();
- if (input_size == 1)
- return TreeHasher::HashLeaf(inputs[0]);
+ if (tree_size == 1)
+ return HashLeaf(leaves[0]);
- const uint64_t split = CalculateNearestPowerOfTwo(input_size);
+ // Find the index of the last leaf in the left sub-tree.
+ const size_t split = CalculateNearestPowerOfTwo(tree_size);
- return ct::internal::HashNodes(
- ReferenceMerkleTreeHash(&inputs[0], split),
- ReferenceMerkleTreeHash(&inputs[split], input_size - split));
+ // Hash the left and right sub-trees, then hash the results.
+ return ct::internal::HashNodes(HashTree(leaves, split),
+ HashTree(&leaves[split], tree_size - split));
}
-// Reference implementation of snapshot consistency. Returns a
-// consistency proof between two snapshots of the tree designated
-// by |inputs|.
-// Call with have_root1 = true.
-std::vector<std::string> ReferenceSnapshotConsistency(std::string* inputs,
- uint64_t snapshot2,
- uint64_t snapshot1,
- bool have_root1) {
+// Returns a Merkle audit proof for the leaf with index |leaf_index|.
+// The tree consists of |leaves[0]| to |leaves[tree_size-1]|.
+// If |leaf_index| is >= |tree_size|, an empty proof will be returned.
+// See RFC6962, section 2.1.1, for more details.
+std::vector<std::string> CreateAuditProof(std::string leaves[],
+ size_t tree_size,
+ size_t leaf_index) {
std::vector<std::string> proof;
- if (snapshot1 == 0 || snapshot1 > snapshot2)
+ if (leaf_index >= tree_size)
+ return proof;
+ if (tree_size == 1)
return proof;
- if (snapshot1 == snapshot2) {
+
+ // Find the index of the first leaf in the right sub-tree.
+ const size_t split = CalculateNearestPowerOfTwo(tree_size);
+
+ // Recurse down the correct branch of the tree (left or right) to reach the
+ // leaf with |leaf_index|. Add the hash of the branch not taken at each step
+ // on the way up to build the proof.
+ if (leaf_index < split) {
+ proof = CreateAuditProof(leaves, split, leaf_index);
+ proof.push_back(HashTree(&leaves[split], tree_size - split));
+ } else {
+ proof =
+ CreateAuditProof(&leaves[split], tree_size - split, leaf_index - split);
+ proof.push_back(HashTree(leaves, split));
+ }
+
+ return proof;
+}
+
+// Returns a Merkle consistency proof between two Merkle trees.
+// The old tree contains |leaves[0]| to |leaves[old_tree_size-1]|.
+// The new tree contains |leaves[0]| to |leaves[new_tree_size-1]|.
+// Call with |contains_old_tree| = true.
+// See RFC6962, section 2.1.2, for more details.
+std::vector<std::string> CreateConsistencyProof(std::string leaves[],
+ size_t new_tree_size,
+ size_t old_tree_size,
+ bool contains_old_tree = true) {
+ std::vector<std::string> proof;
+ if (old_tree_size == 0 || old_tree_size > new_tree_size)
+ return proof;
+ if (old_tree_size == new_tree_size) {
// Consistency proof for two equal subtrees is empty.
- if (!have_root1) {
+ if (!contains_old_tree) {
// Record the hash of this subtree unless it's the root for which
- // the proof was originally requested. (This happens when the snapshot1
- // tree is balanced.)
- proof.push_back(ReferenceMerkleTreeHash(inputs, snapshot1));
+ // the proof was originally requested. (This happens when the old tree is
+ // balanced).
+ proof.push_back(HashTree(leaves, old_tree_size));
}
return proof;
}
- // 0 < snapshot1 < snapshot2
- const uint64_t split = CalculateNearestPowerOfTwo(snapshot2);
+ // Find the index of the last leaf in the left sub-tree.
+ const size_t split = CalculateNearestPowerOfTwo(new_tree_size);
- std::vector<std::string> subproof;
- if (snapshot1 <= split) {
- // Root of snapshot1 is in the left subtree of snapshot2.
+ if (old_tree_size <= split) {
+ // Root of the old tree is in the left subtree of the new tree.
// Prove that the left subtrees are consistent.
- subproof =
- ReferenceSnapshotConsistency(inputs, split, snapshot1, have_root1);
- proof.insert(proof.end(), subproof.begin(), subproof.end());
- // Record the hash of the right subtree (only present in snapshot2).
- proof.push_back(ReferenceMerkleTreeHash(&inputs[split], snapshot2 - split));
+ proof =
+ CreateConsistencyProof(leaves, split, old_tree_size, contains_old_tree);
+ // Record the hash of the right subtree (only present in the new tree).
+ proof.push_back(HashTree(&leaves[split], new_tree_size - split));
} else {
- // Snapshot1 root is at the same level as snapshot2 root.
+ // The old tree root is at the same level as the new tree root.
// Prove that the right subtrees are consistent. The right subtree
- // doesn't contain the root of snapshot1, so set have_root1 = false.
- subproof = ReferenceSnapshotConsistency(&inputs[split], snapshot2 - split,
- snapshot1 - split, false);
- proof.insert(proof.end(), subproof.begin(), subproof.end());
+ // doesn't contain the root of the old tree, so set contains_old_tree =
+ // false.
+ proof = CreateConsistencyProof(&leaves[split], new_tree_size - split,
+ old_tree_size - split,
+ /* contains_old_tree = */ false);
// Record the hash of the left subtree (equal in both trees).
- proof.push_back(ReferenceMerkleTreeHash(&inputs[0], split));
+ proof.push_back(HashTree(leaves, split));
}
return proof;
}
-class CTLogVerifierTestUsingReferenceGenerator
+} // namespace rfc6962
+
+class CTLogVerifierTestUsingGenerator
: public CTLogVerifierTest,
- public ::testing::WithParamInterface<uint64_t> {};
-
-const uint64_t kReferenceTreeSize = 256;
-
-// Tests that every possible valid consistency proof for a tree of a given size
-// verifies correctly. Also checks that invalid variations of each proof fail to
-// verify (see VerifierConsistencyCheck).
-TEST_P(CTLogVerifierTestUsingReferenceGenerator,
- VerifiesValidConsistencyProof) {
- std::vector<std::string> data;
- for (uint64_t i = 0; i < kReferenceTreeSize; ++i)
- data.push_back(std::string(1, static_cast<char>(i)));
-
- const uint64_t tree_size = GetParam();
- const std::string tree_root = ReferenceMerkleTreeHash(data.data(), tree_size);
-
- for (uint64_t snapshot = 1; snapshot <= tree_size; ++snapshot) {
- SCOPED_TRACE(snapshot);
- const std::string snapshot_root =
- ReferenceMerkleTreeHash(data.data(), snapshot);
- const std::vector<std::string> proof =
- ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true);
- VerifierConsistencyCheck(snapshot, tree_size, snapshot_root, tree_root,
- proof);
+ public ::testing::WithParamInterface<size_t /* tree_size */> {};
+
+// Checks that valid consistency proofs for a range of generated Merkle trees
+// verify successfully.
+TEST_P(CTLogVerifierTestUsingGenerator, VerifiesValidConsistencyProof) {
+ const size_t tree_size = GetParam();
+
+ std::vector<std::string> tree_leaves(tree_size);
+ for (size_t i = 0; i < tree_size; ++i)
+ tree_leaves[i].push_back(static_cast<char>(i));
+
+ const std::string tree_root =
+ rfc6962::HashTree(tree_leaves.data(), tree_size);
+
+ // Check consistency proofs for every sub-tree.
+ for (size_t old_tree_size = 0; old_tree_size <= tree_size; ++old_tree_size) {
+ SCOPED_TRACE(old_tree_size);
+ const std::string old_tree_root =
+ rfc6962::HashTree(tree_leaves.data(), old_tree_size);
+ const std::vector<std::string> proof = rfc6962::CreateConsistencyProof(
+ tree_leaves.data(), tree_size, old_tree_size);
+ // Checks that the consistency proof verifies only with the correct tree
+ // sizes and root hashes.
+ CheckVerifyConsistencyProof(*log_, old_tree_size, tree_size, old_tree_root,
+ tree_root, proof);
+ }
+}
+
+// Checks that valid audit proofs for a range of generated Merkle trees verify
+// successfully.
+TEST_P(CTLogVerifierTestUsingGenerator, VerifiesValidAuditProofs) {
+ const size_t tree_size = GetParam();
+
+ std::vector<std::string> tree_leaves(tree_size);
+ for (size_t i = 0; i < tree_size; ++i)
+ tree_leaves[i].push_back(static_cast<char>(i));
+
+ const std::string root = rfc6962::HashTree(tree_leaves.data(), tree_size);
+
+ // Check audit proofs for every leaf in the tree.
+ for (size_t leaf = 0; leaf < tree_size; ++leaf) {
+ SCOPED_TRACE(leaf);
+ std::vector<std::string> proof =
+ rfc6962::CreateAuditProof(tree_leaves.data(), tree_size, leaf);
+ // Checks that the audit proof verifies only for this leaf data, index,
+ // hash, tree size and root hash.
+ CheckVerifyAuditProof(*log_, leaf, tree_size, proof, root,
+ rfc6962::HashLeaf(tree_leaves[leaf]));
}
}
-// Test verification of consistency proofs between all tree sizes from 1 to 128.
-INSTANTIATE_TEST_CASE_P(RangeOfTreeSizesAndSnapshots,
- CTLogVerifierTestUsingReferenceGenerator,
- testing::Range(UINT64_C(1),
- (kReferenceTreeSize / 2) + 1));
+// Test verification of consistency proofs and audit proofs for all tree sizes
+// from 0 to 128.
+INSTANTIATE_TEST_CASE_P(RangeOfTreeSizes,
+ CTLogVerifierTestUsingGenerator,
+ testing::Range(size_t(0), size_t(129)));
} // namespace
diff --git a/chromium/net/cert/ct_objects_extractor.cc b/chromium/net/cert/ct_objects_extractor.cc
index 3453e445d2b..4f451fdd1f2 100644
--- a/chromium/net/cert/ct_objects_extractor.cc
+++ b/chromium/net/cert/ct_objects_extractor.cc
@@ -6,18 +6,15 @@
#include <string.h>
-#include <openssl/bytestring.h>
-#include <openssl/obj.h>
-#include <openssl/x509.h>
-
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "crypto/sha2.h"
#include "net/cert/asn1_util.h"
#include "net/cert/signed_certificate_timestamp.h"
-#include "net/ssl/scoped_openssl_types.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/obj.h"
+#include "third_party/boringssl/src/include/openssl/x509.h"
namespace net {
@@ -25,13 +22,6 @@ namespace ct {
namespace {
-void FreeX509_EXTENSIONS(X509_EXTENSIONS* ptr) {
- sk_X509_EXTENSION_pop_free(ptr, X509_EXTENSION_free);
-}
-
-using ScopedX509_EXTENSIONS =
- crypto::ScopedOpenSSL<X509_EXTENSIONS, FreeX509_EXTENSIONS>;
-
// The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of
// RFC6962.
const uint8_t kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
@@ -49,15 +39,16 @@ bool StringEqualToCBS(const std::string& value1, const CBS* value2) {
return memcmp(value1.data(), CBS_data(value2), CBS_len(value2)) == 0;
}
-ScopedX509 OSCertHandleToOpenSSL(X509Certificate::OSCertHandle os_handle) {
+bssl::UniquePtr<X509> OSCertHandleToOpenSSL(
+ X509Certificate::OSCertHandle os_handle) {
#if defined(USE_OPENSSL_CERTS)
- return ScopedX509(X509Certificate::DupOSCertHandle(os_handle));
+ return bssl::UniquePtr<X509>(X509Certificate::DupOSCertHandle(os_handle));
#else
std::string der_encoded;
if (!X509Certificate::GetDEREncoded(os_handle, &der_encoded))
- return ScopedX509();
+ return bssl::UniquePtr<X509>();
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_encoded.data());
- return ScopedX509(d2i_X509(NULL, &bytes, der_encoded.size()));
+ return bssl::UniquePtr<X509>(d2i_X509(NULL, &bytes, der_encoded.size()));
#endif
}
@@ -171,7 +162,7 @@ bool FindMatchingSingleResponse(CBS* responses,
bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert,
std::string* sct_list) {
- ScopedX509 x509(OSCertHandleToOpenSSL(cert));
+ bssl::UniquePtr<X509> x509(OSCertHandleToOpenSSL(cert));
if (!x509)
return false;
X509_EXTENSIONS* x509_exts = x509->cert_info->extensions;
@@ -187,7 +178,7 @@ bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf,
LogEntry* result) {
result->Reset();
- ScopedX509 leaf_x509(OSCertHandleToOpenSSL(leaf));
+ bssl::UniquePtr<X509> leaf_x509(OSCertHandleToOpenSSL(leaf));
if (!leaf_x509)
return false;
@@ -203,7 +194,7 @@ bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf,
// The Precertificate log entry is the final certificate's TBSCertificate
// without the SCT extension (RFC6962, section 3.2).
- ScopedX509 leaf_copy(X509_dup(leaf_x509.get()));
+ bssl::UniquePtr<X509> leaf_copy(X509_dup(leaf_x509.get()));
if (!leaf_copy || !leaf_copy->cert_info->extensions) {
NOTREACHED();
return false;
@@ -346,7 +337,7 @@ bool ExtractSCTListFromOCSPResponse(X509Certificate::OSCertHandle issuer,
if (!CBS_get_asn1(&single_response, &extensions, kSingleExtensionsTag))
return false;
const uint8_t* ptr = CBS_data(&extensions);
- ScopedX509_EXTENSIONS x509_exts(
+ bssl::UniquePtr<X509_EXTENSIONS> x509_exts(
d2i_X509_EXTENSIONS(NULL, &ptr, CBS_len(&extensions)));
if (!x509_exts || ptr != CBS_data(&extensions) + CBS_len(&extensions))
return false;
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 6afd32224e5..1930ba892ce 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -13,7 +13,6 @@
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "net/cert/ct_sct_to_string.h"
-#include "net/cert/ct_verify_result.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/log/net_log_capture_mode.h"
@@ -76,11 +75,11 @@ std::unique_ptr<base::ListValue> SCTListToPrintableValues(
} // namespace
std::unique_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
- const ct::CTVerifyResult* ct_result,
+ const SignedCertificateTimestampAndStatusList* scts,
NetLogCaptureMode capture_mode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->Set("scts", SCTListToPrintableValues(ct_result->scts));
+ dict->Set("scts", SCTListToPrintableValues(*scts));
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 1c1a7d8ad2e..373a7525337 100644
--- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h
+++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.h
@@ -8,6 +8,8 @@
#include <memory>
#include <string>
+#include "net/cert/signed_certificate_timestamp_and_status.h"
+
namespace base {
class Value;
}
@@ -16,16 +18,12 @@ namespace net {
class NetLogCaptureMode;
-namespace ct {
-struct CTVerifyResult;
-}
-
// Creates a dictionary of processed Signed Certificate Timestamps to be
// logged in the NetLog.
// See the documentation for SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED
// in net/log/net_log_event_type_list.h
std::unique_ptr<base::Value> NetLogSignedCertificateTimestampCallback(
- const ct::CTVerifyResult* ct_result,
+ const SignedCertificateTimestampAndStatusList* scts,
NetLogCaptureMode capture_mode);
// Creates a dictionary of raw Signed Certificate Timestamps to be logged
diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h
index 38ce2efa471..b65a1334b48 100644
--- a/chromium/net/cert/ct_verifier.h
+++ b/chromium/net/cert/ct_verifier.h
@@ -8,14 +8,10 @@
#include <string>
#include "net/base/net_export.h"
+#include "net/cert/signed_certificate_timestamp_and_status.h"
namespace net {
-namespace ct {
-struct CTVerifyResult;
-struct SignedCertificateTimestamp;
-} // namespace ct
-
class CTLogVerifier;
class NetLogWithSource;
class X509Certificate;
@@ -54,7 +50,7 @@ class NET_EXPORT CTVerifier {
virtual int Verify(X509Certificate* cert,
const std::string& stapled_ocsp_response,
const std::string& sct_list_from_tls_extension,
- ct::CTVerifyResult* result,
+ SignedCertificateTimestampAndStatusList* output_scts,
const NetLogWithSource& net_log) = 0;
// Registers |observer| to receive notifications of validated SCTs. Does not
diff --git a/chromium/net/cert/internal/signature_policy.cc b/chromium/net/cert/internal/signature_policy.cc
index 20a4cd3588e..0785cbf6532 100644
--- a/chromium/net/cert/internal/signature_policy.cc
+++ b/chromium/net/cert/internal/signature_policy.cc
@@ -7,8 +7,7 @@
#include "base/logging.h"
#include "net/cert/internal/cert_error_params.h"
#include "net/cert/internal/cert_errors.h"
-
-#include <openssl/obj.h>
+#include "third_party/boringssl/src/include/openssl/obj.h"
namespace net {
diff --git a/chromium/net/cert/internal/verify_name_match.cc b/chromium/net/cert/internal/verify_name_match.cc
index 3cfa4a17586..b999355b457 100644
--- a/chromium/net/cert/internal/verify_name_match.cc
+++ b/chromium/net/cert/internal/verify_name_match.cc
@@ -9,12 +9,12 @@
#include "base/strings/string_util.h"
#include "base/tuple.h"
-#include "crypto/auto_cbb.h"
-#include "crypto/scoped_openssl_types.h"
#include "net/cert/internal/parse_name.h"
#include "net/der/input.h"
#include "net/der/parser.h"
#include "net/der/tag.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
namespace net {
@@ -294,7 +294,7 @@ bool NormalizeName(const der::Input& name_rdn_sequence,
// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
der::Parser rdn_sequence_parser(name_rdn_sequence);
- crypto::AutoCBB cbb;
+ bssl::ScopedCBB cbb;
if (!CBB_init(cbb.get(), 0))
return false;
@@ -316,13 +316,13 @@ bool NormalizeName(const der::Input& name_rdn_sequence,
CBB rdn_cbb;
if (!CBB_add_asn1(cbb.get(), &rdn_cbb, CBS_ASN1_SET))
return false;
- std::vector<crypto::ScopedOpenSSLBytes>
+ std::vector<bssl::UniquePtr<uint8_t>>
scoped_encoded_attribute_type_and_values;
std::vector<der::Input> encoded_attribute_type_and_values;
for (const auto& type_and_value : type_and_values) {
// A top-level CBB for encoding each individual AttributeTypeAndValue.
- crypto::AutoCBB type_and_value_encoder_cbb;
+ bssl::ScopedCBB type_and_value_encoder_cbb;
if (!CBB_init(type_and_value_encoder_cbb.get(), 0))
return false;
@@ -367,7 +367,7 @@ bool NormalizeName(const der::Input& name_rdn_sequence,
if (!CBB_finish(type_and_value_encoder_cbb.get(), &bytes, &len))
return false;
scoped_encoded_attribute_type_and_values.push_back(
- crypto::ScopedOpenSSLBytes(bytes));
+ bssl::UniquePtr<uint8_t>(bytes));
encoded_attribute_type_and_values.push_back(der::Input(bytes, len));
}
diff --git a/chromium/net/cert/internal/verify_name_match_fuzzer.cc b/chromium/net/cert/internal/verify_name_match_fuzzer.cc
index 464108e51d2..3b5f74cf261 100644
--- a/chromium/net/cert/internal/verify_name_match_fuzzer.cc
+++ b/chromium/net/cert/internal/verify_name_match_fuzzer.cc
@@ -11,11 +11,11 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data(data, size);
size_t first_part_size = fuzzed_data.ConsumeUint16();
- base::StringPiece first_part = fuzzed_data.ConsumeBytes(first_part_size);
- base::StringPiece second_part = fuzzed_data.ConsumeRemainingBytes();
+ std::string first_part = fuzzed_data.ConsumeBytes(first_part_size);
+ std::string second_part = fuzzed_data.ConsumeRemainingBytes();
- net::der::Input in1(first_part);
- net::der::Input in2(second_part);
+ net::der::Input in1(&first_part);
+ net::der::Input in2(&second_part);
bool match = net::VerifyNameMatch(in1, in2);
bool reverse_order_match = net::VerifyNameMatch(in2, in1);
// Result should be the same regardless of argument order.
diff --git a/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc b/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc
index 1d4ea048513..971797eca3a 100644
--- a/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc
+++ b/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc
@@ -11,11 +11,11 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::FuzzedDataProvider fuzzed_data(data, size);
size_t first_part_size = fuzzed_data.ConsumeUint16();
- base::StringPiece first_part = fuzzed_data.ConsumeBytes(first_part_size);
- base::StringPiece second_part = fuzzed_data.ConsumeRemainingBytes();
+ std::string first_part = fuzzed_data.ConsumeBytes(first_part_size);
+ std::string second_part = fuzzed_data.ConsumeRemainingBytes();
- net::der::Input in1(first_part);
- net::der::Input in2(second_part);
+ net::der::Input in1(&first_part);
+ net::der::Input in2(&second_part);
bool match = net::VerifyNameInSubtree(in1, in2);
bool reverse_order_match = net::VerifyNameInSubtree(in2, in1);
// If both InSubtree matches are true, then in1 == in2 (modulo normalization).
diff --git a/chromium/net/cert/internal/verify_signed_data.cc b/chromium/net/cert/internal/verify_signed_data.cc
index bd0ee60f5ea..37fc0eb0a9e 100644
--- a/chromium/net/cert/internal/verify_signed_data.cc
+++ b/chromium/net/cert/internal/verify_signed_data.cc
@@ -4,23 +4,22 @@
#include "net/cert/internal/verify_signed_data.h"
-#include <openssl/bytestring.h>
-#include <openssl/digest.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/signature_algorithm.h"
#include "net/cert/internal/signature_policy.h"
#include "net/der/input.h"
#include "net/der/parse_values.h"
#include "net/der/parser.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
namespace net {
@@ -81,7 +80,7 @@ WARN_UNUSED_RESULT bool ApplyRsaPssOptions(const RsaPssParameters* params,
// See https://crbug.com/522228 and https://crbug.com/522232
WARN_UNUSED_RESULT bool ImportPkeyFromSpki(const der::Input& spki,
int expected_pkey_id,
- crypto::ScopedEVP_PKEY* pkey) {
+ bssl::UniquePtr<EVP_PKEY>* pkey) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
CBS cbs;
@@ -153,7 +152,7 @@ WARN_UNUSED_RESULT bool ImportPkeyFromSpki(const der::Input& spki,
//
// Following RFC 3279 in this case.
WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki,
- crypto::ScopedEVP_PKEY* pkey,
+ bssl::UniquePtr<EVP_PKEY>* pkey,
const SignaturePolicy* policy,
CertErrors* errors) {
// TODO(crbug.com/634443): Add more specific errors.
@@ -161,7 +160,7 @@ WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki,
return false;
// Extract the modulus length from the key.
- crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey->get()));
+ RSA* rsa = EVP_PKEY_get0_RSA(pkey->get());
if (!rsa)
return false;
unsigned int modulus_length_bits = BN_num_bits(rsa->n);
@@ -191,7 +190,7 @@ WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm,
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create());
+ bssl::ScopedEVP_MD_CTX ctx;
EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|.
const EVP_MD* digest;
@@ -262,7 +261,7 @@ WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm,
// ... -- Extensible
// }
WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki,
- crypto::ScopedEVP_PKEY* pkey,
+ bssl::UniquePtr<EVP_PKEY>* pkey,
const SignaturePolicy* policy,
CertErrors* errors) {
// TODO(crbug.com/634443): Add more specific errors.
@@ -270,10 +269,10 @@ WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki,
return false;
// Extract the curve name.
- crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey->get()));
- if (!ec.get())
+ EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey->get());
+ if (!ec)
return false; // Unexpected.
- int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get()));
+ int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
if (!policy->IsAcceptableCurveForEcdsa(curve_nid, errors)) {
errors->AddError(kUnacceptableEcdsaCurve);
@@ -296,7 +295,7 @@ bool VerifySignedData(const SignatureAlgorithm& signature_algorithm,
return false;
}
- crypto::ScopedEVP_PKEY public_key;
+ bssl::UniquePtr<EVP_PKEY> public_key;
// Parse the SPKI to an EVP_PKEY appropriate for the signature algorithm.
switch (signature_algorithm.algorithm()) {
diff --git a/chromium/net/cert/internal/verify_signed_data_unittest.cc b/chromium/net/cert/internal/verify_signed_data_unittest.cc
index 7710abc47f2..1f729038ab5 100644
--- a/chromium/net/cert/internal/verify_signed_data_unittest.cc
+++ b/chromium/net/cert/internal/verify_signed_data_unittest.cc
@@ -15,8 +15,7 @@
#include "net/der/parse_values.h"
#include "net/der/parser.h"
#include "testing/gtest/include/gtest/gtest.h"
-
-#include <openssl/obj.h>
+#include "third_party/boringssl/src/include/openssl/obj.h"
namespace net {
diff --git a/chromium/net/cert/jwk_serializer.cc b/chromium/net/cert/jwk_serializer.cc
index 3a6a86d3e7c..0faab404164 100644
--- a/chromium/net/cert/jwk_serializer.cc
+++ b/chromium/net/cert/jwk_serializer.cc
@@ -4,18 +4,16 @@
#include "net/cert/jwk_serializer.h"
-#include <openssl/bn.h>
-#include <openssl/bytestring.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/evp.h>
-
#include "base/base64url.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
namespace net {
@@ -26,10 +24,10 @@ namespace {
bool ConvertEcKeyToJwk(EVP_PKEY* pkey,
base::DictionaryValue* public_key_jwk,
const crypto::OpenSSLErrStackTracer& err_tracer) {
- crypto::ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(pkey));
+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey);
if (!ec_key)
return false;
- const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key.get());
+ const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
if (!ec_group)
return false;
@@ -47,12 +45,12 @@ bool ConvertEcKeyToJwk(EVP_PKEY* pkey,
int degree_bytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
- const EC_POINT* ec_point = EC_KEY_get0_public_key(ec_key.get());
+ const EC_POINT* ec_point = EC_KEY_get0_public_key(ec_key);
if (!ec_point)
return false;
- crypto::ScopedBIGNUM x(BN_new());
- crypto::ScopedBIGNUM y(BN_new());
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
if (!EC_POINT_get_affine_coordinates_GFp(ec_group, ec_point, x.get(), y.get(),
NULL)) {
return false;
@@ -98,7 +96,7 @@ bool ConvertSpkiFromDerToJwk(const base::StringPiece& spki_der,
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki_der.data()),
spki_der.size());
- crypto::ScopedEVP_PKEY pubkey(EVP_parse_public_key(&cbs));
+ bssl::UniquePtr<EVP_PKEY> pubkey(EVP_parse_public_key(&cbs));
if (!pubkey || CBS_len(&cbs) != 0)
return false;
diff --git a/chromium/net/cert/merkle_audit_proof.cc b/chromium/net/cert/merkle_audit_proof.cc
index 675485b2589..f1829af1f3e 100644
--- a/chromium/net/cert/merkle_audit_proof.cc
+++ b/chromium/net/cert/merkle_audit_proof.cc
@@ -31,8 +31,9 @@ uint64_t CalculateAuditPathLength(uint64_t leaf_index, uint64_t tree_size) {
MerkleAuditProof::MerkleAuditProof() {}
MerkleAuditProof::MerkleAuditProof(uint64_t leaf_index,
+ uint64_t tree_size,
const std::vector<std::string>& audit_path)
- : leaf_index(leaf_index), nodes(audit_path) {}
+ : leaf_index(leaf_index), tree_size(tree_size), nodes(audit_path) {}
MerkleAuditProof::~MerkleAuditProof() {}
diff --git a/chromium/net/cert/merkle_audit_proof.h b/chromium/net/cert/merkle_audit_proof.h
index b214891ee14..d7c6e3c52f0 100644
--- a/chromium/net/cert/merkle_audit_proof.h
+++ b/chromium/net/cert/merkle_audit_proof.h
@@ -26,13 +26,21 @@ NET_EXPORT uint64_t CalculateAuditPathLength(uint64_t leaf_index,
struct NET_EXPORT MerkleAuditProof {
MerkleAuditProof();
MerkleAuditProof(uint64_t leaf_index,
+ uint64_t tree_size,
const std::vector<std::string>& audit_path);
~MerkleAuditProof();
// Index of the tree leaf in the log.
+ // Must be provided when fetching the proof from the log.
uint64_t leaf_index = 0;
+ // The proof works only in conjunction with an STH for this tree size.
+ // Must be provided when fetching the proof from the log.
+ uint64_t tree_size = 0;
+
// Audit path nodes.
+ // Using the leaf hash and these nodes, the STH hash can be reconstructed to
+ // prove that leaf was included in the log's tree.
std::vector<std::string> nodes;
};
diff --git a/chromium/net/cert/multi_log_ct_verifier.cc b/chromium/net/cert/multi_log_ct_verifier.cc
index 8dc172677a5..61c07b6d4e5 100644
--- a/chromium/net/cert/multi_log_ct_verifier.cc
+++ b/chromium/net/cert/multi_log_ct_verifier.cc
@@ -15,8 +15,8 @@
#include "net/cert/ct_objects_extractor.h"
#include "net/cert/ct_serialization.h"
#include "net/cert/ct_signed_certificate_timestamp_log_param.h"
-#include "net/cert/ct_verify_result.h"
#include "net/cert/sct_status_flags.h"
+#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/cert/x509_certificate.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_parameters_callback.h"
@@ -50,9 +50,9 @@ void LogSCTOriginToUMA(ct::SignedCertificateTimestamp::Origin origin) {
// This metric would allow measuring:
// * Of all SSL connections, how many had SCTs available for validation.
// * When SCTs are available, how many are available per connection.
-void LogNumSCTsToUMA(const ct::CTVerifyResult& result) {
+void LogNumSCTsToUMA(const SignedCertificateTimestampAndStatusList& scts) {
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.CertificateTransparency.SCTsPerConnection",
- result.scts.size(), 1, 10, 11);
+ scts.size(), 1, 10, 11);
}
void AddSCTAndLogStatus(scoped_refptr<ct::SignedCertificateTimestamp> sct,
@@ -81,15 +81,16 @@ void MultiLogCTVerifier::SetObserver(Observer* observer) {
observer_ = observer;
}
-int MultiLogCTVerifier::Verify(X509Certificate* cert,
- const std::string& stapled_ocsp_response,
- const std::string& sct_list_from_tls_extension,
- ct::CTVerifyResult* result,
- const NetLogWithSource& net_log) {
+int MultiLogCTVerifier::Verify(
+ X509Certificate* cert,
+ const std::string& stapled_ocsp_response,
+ const std::string& sct_list_from_tls_extension,
+ SignedCertificateTimestampAndStatusList* output_scts,
+ const NetLogWithSource& net_log) {
DCHECK(cert);
- DCHECK(result);
+ DCHECK(output_scts);
- result->scts.clear();
+ output_scts->clear();
bool has_verified_scts = false;
@@ -105,7 +106,8 @@ int MultiLogCTVerifier::Verify(X509Certificate* cert,
cert->GetIntermediateCertificates().front(),
&precert_entry) &&
VerifySCTs(embedded_scts, precert_entry,
- ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert, result);
+ ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert,
+ output_scts);
}
std::string sct_list_from_ocsp;
@@ -127,22 +129,24 @@ int MultiLogCTVerifier::Verify(X509Certificate* cert,
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, result);
-
- has_verified_scts |= VerifySCTs(
- sct_list_from_tls_extension, x509_entry,
- ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert, result);
+ 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);
}
NetLogParametersCallback net_log_checked_callback =
- base::Bind(&NetLogSignedCertificateTimestampCallback, result);
+ base::Bind(&NetLogSignedCertificateTimestampCallback, output_scts);
net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED,
net_log_checked_callback);
- LogNumSCTsToUMA(*result);
+ LogNumSCTsToUMA(*output_scts);
if (has_verified_scts)
return OK;
@@ -155,7 +159,7 @@ bool MultiLogCTVerifier::VerifySCTs(
const ct::LogEntry& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
X509Certificate* cert,
- ct::CTVerifyResult* result) {
+ SignedCertificateTimestampAndStatusList* output_scts) {
if (logs_.empty())
return false;
@@ -179,7 +183,7 @@ bool MultiLogCTVerifier::VerifySCTs(
}
decoded_sct->origin = origin;
- verified |= VerifySingleSCT(decoded_sct, expected_entry, cert, result);
+ verified |= VerifySingleSCT(decoded_sct, expected_entry, cert, output_scts);
}
return verified;
@@ -189,12 +193,12 @@ bool MultiLogCTVerifier::VerifySingleSCT(
scoped_refptr<ct::SignedCertificateTimestamp> sct,
const ct::LogEntry& expected_entry,
X509Certificate* cert,
- ct::CTVerifyResult* result) {
+ SignedCertificateTimestampAndStatusList* output_scts) {
// Assume this SCT is untrusted until proven otherwise.
const auto& it = logs_.find(sct->log_id);
if (it == logs_.end()) {
DVLOG(1) << "SCT does not match any known log.";
- AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, &(result->scts));
+ AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, output_scts);
return false;
}
@@ -202,18 +206,18 @@ bool MultiLogCTVerifier::VerifySingleSCT(
if (!it->second->Verify(expected_entry, *sct.get())) {
DVLOG(1) << "Unable to verify SCT signature.";
- AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_SIGNATURE, &(result->scts));
+ AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_SIGNATURE, output_scts);
return false;
}
// SCT verified ok, just make sure the timestamp is legitimate.
if (sct->timestamp > base::Time::Now()) {
DVLOG(1) << "SCT is from the future!";
- AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_TIMESTAMP, &(result->scts));
+ AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_TIMESTAMP, output_scts);
return false;
}
- AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, &(result->scts));
+ AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, output_scts);
if (observer_)
observer_->OnSCTVerified(cert, sct.get());
return true;
diff --git a/chromium/net/cert/multi_log_ct_verifier.h b/chromium/net/cert/multi_log_ct_verifier.h
index 38ea659dfb8..05c2c069264 100644
--- a/chromium/net/cert/multi_log_ct_verifier.h
+++ b/chromium/net/cert/multi_log_ct_verifier.h
@@ -37,7 +37,7 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
int Verify(X509Certificate* cert,
const std::string& stapled_ocsp_response,
const std::string& sct_list_from_tls_extension,
- ct::CTVerifyResult* result,
+ SignedCertificateTimestampAndStatusList* output_scts,
const NetLogWithSource& net_log) override;
void SetObserver(Observer* observer) override;
@@ -50,13 +50,13 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
const ct::LogEntry& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
X509Certificate* cert,
- ct::CTVerifyResult* result);
+ SignedCertificateTimestampAndStatusList* output_scts);
// Verifies a single, parsed SCT against all logs.
bool VerifySingleSCT(scoped_refptr<ct::SignedCertificateTimestamp> sct,
const ct::LogEntry& expected_entry,
X509Certificate* cert,
- ct::CTVerifyResult* result);
+ SignedCertificateTimestampAndStatusList* output_scts);
// Mapping from a log's ID to the verifier for this log.
// A log's ID is the SHA-256 of the log's key, as defined in section 3.2.
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index 7186a3a22e6..2efd7012a46 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -16,10 +16,10 @@
#include "net/base/net_errors.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_serialization.h"
-#include "net/cert/ct_verify_result.h"
#include "net/cert/pem_tokenizer.h"
#include "net/cert/sct_status_flags.h"
#include "net/cert/signed_certificate_timestamp.h"
+#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/cert/x509_certificate.h"
#include "net/log/net_log_source_type.h"
#include "net/log/net_log_with_source.h"
@@ -111,32 +111,33 @@ class MultiLogCTVerifierTest : public ::testing::Test {
return true;
}
- bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain,
- const NetLogWithSource& net_log,
- ct::CTVerifyResult* result) {
- return verifier_->Verify(chain.get(), std::string(), std::string(), result,
- net_log) == OK;
+ 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;
}
bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) {
- ct::CTVerifyResult result;
+ 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(), &result,
+ return verifier_->Verify(chain.get(), std::string(), std::string(), &scts,
net_log) == OK;
}
bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) {
- ct::CTVerifyResult result;
+ SignedCertificateTimestampAndStatusList scts;
TestNetLog test_net_log;
NetLogWithSource net_log =
NetLogWithSource::Make(&test_net_log, NetLogSourceType::CONNECT_JOB);
- return (VerifySinglePrecertificateChain(chain, net_log, &result) &&
- ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription) &&
+ return (VerifySinglePrecertificateChain(chain, net_log, &scts) &&
+ ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) &&
ct::CheckForSCTOrigin(
- result, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
+ scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
CheckForEmbeddedSCTInNetLog(test_net_log));
}
@@ -210,23 +211,23 @@ TEST_F(MultiLogCTVerifierTest,
TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) {
std::string sct_list = ct::GetSCTListForTesting();
- ct::CTVerifyResult result;
- EXPECT_EQ(OK, verifier_->Verify(chain_.get(), std::string(), sct_list,
- &result, NetLogWithSource()));
- ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription));
+ SignedCertificateTimestampAndStatusList scts;
+ EXPECT_EQ(OK, verifier_->Verify(chain_.get(), std::string(), sct_list, &scts,
+ NetLogWithSource()));
+ ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription));
ASSERT_TRUE(ct::CheckForSCTOrigin(
- result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
+ scts, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
}
TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) {
std::string sct_list = ct::GetSCTListWithInvalidSCT();
- ct::CTVerifyResult result;
+ SignedCertificateTimestampAndStatusList scts;
- EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list,
- &result, NetLogWithSource()));
- EXPECT_EQ(1U, result.scts.size());
- EXPECT_EQ("", result.scts[0].sct->log_description);
- EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, result.scts[0].status);
+ EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), 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);
}
TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) {
@@ -239,13 +240,14 @@ TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) {
TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) {
std::string sct_list = ct::GetSCTListWithInvalidSCT();
- ct::CTVerifyResult result;
+ SignedCertificateTimestampAndStatusList scts;
+
int num_valid_scts = NumValidSCTsInStatusHistogram();
int num_invalid_scts = GetValueFromHistogram(
"Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN);
- EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), sct_list,
- &result, NetLogWithSource()));
+ EXPECT_NE(OK, verifier_->Verify(chain_.get(), std::string(), 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 b2e8e28203c..061ecd973f9 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -18,7 +18,6 @@
#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/sha1.h"
-#include "base/stl_util.h"
#include "base/threading/worker_pool.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -345,7 +344,6 @@ MultiThreadedCertVerifier::MultiThreadedCertVerifier(
: requests_(0), inflight_joins_(0), verify_proc_(verify_proc) {}
MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
- base::STLDeleteElements(&inflight_);
}
int MultiThreadedCertVerifier::Verify(const RequestParams& params,
@@ -371,8 +369,8 @@ int MultiThreadedCertVerifier::Verify(const RequestParams& params,
inflight_joins_++;
} else {
// Need to make a new job.
- std::unique_ptr<CertVerifierJob> new_job(
- new CertVerifierJob(params, net_log.net_log(), this));
+ std::unique_ptr<CertVerifierJob> new_job =
+ base::MakeUnique<CertVerifierJob>(params, net_log.net_log(), this);
if (!new_job->Start(verify_proc_, crl_set)) {
// TODO(wtc): log to the NetLog.
@@ -380,8 +378,8 @@ int MultiThreadedCertVerifier::Verify(const RequestParams& params,
return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
}
- job = new_job.release();
- inflight_.insert(job);
+ job = new_job.get();
+ inflight_[job] = std::move(new_job);
if (requests_ == 1)
job->set_is_first_job(true);
@@ -406,15 +404,18 @@ bool MultiThreadedCertVerifier::JobComparator::operator()(
std::unique_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
CertVerifierJob* job) {
DCHECK(CalledOnValidThread());
- bool erased_job = inflight_.erase(job) == 1;
- DCHECK(erased_job);
- return base::WrapUnique(job);
+ auto it = inflight_.find(job);
+ DCHECK(it != inflight_.end());
+ std::unique_ptr<CertVerifierJob> job_ptr = std::move(it->second);
+ inflight_.erase(it);
+ return job_ptr;
}
struct MultiThreadedCertVerifier::JobToRequestParamsComparator {
- bool operator()(const CertVerifierJob* job,
+ bool operator()(const std::pair<CertVerifierJob* const,
+ std::unique_ptr<CertVerifierJob>>& item,
const CertVerifier::RequestParams& value) const {
- return job->key() < value;
+ return item.first->key() < value;
}
};
@@ -425,8 +426,8 @@ CertVerifierJob* MultiThreadedCertVerifier::FindJob(const RequestParams& key) {
// search.
auto it = std::lower_bound(inflight_.begin(), inflight_.end(), key,
JobToRequestParamsComparator());
- if (it != inflight_.end() && !(key < (*it)->key()))
- return *it;
+ if (it != inflight_.end() && !(key < it->first->key()))
+ return it->first;
return nullptr;
}
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index d30d1fbd5d0..6022984dac6 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -8,8 +8,8 @@
#include <stddef.h>
#include <stdint.h>
+#include <map>
#include <memory>
-#include <set>
#include <string>
#include <vector>
@@ -64,8 +64,6 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier
const CertVerifierJob* job2) const;
};
- using JobSet = std::set<CertVerifierJob*, JobComparator>;
-
// Returns an inflight job for |key|. If there is no such job then returns
// null.
CertVerifierJob* FindJob(const RequestParams& key);
@@ -78,8 +76,12 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier
uint64_t requests() const { return requests_; }
uint64_t inflight_joins() const { return inflight_joins_; }
- // inflight_ holds the jobs for which an active verification is taking place.
- JobSet inflight_;
+ // inflight_ holds the jobs for which an active verification is taking place,
+ // mapping the job's raw pointer to an owned pointer. Would be a
+ // set<unique_ptr> but extraction of owned objects from a set of owned types
+ // doesn't come until C++17.
+ std::map<CertVerifierJob*, std::unique_ptr<CertVerifierJob>, JobComparator>
+ inflight_;
uint64_t requests_;
uint64_t inflight_joins_;
diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc
index 8d143a71298..6842643d5f6 100644
--- a/chromium/net/cert/nss_cert_database.cc
+++ b/chromium/net/cert/nss_cert_database.cc
@@ -53,17 +53,8 @@ class CertNotificationForwarder : public NSSCertDatabase::Observer {
~CertNotificationForwarder() override {}
- // NSSCertDatabase::Observer implementation:
- void OnCertAdded(const X509Certificate* cert) override {
- cert_db_->NotifyObserversOfCertAdded(cert);
- }
-
- void OnCertRemoved(const X509Certificate* cert) override {
- cert_db_->NotifyObserversOfCertRemoved(cert);
- }
-
- void OnCACertChanged(const X509Certificate* cert) override {
- cert_db_->NotifyObserversOfCACertChanged(cert);
+ void OnCertDBChanged(const X509Certificate* cert) override {
+ cert_db_->NotifyObserversCertDBChanged(cert);
}
private:
@@ -199,7 +190,7 @@ int NSSCertDatabase::ImportFromPKCS12(CryptoModule* module,
is_extractable,
imported_certs);
if (result == OK)
- NotifyObserversOfCertAdded(NULL);
+ NotifyObserversCertDBChanged(NULL);
return result;
}
@@ -241,7 +232,18 @@ int NSSCertDatabase::ImportUserCert(const std::string& data) {
int result = psm::ImportUserCert(certificates);
if (result == OK)
- NotifyObserversOfCertAdded(NULL);
+ NotifyObserversCertDBChanged(NULL);
+
+ return result;
+}
+
+int NSSCertDatabase::ImportUserCert(X509Certificate* certificate) {
+ CertificateList certificates;
+ certificates.emplace_back(certificate);
+ int result = psm::ImportUserCert(certificates);
+
+ if (result == OK)
+ NotifyObserversCertDBChanged(NULL);
return result;
}
@@ -254,7 +256,7 @@ bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
bool success = psm::ImportCACerts(
slot.get(), certificates, root, trust_bits, not_imported);
if (success)
- NotifyObserversOfCACertChanged(NULL);
+ NotifyObserversCertDBChanged(NULL);
return success;
}
@@ -372,7 +374,7 @@ bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
TrustBits trust_bits) {
bool success = psm::SetCertTrust(cert, type, trust_bits);
if (success)
- NotifyObserversOfCACertChanged(cert);
+ NotifyObserversCertDBChanged(cert);
return success;
}
@@ -380,7 +382,7 @@ bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) {
if (!DeleteCertAndKeyImpl(cert))
return false;
- NotifyObserversOfCertRemoved(cert);
+ NotifyObserversCertDBChanged(cert);
return true;
}
@@ -451,24 +453,13 @@ void NSSCertDatabase::NotifyCertRemovalAndCallBack(
const DeleteCertCallback& callback,
bool success) {
if (success)
- NotifyObserversOfCertRemoved(cert.get());
+ NotifyObserversCertDBChanged(cert.get());
callback.Run(success);
}
-void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCertAdded,
- base::RetainedRef(cert));
-}
-
-void NSSCertDatabase::NotifyObserversOfCertRemoved(
- const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCertRemoved,
- base::RetainedRef(cert));
-}
-
-void NSSCertDatabase::NotifyObserversOfCACertChanged(
+void NSSCertDatabase::NotifyObserversCertDBChanged(
const X509Certificate* cert) {
- observer_list_->Notify(FROM_HERE, &Observer::OnCACertChanged,
+ observer_list_->Notify(FROM_HERE, &Observer::OnCertDBChanged,
base::RetainedRef(cert));
}
diff --git a/chromium/net/cert/nss_cert_database.h b/chromium/net/cert/nss_cert_database.h
index 00e72f3f19b..2ee859dbb71 100644
--- a/chromium/net/cert/nss_cert_database.h
+++ b/chromium/net/cert/nss_cert_database.h
@@ -42,18 +42,10 @@ class NET_EXPORT NSSCertDatabase {
public:
virtual ~Observer() {}
- // Will be called when a new certificate is added.
- // Called with |cert| == NULL after importing a list of certificates
- // in ImportFromPKCS12().
- virtual void OnCertAdded(const X509Certificate* cert) {}
-
- // Will be called when a certificate is removed.
- virtual void OnCertRemoved(const X509Certificate* cert) {}
-
// Will be called when a CA certificate is changed.
// Called with |cert| == NULL after importing a list of certificates
// in ImportCACerts().
- virtual void OnCACertChanged(const X509Certificate* cert) {}
+ virtual void OnCertDBChanged(const X509Certificate* cert) {}
protected:
Observer() {}
@@ -199,6 +191,7 @@ class NET_EXPORT NSSCertDatabase {
// already be installed, otherwise we return ERR_NO_PRIVATE_KEY_FOR_CERT.
// Returns OK or a network error code.
int ImportUserCert(const std::string& data);
+ int ImportUserCert(X509Certificate* cert);
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
@@ -275,9 +268,7 @@ class NET_EXPORT NSSCertDatabase {
protected:
// Broadcasts notifications to all registered observers.
- void NotifyObserversOfCertAdded(const X509Certificate* cert);
- void NotifyObserversOfCertRemoved(const X509Certificate* cert);
- void NotifyObserversOfCACertChanged(const X509Certificate* cert);
+ void NotifyObserversCertDBChanged(const X509Certificate* cert);
private:
// Registers |observer| to receive notifications of certificate changes. The
diff --git a/chromium/net/cert/nss_cert_database_chromeos_unittest.cc b/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
index 05678df5ae7..9cd226411e2 100644
--- a/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
+++ b/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
@@ -85,13 +85,7 @@ class NSSCertDatabaseChromeOSTest : public testing::Test,
}
// CertDatabase::Observer:
- void OnCertAdded(const X509Certificate* cert) override {
- added_.push_back(cert ? cert->os_cert_handle() : NULL);
- }
-
- void OnCertRemoved(const X509Certificate* cert) override {}
-
- void OnCACertChanged(const X509Certificate* cert) override {
+ void OnCertDBChanged(const X509Certificate* cert) override {
added_ca_.push_back(cert ? cert->os_cert_handle() : NULL);
}
@@ -99,7 +93,6 @@ class NSSCertDatabaseChromeOSTest : public testing::Test,
bool observer_added_;
// Certificates that were passed to the CertDatabase observers.
std::vector<CERTCertificate*> added_ca_;
- std::vector<CERTCertificate*> added_;
crypto::ScopedTestNSSChromeOSUser user_1_;
crypto::ScopedTestNSSChromeOSUser user_2_;
@@ -180,13 +173,12 @@ TEST_F(NSSCertDatabaseChromeOSTest, ImportCACerts) {
// Run the message loop so the observer notifications get processed.
base::RunLoop().RunUntilIdle();
- // Should have gotten two OnCACertChanged notifications.
+ // Should have gotten two OnCertDBChanged notifications.
ASSERT_EQ(2U, added_ca_.size());
// TODO(mattm): make NSSCertDatabase actually pass the cert to the callback,
// and enable these checks:
// EXPECT_EQ(certs_1[0]->os_cert_handle(), added_ca_[0]);
// EXPECT_EQ(certs_2[0]->os_cert_handle(), added_ca_[1]);
- EXPECT_EQ(0U, added_.size());
// Tests that the new certs are loaded by async ListCerts method.
CertificateList user_1_certlist_async;
@@ -251,7 +243,6 @@ TEST_F(NSSCertDatabaseChromeOSTest, ImportServerCert) {
// TODO(mattm): ImportServerCert doesn't actually cause any observers to
// fire. Is that correct?
EXPECT_EQ(0U, added_ca_.size());
- EXPECT_EQ(0U, added_.size());
// Tests that the new certs are loaded by async ListCerts method.
CertificateList user_1_certlist_async;
diff --git a/chromium/net/cert/sth_distributor.cc b/chromium/net/cert/sth_distributor.cc
index c511e27a163..61b2ce83370 100644
--- a/chromium/net/cert/sth_distributor.cc
+++ b/chromium/net/cert/sth_distributor.cc
@@ -35,7 +35,8 @@ void STHDistributor::NewSTHObserved(const SignedTreeHead& sth) {
else
*it = sth;
- FOR_EACH_OBSERVER(STHObserver, observer_list_, NewSTHObserved(sth));
+ for (auto& observer : observer_list_)
+ observer.NewSTHObserved(sth);
if (sth.log_id.compare(0, sth.log_id.size(),
reinterpret_cast<const char*>(kPilotLogID),
diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h
index 1775e39379c..a77f0bf5f1d 100644
--- a/chromium/net/cert/test_root_certs.h
+++ b/chromium/net/cert/test_root_certs.h
@@ -12,7 +12,8 @@
#include "net/base/net_export.h"
#if defined(USE_NSS_CERTS)
-#include <list>
+#include <cert.h>
+#include <vector>
#elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
#include <vector>
#elif defined(OS_WIN)
@@ -24,9 +25,7 @@
#include "base/mac/scoped_cftyperef.h"
#endif
-#if defined(USE_NSS_CERTS)
-typedef struct CERTCertificateStr CERTCertificate;
-#elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
+#if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
typedef struct x509_st X509;
#endif
@@ -103,12 +102,35 @@ class NET_EXPORT TestRootCerts {
void Init();
#if defined(USE_NSS_CERTS)
+ // TrustEntry is used to store the original CERTCertificate and CERTCertTrust
+ // for a certificate whose trust status has been changed by the
+ // TestRootCerts.
+ class TrustEntry {
+ public:
+ // Creates a new TrustEntry by incrementing the reference to |certificate|
+ // and copying |trust|.
+ TrustEntry(CERTCertificate* certificate, const CERTCertTrust& trust);
+ ~TrustEntry();
+
+ CERTCertificate* certificate() const { return certificate_; }
+ const CERTCertTrust& trust() const { return trust_; }
+
+ private:
+ // The temporary root certificate.
+ CERTCertificate* certificate_;
+
+ // The original trust settings, before |certificate_| was manipulated to
+ // be a temporarily trusted root.
+ CERTCertTrust trust_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrustEntry);
+ };
+
// It is necessary to maintain a cache of the original certificate trust
// settings, in order to restore them when Clear() is called.
- class TrustEntry;
- std::list<TrustEntry*> trust_cache_;
+ std::vector<std::unique_ptr<TrustEntry>> trust_cache_;
#elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
- std::vector<scoped_refptr<X509Certificate> > temporary_roots_;
+ std::vector<scoped_refptr<X509Certificate>> temporary_roots_;
#elif defined(OS_WIN)
HCERTSTORE temporary_roots_;
#elif defined(OS_MACOSX)
diff --git a/chromium/net/cert/test_root_certs_nss.cc b/chromium/net/cert/test_root_certs_nss.cc
index 99ca63491c9..afa37f13ea2 100644
--- a/chromium/net/cert/test_root_certs_nss.cc
+++ b/chromium/net/cert/test_root_certs_nss.cc
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stl_util.h"
+#include "base/memory/ptr_util.h"
#include "crypto/nss_util.h"
#include "net/cert/x509_certificate.h"
@@ -18,29 +18,6 @@
namespace net {
-// TrustEntry is used to store the original CERTCertificate and CERTCertTrust
-// for a certificate whose trust status has been changed by the
-// TestRootCerts.
-class TestRootCerts::TrustEntry {
- public:
- // Creates a new TrustEntry by incrementing the reference to |certificate|
- // and copying |trust|.
- TrustEntry(CERTCertificate* certificate, const CERTCertTrust& trust);
- ~TrustEntry();
-
- CERTCertificate* certificate() const { return certificate_; }
- const CERTCertTrust& trust() const { return trust_; }
-
- private:
- // The temporary root certificate.
- CERTCertificate* certificate_;
-
- // The original trust settings, before |certificate_| was manipulated to
- // be a temporarily trusted root.
- CERTCertTrust trust_;
-
- DISALLOW_COPY_AND_ASSIGN(TrustEntry);
-};
TestRootCerts::TrustEntry::TrustEntry(CERTCertificate* certificate,
const CERTCertTrust& trust)
@@ -87,7 +64,8 @@ bool TestRootCerts::Add(X509Certificate* certificate) {
return false;
}
- trust_cache_.push_back(new TrustEntry(cert_handle, original_trust));
+ trust_cache_.push_back(
+ base::MakeUnique<TrustEntry>(cert_handle, original_trust));
return true;
}
@@ -97,8 +75,7 @@ void TestRootCerts::Clear() {
// added twice, the second entry's original trust status will be that of
// the first entry, while the first entry contains the desired resultant
// status.
- for (std::list<TrustEntry*>::reverse_iterator it = trust_cache_.rbegin();
- it != trust_cache_.rend(); ++it) {
+ for (auto it = trust_cache_.rbegin(); it != trust_cache_.rend(); ++it) {
CERTCertTrust original_trust = (*it)->trust();
SECStatus rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
(*it)->certificate(),
@@ -108,7 +85,7 @@ void TestRootCerts::Clear() {
// occur after Clear() has been called.
DCHECK_EQ(SECSuccess, rv) << "Cannot restore certificate trust.";
}
- base::STLDeleteElements(&trust_cache_);
+ trust_cache_.clear();
}
bool TestRootCerts::IsEmpty() const {
@@ -117,11 +94,10 @@ bool TestRootCerts::IsEmpty() const {
#if defined(USE_NSS_CERTS)
bool TestRootCerts::Contains(CERTCertificate* cert) const {
- for (std::list<TrustEntry*>::const_iterator it = trust_cache_.begin();
- it != trust_cache_.end(); ++it) {
- if (X509Certificate::IsSameOSCert(cert, (*it)->certificate()))
+ for (const auto& item : trust_cache_)
+ if (X509Certificate::IsSameOSCert(cert, item->certificate()))
return true;
- }
+
return false;
}
#endif
diff --git a/chromium/net/cert/test_root_certs_openssl.cc b/chromium/net/cert/test_root_certs_openssl.cc
index 76906d86f00..0cac6ab3660 100644
--- a/chromium/net/cert/test_root_certs_openssl.cc
+++ b/chromium/net/cert/test_root_certs_openssl.cc
@@ -4,13 +4,12 @@
#include "net/cert/test_root_certs.h"
-#include <openssl/err.h>
-#include <openssl/x509v3.h>
-
#include "base/location.h"
#include "base/logging.h"
#include "crypto/openssl_util.h"
#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
namespace net {
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index 48cc5b5c8c5..7f23e7bf1d4 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -551,7 +551,7 @@ bool X509Certificate::VerifyHostname(
// is not registry controlled, this ensures that all reference domains
// contain at least three domain components when using wildcards.
size_t registry_length =
- registry_controlled_domains::GetRegistryLength(
+ registry_controlled_domains::GetCanonicalHostRegistryLength(
reference_name,
registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
diff --git a/chromium/net/cert/x509_certificate_ios.cc b/chromium/net/cert/x509_certificate_ios.cc
index f50652ce8b6..737970768fb 100644
--- a/chromium/net/cert/x509_certificate_ios.cc
+++ b/chromium/net/cert/x509_certificate_ios.cc
@@ -7,18 +7,16 @@
#include <CommonCrypto/CommonDigest.h>
#include <Security/Security.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-
#include "base/mac/scoped_cftyperef.h"
#include "base/pickle.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "net/base/ip_address.h"
#include "net/cert/x509_util_openssl.h"
#include "net/ssl/openssl_ssl_util.h"
+#include "third_party/boringssl/src/include/openssl/x509.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
using base::ScopedCFTypeRef;
@@ -26,9 +24,6 @@ namespace net {
namespace {
-using ScopedGENERAL_NAMES =
- crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
-
// Returns true if a given |cert_handle| is actually a valid X.509 certificate
// handle.
//
@@ -109,7 +104,7 @@ void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
std::vector<std::string>* dns_names,
std::vector<std::string>* ip_addresses) {
DCHECK(dns_names || ip_addresses);
- ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
+ bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
if (!cert.get())
return;
int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
@@ -117,7 +112,7 @@ void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
if (!alt_name_ext)
return;
- ScopedGENERAL_NAMES alt_names(
+ bssl::UniquePtr<GENERAL_NAMES> alt_names(
reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
if (!alt_names.get())
return;
@@ -150,11 +145,6 @@ void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
}
}
-// Used to free a list of X509_NAMEs and the objects it points to.
-void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) {
- sk_X509_NAME_pop_free(sk, X509_NAME_free);
-}
-
} // namespace
// static
@@ -173,7 +163,7 @@ void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
void X509Certificate::Initialize() {
crypto::EnsureOpenSSLInit();
- ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
+ bssl::UniquePtr<X509> x509_cert = OSCertHandleToOpenSSL(cert_handle_);
if (!x509_cert)
return;
ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get());
@@ -342,10 +332,10 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
PublicKeyType* type) {
*type = kPublicKeyTypeUnknown;
*size_bits = 0;
- ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
+ bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
if (!cert)
return;
- crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
+ bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get()));
if (!scoped_key)
return;
@@ -392,8 +382,7 @@ bool X509Certificate::IsIssuedByEncoded(
// Convert to a temporary list of X509_NAME objects.
// It will own the objects it points to.
- crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>
- issuer_names(sk_X509_NAME_new_null());
+ bssl::UniquePtr<STACK_OF(X509_NAME)> issuer_names(sk_X509_NAME_new_null());
if (!issuer_names)
return false;
@@ -407,7 +396,7 @@ bool X509Certificate::IsIssuedByEncoded(
sk_X509_NAME_push(issuer_names.get(), ca_name);
}
- ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
+ bssl::UniquePtr<X509> x509_cert = OSCertHandleToOpenSSL(cert_handle_);
if (!x509_cert)
return false;
X509_NAME* cert_issuer = X509_get_issuer_name(x509_cert.get());
@@ -423,7 +412,7 @@ bool X509Certificate::IsIssuedByEncoded(
for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
it != intermediate_ca_certs_.end(); ++it) {
- ScopedX509 intermediate_cert = OSCertHandleToOpenSSL(*it);
+ bssl::UniquePtr<X509> intermediate_cert = OSCertHandleToOpenSSL(*it);
if (!intermediate_cert)
return false;
cert_issuer = X509_get_issuer_name(intermediate_cert.get());
@@ -443,10 +432,10 @@ bool X509Certificate::IsIssuedByEncoded(
// static
bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) {
- ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
+ bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
if (!cert)
return false;
- crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
+ bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get()));
if (!scoped_key)
return false;
if (!X509_verify(cert.get(), scoped_key.get()))
diff --git a/chromium/net/cert/x509_certificate_openssl.cc b/chromium/net/cert/x509_certificate_openssl.cc
index e22ea9f099d..30d9598a50a 100644
--- a/chromium/net/cert/x509_certificate_openssl.cc
+++ b/chromium/net/cert/x509_certificate_openssl.cc
@@ -4,15 +4,6 @@
#include "net/cert/x509_certificate.h"
-#include <openssl/asn1.h>
-#include <openssl/bytestring.h>
-#include <openssl/crypto.h>
-#include <openssl/obj_mac.h>
-#include <openssl/pem.h>
-#include <openssl/sha.h>
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/numerics/safe_conversions.h"
@@ -22,10 +13,17 @@
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_util_openssl.h"
+#include "third_party/boringssl/src/include/openssl/asn1.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/crypto.h"
+#include "third_party/boringssl/src/include/openssl/obj_mac.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
#if defined(OS_ANDROID)
#include "base/logging.h"
@@ -36,9 +34,6 @@ namespace net {
namespace {
-using ScopedGENERAL_NAMES =
- crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
-
void CreateOSCertHandlesFromPKCS7Bytes(
const char* data,
size_t length,
@@ -106,7 +101,7 @@ void ParseSubjectAltName(X509Certificate::OSCertHandle cert,
if (!alt_name_ext)
return;
- ScopedGENERAL_NAMES alt_names(
+ bssl::UniquePtr<GENERAL_NAMES> alt_names(
reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
if (!alt_names.get())
return;
@@ -164,16 +159,11 @@ class X509InitSingleton {
ResetCertStore();
}
- crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_;
+ bssl::UniquePtr<X509_STORE> store_;
DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
};
-// Used to free a list of X509_NAMEs and the objects it points to.
-void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) {
- sk_X509_NAME_pop_free(sk, X509_NAME_free);
-}
-
} // namespace
// static
@@ -361,11 +351,10 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
*type = kPublicKeyTypeUnknown;
*size_bits = 0;
- crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle));
+ bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle));
if (!scoped_key.get())
return;
- CHECK(scoped_key.get());
EVP_PKEY* key = scoped_key.get();
switch (key->type) {
@@ -395,8 +384,7 @@ bool X509Certificate::IsIssuedByEncoded(
// Convert to a temporary list of X509_NAME objects.
// It will own the objects it points to.
- crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>
- issuer_names(sk_X509_NAME_new_null());
+ bssl::UniquePtr<STACK_OF(X509_NAME)> issuer_names(sk_X509_NAME_new_null());
if (!issuer_names.get())
return false;
@@ -442,7 +430,7 @@ bool X509Certificate::IsIssuedByEncoded(
// static
bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
- crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle));
+ bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle));
if (!scoped_key)
return false;
if (!X509_verify(cert_handle, scoped_key.get()))
diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc
index 771dda12122..9cadb266849 100644
--- a/chromium/net/cert/x509_certificate_unittest.cc
+++ b/chromium/net/cert/x509_certificate_unittest.cc
@@ -492,6 +492,32 @@ TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) {
}
}
+TEST(X509CertificateTest, HasTLSFeatureExtension) {
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> cert =
+ ImportCertFromFile(certs_dir, "tls_feature_extension.pem");
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
+
+ std::string derBytes;
+ EXPECT_TRUE(
+ X509Certificate::GetDEREncoded(cert->os_cert_handle(), &derBytes));
+
+ EXPECT_TRUE(asn1::HasTLSFeatureExtension(derBytes));
+}
+
+TEST(X509CertificateTest, DoesNotHaveTLSFeatureExtension) {
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> cert =
+ ImportCertFromFile(certs_dir, "ok_cert.pem");
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
+
+ std::string derBytes;
+ EXPECT_TRUE(
+ X509Certificate::GetDEREncoded(cert->os_cert_handle(), &derBytes));
+
+ EXPECT_FALSE(asn1::HasTLSFeatureExtension(derBytes));
+}
+
// Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
// call X509Certificate::CreateFromHandle several times and observe whether
// it returns a cached or new OSCertHandle.
diff --git a/chromium/net/cert/x509_certificate_win.cc b/chromium/net/cert/x509_certificate_win.cc
index 4c6e389177b..c67011e06b9 100644
--- a/chromium/net/cert/x509_certificate_win.cc
+++ b/chromium/net/cert/x509_certificate_win.cc
@@ -6,8 +6,6 @@
#include <memory>
-#include <openssl/sha.h>
-
#include "base/logging.h"
#include "base/memory/free_deleter.h"
#include "base/numerics/safe_conversions.h"
@@ -19,6 +17,7 @@
#include "crypto/scoped_capi_types.h"
#include "crypto/sha2.h"
#include "net/base/net_errors.h"
+#include "third_party/boringssl/src/include/openssl/sha.h"
using base::Time;
diff --git a/chromium/net/cert/x509_util_openssl.cc b/chromium/net/cert/x509_util_openssl.cc
index 4c6ee78547e..4a2aba01dc6 100644
--- a/chromium/net/cert/x509_util_openssl.cc
+++ b/chromium/net/cert/x509_util_openssl.cc
@@ -5,9 +5,6 @@
#include "net/cert/x509_util_openssl.h"
#include <limits.h>
-#include <openssl/asn1.h>
-#include <openssl/digest.h>
-#include <openssl/mem.h>
#include <algorithm>
#include <memory>
@@ -20,27 +17,19 @@
#include "crypto/ec_private_key.h"
#include "crypto/openssl_util.h"
#include "crypto/rsa_private_key.h"
-#include "crypto/scoped_openssl_types.h"
#include "net/cert/internal/parse_certificate.h"
#include "net/cert/internal/signature_algorithm.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
-#include "net/ssl/scoped_openssl_types.h"
+#include "third_party/boringssl/src/include/openssl/asn1.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
namespace net {
namespace {
-using ScopedASN1_INTEGER =
- crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free>;
-using ScopedASN1_OCTET_STRING =
- crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>;
-using ScopedASN1_STRING = crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free>;
-using ScopedASN1_TIME = crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free>;
-using ScopedX509_EXTENSION =
- crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free>;
-
const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) {
switch (alg) {
case x509_util::DIGEST_SHA1:
@@ -57,34 +46,34 @@ namespace x509_util {
namespace {
-X509* CreateCertificate(EVP_PKEY* key,
- DigestAlgorithm alg,
- const std::string& common_name,
- uint32_t serial_number,
- base::Time not_valid_before,
- base::Time not_valid_after) {
+bssl::UniquePtr<X509> CreateCertificate(EVP_PKEY* key,
+ DigestAlgorithm alg,
+ const std::string& common_name,
+ uint32_t serial_number,
+ base::Time not_valid_before,
+ base::Time not_valid_after) {
// Put the serial number into an OpenSSL-friendly object.
- ScopedASN1_INTEGER asn1_serial(ASN1_INTEGER_new());
+ bssl::UniquePtr<ASN1_INTEGER> asn1_serial(ASN1_INTEGER_new());
if (!asn1_serial.get() ||
!ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) {
LOG(ERROR) << "Invalid serial number " << serial_number;
- return NULL;
+ return nullptr;
}
// Do the same for the time stamps.
- ScopedASN1_TIME asn1_not_before_time(
- ASN1_TIME_set(NULL, not_valid_before.ToTimeT()));
+ bssl::UniquePtr<ASN1_TIME> asn1_not_before_time(
+ ASN1_TIME_set(nullptr, not_valid_before.ToTimeT()));
if (!asn1_not_before_time.get()) {
LOG(ERROR) << "Invalid not_valid_before time: "
<< not_valid_before.ToTimeT();
- return NULL;
+ return nullptr;
}
- ScopedASN1_TIME asn1_not_after_time(
- ASN1_TIME_set(NULL, not_valid_after.ToTimeT()));
+ bssl::UniquePtr<ASN1_TIME> asn1_not_after_time(
+ ASN1_TIME_set(nullptr, not_valid_after.ToTimeT()));
if (!asn1_not_after_time.get()) {
LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT();
- return NULL;
+ return nullptr;
}
// Because |common_name| only contains a common name and starts with 'CN=',
@@ -95,11 +84,11 @@ X509* CreateCertificate(EVP_PKEY* key,
if (common_name.size() < kCommonNamePrefixLen ||
strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) {
LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix;
- return NULL;
+ return nullptr;
}
if (common_name.size() > INT_MAX) {
LOG(ERROR) << "Common name too long";
- return NULL;
+ return nullptr;
}
unsigned char* common_name_str =
reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) +
@@ -107,7 +96,7 @@ X509* CreateCertificate(EVP_PKEY* key,
int common_name_len =
static_cast<int>(common_name.size() - kCommonNamePrefixLen);
- ScopedX509_NAME name(X509_NAME_new());
+ bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(),
NID_commonName,
MBSTRING_ASC,
@@ -116,11 +105,11 @@ X509* CreateCertificate(EVP_PKEY* key,
-1,
0)) {
LOG(ERROR) << "Can't parse common name: " << common_name.c_str();
- return NULL;
+ return nullptr;
}
// Now create certificate and populate it.
- ScopedX509 cert(X509_new());
+ bssl::UniquePtr<X509> cert(X509_new());
if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ ||
!X509_set_pubkey(cert.get(), key) ||
!X509_set_serialNumber(cert.get(), asn1_serial.get()) ||
@@ -129,10 +118,10 @@ X509* CreateCertificate(EVP_PKEY* key,
!X509_set_subject_name(cert.get(), name.get()) ||
!X509_set_issuer_name(cert.get(), name.get())) {
LOG(ERROR) << "Could not create certificate";
- return NULL;
+ return nullptr;
}
- return cert.release();
+ return cert;
}
// DER-encodes |x509|. On success, returns true and writes the
@@ -211,13 +200,10 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
base::Time not_valid_after,
std::string* der_encoded) {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedX509 cert(CreateCertificate(key->key(),
- alg,
- common_name,
- serial_number,
- not_valid_before,
- not_valid_after));
- if (!cert.get())
+ bssl::UniquePtr<X509> cert =
+ CreateCertificate(key->key(), alg, common_name, serial_number,
+ not_valid_before, not_valid_after);
+ if (!cert)
return false;
return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded);
diff --git a/chromium/net/cert/x509_util_openssl.h b/chromium/net/cert/x509_util_openssl.h
index c77aed07a7a..b735c1ac21a 100644
--- a/chromium/net/cert/x509_util_openssl.h
+++ b/chromium/net/cert/x509_util_openssl.h
@@ -5,14 +5,13 @@
#ifndef NET_CERT_X509_UTIL_OPENSSL_H_
#define NET_CERT_X509_UTIL_OPENSSL_H_
-#include <openssl/asn1.h>
-#include <openssl/x509v3.h>
-
#include <string>
#include <vector>
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
+#include "third_party/boringssl/src/include/openssl/asn1.h"
+#include "third_party/boringssl/src/include/openssl/x509v3.h"
namespace base {
class Time;