diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 21:48:11 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 21:48:11 +0000 |
commit | 6e7845aed4759ab35d722ce0551b5a90d21e7640 (patch) | |
tree | f29a3f007f7ded842d2096446ff7ecaf186cb362 /net/base | |
parent | a6b4f91d970aa2b71b0f3552dbc11e94f7650fd5 (diff) | |
download | chromium_src-6e7845aed4759ab35d722ce0551b5a90d21e7640.zip chromium_src-6e7845aed4759ab35d722ce0551b5a90d21e7640.tar.gz chromium_src-6e7845aed4759ab35d722ce0551b5a90d21e7640.tar.bz2 |
net: extract net/cert out of net/base
This introduces the following dependency of net/base on things outside:
net/base/openssl_client_key_store.cc:#include "net/cert/x509_certificate.h"
BUG=70818
Review URL: https://codereview.chromium.org/13006020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191450 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base')
92 files changed, 2 insertions, 20988 deletions
diff --git a/net/base/asn1_util.cc b/net/base/asn1_util.cc deleted file mode 100644 index 2f606b6..0000000 --- a/net/base/asn1_util.cc +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/asn1_util.h" - -namespace net { - -namespace asn1 { - -bool ParseElement(base::StringPiece* in, - unsigned tag_value, - base::StringPiece* out, - unsigned *out_header_len) { - const uint8* data = reinterpret_cast<const uint8*>(in->data()); - - // We don't support kAny and kOptional at the same time. - if ((tag_value & kAny) && (tag_value & kOptional)) - return false; - - if (in->empty() && (tag_value & kOptional)) { - if (out_header_len) - *out_header_len = 0; - if (out) - *out = base::StringPiece(); - return true; - } - - if (in->size() < 2) - return false; - - if (tag_value != kAny && - static_cast<unsigned char>(data[0]) != (tag_value & 0xff)) { - if (tag_value & kOptional) { - if (out_header_len) - *out_header_len = 0; - if (out) - *out = base::StringPiece(); - return true; - } - return false; - } - - size_t len = 0; - if ((data[1] & 0x80) == 0) { - // short form length - if (out_header_len) - *out_header_len = 2; - len = static_cast<size_t>(data[1]) + 2; - } else { - // long form length - const unsigned num_bytes = data[1] & 0x7f; - if (num_bytes == 0 || num_bytes > 2) - return false; - if (in->size() < 2 + num_bytes) - return false; - len = data[2]; - if (num_bytes == 2) { - if (len == 0) { - // the length encoding must be minimal. - return false; - } - len <<= 8; - len += data[3]; - } - if (len < 128) { - // the length should have been encoded in short form. This distinguishes - // DER from BER encoding. - return false; - } - if (out_header_len) - *out_header_len = 2 + num_bytes; - len += 2 + num_bytes; - } - - if (in->size() < len) - return false; - if (out) - *out = base::StringPiece(in->data(), len); - in->remove_prefix(len); - return true; -} - -bool GetElement(base::StringPiece* in, - unsigned tag_value, - base::StringPiece* out) { - unsigned header_len; - if (!ParseElement(in, tag_value, out, &header_len)) - return false; - if (out) - out->remove_prefix(header_len); - return true; -} - -// SeekToSPKI changes |cert| so that it points to a suffix of the -// TBSCertificate where the suffix begins at the start of the ASN.1 -// SubjectPublicKeyInfo value. -static bool SeekToSPKI(base::StringPiece* cert) { - // From RFC 5280, section 4.1 - // Certificate ::= SEQUENCE { - // tbsCertificate TBSCertificate, - // signatureAlgorithm AlgorithmIdentifier, - // signatureValue BIT STRING } - - // TBSCertificate ::= SEQUENCE { - // version [0] EXPLICIT Version DEFAULT v1, - // serialNumber CertificateSerialNumber, - // signature AlgorithmIdentifier, - // issuer Name, - // validity Validity, - // subject Name, - // subjectPublicKeyInfo SubjectPublicKeyInfo, - - base::StringPiece certificate; - if (!GetElement(cert, kSEQUENCE, &certificate)) - return false; - - // We don't allow junk after the certificate. - if (!cert->empty()) - return false; - - base::StringPiece tbs_certificate; - if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate)) - return false; - - if (!GetElement(&tbs_certificate, - kOptional | kConstructed | kContextSpecific | 0, - NULL)) { - return false; - } - - // serialNumber - if (!GetElement(&tbs_certificate, kINTEGER, NULL)) - return false; - // signature - if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) - return false; - // issuer - if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) - return false; - // validity - if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) - return false; - // subject - if (!GetElement(&tbs_certificate, kSEQUENCE, NULL)) - return false; - *cert = tbs_certificate; - return true; -} - -bool ExtractSPKIFromDERCert(base::StringPiece cert, - base::StringPiece* spki_out) { - if (!SeekToSPKI(&cert)) - return false; - if (!ParseElement(&cert, kSEQUENCE, spki_out, NULL)) - return false; - return true; -} - -bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki, - base::StringPiece* spk_out) { - // From RFC 5280, Section 4.1 - // SubjectPublicKeyInfo ::= SEQUENCE { - // algorithm AlgorithmIdentifier, - // subjectPublicKey BIT STRING } - // - // AlgorithmIdentifier ::= SEQUENCE { - // algorithm OBJECT IDENTIFIER, - // parameters ANY DEFINED BY algorithm OPTIONAL } - - // Step into SubjectPublicKeyInfo sequence. - base::StringPiece spki_contents; - if (!asn1::GetElement(&spki, asn1::kSEQUENCE, &spki_contents)) - return false; - - // Step over algorithm field (a SEQUENCE). - base::StringPiece algorithm; - if (!asn1::GetElement(&spki_contents, asn1::kSEQUENCE, &algorithm)) - return false; - - // Extract the subjectPublicKey field. - if (!asn1::GetElement(&spki_contents, asn1::kBITSTRING, spk_out)) - return false; - return true; -} - - -bool ExtractCRLURLsFromDERCert(base::StringPiece cert, - std::vector<base::StringPiece>* urls_out) { - urls_out->clear(); - std::vector<base::StringPiece> tmp_urls_out; - - if (!SeekToSPKI(&cert)) - 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 (!GetElement(&cert, kSEQUENCE, NULL)) - return false; - // issuerUniqueID - if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL)) - return false; - // subjectUniqueID - if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL)) - return false; - - base::StringPiece extensions_seq; - if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3, - &extensions_seq)) { - return false; - } - - if (extensions_seq.empty()) - return true; - - // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - // Extension ::= SEQUENCE { - // extnID OBJECT IDENTIFIER, - // critical BOOLEAN DEFAULT FALSE, - // extnValue OCTET STRING - - // |extensions_seq| was EXPLICITly tagged, so we still need to remove the - // ASN.1 SEQUENCE header. - base::StringPiece extensions; - if (!GetElement(&extensions_seq, kSEQUENCE, &extensions)) - return false; - - while (extensions.size() > 0) { - base::StringPiece extension; - if (!GetElement(&extensions, kSEQUENCE, &extension)) - return false; - - base::StringPiece oid; - if (!GetElement(&extension, kOID, &oid)) - return false; - - // kCRLDistributionPointsOID is the DER encoding of the OID for the X.509 - // CRL Distribution Points extension. - static const uint8 kCRLDistributionPointsOID[] = {0x55, 0x1d, 0x1f}; - - if (oid.size() != sizeof(kCRLDistributionPointsOID) || - memcmp(oid.data(), kCRLDistributionPointsOID, oid.size()) != 0) { - continue; - } - - // critical - GetElement(&extension, kBOOLEAN, NULL); - - // extnValue - base::StringPiece extension_value; - if (!GetElement(&extension, kOCTETSTRING, &extension_value)) - return false; - - // RFC 5280, section 4.2.1.13. - // - // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint - // - // DistributionPoint ::= SEQUENCE { - // distributionPoint [0] DistributionPointName OPTIONAL, - // reasons [1] ReasonFlags OPTIONAL, - // cRLIssuer [2] GeneralNames OPTIONAL } - - base::StringPiece distribution_points; - if (!GetElement(&extension_value, kSEQUENCE, &distribution_points)) - return false; - - while (distribution_points.size() > 0) { - base::StringPiece distrib_point; - if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point)) - return false; - - base::StringPiece name; - if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0, - &name)) { - // If it doesn't contain a name then we skip it. - continue; - } - - if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) { - // If it contains a subset of reasons then we skip it. We aren't - // interested in subsets of CRLs and the RFC states that there MUST be - // a CRL that covers all reasons. - continue; - } - - if (GetElement(&distrib_point, - kContextSpecific | kConstructed | 2, NULL)) { - // If it contains a alternative issuer, then we skip it. - continue; - } - - // DistributionPointName ::= CHOICE { - // fullName [0] GeneralNames, - // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } - base::StringPiece general_names; - if (!GetElement(&name, - kContextSpecific | kConstructed | 0, &general_names)) { - continue; - } - - // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - // GeneralName ::= CHOICE { - // ... - // uniformResourceIdentifier [6] IA5String, - // ... - while (general_names.size() > 0) { - base::StringPiece url; - if (GetElement(&general_names, kContextSpecific | 6, &url)) { - tmp_urls_out.push_back(url); - } else { - if (!GetElement(&general_names, kAny, NULL)) - return false; - } - } - } - } - - urls_out->swap(tmp_urls_out); - return true; -} - -} // namespace asn1 - -} // namespace net diff --git a/net/base/asn1_util.h b/net/base/asn1_util.h deleted file mode 100644 index 7c584c4..0000000 --- a/net/base/asn1_util.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_ASN1_UTIL_H_ -#define NET_BASE_ASN1_UTIL_H_ - -#include <vector> - -#include "base/string_piece.h" -#include "net/base/net_export.h" - -namespace net { - -namespace asn1 { - -// These are the DER encodings of the tag byte for ASN.1 objects. -static const unsigned kBOOLEAN = 0x01; -static const unsigned kINTEGER = 0x02; -static const unsigned kBITSTRING = 0x03; -static const unsigned kOCTETSTRING = 0x04; -static const unsigned kOID = 0x06; -static const unsigned kSEQUENCE = 0x30; - -// These are flags that can be ORed with the above tag numbers. -static const unsigned kContextSpecific = 0x80; -static const unsigned kConstructed = 0x20; - -// kAny matches any tag value; -static const unsigned kAny = 0x10000; -// kOptional denotes an optional element. -static const unsigned kOptional = 0x20000; - -// ParseElement parses a DER encoded ASN1 element from |in|, requiring that -// it have the given |tag_value|. It returns true on success. The following -// limitations are imposed: -// 1) tag numbers > 31 are not permitted. -// 2) lengths > 65535 are not permitted. -// On successful return: -// |in| is advanced over the element -// |out| contains the element, including the tag and length bytes. -// |out_header_len| contains the length of the tag and length bytes in |out|. -// -// If |tag_value & kOptional| is true then *out_header_len can be zero after a -// true return value if the element was not found. -bool ParseElement(base::StringPiece* in, - unsigned tag_value, - base::StringPiece* out, - unsigned *out_header_len); - -// GetElement performs the same actions as ParseElement, except that the header -// bytes are not included in the output. -// -// If |tag_value & kOptional| is true then this function cannot distinguish -// between a missing optional element and an empty one. -bool GetElement(base::StringPiece* in, - unsigned tag_value, - base::StringPiece* out); - -// ExtractSPKIFromDERCert parses the DER encoded certificate in |cert| and -// extracts the bytes of the SubjectPublicKeyInfo. On successful return, -// |spki_out| is set to contain the SPKI, pointing into |cert|. -NET_EXPORT_PRIVATE bool ExtractSPKIFromDERCert(base::StringPiece cert, - base::StringPiece* spki_out); - -// ExtractSubjectPublicKeyFromSPKI parses the DER encoded SubjectPublicKeyInfo -// in |spki| and extracts the bytes of the SubjectPublicKey. On successful -// return, |spk_out| is set to contain the public key, pointing into |spki|. -NET_EXPORT_PRIVATE bool ExtractSubjectPublicKeyFromSPKI( - base::StringPiece spki, - base::StringPiece* spk_out); - -// ExtractCRLURLsFromDERCert parses the DER encoded certificate in |cert| and -// extracts the URL of each CRL. On successful return, the elements of -// |urls_out| point into |cert|. -// -// CRLs that only cover a subset of the reasons are omitted as the spec -// requires that at least one CRL be included that covers all reasons. -// -// CRLs that use an alternative issuer are also omitted. -// -// The nested set of GeneralNames is flattened into a single list because -// having several CRLs with one location is equivalent to having one CRL with -// several locations as far as a CRL filter is concerned. -NET_EXPORT_PRIVATE bool ExtractCRLURLsFromDERCert( - base::StringPiece cert, - std::vector<base::StringPiece>* urls_out); - -} // namespace asn1 - -} // namespace net - -#endif // NET_BASE_ASN1_UTIL_H_ diff --git a/net/base/cert_database.cc b/net/base/cert_database.cc deleted file mode 100644 index ec2f0b8..0000000 --- a/net/base/cert_database.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include "base/memory/singleton.h" -#include "base/observer_list_threadsafe.h" - -namespace net { - -// static -CertDatabase* CertDatabase::GetInstance() { - return Singleton<CertDatabase>::get(); -} - -void CertDatabase::AddObserver(Observer* observer) { - observer_list_->AddObserver(observer); -} - -void CertDatabase::RemoveObserver(Observer* observer) { - observer_list_->RemoveObserver(observer); -} - -void CertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { - observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); -} - -void CertDatabase::NotifyObserversOfCertRemoved(const X509Certificate* cert) { - observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); -} - -void CertDatabase::NotifyObserversOfCertTrustChanged( - const X509Certificate* cert) { - observer_list_->Notify( - &Observer::OnCertTrustChanged, make_scoped_refptr(cert)); -} - -} // namespace net diff --git a/net/base/cert_database.h b/net/base/cert_database.h deleted file mode 100644 index d71a254..0000000 --- a/net/base/cert_database.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_DATABASE_H_ -#define NET_BASE_CERT_DATABASE_H_ - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/net_export.h" -#include "net/base/x509_certificate.h" - -template <typename T> struct DefaultSingletonTraits; -template <class ObserverType> class ObserverListThreadSafe; - -namespace net { - -// This class provides cross-platform functions to verify and add user -// certificates, and to observe changes to the underlying certificate stores. - -// TODO(gauravsh): This class could be augmented with methods -// for all operations that manipulate the underlying system -// certificate store. - -class NET_EXPORT CertDatabase { - public: - // A CertDatabase::Observer will be notified on certificate database changes. - // The change could be either a new user certificate is added or trust on - // a certificate is changed. Observers can register themselves - // via CertDatabase::AddObserver, and can un-register with - // CertDatabase::RemoveObserver. - class NET_EXPORT Observer { - public: - virtual ~Observer() {} - - // Will be called when a new certificate is added. - 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 certificate's trust is changed. - virtual void OnCertTrustChanged(const X509Certificate* cert) {} - - protected: - Observer() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Observer); - }; - - // 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. - void AddObserver(Observer* observer); - - // Unregisters |observer| from receiving notifications. This must be called - // on the same thread on which AddObserver() was called. - void RemoveObserver(Observer* observer); - -#if defined(OS_MACOSX) && !defined(OS_IOS) - // Configures the current message loop to observe and forward events from - // Keychain services. The MessageLoop must have an associated CFRunLoop, - // which means that this must be called from a MessageLoop of TYPE_UI. - void SetMessageLoopForKeychainEvents(); -#endif - - private: - friend struct DefaultSingletonTraits<CertDatabase>; - - CertDatabase(); - ~CertDatabase(); - - // Broadcasts notifications to all registered observers. - void NotifyObserversOfCertAdded(const X509Certificate* cert); - void NotifyObserversOfCertRemoved(const X509Certificate* cert); - void NotifyObserversOfCertTrustChanged(const X509Certificate* cert); - - const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; - -#if defined(USE_NSS) || (defined(OS_MACOSX) && !defined(OS_IOS)) - class Notifier; - friend class Notifier; - scoped_ptr<Notifier> notifier_; -#endif - - DISALLOW_COPY_AND_ASSIGN(CertDatabase); -}; - -} // namespace net - -#endif // NET_BASE_CERT_DATABASE_H_ diff --git a/net/base/cert_database_android.cc b/net/base/cert_database_android.cc deleted file mode 100644 index c441089..0000000 --- a/net/base/cert_database_android.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "net/base/net_errors.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { -} - -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; -} - -} // namespace net diff --git a/net/base/cert_database_ios.cc b/net/base/cert_database_ios.cc deleted file mode 100644 index b7e6ad3..0000000 --- a/net/base/cert_database_ios.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "net/base/net_errors.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) {} - -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/net/base/cert_database_mac.cc b/net/base/cert_database_mac.cc deleted file mode 100644 index 2d3ef14..0000000 --- a/net/base/cert_database_mac.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include <Security/Security.h> - -#include "base/logging.h" -#include "base/mac/mac_logging.h" -#include "base/message_loop.h" -#include "base/observer_list_threadsafe.h" -#include "base/process_util.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/lock.h" -#include "crypto/mac_security_services_lock.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -// Helper that observes events from the Keychain and forwards them to the -// given CertDatabase. -class CertDatabase::Notifier { - public: - // Creates a new Notifier that will forward Keychain events to |cert_db|. - // |message_loop| must refer to a thread with an associated CFRunLoop - a - // TYPE_UI thread. Events will be dispatched from this message loop. - Notifier(CertDatabase* cert_db, MessageLoop* message_loop) - : cert_db_(cert_db), - registered_(false), - called_shutdown_(false) { - // Ensure an associated CFRunLoop. - DCHECK(message_loop->IsType(MessageLoop::TYPE_UI)); - task_runner_ = message_loop->message_loop_proxy(); - task_runner_->PostTask(FROM_HERE, - base::Bind(&Notifier::Init, - base::Unretained(this))); - } - - // Should be called from the |task_runner_|'s thread. Use Shutdown() - // to shutdown on arbitrary threads. - ~Notifier() { - DCHECK(called_shutdown_); - // Only unregister from the same thread where registration was performed. - if (registered_ && task_runner_->RunsTasksOnCurrentThread()) - SecKeychainRemoveCallback(&Notifier::KeychainCallback); - } - - void Shutdown() { - called_shutdown_ = true; - if (!task_runner_->DeleteSoon(FROM_HERE, this)) { - // If the task runner is no longer running, it's safe to just delete - // the object, since no further events will or can be delivered by - // Keychain Services. - delete this; - } - } - - private: - void Init() { - SecKeychainEventMask event_mask = - kSecKeychainListChangedMask | kSecTrustSettingsChangedEventMask; - OSStatus status = SecKeychainAddCallback(&Notifier::KeychainCallback, - event_mask, this); - if (status == noErr) - registered_ = true; - } - - // SecKeychainCallback function that receives notifications from securityd - // and forwards them to the |cert_db_|. - static OSStatus KeychainCallback(SecKeychainEvent keychain_event, - SecKeychainCallbackInfo* info, - void* context); - - CertDatabase* const cert_db_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - bool registered_; - bool called_shutdown_; -}; - -// static -OSStatus CertDatabase::Notifier::KeychainCallback( - SecKeychainEvent keychain_event, - SecKeychainCallbackInfo* info, - void* context) { - Notifier* that = reinterpret_cast<Notifier*>(context); - - if (info->version > SEC_KEYCHAIN_SETTINGS_VERS1) { - NOTREACHED(); - return errSecWrongSecVersion; - } - - if (info->pid == base::GetCurrentProcId()) { - // Ignore events generated by the current process, as the assumption is - // that they have already been handled. This may miss events that - // originated as a result of spawning native dialogs that allow the user - // to modify Keychain settings. However, err on the side of missing - // events rather than sending too many events. - return errSecSuccess; - } - - switch (keychain_event) { - case kSecKeychainListChangedEvent: - case kSecTrustSettingsChangedEvent: - that->cert_db_->NotifyObserversOfCertTrustChanged(NULL); - break; - } - - return errSecSuccess; -} - -void CertDatabase::SetMessageLoopForKeychainEvents() { - // Shutdown will take care to delete the notifier on the right thread. - if (notifier_.get()) - notifier_.release()->Shutdown(); - - notifier_.reset(new Notifier(this, MessageLoopForUI::current())); -} - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { -} - -CertDatabase::~CertDatabase() { - // Shutdown will take care to delete the notifier on the right thread. - if (notifier_.get()) - 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/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc deleted file mode 100644 index e0f4ca6..0000000 --- a/net/base/cert_database_nss.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include <cert.h> -#include <pk11pub.h> -#include <secmod.h> - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "crypto/nss_util.h" -#include "net/base/net_errors.h" -#include "net/base/nss_cert_database.h" -#include "net/base/x509_certificate.h" - -namespace net { - -// Helper that observes events from the NSSCertDatabase and forwards them to -// the given CertDatabase. -class CertDatabase::Notifier : public NSSCertDatabase::Observer { - public: - explicit Notifier(CertDatabase* cert_db) : cert_db_(cert_db) { - NSSCertDatabase::GetInstance()->AddObserver(this); - } - - virtual ~Notifier() { - NSSCertDatabase::GetInstance()->RemoveObserver(this); - } - - // NSSCertDatabase::Observer implementation: - virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE { - cert_db_->NotifyObserversOfCertAdded(cert); - } - - virtual void OnCertRemoved(const X509Certificate* cert) OVERRIDE { - cert_db_->NotifyObserversOfCertRemoved(cert); - } - - virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE { - cert_db_->NotifyObserversOfCertTrustChanged(cert); - } - - private: - CertDatabase* cert_db_; - - DISALLOW_COPY_AND_ASSIGN(Notifier); -}; - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { - // Observe NSSCertDatabase events and forward them to observers of - // CertDatabase. This also makes sure that NSS has been initialized. - notifier_.reset(new Notifier(this)); -} - -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) { - CERTCertificate* cert = cert_obj->os_cert_handle(); - PK11SlotInfo* slot = NULL; - - { - crypto::AutoNSSWriteLock lock; - slot = PK11_ImportCertForKey( - cert, - cert_obj->GetDefaultNickname(net::USER_CERT).c_str(), - NULL); - } - - if (!slot) { - LOG(ERROR) << "Couldn't import user certificate."; - return ERR_ADD_USER_CERT_FAILED; - } - PK11_FreeSlot(slot); - NotifyObserversOfCertAdded(cert_obj); - return OK; -} - -} // namespace net diff --git a/net/base/cert_database_openssl.cc b/net/base/cert_database_openssl.cc deleted file mode 100644 index 8d73b3a..0000000 --- a/net/base/cert_database_openssl.cc +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include <openssl/x509.h> - -#include "base/logging.h" -#include "base/observer_list_threadsafe.h" -#include "crypto/openssl_util.h" -#include "net/base/crypto_module.h" -#include "net/base/net_errors.h" -#include "net/base/openssl_private_key_store.h" -#include "net/base/x509_certificate.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { -} - -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::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> 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/net/base/cert_database_win.cc b/net/base/cert_database_win.cc deleted file mode 100644 index f0f0dbd..0000000 --- a/net/base/cert_database_win.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_database.h" - -#include <windows.h> -#include <wincrypt.h> -#pragma comment(lib, "crypt32.lib") - -#include "base/observer_list_threadsafe.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -CertDatabase::CertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { -} - -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/net/base/cert_status_flags.cc b/net/base/cert_status_flags.cc deleted file mode 100644 index 07b9751..0000000 --- a/net/base/cert_status_flags.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_status_flags.h" - -#include "base/logging.h" -#include "net/base/net_errors.h" - -namespace net { - -bool IsCertStatusMinorError(CertStatus cert_status) { - static const CertStatus kMinorErrors = - CERT_STATUS_UNABLE_TO_CHECK_REVOCATION | - CERT_STATUS_NO_REVOCATION_MECHANISM; - cert_status &= CERT_STATUS_ALL_ERRORS; - return cert_status != 0 && (cert_status & ~kMinorErrors) == 0; -} - -CertStatus MapNetErrorToCertStatus(int error) { - switch (error) { - case ERR_CERT_COMMON_NAME_INVALID: - return CERT_STATUS_COMMON_NAME_INVALID; - case ERR_CERT_DATE_INVALID: - return CERT_STATUS_DATE_INVALID; - case ERR_CERT_AUTHORITY_INVALID: - return CERT_STATUS_AUTHORITY_INVALID; - case ERR_CERT_NO_REVOCATION_MECHANISM: - return CERT_STATUS_NO_REVOCATION_MECHANISM; - case ERR_CERT_UNABLE_TO_CHECK_REVOCATION: - return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; - case ERR_CERT_REVOKED: - return CERT_STATUS_REVOKED; - // We added the ERR_CERT_CONTAINS_ERRORS error code when we were using - // WinInet, but we never figured out how it differs from ERR_CERT_INVALID. - // We should not use ERR_CERT_CONTAINS_ERRORS in new code. - case ERR_CERT_CONTAINS_ERRORS: - NOTREACHED(); - // Falls through. - case ERR_CERT_INVALID: - return CERT_STATUS_INVALID; - case ERR_CERT_WEAK_SIGNATURE_ALGORITHM: - return CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; - case ERR_CERT_WEAK_KEY: - return CERT_STATUS_WEAK_KEY; - default: - return 0; - } -} - -int MapCertStatusToNetError(CertStatus cert_status) { - // A certificate may have multiple errors. We report the most - // serious error. - - // Unrecoverable errors - if (cert_status & CERT_STATUS_REVOKED) - return ERR_CERT_REVOKED; - if (cert_status & CERT_STATUS_INVALID) - return ERR_CERT_INVALID; - - // Recoverable errors - if (cert_status & CERT_STATUS_AUTHORITY_INVALID) - return ERR_CERT_AUTHORITY_INVALID; - if (cert_status & CERT_STATUS_COMMON_NAME_INVALID) - return ERR_CERT_COMMON_NAME_INVALID; - if (cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM) - return ERR_CERT_WEAK_SIGNATURE_ALGORITHM; - if (cert_status & CERT_STATUS_WEAK_KEY) - return ERR_CERT_WEAK_KEY; - if (cert_status & CERT_STATUS_DATE_INVALID) - return ERR_CERT_DATE_INVALID; - - // Unknown status. Give it the benefit of the doubt. - if (cert_status & CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) - return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; - if (cert_status & CERT_STATUS_NO_REVOCATION_MECHANISM) - return ERR_CERT_NO_REVOCATION_MECHANISM; - - NOTREACHED(); - return ERR_UNEXPECTED; -} - -} // namespace net diff --git a/net/base/cert_status_flags.h b/net/base/cert_status_flags.h deleted file mode 100644 index ff23375..0000000 --- a/net/base/cert_status_flags.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_STATUS_FLAGS_H_ -#define NET_BASE_CERT_STATUS_FLAGS_H_ - -#include "base/basictypes.h" -#include "net/base/net_export.h" - -namespace net { - -// Bitmask of status flags of a certificate, representing any errors, as well as -// other non-error status information such as whether the certificate is EV. -typedef uint32 CertStatus; - -// The possible status bits for CertStatus. -// NOTE: Because these names have appeared in bug reports, we preserve them as -// MACRO_STYLE for continuity, instead of renaming them to kConstantStyle as -// befits most static consts. -// Bits 0 to 15 are for errors. -static const CertStatus CERT_STATUS_ALL_ERRORS = 0xFFFF; -static const CertStatus CERT_STATUS_COMMON_NAME_INVALID = 1 << 0; -static const CertStatus CERT_STATUS_DATE_INVALID = 1 << 1; -static const CertStatus CERT_STATUS_AUTHORITY_INVALID = 1 << 2; -// 1 << 3 is reserved for ERR_CERT_CONTAINS_ERRORS (not useful with WinHTTP). -static const CertStatus CERT_STATUS_NO_REVOCATION_MECHANISM = 1 << 4; -static const CertStatus CERT_STATUS_UNABLE_TO_CHECK_REVOCATION = 1 << 5; -static const CertStatus CERT_STATUS_REVOKED = 1 << 6; -static const CertStatus CERT_STATUS_INVALID = 1 << 7; -static const CertStatus CERT_STATUS_WEAK_SIGNATURE_ALGORITHM = 1 << 8; -// 1 << 9 was used for CERT_STATUS_NOT_IN_DNS -static const CertStatus CERT_STATUS_NON_UNIQUE_NAME = 1 << 10; -static const CertStatus CERT_STATUS_WEAK_KEY = 1 << 11; - -// Bits 16 to 31 are for non-error statuses. -static const CertStatus CERT_STATUS_IS_EV = 1 << 16; -static const CertStatus CERT_STATUS_REV_CHECKING_ENABLED = 1 << 17; -// bit 18 was CERT_STATUS_IS_DNSSEC. - -// Returns true if the specified cert status has an error set. -static inline bool IsCertStatusError(CertStatus status) { - return (CERT_STATUS_ALL_ERRORS & status) != 0; -} - -// IsCertStatusMinorError returns true iff |cert_status| indicates a condition -// that should typically be ignored by automated requests. (i.e. a revocation -// check failure.) -NET_EXPORT bool IsCertStatusMinorError(CertStatus cert_status); - -// Maps a network error code to the equivalent certificate status flag. If -// the error code is not a certificate error, it is mapped to 0. -NET_EXPORT CertStatus MapNetErrorToCertStatus(int error); - -// Maps the most serious certificate error in the certificate status flags -// to the equivalent network error code. -NET_EXPORT int MapCertStatusToNetError(CertStatus cert_status); - -} // namespace net - -#endif // NET_BASE_CERT_STATUS_FLAGS_H_ diff --git a/net/base/cert_test_util.cc b/net/base/cert_test_util.cc deleted file mode 100644 index 11b9a71..0000000 --- a/net/base/cert_test_util.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_test_util.h" - -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "net/base/ev_root_ca_metadata.h" -#include "net/base/x509_certificate.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -CertificateList CreateCertificateListFromFile( - const base::FilePath& certs_dir, - const std::string& cert_file, - int format) { - base::FilePath cert_path = certs_dir.AppendASCII(cert_file); - std::string cert_data; - if (!file_util::ReadFileToString(cert_path, &cert_data)) - return CertificateList(); - return X509Certificate::CreateCertificateListFromBytes(cert_data.data(), - cert_data.size(), - format); -} - -scoped_refptr<X509Certificate> ImportCertFromFile( - const base::FilePath& certs_dir, - const std::string& cert_file) { - base::FilePath cert_path = certs_dir.AppendASCII(cert_file); - std::string cert_data; - if (!file_util::ReadFileToString(cert_path, &cert_data)) - return NULL; - - CertificateList certs_in_file = - X509Certificate::CreateCertificateListFromBytes( - cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO); - if (certs_in_file.empty()) - return NULL; - return certs_in_file[0]; -} - -ScopedTestEVPolicy::ScopedTestEVPolicy(EVRootCAMetadata* ev_root_ca_metadata, - const SHA1HashValue& fingerprint, - const char* policy) - : fingerprint_(fingerprint), - ev_root_ca_metadata_(ev_root_ca_metadata) { - EXPECT_TRUE(ev_root_ca_metadata->AddEVCA(fingerprint, policy)); -} - -ScopedTestEVPolicy::~ScopedTestEVPolicy() { - EXPECT_TRUE(ev_root_ca_metadata_->RemoveEVCA(fingerprint_)); -} - -} // namespace net diff --git a/net/base/cert_test_util.h b/net/base/cert_test_util.h deleted file mode 100644 index db49e87..0000000 --- a/net/base/cert_test_util.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_TEST_UTIL_H_ -#define NET_BASE_CERT_TEST_UTIL_H_ - -#include <string> - -#include "base/memory/ref_counted.h" -#include "net/base/x509_cert_types.h" -#include "net/base/x509_certificate.h" - -namespace base { -class FilePath; -} - -namespace net { - -class EVRootCAMetadata; - -CertificateList CreateCertificateListFromFile(const base::FilePath& certs_dir, - const std::string& cert_file, - int format); - -// Imports a certificate file in the directory net::GetTestCertsDirectory() -// returns. -// |certs_dir| represents the test certificates directory. |cert_file| is the -// name of the certificate file. If cert_file contains multiple certificates, -// the first certificate found will be returned. -scoped_refptr<X509Certificate> ImportCertFromFile(const base::FilePath& certs_dir, - const std::string& cert_file); - -// ScopedTestEVPolicy causes certificates marked with |policy|, issued from a -// root with the given fingerprint, to be treated as EV. |policy| is expressed -// as a string of dotted numbers: i.e. "1.2.3.4". -// This should only be used in unittests as adding a CA twice causes a CHECK -// failure. -class ScopedTestEVPolicy { - public: - ScopedTestEVPolicy(EVRootCAMetadata* ev_root_ca_metadata, - const SHA1HashValue& fingerprint, - const char* policy); - ~ScopedTestEVPolicy(); - - private: - SHA1HashValue fingerprint_; - EVRootCAMetadata* const ev_root_ca_metadata_; -}; - -} // namespace net - -#endif // NET_BASE_CERT_TEST_UTIL_H_ diff --git a/net/base/cert_trust_anchor_provider.h b/net/base/cert_trust_anchor_provider.h deleted file mode 100644 index 6a95068..0000000 --- a/net/base/cert_trust_anchor_provider.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_TRUST_ANCHOR_PROVIDER_H_ -#define NET_BASE_CERT_TRUST_ANCHOR_PROVIDER_H_ - -#include <vector> - -#include "base/memory/ref_counted.h" -#include "net/base/net_export.h" - -namespace net { - -class X509Certificate; -typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; - -// Interface to retrieve the current list of additional trust anchors. -// This is used by CertVerifier to get a list of anchors to trust in addition to -// the anchors known to the CertVerifier. -class NET_EXPORT CertTrustAnchorProvider { - public: - virtual ~CertTrustAnchorProvider() {} - - // Returns a list of certificates to be used as trust anchors during - // certificate validation, in addition to (eg: the union of) any pre-existing - // or pre-configured trust anchors. - virtual const CertificateList& GetAdditionalTrustAnchors() = 0; -}; - -} // namespace net - -#endif // NET_BASE_CERT_TRUST_ANCHOR_PROVIDER_H_ diff --git a/net/base/cert_type.h b/net/base/cert_type.h deleted file mode 100644 index d9cb8a5..0000000 --- a/net/base/cert_type.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_TYPE_H_ -#define NET_BASE_CERT_TYPE_H_ - -namespace net { - -// Constants to classify the type of a certificate. -// This is only used in the context of CertDatabase, but is defined outside to -// avoid an awkwardly long type name. -// The type is a combination of intrinsic properties, such as the presense of an -// Certificate Authority Basic Constraint, and assigned trust values. For -// example, a cert with no basic constraints or trust would be classified as -// UNKNOWN_CERT. If that cert is then trusted with SetCertTrust(cert, -// SERVER_CERT, TRUSTED_SSL), it would become a SERVER_CERT. -enum CertType { - UNKNOWN_CERT, - CA_CERT, - USER_CERT, - SERVER_CERT, - NUM_CERT_TYPES -}; - -} // namespace net - -#endif // NET_BASE_CERT_TYPE_H_ diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc deleted file mode 100644 index fd28f1d..0000000 --- a/net/base/cert_verifier.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verifier.h" - -#include "net/base/cert_verify_proc.h" -#include "net/base/multi_threaded_cert_verifier.h" - -namespace net { - -CertVerifier* CertVerifier::CreateDefault() { - return new MultiThreadedCertVerifier(CertVerifyProc::CreateDefault()); -} - -} // namespace net diff --git a/net/base/cert_verifier.h b/net/base/cert_verifier.h deleted file mode 100644 index 36312d3..0000000 --- a/net/base/cert_verifier.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFIER_H_ -#define NET_BASE_CERT_VERIFIER_H_ - -#include <string> - -#include "base/basictypes.h" -#include "net/base/completion_callback.h" -#include "net/base/net_export.h" - -namespace net { - -class BoundNetLog; -class CertVerifyResult; -class CRLSet; -class X509Certificate; - -// CertVerifier represents a service for verifying certificates. -// -// CertVerifiers can handle multiple requests at a time. A simpler alternative -// for consumers that only have 1 outstanding request at a time is to create a -// SingleRequestCertVerifier wrapper around CertVerifier (which will -// automatically cancel the single request when it goes out of scope). -class NET_EXPORT CertVerifier { - public: - // Opaque pointer type used to cancel outstanding requests. - typedef void* RequestHandle; - - enum VerifyFlags { - // If set, enables online revocation checking via CRLs and OCSP for the - // certificate chain. - VERIFY_REV_CHECKING_ENABLED = 1 << 0, - - // If set, and the certificate being verified may be an EV certificate, - // attempt to verify the certificate according to the EV processing - // guidelines. In order to successfully verify a certificate as EV, - // either an online or offline revocation check must be successfully - // completed. To ensure it's possible to complete a revocation check, - // callers should also specify either VERIFY_REV_CHECKING_ENABLED or - // VERIFY_REV_CHECKING_ENABLED_EV_ONLY (to enable online checks), and - // VERIFY_CERT_IO_ENABLED (to enable network fetches for online checks). - VERIFY_EV_CERT = 1 << 1, - - // If set, permits NSS to use the network when verifying certificates, - // such as to fetch missing intermediates or to check OCSP or CRLs. - // TODO(rsleevi): http://crbug.com/143300 - Define this flag for all - // verification engines with well-defined semantics, rather than being - // NSS only. - VERIFY_CERT_IO_ENABLED = 1 << 2, - - // If set, enables online revocation checking via CRLs or OCSP, but only - // for certificates which may be EV, and only when VERIFY_EV_CERT is also - // set. - VERIFY_REV_CHECKING_ENABLED_EV_ONLY = 1 << 3, - }; - - // When the verifier is destroyed, all certificate verification requests are - // canceled, and their completion callbacks will not be called. - virtual ~CertVerifier() {} - - // Verifies the given certificate against the given hostname as an SSL server. - // Returns OK if successful or an error code upon failure. - // - // The |*verify_result| structure, including the |verify_result->cert_status| - // bitmask, is always filled out regardless of the return value. If the - // certificate has multiple errors, the corresponding status flags are set in - // |verify_result->cert_status|, and the error code for the most serious - // error is returned. - // - // |flags| is bitwise OR'd of VerifyFlags. - // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, certificate revocation - // checking is performed. - // - // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is - // performed. If |flags| is VERIFY_EV_CERT (that is, - // VERIFY_REV_CHECKING_ENABLED is not set), EV certificate verification will - // not be performed. - // - // |crl_set| points to an optional CRLSet structure which can be used to - // avoid revocation checks over the network. - // - // |callback| must not be null. ERR_IO_PENDING is returned if the operation - // could not be completed synchronously, in which case the result code will - // be passed to the callback when available. - // - // |*out_req| will be filled with a handle to the async request. - // This handle is not valid after the request has completed. - // - // TODO(rsleevi): Move CRLSet* out of the CertVerifier signature. - virtual int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - RequestHandle* out_req, - const BoundNetLog& net_log) = 0; - - // Cancels the specified request. |req| is the handle returned by Verify(). - // After a request is canceled, its completion callback will not be called. - virtual void CancelRequest(RequestHandle req) = 0; - - // Creates a CertVerifier implementation that verifies certificates using - // the preferred underlying cryptographic libraries. - static CertVerifier* CreateDefault(); -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFIER_H_ diff --git a/net/base/cert_verify_proc.cc b/net/base/cert_verify_proc.cc deleted file mode 100644 index 0c017c5..0000000 --- a/net/base/cert_verify_proc.cc +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc.h" - -#include "base/metrics/histogram.h" -#include "base/sha1.h" -#include "build/build_config.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crl_set.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -#if defined(USE_NSS) || defined(OS_IOS) -#include "net/base/cert_verify_proc_nss.h" -#elif defined(USE_OPENSSL) && !defined(OS_ANDROID) -#include "net/base/cert_verify_proc_openssl.h" -#elif defined(OS_ANDROID) -#include "net/base/cert_verify_proc_android.h" -#elif defined(OS_MACOSX) -#include "net/base/cert_verify_proc_mac.h" -#elif defined(OS_WIN) -#include "net/base/cert_verify_proc_win.h" -#else -#error Implement certificate verification. -#endif - - -namespace net { - -namespace { - -// Returns true if |type| is |kPublicKeyTypeRSA| or |kPublicKeyTypeDSA|, and -// if |size_bits| is < 1024. Note that this means there may be false -// negatives: keys for other algorithms and which are weak will pass this -// test. -bool IsWeakKey(X509Certificate::PublicKeyType type, size_t size_bits) { - switch (type) { - case X509Certificate::kPublicKeyTypeRSA: - case X509Certificate::kPublicKeyTypeDSA: - return size_bits < 1024; - default: - return false; - } -} - -} // namespace - -// static -CertVerifyProc* CertVerifyProc::CreateDefault() { -#if defined(USE_NSS) || defined(OS_IOS) - return new CertVerifyProcNSS(); -#elif defined(USE_OPENSSL) && !defined(OS_ANDROID) - return new CertVerifyProcOpenSSL(); -#elif defined(OS_ANDROID) - return new CertVerifyProcAndroid(); -#elif defined(OS_MACOSX) - return new CertVerifyProcMac(); -#elif defined(OS_WIN) - return new CertVerifyProcWin(); -#else - return NULL; -#endif -} - -CertVerifyProc::CertVerifyProc() {} - -CertVerifyProc::~CertVerifyProc() {} - -int CertVerifyProc::Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - verify_result->Reset(); - verify_result->verified_cert = cert; - - if (IsBlacklisted(cert)) { - verify_result->cert_status |= CERT_STATUS_REVOKED; - return ERR_CERT_REVOKED; - } - - // If EV verification was requested and no CRLSet is present, or if the - // CRLSet has expired, then enable online revocation checks. If the online - // check fails, EV status won't be shown. - // - // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully - // disable revocation checking. - if ((flags & CertVerifier::VERIFY_EV_CERT) && - (!crl_set || crl_set->IsExpired())) { - flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY; - } - - int rv = VerifyInternal(cert, hostname, flags, crl_set, - additional_trust_anchors, verify_result); - - // This check is done after VerifyInternal so that VerifyInternal can fill - // in the list of public key hashes. - if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) { - verify_result->cert_status |= CERT_STATUS_REVOKED; - rv = MapCertStatusToNetError(verify_result->cert_status); - } - - // Check for weak keys in the entire verified chain. - size_t size_bits = 0; - X509Certificate::PublicKeyType type = - X509Certificate::kPublicKeyTypeUnknown; - bool weak_key = false; - - X509Certificate::GetPublicKeyInfo( - verify_result->verified_cert->os_cert_handle(), &size_bits, &type); - if (IsWeakKey(type, size_bits)) { - weak_key = true; - } else { - const X509Certificate::OSCertHandles& intermediates = - verify_result->verified_cert->GetIntermediateCertificates(); - for (size_t i = 0; i < intermediates.size(); ++i) { - X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type); - if (IsWeakKey(type, size_bits)) - weak_key = true; - } - } - - if (weak_key) { - verify_result->cert_status |= CERT_STATUS_WEAK_KEY; - // Avoid replacing a more serious error, such as an OS/library failure, - // by ensuring that if verification failed, it failed with a certificate - // error. - if (rv == OK || IsCertificateError(rv)) - rv = MapCertStatusToNetError(verify_result->cert_status); - } - - // Treat certificates signed using broken signature algorithms as invalid. - if (verify_result->has_md2 || verify_result->has_md4) { - verify_result->cert_status |= CERT_STATUS_INVALID; - rv = MapCertStatusToNetError(verify_result->cert_status); - } - - // Flag certificates using weak signature algorithms. - if (verify_result->has_md5) { - 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 - // error. - if (rv == OK || IsCertificateError(rv)) - rv = MapCertStatusToNetError(verify_result->cert_status); - } - - return rv; -} - -// static -bool CertVerifyProc::IsBlacklisted(X509Certificate* cert) { - static const unsigned kComodoSerialBytes = 16; - static const uint8 kComodoSerials[][kComodoSerialBytes] = { - // Not a real certificate. For testing only. - {0x07,0x7a,0x59,0xbc,0xd5,0x34,0x59,0x60,0x1c,0xa6,0x90,0x72,0x67,0xa6,0xdd,0x1c}, - - // The next nine certificates all expire on Fri Mar 14 23:59:59 2014. - // Some serial numbers actually have a leading 0x00 byte required to - // encode a positive integer in DER if the most significant bit is 0. - // We omit the leading 0x00 bytes to make all serial numbers 16 bytes. - - // Subject: CN=mail.google.com - // subjectAltName dNSName: mail.google.com, www.mail.google.com - {0x04,0x7e,0xcb,0xe9,0xfc,0xa5,0x5f,0x7b,0xd0,0x9e,0xae,0x36,0xe1,0x0c,0xae,0x1e}, - // Subject: CN=global trustee - // subjectAltName dNSName: global trustee - // Note: not a CA certificate. - {0xd8,0xf3,0x5f,0x4e,0xb7,0x87,0x2b,0x2d,0xab,0x06,0x92,0xe3,0x15,0x38,0x2f,0xb0}, - // Subject: CN=login.live.com - // subjectAltName dNSName: login.live.com, www.login.live.com - {0xb0,0xb7,0x13,0x3e,0xd0,0x96,0xf9,0xb5,0x6f,0xae,0x91,0xc8,0x74,0xbd,0x3a,0xc0}, - // Subject: CN=addons.mozilla.org - // subjectAltName dNSName: addons.mozilla.org, www.addons.mozilla.org - {0x92,0x39,0xd5,0x34,0x8f,0x40,0xd1,0x69,0x5a,0x74,0x54,0x70,0xe1,0xf2,0x3f,0x43}, - // Subject: CN=login.skype.com - // subjectAltName dNSName: login.skype.com, www.login.skype.com - {0xe9,0x02,0x8b,0x95,0x78,0xe4,0x15,0xdc,0x1a,0x71,0x0a,0x2b,0x88,0x15,0x44,0x47}, - // Subject: CN=login.yahoo.com - // subjectAltName dNSName: login.yahoo.com, www.login.yahoo.com - {0xd7,0x55,0x8f,0xda,0xf5,0xf1,0x10,0x5b,0xb2,0x13,0x28,0x2b,0x70,0x77,0x29,0xa3}, - // Subject: CN=www.google.com - // subjectAltName dNSName: www.google.com, google.com - {0xf5,0xc8,0x6a,0xf3,0x61,0x62,0xf1,0x3a,0x64,0xf5,0x4f,0x6d,0xc9,0x58,0x7c,0x06}, - // Subject: CN=login.yahoo.com - // subjectAltName dNSName: login.yahoo.com - {0x39,0x2a,0x43,0x4f,0x0e,0x07,0xdf,0x1f,0x8a,0xa3,0x05,0xde,0x34,0xe0,0xc2,0x29}, - // Subject: CN=login.yahoo.com - // subjectAltName dNSName: login.yahoo.com - {0x3e,0x75,0xce,0xd4,0x6b,0x69,0x30,0x21,0x21,0x88,0x30,0xae,0x86,0xa8,0x2a,0x71}, - }; - - const std::string& serial_number = cert->serial_number(); - if (!serial_number.empty() && (serial_number[0] & 0x80) != 0) { - // This is a negative serial number, which isn't technically allowed but - // which probably happens. In order to avoid confusing a negative serial - // number with a positive one once the leading zeros have been removed, we - // disregard it. - return false; - } - - base::StringPiece serial(serial_number); - // Remove leading zeros. - while (serial.size() > 1 && serial[0] == 0) - serial.remove_prefix(1); - - if (serial.size() == kComodoSerialBytes) { - for (unsigned i = 0; i < arraysize(kComodoSerials); i++) { - if (memcmp(kComodoSerials[i], serial.data(), kComodoSerialBytes) == 0) { - UMA_HISTOGRAM_ENUMERATION("Net.SSLCertBlacklisted", i, - arraysize(kComodoSerials) + 1); - return true; - } - } - } - - return false; -} - -// static -// NOTE: This implementation assumes and enforces that the hashes are SHA1. -bool CertVerifyProc::IsPublicKeyBlacklisted( - const HashValueVector& public_key_hashes) { - static const unsigned kNumHashes = 10; - static const uint8 kHashes[kNumHashes][base::kSHA1Length] = { - // Subject: CN=DigiNotar Root CA - // Issuer: CN=Entrust.net x2 and self-signed - {0x41, 0x0f, 0x36, 0x36, 0x32, 0x58, 0xf3, 0x0b, 0x34, 0x7d, - 0x12, 0xce, 0x48, 0x63, 0xe4, 0x33, 0x43, 0x78, 0x06, 0xa8}, - // Subject: CN=DigiNotar Cyber CA - // Issuer: CN=GTE CyberTrust Global Root - {0xc4, 0xf9, 0x66, 0x37, 0x16, 0xcd, 0x5e, 0x71, 0xd6, 0x95, - 0x0b, 0x5f, 0x33, 0xce, 0x04, 0x1c, 0x95, 0xb4, 0x35, 0xd1}, - // Subject: CN=DigiNotar Services 1024 CA - // Issuer: CN=Entrust.net - {0xe2, 0x3b, 0x8d, 0x10, 0x5f, 0x87, 0x71, 0x0a, 0x68, 0xd9, - 0x24, 0x80, 0x50, 0xeb, 0xef, 0xc6, 0x27, 0xbe, 0x4c, 0xa6}, - // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2 - // Issuer: CN=Staat der Nederlanden Organisatie CA - G2 - {0x7b, 0x2e, 0x16, 0xbc, 0x39, 0xbc, 0xd7, 0x2b, 0x45, 0x6e, - 0x9f, 0x05, 0x5d, 0x1d, 0xe6, 0x15, 0xb7, 0x49, 0x45, 0xdb}, - // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven - // Issuer: CN=Staat der Nederlanden Overheid CA - {0xe8, 0xf9, 0x12, 0x00, 0xc6, 0x5c, 0xee, 0x16, 0xe0, 0x39, - 0xb9, 0xf8, 0x83, 0x84, 0x16, 0x61, 0x63, 0x5f, 0x81, 0xc5}, - // Subject: O=Digicert Sdn. Bhd. - // Issuer: CN=GTE CyberTrust Global Root - // Expires: Jul 17 15:16:54 2012 GMT - {0x01, 0x29, 0xbc, 0xd5, 0xb4, 0x48, 0xae, 0x8d, 0x24, 0x96, - 0xd1, 0xc3, 0xe1, 0x97, 0x23, 0x91, 0x90, 0x88, 0xe1, 0x52}, - // Subject: O=Digicert Sdn. Bhd. - // Issuer: CN=Entrust.net Certification Authority (2048) - // Expires: Jul 16 17:53:37 2015 GMT - {0xd3, 0x3c, 0x5b, 0x41, 0xe4, 0x5c, 0xc4, 0xb3, 0xbe, 0x9a, - 0xd6, 0x95, 0x2c, 0x4e, 0xcc, 0x25, 0x28, 0x03, 0x29, 0x81}, - // Issuer: CN=Trustwave Organization Issuing CA, Level 2 - // Covers two certificates, the latter of which expires Apr 15 21:09:30 - // 2021 GMT. - {0xe1, 0x2d, 0x89, 0xf5, 0x6d, 0x22, 0x76, 0xf8, 0x30, 0xe6, - 0xce, 0xaf, 0xa6, 0x6c, 0x72, 0x5c, 0x0b, 0x41, 0xa9, 0x32}, - // Cyberoam CA certificate. Private key leaked, but this certificate would - // only have been installed by Cyberoam customers. The certificate expires - // in 2036, but we can probably remove in a couple of years (2014). - {0xd9, 0xf5, 0xc6, 0xce, 0x57, 0xff, 0xaa, 0x39, 0xcc, 0x7e, - 0xd1, 0x72, 0xbd, 0x53, 0xe0, 0xd3, 0x07, 0x83, 0x4b, 0xd1}, - // Win32/Sirefef.gen!C generates fake certifciates with this public key. - {0xa4, 0xf5, 0x6e, 0x9e, 0x1d, 0x9a, 0x3b, 0x7b, 0x1a, 0xc3, - 0x31, 0xcf, 0x64, 0xfc, 0x76, 0x2c, 0xd0, 0x51, 0xfb, 0xa4}, - }; - - for (unsigned i = 0; i < kNumHashes; i++) { - for (HashValueVector::const_iterator j = public_key_hashes.begin(); - j != public_key_hashes.end(); ++j) { - if (j->tag == HASH_VALUE_SHA1 && - memcmp(j->data(), kHashes[i], base::kSHA1Length) == 0) { - return true; - } - } - } - - return false; -} - -} // namespace net diff --git a/net/base/cert_verify_proc.h b/net/base/cert_verify_proc.h deleted file mode 100644 index 2830874..0000000 --- a/net/base/cert_verify_proc.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_H_ -#define NET_BASE_CERT_VERIFY_PROC_H_ - -#include <string> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" -#include "net/base/net_export.h" -#include "net/base/x509_cert_types.h" - -namespace net { - -class CertVerifyResult; -class CRLSet; -class X509Certificate; -typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; - -// Class to perform certificate path building and verification for various -// certificate uses. All methods of this class must be thread-safe, as they -// may be called from various non-joinable worker threads. -class NET_EXPORT CertVerifyProc - : public base::RefCountedThreadSafe<CertVerifyProc> { - public: - // Creates and returns the default CertVerifyProc. - static CertVerifyProc* CreateDefault(); - - // Verifies the certificate against the given hostname as an SSL server - // certificate. Returns OK if successful or an error code upon failure. - // - // The |*verify_result| structure, including the |verify_result->cert_status| - // bitmask, is always filled out regardless of the return value. If the - // certificate has multiple errors, the corresponding status flags are set in - // |verify_result->cert_status|, and the error code for the most serious - // error is returned. - // - // |flags| is bitwise OR'd of VerifyFlags: - // - // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, online certificate - // revocation checking is performed (i.e. OCSP and downloading CRLs). CRLSet - // based revocation checking is always enabled, regardless of this flag, if - // |crl_set| is given. - // - // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is - // performed. - // - // |crl_set| points to an optional CRLSet structure which can be used to - // avoid revocation checks over the network. - // - // |additional_trust_anchors| lists certificates that can be trusted when - // building a certificate chain, in addition to the anchors known to the - // implementation. - int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result); - - // Returns true if the implementation supports passing additional trust - // anchors to the Verify() call. The |additional_trust_anchors| parameter - // passed to Verify() is ignored when this returns false. - virtual bool SupportsAdditionalTrustAnchors() const = 0; - - protected: - friend class base::RefCountedThreadSafe<CertVerifyProc>; - FRIEND_TEST_ALL_PREFIXES(CertVerifyProcTest, DigiNotarCerts); - - CertVerifyProc(); - virtual ~CertVerifyProc(); - - private: - // Performs the actual verification using the desired underlying - // cryptographic library. - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) = 0; - - // Returns true if |cert| is explicitly blacklisted. - static bool IsBlacklisted(X509Certificate* cert); - - // IsPublicKeyBlacklisted returns true iff one of |public_key_hashes| (which - // are hashes of SubjectPublicKeyInfo structures) is explicitly blocked. - static bool IsPublicKeyBlacklisted(const HashValueVector& public_key_hashes); -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_H_ diff --git a/net/base/cert_verify_proc_android.cc b/net/base/cert_verify_proc_android.cc deleted file mode 100644 index c11e66e..0000000 --- a/net/base/cert_verify_proc_android.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc_android.h" - -#include <string> -#include <vector> - -#include "base/logging.h" -#include "net/android/cert_verify_result_android.h" -#include "net/android/network_library.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verify_result.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -// Returns true if the certificate verification call was successful (regardless -// of its result), i.e. if |verify_result| was set. Otherwise returns false. -bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes, - CertVerifyResult* verify_result) { - // TODO(joth): Fetch the authentication type from SSL rather than hardcode. - android::CertVerifyResultAndroid android_result = - android::VerifyX509CertChain(cert_bytes, "RSA"); - switch (android_result) { - case android::VERIFY_FAILED: - return false; - case android::VERIFY_OK: - break; - case android::VERIFY_NO_TRUSTED_ROOT: - verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; - break; - case android::VERIFY_EXPIRED: - case android::VERIFY_NOT_YET_VALID: - verify_result->cert_status |= CERT_STATUS_DATE_INVALID; - break; - case android::VERIFY_UNABLE_TO_PARSE: - verify_result->cert_status |= CERT_STATUS_INVALID; - break; - default: - NOTREACHED(); - verify_result->cert_status |= CERT_STATUS_INVALID; - break; - } - return true; -} - -bool GetChainDEREncodedBytes(X509Certificate* cert, - std::vector<std::string>* chain_bytes) { - X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); - X509Certificate::OSCertHandles cert_handles = - cert->GetIntermediateCertificates(); - - // Make sure the peer's own cert is the first in the chain, if it's not - // already there. - if (cert_handles.empty() || cert_handles[0] != cert_handle) - cert_handles.insert(cert_handles.begin(), cert_handle); - - chain_bytes->reserve(cert_handles.size()); - for (X509Certificate::OSCertHandles::const_iterator it = - cert_handles.begin(); it != cert_handles.end(); ++it) { - std::string cert_bytes; - if(!X509Certificate::GetDEREncoded(*it, &cert_bytes)) - return false; - chain_bytes->push_back(cert_bytes); - } - return true; -} - -} // namespace - -CertVerifyProcAndroid::CertVerifyProcAndroid() {} - -CertVerifyProcAndroid::~CertVerifyProcAndroid() {} - -bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const { - return false; -} - -int CertVerifyProcAndroid::VerifyInternal( - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - if (!cert->VerifyNameMatch(hostname)) - verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; - - std::vector<std::string> cert_bytes; - if (!GetChainDEREncodedBytes(cert, &cert_bytes)) - return ERR_CERT_INVALID; - if (!VerifyFromAndroidTrustManager(cert_bytes, verify_result)) { - NOTREACHED(); - return ERR_FAILED; - } - if (IsCertStatusError(verify_result->cert_status)) - return MapCertStatusToNetError(verify_result->cert_status); - - // TODO(ppi): Implement missing functionality: yielding the constructed trust - // chain, public key hashes of its certificates and |is_issued_by_known_root| - // flag. All of the above require specific support from the platform, missing - // in the Java APIs. See also: http://crbug.com/116838 - - // Until the required support is available in the platform, we don't know if - // the trust root at the end of the chain was standard or user-added, so we - // mark all correctly verified certificates as issued by a known root. - verify_result->is_issued_by_known_root = true; - - return OK; -} - -} // namespace net diff --git a/net/base/cert_verify_proc_android.h b/net/base/cert_verify_proc_android.h deleted file mode 100644 index bfd5e12..0000000 --- a/net/base/cert_verify_proc_android.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_ANDROID_H_ -#define NET_BASE_CERT_VERIFY_PROC_ANDROID_H_ - -#include "net/base/cert_verify_proc.h" - -namespace net { - -// Performs certificate verification on Android by calling the platform -// TrustManager through JNI. -class CertVerifyProcAndroid : public CertVerifyProc { - public: - CertVerifyProcAndroid(); - - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE; - - protected: - virtual ~CertVerifyProcAndroid(); - - private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_ANDROID_H_ diff --git a/net/base/cert_verify_proc_mac.cc b/net/base/cert_verify_proc_mac.cc deleted file mode 100644 index a8f3e28..0000000 --- a/net/base/cert_verify_proc_mac.cc +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc_mac.h" - -#include <CommonCrypto/CommonDigest.h> -#include <CoreServices/CoreServices.h> -#include <Security/Security.h> - -#include <string> -#include <vector> - -#include "base/logging.h" -#include "base/mac/mac_logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/sha1.h" -#include "base/string_piece.h" -#include "base/synchronization/lock.h" -#include "crypto/mac_security_services_lock.h" -#include "crypto/nss_util.h" -#include "crypto/sha2.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crl_set.h" -#include "net/base/net_errors.h" -#include "net/base/test_root_certs.h" -#include "net/base/x509_certificate.h" -#include "net/base/x509_certificate_known_roots_mac.h" -#include "net/base/x509_util_mac.h" - -// From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with -// SecTrustCopyExtendedResult. -#ifndef kSecEVOrganizationName -#define kSecEVOrganizationName CFSTR("Organization") -#endif - -using base::mac::ScopedCFTypeRef; - -namespace net { - -namespace { - -typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef, - CFDictionaryRef*); - -int NetErrorFromOSStatus(OSStatus status) { - switch (status) { - case noErr: - return OK; - case errSecNotAvailable: - case errSecNoCertificateModule: - case errSecNoPolicyModule: - return ERR_NOT_IMPLEMENTED; - case errSecAuthFailed: - return ERR_ACCESS_DENIED; - default: { - OSSTATUS_LOG(ERROR, status) << "Unknown error mapped to ERR_FAILED"; - return ERR_FAILED; - } - } -} - -CertStatus CertStatusFromOSStatus(OSStatus status) { - switch (status) { - case noErr: - return 0; - - case CSSMERR_TP_INVALID_ANCHOR_CERT: - case CSSMERR_TP_NOT_TRUSTED: - case CSSMERR_TP_INVALID_CERT_AUTHORITY: - return CERT_STATUS_AUTHORITY_INVALID; - - case CSSMERR_TP_CERT_EXPIRED: - case CSSMERR_TP_CERT_NOT_VALID_YET: - // "Expired" and "not yet valid" collapse into a single status. - return CERT_STATUS_DATE_INVALID; - - case CSSMERR_TP_CERT_REVOKED: - case CSSMERR_TP_CERT_SUSPENDED: - return CERT_STATUS_REVOKED; - - case CSSMERR_APPLETP_HOSTNAME_MISMATCH: - return CERT_STATUS_COMMON_NAME_INVALID; - - case CSSMERR_APPLETP_CRL_NOT_FOUND: - case CSSMERR_APPLETP_OCSP_UNAVAILABLE: - case CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK: - return CERT_STATUS_NO_REVOCATION_MECHANISM; - - case CSSMERR_APPLETP_CRL_EXPIRED: - case CSSMERR_APPLETP_CRL_NOT_VALID_YET: - case CSSMERR_APPLETP_CRL_SERVER_DOWN: - case CSSMERR_APPLETP_CRL_NOT_TRUSTED: - case CSSMERR_APPLETP_CRL_INVALID_ANCHOR_CERT: - case CSSMERR_APPLETP_CRL_POLICY_FAIL: - case CSSMERR_APPLETP_OCSP_BAD_RESPONSE: - case CSSMERR_APPLETP_OCSP_BAD_REQUEST: - case CSSMERR_APPLETP_OCSP_STATUS_UNRECOGNIZED: - case CSSMERR_APPLETP_NETWORK_FAILURE: - case CSSMERR_APPLETP_OCSP_NOT_TRUSTED: - case CSSMERR_APPLETP_OCSP_INVALID_ANCHOR_CERT: - case CSSMERR_APPLETP_OCSP_SIG_ERROR: - case CSSMERR_APPLETP_OCSP_NO_SIGNER: - case CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ: - case CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR: - case CSSMERR_APPLETP_OCSP_RESP_TRY_LATER: - case CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED: - case CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED: - case CSSMERR_APPLETP_OCSP_NONCE_MISMATCH: - // We asked for a revocation check, but didn't get it. - return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; - - case CSSMERR_APPLETP_CRL_BAD_URI: - case CSSMERR_APPLETP_IDP_FAIL: - return CERT_STATUS_INVALID; - - case CSSMERR_CSP_UNSUPPORTED_KEY_SIZE: - // Mapping UNSUPPORTED_KEY_SIZE to CERT_STATUS_WEAK_KEY is not strictly - // accurate, as the error may have been returned due to a key size - // that exceeded the maximum supported. However, within - // CertVerifyProcMac::VerifyInternal(), this code should only be - // encountered as a certificate status code, and only when the key size - // is smaller than the minimum required (1024 bits). - return CERT_STATUS_WEAK_KEY; - - default: { - // Failure was due to something Chromium doesn't define a - // specific status for (such as basic constraints violation, or - // unknown critical extension) - OSSTATUS_LOG(WARNING, status) - << "Unknown error mapped to CERT_STATUS_INVALID"; - return CERT_STATUS_INVALID; - } - } -} - -// Creates a series of SecPolicyRefs to be added to a SecTrustRef used to -// validate a certificate for an SSL server. |hostname| contains the name of -// the SSL server that the certificate should be verified against. |flags| is -// a bitwise-OR of VerifyFlags that can further alter how trust is validated, -// such as how revocation is checked. If successful, returns noErr, and -// stores the resultant array of SecPolicyRefs in |policies|. -OSStatus CreateTrustPolicies(const std::string& hostname, - int flags, - ScopedCFTypeRef<CFArrayRef>* policies) { - ScopedCFTypeRef<CFMutableArrayRef> local_policies( - CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); - if (!local_policies) - return memFullErr; - - SecPolicyRef ssl_policy; - OSStatus status = x509_util::CreateSSLServerPolicy(hostname, &ssl_policy); - if (status) - return status; - CFArrayAppendValue(local_policies, ssl_policy); - CFRelease(ssl_policy); - - // Explicitly add revocation policies, in order to override system - // revocation checking policies and instead respect the application-level - // revocation preference. - status = x509_util::CreateRevocationPolicies( - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY), - local_policies); - if (status) - return status; - - policies->reset(local_policies.release()); - return noErr; -} - -// Saves some information about the certificate chain |cert_chain| in -// |*verify_result|. The caller MUST initialize |*verify_result| before -// calling this function. -void GetCertChainInfo(CFArrayRef cert_chain, - CSSM_TP_APPLE_EVIDENCE_INFO* chain_info, - CertVerifyResult* verify_result) { - SecCertificateRef verified_cert = NULL; - std::vector<SecCertificateRef> verified_chain; - for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { - SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); - if (i == 0) { - verified_cert = chain_cert; - } else { - verified_chain.push_back(chain_cert); - } - - if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) || - (chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) { - // The current certificate is either in the user's trusted store or is - // a root (self-signed) certificate. Ignore the signature algorithm for - // these certificates, as it is meaningless for security. We allow - // self-signed certificates (i == 0 & IS_ROOT), since we accept that - // any security assertions by such a cert are inherently meaningless. - continue; - } - - x509_util::CSSMCachedCertificate cached_cert; - OSStatus status = cached_cert.Init(chain_cert); - if (status) - continue; - x509_util::CSSMFieldValue signature_field; - status = cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, - &signature_field); - if (status || !signature_field.field()) - continue; - // Match the behaviour of OS X system tools and defensively check that - // sizes are appropriate. This would indicate a critical failure of the - // OS X certificate library, but based on history, it is best to play it - // safe. - const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm = - signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>(); - if (!sig_algorithm) - continue; - - const CSSM_OID* alg_oid = &sig_algorithm->algorithm; - if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA)) { - verify_result->has_md2 = true; - if (i != 0) - verify_result->has_md2_ca = true; - } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA)) { - verify_result->has_md4 = true; - } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA)) { - verify_result->has_md5 = true; - if (i != 0) - verify_result->has_md5_ca = true; - } - } - if (!verified_cert) - return; - - verify_result->verified_cert = - X509Certificate::CreateFromHandle(verified_cert, verified_chain); -} - -void AppendPublicKeyHashes(CFArrayRef chain, - HashValueVector* hashes) { - const CFIndex n = CFArrayGetCount(chain); - for (CFIndex i = 0; i < n; i++) { - SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); - - CSSM_DATA cert_data; - OSStatus err = SecCertificateGetData(cert, &cert_data); - DCHECK_EQ(err, noErr); - base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data), - cert_data.Length); - base::StringPiece spki_bytes; - if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) - continue; - - HashValue sha1(HASH_VALUE_SHA1); - CC_SHA1(spki_bytes.data(), spki_bytes.size(), sha1.data()); - hashes->push_back(sha1); - - HashValue sha256(HASH_VALUE_SHA256); - CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data()); - hashes->push_back(sha256); - } -} - -bool CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) { - if (CFArrayGetCount(chain) == 0) - return true; - - // We iterate from the root certificate down to the leaf, keeping track of - // the issuer's SPKI at each step. - std::string issuer_spki_hash; - for (CFIndex i = CFArrayGetCount(chain) - 1; i >= 0; i--) { - SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); - - CSSM_DATA cert_data; - OSStatus err = SecCertificateGetData(cert, &cert_data); - if (err != noErr) { - NOTREACHED(); - continue; - } - base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data), - cert_data.Length); - base::StringPiece spki; - if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) { - NOTREACHED(); - continue; - } - - const std::string spki_hash = crypto::SHA256HashString(spki); - x509_util::CSSMCachedCertificate cached_cert; - if (cached_cert.Init(cert) != CSSM_OK) { - NOTREACHED(); - continue; - } - x509_util::CSSMFieldValue serial_number; - err = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, &serial_number); - if (err || !serial_number.field()) { - NOTREACHED(); - continue; - } - - base::StringPiece serial( - reinterpret_cast<const char*>(serial_number.field()->Data), - serial_number.field()->Length); - - CRLSet::Result result = crl_set->CheckSPKI(spki_hash); - - if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) - result = crl_set->CheckSerial(serial, issuer_spki_hash); - - issuer_spki_hash = spki_hash; - - switch (result) { - case CRLSet::REVOKED: - return false; - case CRLSet::UNKNOWN: - case CRLSet::GOOD: - continue; - default: - NOTREACHED(); - return false; - } - } - - return true; -} - -// IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA -// that we recognise as a standard root. -// static -bool IsIssuedByKnownRoot(CFArrayRef chain) { - int n = CFArrayGetCount(chain); - if (n < 1) - return false; - SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1))); - SHA1HashValue hash = X509Certificate::CalculateFingerprint(root_ref); - return IsSHA1HashInSortedArray( - hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes)); -} - -} // namespace - -CertVerifyProcMac::CertVerifyProcMac() {} - -CertVerifyProcMac::~CertVerifyProcMac() {} - -bool CertVerifyProcMac::SupportsAdditionalTrustAnchors() const { - return false; -} - -int CertVerifyProcMac::VerifyInternal( - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - ScopedCFTypeRef<CFArrayRef> trust_policies; - OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies); - if (status) - return NetErrorFromOSStatus(status); - - // Create and configure a SecTrustRef, which takes our certificate(s) - // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an - // array of certificates, the first of which is the certificate we're - // verifying, and the subsequent (optional) certificates are used for - // chain building. - ScopedCFTypeRef<CFArrayRef> cert_array(cert->CreateOSCertChainForCert()); - - // Serialize all calls that may use the Keychain, to work around various - // issues in OS X 10.6+ with multi-threaded access to Security.framework. - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - - SecTrustRef trust_ref = NULL; - status = SecTrustCreateWithCertificates(cert_array, trust_policies, - &trust_ref); - if (status) - return NetErrorFromOSStatus(status); - ScopedCFTypeRef<SecTrustRef> scoped_trust_ref(trust_ref); - - if (TestRootCerts::HasInstance()) { - status = TestRootCerts::GetInstance()->FixupSecTrustRef(trust_ref); - if (status) - return NetErrorFromOSStatus(status); - } - - CSSM_APPLE_TP_ACTION_DATA tp_action_data; - memset(&tp_action_data, 0, sizeof(tp_action_data)); - tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION; - // Allow CSSM to download any missing intermediate certificates if an - // authorityInfoAccess extension or issuerAltName extension is present. - tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET | - CSSM_TP_ACTION_TRUST_SETTINGS; - - // Note: For EV certificates, the Apple TP will handle setting these flags - // as part of EV evaluation. - if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) { - // Require a positive result from an OCSP responder or a CRL (or both) - // for every certificate in the chain. The Apple TP automatically - // excludes the self-signed root from this requirement. If a certificate - // is missing both a crlDistributionPoints extension and an - // authorityInfoAccess extension with an OCSP responder URL, then we - // will get a kSecTrustResultRecoverableTrustFailure back from - // SecTrustEvaluate(), with a - // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case, - // we'll set our own result to include - // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are - // present, and a check fails (server unavailable, OCSP retry later, - // signature mismatch), then we'll set our own result to include - // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION. - tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT; - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - - // Note, even if revocation checking is disabled, SecTrustEvaluate() will - // modify the OCSP options so as to attempt OCSP checking if it believes a - // certificate may chain to an EV root. However, because network fetches - // are disabled in CreateTrustPolicies() when revocation checking is - // disabled, these will only go against the local cache. - } - - CFDataRef action_data_ref = - CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast<UInt8*>(&tp_action_data), - sizeof(tp_action_data), kCFAllocatorNull); - if (!action_data_ref) - return ERR_OUT_OF_MEMORY; - ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref); - status = SecTrustSetParameters(trust_ref, CSSM_TP_ACTION_DEFAULT, - action_data_ref); - if (status) - return NetErrorFromOSStatus(status); - - // Verify the certificate. A non-zero result from SecTrustGetResult() - // indicates that some fatal error occurred and the chain couldn't be - // processed, not that the chain contains no errors. We need to examine the - // output of SecTrustGetResult() to determine that. - SecTrustResultType trust_result; - status = SecTrustEvaluate(trust_ref, &trust_result); - if (status) - return NetErrorFromOSStatus(status); - CFArrayRef completed_chain = NULL; - CSSM_TP_APPLE_EVIDENCE_INFO* chain_info; - status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain, - &chain_info); - if (status) - return NetErrorFromOSStatus(status); - ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain); - - if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set)) - verify_result->cert_status |= CERT_STATUS_REVOKED; - - GetCertChainInfo(scoped_completed_chain.get(), chain_info, verify_result); - - // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits - // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds - // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping - // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only - // error was due to an unsupported key size. - bool policy_failed = false; - bool weak_key = false; - - // Evaluate the results - OSStatus cssm_result; - switch (trust_result) { - case kSecTrustResultUnspecified: - case kSecTrustResultProceed: - // Certificate chain is valid and trusted ("unspecified" indicates that - // the user has not explicitly set a trust setting) - break; - - case kSecTrustResultDeny: - case kSecTrustResultConfirm: - // Certificate chain is explicitly untrusted. For kSecTrustResultConfirm, - // we're following what Secure Transport does and treating it as - // "deny". - verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; - break; - - case kSecTrustResultRecoverableTrustFailure: - // Certificate chain has a failure that can be overridden by the user. - status = SecTrustGetCssmResultCode(trust_ref, &cssm_result); - if (status) - return NetErrorFromOSStatus(status); - if (cssm_result == CSSMERR_TP_VERIFY_ACTION_FAILED) { - policy_failed = true; - } else { - verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); - } - // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO - // structure which can catch multiple errors from each certificate. - for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain); - index < chain_count; ++index) { - if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED || - chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET) - verify_result->cert_status |= CERT_STATUS_DATE_INVALID; - if (!IsCertStatusError(verify_result->cert_status) && - chain_info[index].NumStatusCodes == 0) { - LOG(WARNING) << "chain_info[" << index << "].NumStatusCodes is 0" - ", chain_info[" << index << "].StatusBits is " - << chain_info[index].StatusBits; - } - for (uint32 status_code_index = 0; - status_code_index < chain_info[index].NumStatusCodes; - ++status_code_index) { - CertStatus mapped_status = CertStatusFromOSStatus( - chain_info[index].StatusCodes[status_code_index]); - if (mapped_status == CERT_STATUS_WEAK_KEY) - weak_key = true; - verify_result->cert_status |= mapped_status; - } - } - if (policy_failed && !weak_key) { - // If CSSMERR_TP_VERIFY_ACTION_FAILED wasn't returned due to a weak - // key, map it back to an appropriate error code. - verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); - } - if (!IsCertStatusError(verify_result->cert_status)) { - LOG(ERROR) << "cssm_result=" << cssm_result; - verify_result->cert_status |= CERT_STATUS_INVALID; - NOTREACHED(); - } - break; - - default: - status = SecTrustGetCssmResultCode(trust_ref, &cssm_result); - if (status) - return NetErrorFromOSStatus(status); - verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); - if (!IsCertStatusError(verify_result->cert_status)) { - LOG(WARNING) << "trust_result=" << trust_result; - verify_result->cert_status |= CERT_STATUS_INVALID; - } - break; - } - - // Perform hostname verification independent of SecTrustEvaluate. In order to - // do so, mask off any reported name errors first. - verify_result->cert_status &= ~CERT_STATUS_COMMON_NAME_INVALID; - if (!cert->VerifyNameMatch(hostname)) - verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; - - // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be - // compatible with Windows, which in turn implements this behavior to be - // compatible with WinHTTP, which doesn't report this error (bug 3004). - verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; - - AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes); - verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain); - - if (IsCertStatusError(verify_result->cert_status)) - return MapCertStatusToNetError(verify_result->cert_status); - - if (flags & CertVerifier::VERIFY_EV_CERT) { - // Determine the certificate's EV status using SecTrustCopyExtendedResult(), - // which we need to look up because the function wasn't added until - // Mac OS X 10.5.7. - // Note: "ExtendedResult" means extended validation results. - CFBundleRef bundle = - CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); - if (bundle) { - SecTrustCopyExtendedResultFuncPtr copy_extended_result = - reinterpret_cast<SecTrustCopyExtendedResultFuncPtr>( - CFBundleGetFunctionPointerForName(bundle, - CFSTR("SecTrustCopyExtendedResult"))); - if (copy_extended_result) { - CFDictionaryRef ev_dict_temp = NULL; - status = copy_extended_result(trust_ref, &ev_dict_temp); - ScopedCFTypeRef<CFDictionaryRef> ev_dict(ev_dict_temp); - ev_dict_temp = NULL; - if (status == noErr && ev_dict) { - // In 10.7.3, SecTrustCopyExtendedResult returns noErr and populates - // ev_dict even for non-EV certificates, but only EV certificates - // will cause ev_dict to contain kSecEVOrganizationName. In previous - // releases, SecTrustCopyExtendedResult would only return noErr and - // populate ev_dict for EV certificates, but would always include - // kSecEVOrganizationName in that case, so checking for this key is - // appropriate for all known versions of SecTrustCopyExtendedResult. - // The actual organization name is unneeded here and can be accessed - // through other means. All that matters here is the OS' conception - // of whether or not the certificate is EV. - if (CFDictionaryContainsKey(ev_dict, - kSecEVOrganizationName)) { - verify_result->cert_status |= CERT_STATUS_IS_EV; - if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - } - } - } - } - } - - return OK; -} - -} // namespace net diff --git a/net/base/cert_verify_proc_mac.h b/net/base/cert_verify_proc_mac.h deleted file mode 100644 index e28ba51..0000000 --- a/net/base/cert_verify_proc_mac.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_MAC_H_ -#define NET_BASE_CERT_VERIFY_PROC_MAC_H_ - -#include "net/base/cert_verify_proc.h" - -namespace net { - -// Performs certificate path construction and validation using OS X's -// Security.framework. -class CertVerifyProcMac : public CertVerifyProc { - public: - CertVerifyProcMac(); - - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE; - - protected: - virtual ~CertVerifyProcMac(); - - private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_MAC_H_ diff --git a/net/base/cert_verify_proc_nss.cc b/net/base/cert_verify_proc_nss.cc deleted file mode 100644 index c8c4f39..0000000 --- a/net/base/cert_verify_proc_nss.cc +++ /dev/null @@ -1,881 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc_nss.h" - -#include <string> -#include <vector> - -#include <cert.h> -#include <nss.h> -#include <prerror.h> -#include <secerr.h> -#include <sechash.h> -#include <sslerr.h> - -#include "base/logging.h" -#include "crypto/nss_util.h" -#include "crypto/scoped_nss_types.h" -#include "crypto/sha2.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crl_set.h" -#include "net/base/ev_root_ca_metadata.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" -#include "net/base/x509_util_nss.h" - -#if defined(OS_IOS) -#include <CommonCrypto/CommonDigest.h> -#include "net/base/x509_util_ios.h" -#endif // defined(OS_IOS) - -#define NSS_VERSION_NUM (NSS_VMAJOR * 10000 + NSS_VMINOR * 100 + NSS_VPATCH) -#if NSS_VERSION_NUM < 31305 -// Added in NSS 3.13.5. -#define SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED -8016 -#endif - -#if NSS_VERSION_NUM < 31402 -// Added in NSS 3.14.2. -#define cert_pi_useOnlyTrustAnchors static_cast<CERTValParamInType>(14) -#endif - -namespace net { - -namespace { - -typedef scoped_ptr_malloc< - CERTCertificatePolicies, - crypto::NSSDestroyer<CERTCertificatePolicies, - CERT_DestroyCertificatePoliciesExtension> > - ScopedCERTCertificatePolicies; - -typedef scoped_ptr_malloc< - CERTCertList, - crypto::NSSDestroyer<CERTCertList, CERT_DestroyCertList> > - ScopedCERTCertList; - -// ScopedCERTValOutParam manages destruction of values in the CERTValOutParam -// array that cvout points to. cvout must be initialized as passed to -// CERT_PKIXVerifyCert, so that the array must be terminated with -// cert_po_end type. -// When it goes out of scope, it destroys values of cert_po_trustAnchor -// and cert_po_certList types, but doesn't release the array itself. -class ScopedCERTValOutParam { - public: - explicit ScopedCERTValOutParam(CERTValOutParam* cvout) - : cvout_(cvout) {} - - ~ScopedCERTValOutParam() { - if (cvout_ == NULL) - return; - for (CERTValOutParam *p = cvout_; p->type != cert_po_end; p++) { - switch (p->type) { - case cert_po_trustAnchor: - if (p->value.pointer.cert) { - CERT_DestroyCertificate(p->value.pointer.cert); - p->value.pointer.cert = NULL; - } - break; - case cert_po_certList: - if (p->value.pointer.chain) { - CERT_DestroyCertList(p->value.pointer.chain); - p->value.pointer.chain = NULL; - } - break; - default: - break; - } - } - } - - private: - CERTValOutParam* cvout_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCERTValOutParam); -}; - -// Map PORT_GetError() return values to our network error codes. -int MapSecurityError(int err) { - switch (err) { - case PR_DIRECTORY_LOOKUP_ERROR: // DNS lookup error. - return ERR_NAME_NOT_RESOLVED; - case SEC_ERROR_INVALID_ARGS: - return ERR_INVALID_ARGUMENT; - case SSL_ERROR_BAD_CERT_DOMAIN: - return ERR_CERT_COMMON_NAME_INVALID; - case SEC_ERROR_INVALID_TIME: - case SEC_ERROR_EXPIRED_CERTIFICATE: - case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: - return ERR_CERT_DATE_INVALID; - case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_ISSUER: - case SEC_ERROR_CA_CERT_INVALID: - return ERR_CERT_AUTHORITY_INVALID; - // TODO(port): map ERR_CERT_NO_REVOCATION_MECHANISM. - case SEC_ERROR_OCSP_BAD_HTTP_RESPONSE: - case SEC_ERROR_OCSP_SERVER_ERROR: - return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; - case SEC_ERROR_REVOKED_CERTIFICATE: - case SEC_ERROR_UNTRUSTED_CERT: // Treat as revoked. - return ERR_CERT_REVOKED; - case SEC_ERROR_BAD_DER: - case SEC_ERROR_BAD_SIGNATURE: - case SEC_ERROR_CERT_NOT_VALID: - // TODO(port): add an ERR_CERT_WRONG_USAGE error code. - case SEC_ERROR_CERT_USAGES_INVALID: - case SEC_ERROR_INADEQUATE_KEY_USAGE: // Key usage. - case SEC_ERROR_INADEQUATE_CERT_TYPE: // Extended key usage and whether - // the certificate is a CA. - case SEC_ERROR_POLICY_VALIDATION_FAILED: - case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: - case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: - case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: - case SEC_ERROR_EXTENSION_VALUE_INVALID: - return ERR_CERT_INVALID; - case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: - return ERR_CERT_WEAK_SIGNATURE_ALGORITHM; - default: - LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; - return ERR_FAILED; - } -} - -// Map PORT_GetError() return values to our cert status flags. -CertStatus MapCertErrorToCertStatus(int err) { - int net_error = MapSecurityError(err); - return MapNetErrorToCertStatus(net_error); -} - -// Saves some information about the certificate chain cert_list in -// *verify_result. The caller MUST initialize *verify_result before calling -// this function. -// Note that cert_list[0] is the end entity certificate. -void GetCertChainInfo(CERTCertList* cert_list, - CERTCertificate* root_cert, - CertVerifyResult* verify_result) { - // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the - // NSS version currently in use: - // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*) - // 2. use ident libnss3.so* for the library's version - DCHECK(cert_list); - - CERTCertificate* verified_cert = NULL; - std::vector<CERTCertificate*> verified_chain; - int i = 0; - for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(node, cert_list); - node = CERT_LIST_NEXT(node), ++i) { - if (i == 0) { - verified_cert = node->cert; - } else { - // Because of an NSS bug, CERT_PKIXVerifyCert may chain a self-signed - // certificate of a root CA to another certificate of the same root CA - // key. Detect that error and ignore the root CA certificate. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=721288. - if (node->cert->isRoot) { - // NOTE: isRoot doesn't mean the certificate is a trust anchor. It - // means the certificate is self-signed. Here we assume isRoot only - // implies the certificate is self-issued. - CERTCertListNode* next_node = CERT_LIST_NEXT(node); - CERTCertificate* next_cert; - if (!CERT_LIST_END(next_node, cert_list)) { - next_cert = next_node->cert; - } else { - next_cert = root_cert; - } - // Test that |node->cert| is actually a self-signed certificate - // whose key is equal to |next_cert|, and not a self-issued - // certificate signed by another key of the same CA. - if (next_cert && SECITEM_ItemsAreEqual(&node->cert->derPublicKey, - &next_cert->derPublicKey)) { - continue; - } - } - verified_chain.push_back(node->cert); - } - - SECAlgorithmID& signature = node->cert->signature; - SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm); - switch (oid_tag) { - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - verify_result->has_md5 = true; - if (i != 0) - verify_result->has_md5_ca = true; - break; - case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: - verify_result->has_md2 = true; - if (i != 0) - verify_result->has_md2_ca = true; - break; - case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: - verify_result->has_md4 = true; - break; - default: - break; - } - } - - if (root_cert) - verified_chain.push_back(root_cert); -#if defined(OS_IOS) - verify_result->verified_cert = - x509_util_ios::CreateCertFromNSSHandles(verified_cert, verified_chain); -#else - verify_result->verified_cert = - X509Certificate::CreateFromHandle(verified_cert, verified_chain); -#endif // defined(OS_IOS) -} - -// IsKnownRoot returns true if the given certificate is one that we believe -// is a standard (as opposed to user-installed) root. -bool IsKnownRoot(CERTCertificate* root) { - if (!root || !root->slot) - return false; - - // This magic name is taken from - // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/builtins/constants.c&rev=1.13&mark=86,89#79 - return 0 == strcmp(PK11_GetSlotName(root->slot), - "NSS Builtin Objects"); -} - -// Returns true if the given certificate is one of the additional trust anchors. -bool IsAdditionalTrustAnchor(CERTCertList* additional_trust_anchors, - CERTCertificate* root) { - if (!additional_trust_anchors || !root) - return false; - for (CERTCertListNode* node = CERT_LIST_HEAD(additional_trust_anchors); - !CERT_LIST_END(node, additional_trust_anchors); - node = CERT_LIST_NEXT(node)) { - if (CERT_CompareCerts(node->cert, root)) - return true; - } - return false; -} - -enum CRLSetResult { - kCRLSetRevoked, - kCRLSetOk, - kCRLSetError, -}; - -// CheckRevocationWithCRLSet attempts to check each element of |cert_list| -// against |crl_set|. It returns: -// kCRLSetRevoked: if any element of the chain is known to have been revoked. -// kCRLSetError: if an error occurs in processing. -// kCRLSetOk: if no element in the chain is known to have been revoked. -CRLSetResult CheckRevocationWithCRLSet(CERTCertList* cert_list, - CERTCertificate* root, - CRLSet* crl_set) { - std::vector<CERTCertificate*> certs; - - if (cert_list) { - for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(node, cert_list); - node = CERT_LIST_NEXT(node)) { - certs.push_back(node->cert); - } - } - if (root) - certs.push_back(root); - - // We iterate from the root certificate down to the leaf, keeping track of - // the issuer's SPKI at each step. - std::string issuer_spki_hash; - for (std::vector<CERTCertificate*>::reverse_iterator i = certs.rbegin(); - i != certs.rend(); ++i) { - CERTCertificate* cert = *i; - - base::StringPiece der(reinterpret_cast<char*>(cert->derCert.data), - cert->derCert.len); - - base::StringPiece spki; - if (!asn1::ExtractSPKIFromDERCert(der, &spki)) { - NOTREACHED(); - return kCRLSetError; - } - const std::string spki_hash = crypto::SHA256HashString(spki); - - base::StringPiece serial_number = base::StringPiece( - reinterpret_cast<char*>(cert->serialNumber.data), - cert->serialNumber.len); - - CRLSet::Result result = crl_set->CheckSPKI(spki_hash); - - if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) - result = crl_set->CheckSerial(serial_number, issuer_spki_hash); - - issuer_spki_hash = spki_hash; - - switch (result) { - case CRLSet::REVOKED: - return kCRLSetRevoked; - case CRLSet::UNKNOWN: - case CRLSet::GOOD: - continue; - default: - NOTREACHED(); - return kCRLSetError; - } - } - - return kCRLSetOk; -} - -// Forward declarations. -SECStatus RetryPKIXVerifyCertWithWorkarounds( - CERTCertificate* cert_handle, int num_policy_oids, - bool cert_io_enabled, std::vector<CERTValInParam>* cvin, - CERTValOutParam* cvout); -SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle); - -// Call CERT_PKIXVerifyCert for the cert_handle. -// Verification results are stored in an array of CERTValOutParam. -// If policy_oids is not NULL and num_policy_oids is positive, policies -// are also checked. -// additional_trust_anchors is an optional list of certificates that can be -// trusted as anchors when building a certificate chain. -// Caller must initialize cvout before calling this function. -SECStatus PKIXVerifyCert(CERTCertificate* cert_handle, - bool check_revocation, - bool cert_io_enabled, - const SECOidTag* policy_oids, - int num_policy_oids, - CERTCertList* additional_trust_anchors, - CERTValOutParam* cvout) { - bool use_crl = check_revocation; - bool use_ocsp = check_revocation; - - // These CAs have multiple keys, which trigger two bugs in NSS's CRL code. - // 1. NSS may use one key to verify a CRL signed with another key, - // incorrectly concluding that the CRL's signature is invalid. - // Hopefully this bug will be fixed in NSS 3.12.9. - // 2. NSS considers all certificates issued by the CA as revoked when it - // receives a CRL with an invalid signature. This overly strict policy - // has been relaxed in NSS 3.12.7. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=562542. - // So we have to turn off CRL checking for these CAs. See - // http://crbug.com/55695. - static const char* const kMultipleKeyCA[] = { - "CN=Microsoft Secure Server Authority," - "DC=redmond,DC=corp,DC=microsoft,DC=com", - "CN=Microsoft Secure Server Authority", - }; - - if (!NSS_VersionCheck("3.12.7")) { - for (size_t i = 0; i < arraysize(kMultipleKeyCA); ++i) { - if (strcmp(cert_handle->issuerName, kMultipleKeyCA[i]) == 0) { - use_crl = false; - break; - } - } - } - - PRUint64 revocation_method_flags = - CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD | - CERT_REV_M_ALLOW_NETWORK_FETCHING | - CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE | - CERT_REV_M_IGNORE_MISSING_FRESH_INFO | - CERT_REV_M_STOP_TESTING_ON_FRESH_INFO; - PRUint64 revocation_method_independent_flags = - CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; - if (check_revocation && policy_oids && num_policy_oids > 0) { - // EV verification requires revocation checking. Consider the certificate - // revoked if we don't have revocation info. - // TODO(wtc): Add a bool parameter to expressly specify we're doing EV - // verification or we want strict revocation flags. - revocation_method_flags |= CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE; - revocation_method_independent_flags |= - CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE; - } else { - revocation_method_flags |= CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE; - revocation_method_independent_flags |= - CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT; - } - PRUint64 method_flags[2]; - method_flags[cert_revocation_method_crl] = revocation_method_flags; - method_flags[cert_revocation_method_ocsp] = revocation_method_flags; - - if (use_crl) { - method_flags[cert_revocation_method_crl] |= - CERT_REV_M_TEST_USING_THIS_METHOD; - } - if (use_ocsp) { - method_flags[cert_revocation_method_ocsp] |= - CERT_REV_M_TEST_USING_THIS_METHOD; - } - - CERTRevocationMethodIndex preferred_revocation_methods[1]; - if (use_ocsp) { - preferred_revocation_methods[0] = cert_revocation_method_ocsp; - } else { - preferred_revocation_methods[0] = cert_revocation_method_crl; - } - - CERTRevocationFlags revocation_flags; - revocation_flags.leafTests.number_of_defined_methods = - arraysize(method_flags); - revocation_flags.leafTests.cert_rev_flags_per_method = method_flags; - revocation_flags.leafTests.number_of_preferred_methods = - arraysize(preferred_revocation_methods); - revocation_flags.leafTests.preferred_methods = preferred_revocation_methods; - revocation_flags.leafTests.cert_rev_method_independent_flags = - revocation_method_independent_flags; - - revocation_flags.chainTests.number_of_defined_methods = - arraysize(method_flags); - revocation_flags.chainTests.cert_rev_flags_per_method = method_flags; - revocation_flags.chainTests.number_of_preferred_methods = - arraysize(preferred_revocation_methods); - revocation_flags.chainTests.preferred_methods = preferred_revocation_methods; - revocation_flags.chainTests.cert_rev_method_independent_flags = - revocation_method_independent_flags; - - - std::vector<CERTValInParam> cvin; - cvin.reserve(7); - CERTValInParam in_param; - in_param.type = cert_pi_revocationFlags; - in_param.value.pointer.revocation = &revocation_flags; - cvin.push_back(in_param); - if (policy_oids && num_policy_oids > 0) { - in_param.type = cert_pi_policyOID; - in_param.value.arraySize = num_policy_oids; - in_param.value.array.oids = policy_oids; - cvin.push_back(in_param); - } - if (additional_trust_anchors) { - in_param.type = cert_pi_trustAnchors; - in_param.value.pointer.chain = additional_trust_anchors; - cvin.push_back(in_param); - in_param.type = cert_pi_useOnlyTrustAnchors; - in_param.value.scalar.b = PR_FALSE; - cvin.push_back(in_param); - } - in_param.type = cert_pi_end; - cvin.push_back(in_param); - - SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, - &cvin[0], cvout, NULL); - if (rv != SECSuccess) { - rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, - cert_io_enabled, &cvin, cvout); - } - return rv; -} - -// PKIXVerifyCert calls this function to work around some bugs in -// CERT_PKIXVerifyCert. All the arguments of this function are either the -// arguments or local variables of PKIXVerifyCert. -SECStatus RetryPKIXVerifyCertWithWorkarounds( - CERTCertificate* cert_handle, int num_policy_oids, - bool cert_io_enabled, std::vector<CERTValInParam>* cvin, - CERTValOutParam* cvout) { - // We call this function when the first CERT_PKIXVerifyCert call in - // PKIXVerifyCert failed, so we initialize |rv| to SECFailure. - SECStatus rv = SECFailure; - int nss_error = PORT_GetError(); - CERTValInParam in_param; - - // If we get SEC_ERROR_UNKNOWN_ISSUER, we may be missing an intermediate - // CA certificate, so we retry with cert_pi_useAIACertFetch. - // cert_pi_useAIACertFetch has several bugs in its error handling and - // error reporting (NSS bug 528743), so we don't use it by default. - // Note: When building a certificate chain, CERT_PKIXVerifyCert may - // incorrectly pick a CA certificate with the same subject name as the - // missing intermediate CA certificate, and fail with the - // SEC_ERROR_BAD_SIGNATURE error (NSS bug 524013), so we also retry with - // cert_pi_useAIACertFetch on SEC_ERROR_BAD_SIGNATURE. - if (cert_io_enabled && - (nss_error == SEC_ERROR_UNKNOWN_ISSUER || - nss_error == SEC_ERROR_BAD_SIGNATURE)) { - DCHECK_EQ(cvin->back().type, cert_pi_end); - cvin->pop_back(); - in_param.type = cert_pi_useAIACertFetch; - in_param.value.scalar.b = PR_TRUE; - cvin->push_back(in_param); - in_param.type = cert_pi_end; - cvin->push_back(in_param); - rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, - &(*cvin)[0], cvout, NULL); - if (rv == SECSuccess) - return rv; - int new_nss_error = PORT_GetError(); - if (new_nss_error == SEC_ERROR_INVALID_ARGS || - new_nss_error == SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE || - new_nss_error == SEC_ERROR_BAD_INFO_ACCESS_LOCATION || - new_nss_error == SEC_ERROR_BAD_HTTP_RESPONSE || - new_nss_error == SEC_ERROR_BAD_LDAP_RESPONSE || - !IS_SEC_ERROR(new_nss_error)) { - // Use the original error code because of cert_pi_useAIACertFetch's - // bad error reporting. - PORT_SetError(nss_error); - return rv; - } - nss_error = new_nss_error; - } - - // If an intermediate CA certificate has requireExplicitPolicy in its - // policyConstraints extension, CERT_PKIXVerifyCert fails with - // SEC_ERROR_POLICY_VALIDATION_FAILED because we didn't specify any - // certificate policy (NSS bug 552775). So we retry with the certificate - // policy found in the server certificate. - if (nss_error == SEC_ERROR_POLICY_VALIDATION_FAILED && - num_policy_oids == 0) { - SECOidTag policy = GetFirstCertPolicy(cert_handle); - if (policy != SEC_OID_UNKNOWN) { - DCHECK_EQ(cvin->back().type, cert_pi_end); - cvin->pop_back(); - in_param.type = cert_pi_policyOID; - in_param.value.arraySize = 1; - in_param.value.array.oids = &policy; - cvin->push_back(in_param); - in_param.type = cert_pi_end; - cvin->push_back(in_param); - rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, - &(*cvin)[0], cvout, NULL); - if (rv != SECSuccess) { - // Use the original error code. - PORT_SetError(nss_error); - } - } - } - - return rv; -} - -// Decodes the certificatePolicies extension of the certificate. Returns -// NULL if the certificate doesn't have the extension or the extension can't -// be decoded. The returned value must be freed with a -// CERT_DestroyCertificatePoliciesExtension call. -CERTCertificatePolicies* DecodeCertPolicies( - CERTCertificate* cert_handle) { - SECItem policy_ext; - SECStatus rv = CERT_FindCertExtension(cert_handle, - SEC_OID_X509_CERTIFICATE_POLICIES, - &policy_ext); - if (rv != SECSuccess) - return NULL; - CERTCertificatePolicies* policies = - CERT_DecodeCertificatePoliciesExtension(&policy_ext); - SECITEM_FreeItem(&policy_ext, PR_FALSE); - return policies; -} - -// Returns the OID tag for the first certificate policy in the certificate's -// certificatePolicies extension. Returns SEC_OID_UNKNOWN if the certificate -// has no certificate policy. -SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle) { - ScopedCERTCertificatePolicies policies(DecodeCertPolicies(cert_handle)); - if (!policies.get()) - return SEC_OID_UNKNOWN; - - CERTPolicyInfo* policy_info = policies->policyInfos[0]; - if (!policy_info) - return SEC_OID_UNKNOWN; - if (policy_info->oid != SEC_OID_UNKNOWN) - return policy_info->oid; - - // The certificate policy is unknown to NSS. We need to create a dynamic - // OID tag for the policy. - SECOidData od; - od.oid.len = policy_info->policyID.len; - od.oid.data = policy_info->policyID.data; - od.offset = SEC_OID_UNKNOWN; - // NSS doesn't allow us to pass an empty description, so I use a hardcoded, - // default description here. The description doesn't need to be unique for - // each OID. - od.desc = "a certificate policy"; - od.mechanism = CKM_INVALID_MECHANISM; - od.supportedExtension = INVALID_CERT_EXTENSION; - return SECOID_AddEntry(&od); -} - -HashValue CertPublicKeyHashSHA1(CERTCertificate* cert) { - HashValue hash(HASH_VALUE_SHA1); -#if defined(OS_IOS) - CC_SHA1(cert->derPublicKey.data, cert->derPublicKey.len, hash.data()); -#else - SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, hash.data(), - cert->derPublicKey.data, cert->derPublicKey.len); - DCHECK_EQ(SECSuccess, rv); -#endif - return hash; -} - -HashValue CertPublicKeyHashSHA256(CERTCertificate* cert) { - HashValue hash(HASH_VALUE_SHA256); -#if defined(OS_IOS) - CC_SHA256(cert->derPublicKey.data, cert->derPublicKey.len, hash.data()); -#else - SECStatus rv = HASH_HashBuf(HASH_AlgSHA256, hash.data(), - cert->derPublicKey.data, cert->derPublicKey.len); - DCHECK_EQ(rv, SECSuccess); -#endif - return hash; -} - -void AppendPublicKeyHashes(CERTCertList* cert_list, - CERTCertificate* root_cert, - HashValueVector* hashes) { - for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(node, cert_list); - node = CERT_LIST_NEXT(node)) { - hashes->push_back(CertPublicKeyHashSHA1(node->cert)); - hashes->push_back(CertPublicKeyHashSHA256(node->cert)); - } - if (root_cert) { - hashes->push_back(CertPublicKeyHashSHA1(root_cert)); - hashes->push_back(CertPublicKeyHashSHA256(root_cert)); - } -} - -// Returns true if |cert_handle| contains a policy OID that is an EV policy -// OID according to |metadata|, storing the resulting policy OID in -// |*ev_policy_oid|. A true return is not sufficient to establish that a -// certificate is EV, but a false return is sufficient to establish the -// certificate cannot be EV. -bool IsEVCandidate(EVRootCAMetadata* metadata, - CERTCertificate* cert_handle, - SECOidTag* ev_policy_oid) { - DCHECK(cert_handle); - ScopedCERTCertificatePolicies policies(DecodeCertPolicies(cert_handle)); - if (!policies.get()) - return false; - - CERTPolicyInfo** policy_infos = policies->policyInfos; - while (*policy_infos != NULL) { - CERTPolicyInfo* policy_info = *policy_infos++; - // If the Policy OID is unknown, that implicitly means it has not been - // registered as an EV policy. - if (policy_info->oid == SEC_OID_UNKNOWN) - continue; - if (metadata->IsEVPolicyOID(policy_info->oid)) { - *ev_policy_oid = policy_info->oid; - return true; - } - } - - return false; -} - -// Studied Mozilla's code (esp. security/manager/ssl/src/nsIdentityChecking.cpp -// and nsNSSCertHelper.cpp) to learn how to verify EV certificate. -// TODO(wtc): A possible optimization is that we get the trust anchor from -// the first PKIXVerifyCert call. We look up the EV policy for the trust -// anchor. If the trust anchor has no EV policy, we know the cert isn't EV. -// Otherwise, we pass just that EV policy (as opposed to all the EV policies) -// to the second PKIXVerifyCert call. -bool VerifyEV(CERTCertificate* cert_handle, - int flags, - CRLSet* crl_set, - EVRootCAMetadata* metadata, - SECOidTag ev_policy_oid, - CERTCertList* additional_trust_anchors) { - CERTValOutParam cvout[3]; - int cvout_index = 0; - cvout[cvout_index].type = cert_po_certList; - cvout[cvout_index].value.pointer.chain = NULL; - int cvout_cert_list_index = cvout_index; - cvout_index++; - cvout[cvout_index].type = cert_po_trustAnchor; - cvout[cvout_index].value.pointer.cert = NULL; - int cvout_trust_anchor_index = cvout_index; - cvout_index++; - cvout[cvout_index].type = cert_po_end; - ScopedCERTValOutParam scoped_cvout(cvout); - - bool rev_checking_enabled = - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) || - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); - - SECStatus status = PKIXVerifyCert( - cert_handle, - rev_checking_enabled, - flags & CertVerifier::VERIFY_CERT_IO_ENABLED, - &ev_policy_oid, - 1, - additional_trust_anchors, - cvout); - if (status != SECSuccess) - return false; - - CERTCertificate* root_ca = - cvout[cvout_trust_anchor_index].value.pointer.cert; - if (root_ca == NULL) - return false; - - // This second PKIXVerifyCert call could have found a different certification - // path and one or more of the certificates on this new path, that weren't on - // the old path, might have been revoked. - if (crl_set) { - CRLSetResult crl_set_result = CheckRevocationWithCRLSet( - cvout[cvout_cert_list_index].value.pointer.chain, - cvout[cvout_trust_anchor_index].value.pointer.cert, - crl_set); - if (crl_set_result == kCRLSetRevoked) - return false; - } - -#if defined(OS_IOS) - SHA1HashValue fingerprint = x509_util_ios::CalculateFingerprintNSS(root_ca); -#else - SHA1HashValue fingerprint = - X509Certificate::CalculateFingerprint(root_ca); -#endif - return metadata->HasEVPolicyOID(fingerprint, ev_policy_oid); -} - -CERTCertList* CertificateListToCERTCertList(const CertificateList& list) { - CERTCertList* result = CERT_NewCertList(); - for (size_t i = 0; i < list.size(); ++i) { -#if defined(OS_IOS) - // X509Certificate::os_cert_handle() on iOS is a SecCertificateRef; convert - // it to an NSS CERTCertificate. - CERTCertificate* cert = x509_util_ios::CreateNSSCertHandleFromOSHandle( - list[i]->os_cert_handle()); -#else - CERTCertificate* cert = list[i]->os_cert_handle(); -#endif - CERT_AddCertToListTail(result, CERT_DupCertificate(cert)); - } - return result; -} - -} // namespace - -CertVerifyProcNSS::CertVerifyProcNSS() {} - -CertVerifyProcNSS::~CertVerifyProcNSS() {} - -bool CertVerifyProcNSS::SupportsAdditionalTrustAnchors() const { - // This requires APIs introduced in 3.14.2. - return NSS_VersionCheck("3.14.2"); -} - -int CertVerifyProcNSS::VerifyInternal( - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { -#if defined(OS_IOS) - // For iOS, the entire chain must be loaded into NSS's in-memory certificate - // store. - x509_util_ios::NSSCertChain scoped_chain(cert); - CERTCertificate* cert_handle = scoped_chain.cert_handle(); -#else - CERTCertificate* cert_handle = cert->os_cert_handle(); -#endif // defined(OS_IOS) - - // Make sure that the hostname matches with the common name of the cert. - SECStatus status = CERT_VerifyCertName(cert_handle, hostname.c_str()); - if (status != SECSuccess) - verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; - - // Make sure that the cert is valid now. - SECCertTimeValidity validity = CERT_CheckCertValidTimes( - cert_handle, PR_Now(), PR_TRUE); - if (validity != secCertTimeValid) - verify_result->cert_status |= CERT_STATUS_DATE_INVALID; - - CERTValOutParam cvout[3]; - int cvout_index = 0; - cvout[cvout_index].type = cert_po_certList; - cvout[cvout_index].value.pointer.chain = NULL; - int cvout_cert_list_index = cvout_index; - cvout_index++; - cvout[cvout_index].type = cert_po_trustAnchor; - cvout[cvout_index].value.pointer.cert = NULL; - int cvout_trust_anchor_index = cvout_index; - cvout_index++; - cvout[cvout_index].type = cert_po_end; - ScopedCERTValOutParam scoped_cvout(cvout); - - EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); - SECOidTag ev_policy_oid = SEC_OID_UNKNOWN; - bool is_ev_candidate = - (flags & CertVerifier::VERIFY_EV_CERT) && - IsEVCandidate(metadata, cert_handle, &ev_policy_oid); - bool cert_io_enabled = flags & CertVerifier::VERIFY_CERT_IO_ENABLED; - bool check_revocation = - cert_io_enabled && - ((flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) || - ((flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) && - is_ev_candidate)); - if (check_revocation) - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - - ScopedCERTCertList trust_anchors; - if (SupportsAdditionalTrustAnchors() && !additional_trust_anchors.empty()) { - trust_anchors.reset( - CertificateListToCERTCertList(additional_trust_anchors)); - } - - status = PKIXVerifyCert(cert_handle, check_revocation, cert_io_enabled, - NULL, 0, trust_anchors.get(), cvout); - - if (status == SECSuccess) { - AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, - cvout[cvout_trust_anchor_index].value.pointer.cert, - &verify_result->public_key_hashes); - - verify_result->is_issued_by_known_root = - IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); - verify_result->is_issued_by_additional_trust_anchor = - IsAdditionalTrustAnchor( - trust_anchors.get(), - cvout[cvout_trust_anchor_index].value.pointer.cert); - - GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, - cvout[cvout_trust_anchor_index].value.pointer.cert, - verify_result); - } - - if (crl_set) { - CRLSetResult crl_set_result = CheckRevocationWithCRLSet( - cvout[cvout_cert_list_index].value.pointer.chain, - cvout[cvout_trust_anchor_index].value.pointer.cert, - crl_set); - if (crl_set_result == kCRLSetRevoked) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - status = SECFailure; - } - } - - if (status != SECSuccess) { - int err = PORT_GetError(); - LOG(ERROR) << "CERT_PKIXVerifyCert for " << hostname - << " failed err=" << err; - // CERT_PKIXVerifyCert rerports the wrong error code for - // expired certificates (NSS bug 491174) - if (err == SEC_ERROR_CERT_NOT_VALID && - (verify_result->cert_status & CERT_STATUS_DATE_INVALID)) - err = SEC_ERROR_EXPIRED_CERTIFICATE; - CertStatus cert_status = MapCertErrorToCertStatus(err); - if (cert_status) { - verify_result->cert_status |= cert_status; - return MapCertStatusToNetError(verify_result->cert_status); - } - // |err| is not a certificate error. - return MapSecurityError(err); - } - - if (IsCertStatusError(verify_result->cert_status)) - return MapCertStatusToNetError(verify_result->cert_status); - - if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate && - VerifyEV(cert_handle, flags, crl_set, metadata, ev_policy_oid, - trust_anchors.get())) { - verify_result->cert_status |= CERT_STATUS_IS_EV; - } - - return OK; -} - -} // namespace net diff --git a/net/base/cert_verify_proc_nss.h b/net/base/cert_verify_proc_nss.h deleted file mode 100644 index 8dcd235..0000000 --- a/net/base/cert_verify_proc_nss.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_NSS_H_ -#define NET_BASE_CERT_VERIFY_PROC_NSS_H_ - -#include "net/base/cert_verify_proc.h" -#include "net/base/net_export.h" - -namespace net { - -// Performs certificate path construction and validation using NSS's libpkix. -class NET_EXPORT_PRIVATE CertVerifyProcNSS : public CertVerifyProc { - public: - CertVerifyProcNSS(); - - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE; - - protected: - virtual ~CertVerifyProcNSS(); - - private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_NSS_H_ diff --git a/net/base/cert_verify_proc_openssl.cc b/net/base/cert_verify_proc_openssl.cc deleted file mode 100644 index 964ba26..0000000 --- a/net/base/cert_verify_proc_openssl.cc +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/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/sha2.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -// Maps X509_STORE_CTX_get_error() return values to our cert status flags. -CertStatus MapCertErrorToCertStatus(int err) { - switch (err) { - case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: - return CERT_STATUS_COMMON_NAME_INVALID; - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_CRL_NOT_YET_VALID: - case X509_V_ERR_CRL_HAS_EXPIRED: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - return CERT_STATUS_DATE_INVALID; - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - case X509_V_ERR_UNABLE_TO_GET_CRL: - case X509_V_ERR_INVALID_CA: - case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - case X509_V_ERR_INVALID_NON_CA: - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - return CERT_STATUS_AUTHORITY_INVALID; -#if 0 -// TODO(bulach): what should we map to these status? - return CERT_STATUS_NO_REVOCATION_MECHANISM; - return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; -#endif - case X509_V_ERR_CERT_REVOKED: - return CERT_STATUS_REVOKED; - // All these status are mapped to CERT_STATUS_INVALID. - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - case X509_V_ERR_OUT_OF_MEM: - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - case X509_V_ERR_INVALID_PURPOSE: - case X509_V_ERR_CERT_UNTRUSTED: - case X509_V_ERR_CERT_REJECTED: - case X509_V_ERR_AKID_SKID_MISMATCH: - case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: - case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: - case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: - case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: - case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: - case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: - case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - case X509_V_ERR_INVALID_EXTENSION: - case X509_V_ERR_INVALID_POLICY_EXTENSION: - case X509_V_ERR_NO_EXPLICIT_POLICY: - case X509_V_ERR_UNNESTED_RESOURCE: - case X509_V_ERR_APPLICATION_VERIFICATION: - return CERT_STATUS_INVALID; - default: - NOTREACHED() << "Invalid X509 err " << err; - return CERT_STATUS_INVALID; - } -} - -// 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); -} - -void GetCertChainInfo(X509_STORE_CTX* store_ctx, - CertVerifyResult* verify_result) { - STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(store_ctx); - X509* verified_cert = NULL; - std::vector<X509*> verified_chain; - for (int i = 0; i < sk_X509_num(chain); ++i) { - X509* cert = sk_X509_value(chain, i); - if (i == 0) { - verified_cert = cert; - } else { - verified_chain.push_back(cert); - } - - // Only check the algorithm status for certificates that are not in the - // trust store. - if (i < store_ctx->last_untrusted) { - int sig_alg = OBJ_obj2nid(cert->sig_alg->algorithm); - if (sig_alg == NID_md2WithRSAEncryption) { - verify_result->has_md2 = true; - if (i != 0) - verify_result->has_md2_ca = true; - } else if (sig_alg == NID_md4WithRSAEncryption) { - verify_result->has_md4 = true; - } else if (sig_alg == NID_md5WithRSAEncryption) { - verify_result->has_md5 = true; - if (i != 0) - verify_result->has_md5_ca = true; - } - } - } - - if (verified_cert) { - verify_result->verified_cert = - X509Certificate::CreateFromHandle(verified_cert, verified_chain); - } -} - -void AppendPublicKeyHashes(X509_STORE_CTX* store_ctx, - HashValueVector* hashes) { - STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(store_ctx); - for (int i = 0; i < sk_X509_num(chain); ++i) { - X509* cert = sk_X509_value(chain, i); - - std::string der_data; - if (!X509Certificate::GetDEREncoded(cert, &der_data)) - continue; - - base::StringPiece der_bytes(der_data); - base::StringPiece spki_bytes; - if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) - continue; - - HashValue sha1(HASH_VALUE_SHA1); - base::SHA1HashBytes(reinterpret_cast<const uint8*>(spki_bytes.data()), - spki_bytes.size(), sha1.data()); - hashes->push_back(sha1); - - HashValue sha256(HASH_VALUE_SHA256); - crypto::SHA256HashString(spki_bytes, sha1.data(), crypto::kSHA256Length); - hashes->push_back(sha256); - } -} - -} // namespace - -CertVerifyProcOpenSSL::CertVerifyProcOpenSSL() {} - -CertVerifyProcOpenSSL::~CertVerifyProcOpenSSL() {} - -bool CertVerifyProcOpenSSL::SupportsAdditionalTrustAnchors() const { - return false; -} - -int CertVerifyProcOpenSSL::VerifyInternal( - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - crypto::EnsureOpenSSLInit(); - - if (!cert->VerifyNameMatch(hostname)) - verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; - - crypto::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx( - X509_STORE_CTX_new()); - - crypto::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates( - sk_X509_new_null()); - if (!intermediates.get()) - return ERR_OUT_OF_MEMORY; - - const X509Certificate::OSCertHandles& os_intermediates = - cert->GetIntermediateCertificates(); - for (X509Certificate::OSCertHandles::const_iterator it = - os_intermediates.begin(); it != os_intermediates.end(); ++it) { - if (!sk_X509_push(intermediates.get(), *it)) - return ERR_OUT_OF_MEMORY; - } - if (X509_STORE_CTX_init(ctx.get(), X509Certificate::cert_store(), - cert->os_cert_handle(), intermediates.get()) != 1) { - NOTREACHED(); - return ERR_FAILED; - } - - if (X509_verify_cert(ctx.get()) != 1) { - int x509_error = X509_STORE_CTX_get_error(ctx.get()); - CertStatus cert_status = MapCertErrorToCertStatus(x509_error); - LOG(ERROR) << "X509 Verification error " - << X509_verify_cert_error_string(x509_error) - << " : " << x509_error - << " : " << X509_STORE_CTX_get_error_depth(ctx.get()) - << " : " << cert_status; - verify_result->cert_status |= cert_status; - } - - GetCertChainInfo(ctx.get(), verify_result); - AppendPublicKeyHashes(ctx.get(), &verify_result->public_key_hashes); - if (IsCertStatusError(verify_result->cert_status)) - return MapCertStatusToNetError(verify_result->cert_status); - - // Currently we only ues OpenSSL's default root CA paths, so treat all - // correctly verified certs as being from a known root. - // TODO(joth): if the motivations described in - // http://src.chromium.org/viewvc/chrome?view=rev&revision=80778 become an - // issue on OpenSSL builds, we will need to embed a hardcoded list of well - // known root CAs, as per the _mac and _win versions. - verify_result->is_issued_by_known_root = true; - - return OK; -} - -} // namespace net diff --git a/net/base/cert_verify_proc_openssl.h b/net/base/cert_verify_proc_openssl.h deleted file mode 100644 index 5777bcc..0000000 --- a/net/base/cert_verify_proc_openssl.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_OPENSSL_H_ -#define NET_BASE_CERT_VERIFY_PROC_OPENSSL_H_ - -#include "net/base/cert_verify_proc.h" - -namespace net { - -// Performs certificate path construction and validation using OpenSSL. -class CertVerifyProcOpenSSL : public CertVerifyProc { - public: - CertVerifyProcOpenSSL(); - - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE; - - protected: - virtual ~CertVerifyProcOpenSSL(); - - private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_OPENSSL_H_ diff --git a/net/base/cert_verify_proc_unittest.cc b/net/base/cert_verify_proc_unittest.cc deleted file mode 100644 index 0b0a141..0000000 --- a/net/base/cert_verify_proc_unittest.cc +++ /dev/null @@ -1,1068 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc.h" - -#include <vector> - -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/sha1.h" -#include "base/string_number_conversions.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_test_util.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crl_set.h" -#include "net/base/net_errors.h" -#include "net/base/test_certificate_data.h" -#include "net/base/test_data_directory.h" -#include "net/base/test_root_certs.h" -#include "net/base/x509_certificate.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#elif defined(OS_MACOSX) && !defined(OS_IOS) -#include "base/mac/mac_util.h" -#endif - -using base::HexEncode; - -namespace net { - -namespace { - -// A certificate for www.paypal.com with a NULL byte in the common name. -// From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 -unsigned char paypal_null_fingerprint[] = { - 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, - 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 -}; - -} // namespace - -class CertVerifyProcTest : public testing::Test { - public: - CertVerifyProcTest() - : verify_proc_(CertVerifyProc::CreateDefault()) { - } - virtual ~CertVerifyProcTest() {} - - protected: - bool SupportsAdditionalTrustAnchors() { - return verify_proc_->SupportsAdditionalTrustAnchors(); - } - - int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - return verify_proc_->Verify(cert, hostname, flags, crl_set, - additional_trust_anchors, verify_result); - } - - const CertificateList empty_cert_list_; - - private: - scoped_refptr<CertVerifyProc> verify_proc_; -}; - -TEST_F(CertVerifyProcTest, WithoutRevocationChecking) { - // Check that verification without revocation checking works. - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), - "googlenew.chain.pem", - X509Certificate::FORMAT_PEM_CERT_SEQUENCE); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - - scoped_refptr<X509Certificate> google_full_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - EXPECT_EQ(OK, Verify(google_full_chain, "www.google.com", 0 /* flags */, - NULL, empty_cert_list_, &verify_result)); -} - -#if defined(OS_ANDROID) || defined(USE_OPENSSL) -// TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported. -#define MAYBE_EVVerification DISABLED_EVVerification -#else -#define MAYBE_EVVerification EVVerification -#endif -TEST_F(CertVerifyProcTest, MAYBE_EVVerification) { - // This certificate will expire Jun 21, 2013. - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), - "comodo.chain.pem", - X509Certificate::FORMAT_PEM_CERT_SEQUENCE); - ASSERT_EQ(3U, certs.size()); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - intermediates.push_back(certs[2]->os_cert_handle()); - - scoped_refptr<X509Certificate> comodo_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - - scoped_refptr<CRLSet> crl_set(CRLSet::EmptyCRLSetForTesting()); - CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_EV_CERT; - int error = Verify(comodo_chain, "comodo.com", flags, crl_set.get(), - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); -} - -TEST_F(CertVerifyProcTest, PaypalNullCertParsing) { - scoped_refptr<X509Certificate> paypal_null_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(paypal_null_der), - sizeof(paypal_null_der))); - - ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert); - - const SHA1HashValue& fingerprint = - paypal_null_cert->fingerprint(); - for (size_t i = 0; i < 20; ++i) - EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]); - - int flags = 0; - CertVerifyResult verify_result; - int error = Verify(paypal_null_cert, "www.paypal.com", flags, NULL, - empty_cert_list_, &verify_result); -#if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID) - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); -#else - // TOOD(bulach): investigate why macosx and win aren't returning - // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID. - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); -#endif - // Either the system crypto library should correctly report a certificate - // name mismatch, or our certificate blacklist should cause us to report an - // invalid certificate. -#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS) - EXPECT_TRUE(verify_result.cert_status & - (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID)); -#endif -} - -// A regression test for http://crbug.com/31497. -// This certificate will expire on 2012-04-08. The test will still -// pass if error == ERR_CERT_DATE_INVALID. TODO(wtc): generate test -// certificates for this unit test. http://crbug.com/111742 -TEST_F(CertVerifyProcTest, IntermediateCARequireExplicitPolicy) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - // The intermediate CA certificate's policyConstraints extension has a - // requireExplicitPolicy field with SkipCerts=0. - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, "dod_ca_17_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - - scoped_refptr<X509Certificate> root_cert = - ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der"); - ScopedTestRoot scoped_root(root_cert); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - int flags = 0; - CertVerifyResult verify_result; - int error = Verify(cert_chain, "www.us.army.mil", flags, NULL, - empty_cert_list_, &verify_result); - if (error == OK) { - EXPECT_EQ(0U, verify_result.cert_status); - } else { - EXPECT_EQ(ERR_CERT_DATE_INVALID, error); - EXPECT_EQ(CERT_STATUS_DATE_INVALID, verify_result.cert_status); - } -} - - -// Test for bug 58437. -// This certificate will expire on 2011-12-21. The test will still -// pass if error == ERR_CERT_DATE_INVALID. -// This test is DISABLED because it appears that we cannot do -// certificate revocation checking when running all of the net unit tests. -// This test passes when run individually, but when run with all of the net -// unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is -// SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation -// status, i.e. that the revocation check is failing for some reason. -TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED | - CertVerifier::VERIFY_EV_CERT; - int error = Verify(cert_chain, "2029.globalsign.com", flags, NULL, - empty_cert_list_, &verify_result); - if (error == OK) - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); - else - EXPECT_EQ(ERR_CERT_DATE_INVALID, error); -} - -// Test that verifying an ECDSA certificate doesn't crash on XP. (See -// crbug.com/144466). -TEST_F(CertVerifyProcTest, ECDSA_RSA) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> cert = - ImportCertFromFile(certs_dir, - "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem"); - - CertVerifyResult verify_result; - Verify(cert, "127.0.0.1", 0, NULL, empty_cert_list_, &verify_result); - - // We don't check verify_result because the certificate is signed by an - // unknown CA and will be considered invalid on XP because of the ECDSA - // public key. -} - -// Currently, only RSA and DSA keys are checked for weakness, and our example -// weak size is 768. These could change in the future. -// -// Note that this means there may be false negatives: keys for other -// algorithms and which are weak will pass this test. -static bool IsWeakKeyType(const std::string& key_type) { - size_t pos = key_type.find("-"); - std::string size = key_type.substr(0, pos); - std::string type = key_type.substr(pos + 1); - - if (type == "rsa" || type == "dsa") - return size == "768"; - - return false; -} - -TEST_F(CertVerifyProcTest, RejectWeakKeys) { - base::FilePath certs_dir = GetTestCertsDirectory(); - typedef std::vector<std::string> Strings; - Strings key_types; - - // generate-weak-test-chains.sh currently has: - // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa" - // We must use the same key types here. The filenames generated look like: - // 2048-rsa-ee-by-768-rsa-intermediate.pem - key_types.push_back("768-rsa"); - key_types.push_back("1024-rsa"); - key_types.push_back("2048-rsa"); - - bool use_ecdsa = true; -#if defined(OS_WIN) - use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP; -#endif - - if (use_ecdsa) - key_types.push_back("prime256v1-ecdsa"); - - // Add the root that signed the intermediates for this test. - scoped_refptr<X509Certificate> root_cert = - ImportCertFromFile(certs_dir, "2048-rsa-root.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); - ScopedTestRoot scoped_root(root_cert); - - // Now test each chain. - for (Strings::const_iterator ee_type = key_types.begin(); - ee_type != key_types.end(); ++ee_type) { - for (Strings::const_iterator signer_type = key_types.begin(); - signer_type != key_types.end(); ++signer_type) { - std::string basename = *ee_type + "-ee-by-" + *signer_type + - "-intermediate.pem"; - SCOPED_TRACE(basename); - scoped_refptr<X509Certificate> ee_cert = - ImportCertFromFile(certs_dir, basename); - ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); - - basename = *signer_type + "-intermediate.pem"; - scoped_refptr<X509Certificate> intermediate = - ImportCertFromFile(certs_dir, basename); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - int error = Verify(cert_chain, "127.0.0.1", 0, NULL, - empty_cert_list_, &verify_result); - - if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) { - EXPECT_NE(OK, error); - EXPECT_EQ(CERT_STATUS_WEAK_KEY, - verify_result.cert_status & CERT_STATUS_WEAK_KEY); - EXPECT_NE(CERT_STATUS_INVALID, - verify_result.cert_status & CERT_STATUS_INVALID); - } else { - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY); - } - } - } -} - -// Test for bug 108514. -// The certificate will expire on 2012-07-20. The test will still -// pass if error == ERR_CERT_DATE_INVALID. TODO(rsleevi): generate test -// certificates for this unit test. http://crbug.com/111730 -TEST_F(CertVerifyProcTest, ExtraneousMD5RootCert) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "images_etrade_wallst_com.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, "globalsign_orgv1_ca.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - - scoped_refptr<X509Certificate> md5_root_cert = - ImportCertFromFile(certs_dir, "globalsign_root_ca_md5.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), md5_root_cert); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - intermediates.push_back(md5_root_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - int flags = 0; - int error = Verify(cert_chain, "images.etrade.wallst.com", flags, NULL, - empty_cert_list_, &verify_result); - if (error != OK) - EXPECT_EQ(ERR_CERT_DATE_INVALID, error); - - EXPECT_FALSE(verify_result.has_md5); - EXPECT_FALSE(verify_result.has_md5_ca); -} - -// Test for bug 94673. -TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "google_diginotar.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED; - int error = Verify(cert_chain, "mail.google.com", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_NE(OK, error); - - // Now turn off revocation checking. Certificate verification should still - // fail. - flags = 0; - error = Verify(cert_chain, "mail.google.com", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_NE(OK, error); -} - -TEST_F(CertVerifyProcTest, DigiNotarCerts) { - static const char* const kDigiNotarFilenames[] = { - "diginotar_root_ca.pem", - "diginotar_cyber_ca.pem", - "diginotar_services_1024_ca.pem", - "diginotar_pkioverheid.pem", - "diginotar_pkioverheid_g2.pem", - NULL, - }; - - base::FilePath certs_dir = GetTestCertsDirectory(); - - for (size_t i = 0; kDigiNotarFilenames[i]; i++) { - scoped_refptr<X509Certificate> diginotar_cert = - ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]); - std::string der_bytes; - ASSERT_TRUE(X509Certificate::GetDEREncoded( - diginotar_cert->os_cert_handle(), &der_bytes)); - - base::StringPiece spki; - ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki)); - - std::string spki_sha1 = base::SHA1HashString(spki.as_string()); - - HashValueVector public_keys; - HashValue hash(HASH_VALUE_SHA1); - ASSERT_EQ(hash.size(), spki_sha1.size()); - memcpy(hash.data(), spki_sha1.data(), spki_sha1.size()); - public_keys.push_back(hash); - - EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) << - "Public key not blocked for " << kDigiNotarFilenames[i]; - } -} - -TEST_F(CertVerifyProcTest, TestKnownRoot) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, "certse.pem", X509Certificate::FORMAT_AUTO); - ASSERT_EQ(3U, certs.size()); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - intermediates.push_back(certs[2]->os_cert_handle()); - - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - - int flags = 0; - CertVerifyResult verify_result; - // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug - // against agl. See also PublicKeyHashes. - int error = Verify(cert_chain, "cert.se", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - EXPECT_TRUE(verify_result.is_issued_by_known_root); -} - -TEST_F(CertVerifyProcTest, PublicKeyHashes) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, "certse.pem", X509Certificate::FORMAT_AUTO); - ASSERT_EQ(3U, certs.size()); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - intermediates.push_back(certs[2]->os_cert_handle()); - - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - int flags = 0; - CertVerifyResult verify_result; - - // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug - // against agl. See also TestKnownRoot. - int error = Verify(cert_chain, "cert.se", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - ASSERT_LE(3u, verify_result.public_key_hashes.size()); - - HashValueVector sha1_hashes; - for (unsigned i = 0; i < verify_result.public_key_hashes.size(); ++i) { - if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1) - continue; - sha1_hashes.push_back(verify_result.public_key_hashes[i]); - } - ASSERT_LE(3u, sha1_hashes.size()); - - for (unsigned i = 0; i < 3; ++i) { - EXPECT_EQ(HexEncode(kCertSESPKIs[i], base::kSHA1Length), - HexEncode(sha1_hashes[i].data(), base::kSHA1Length)); - } -} - -// A regression test for http://crbug.com/70293. -// The Key Usage extension in this RSA SSL server certificate does not have -// the keyEncipherment bit. -TEST_F(CertVerifyProcTest, InvalidKeyUsage) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - int flags = 0; - CertVerifyResult verify_result; - int error = Verify(server_cert, "jira.aquameta.com", flags, NULL, - empty_cert_list_, &verify_result); -#if defined(USE_OPENSSL) - // This certificate has two errors: "invalid key usage" and "untrusted CA". - // However, OpenSSL returns only one (the latter), and we can't detect - // the other errors. - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); -#else - EXPECT_EQ(ERR_CERT_INVALID, error); - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); -#endif - // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors - // from NSS. -#if !defined(USE_NSS) && !defined(OS_IOS) - // The certificate is issued by an unknown CA. - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); -#endif -} - -// Basic test for returning the chain in CertVerifyResult. Note that the -// returned chain may just be a reflection of the originally supplied chain; -// that is, if any errors occur, the default chain returned is an exact copy -// of the certificate to be verified. The remaining VerifyReturn* tests are -// used to ensure that the actual, verified chain is being returned by -// Verify(). -TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, "x509_verify_results.chain.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(3U, certs.size()); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - intermediates.push_back(certs[2]->os_cert_handle()); - - ScopedTestRoot scoped_root(certs[2]); - - scoped_refptr<X509Certificate> google_full_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); - ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); - - CertVerifyResult verify_result; - EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - - EXPECT_NE(google_full_chain, verify_result.verified_cert); - EXPECT_TRUE(X509Certificate::IsSameOSCert( - google_full_chain->os_cert_handle(), - verify_result.verified_cert->os_cert_handle())); - const X509Certificate::OSCertHandles& return_intermediates = - verify_result.verified_cert->GetIntermediateCertificates(); - ASSERT_EQ(2U, return_intermediates.size()); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], - certs[1]->os_cert_handle())); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], - certs[2]->os_cert_handle())); -} - -// Test that the certificate returned in CertVerifyResult is able to reorder -// certificates that are not ordered from end-entity to root. While this is -// a protocol violation if sent during a TLS handshake, if multiple sources -// of intermediate certificates are combined, it's possible that order may -// not be maintained. -TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, "x509_verify_results.chain.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(3U, certs.size()); - - // Construct the chain out of order. - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[2]->os_cert_handle()); - intermediates.push_back(certs[1]->os_cert_handle()); - - ScopedTestRoot scoped_root(certs[2]); - - scoped_refptr<X509Certificate> google_full_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); - ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); - - CertVerifyResult verify_result; - EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - - EXPECT_NE(google_full_chain, verify_result.verified_cert); - EXPECT_TRUE(X509Certificate::IsSameOSCert( - google_full_chain->os_cert_handle(), - verify_result.verified_cert->os_cert_handle())); - const X509Certificate::OSCertHandles& return_intermediates = - verify_result.verified_cert->GetIntermediateCertificates(); - ASSERT_EQ(2U, return_intermediates.size()); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], - certs[1]->os_cert_handle())); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], - certs[2]->os_cert_handle())); -} - -// Test that Verify() filters out certificates which are not related to -// or part of the certificate chain being verified. -TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, "x509_verify_results.chain.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(3U, certs.size()); - ScopedTestRoot scoped_root(certs[2]); - - scoped_refptr<X509Certificate> unrelated_dod_certificate = - ImportCertFromFile(certs_dir, "dod_ca_17_cert.der"); - scoped_refptr<X509Certificate> unrelated_dod_certificate2 = - ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate); - ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate2); - - // Interject unrelated certificates into the list of intermediates. - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(unrelated_dod_certificate->os_cert_handle()); - intermediates.push_back(certs[1]->os_cert_handle()); - intermediates.push_back(unrelated_dod_certificate2->os_cert_handle()); - intermediates.push_back(certs[2]->os_cert_handle()); - - scoped_refptr<X509Certificate> google_full_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); - ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size()); - - CertVerifyResult verify_result; - EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); - - EXPECT_NE(google_full_chain, verify_result.verified_cert); - EXPECT_TRUE(X509Certificate::IsSameOSCert( - google_full_chain->os_cert_handle(), - verify_result.verified_cert->os_cert_handle())); - const X509Certificate::OSCertHandles& return_intermediates = - verify_result.verified_cert->GetIntermediateCertificates(); - ASSERT_EQ(2U, return_intermediates.size()); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], - certs[1]->os_cert_handle())); - EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], - certs[2]->os_cert_handle())); -} - -TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) { - if (!SupportsAdditionalTrustAnchors()) { - LOG(INFO) << "Skipping this test in this platform."; - return; - } - - // |ca_cert| is the issuer of |cert|. - CertificateList ca_cert_list = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_cert_list.size()); - scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]); - - CertificateList cert_list = CreateCertificateListFromFile( - GetTestCertsDirectory(), "ok_cert.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - - // Verification of |cert| fails when |ca_cert| is not in the trust anchors - // list. - int flags = 0; - CertVerifyResult verify_result; - int error = Verify(cert, "127.0.0.1", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); - EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); - EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); - - // Now add the |ca_cert| to the |trust_anchors|, and verification should pass. - CertificateList trust_anchors; - trust_anchors.push_back(ca_cert); - error = Verify(cert, "127.0.0.1", flags, NULL, trust_anchors, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor); - - // Clearing the |trust_anchors| makes verification fail again (the cache - // should be skipped). - error = Verify(cert, "127.0.0.1", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); - EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); - EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); -} - -#if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX) -static const uint8 kCRLSetThawteSPKIBlocked[] = { - 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x36, 0x58, 0x36, 0x4d, 0x78, 0x52, 0x37, - 0x58, 0x70, 0x4d, 0x51, 0x4b, 0x78, 0x49, 0x41, 0x39, 0x50, 0x6a, 0x36, 0x37, - 0x36, 0x38, 0x76, 0x74, 0x55, 0x6b, 0x6b, 0x7a, 0x48, 0x79, 0x7a, 0x41, 0x6f, - 0x6d, 0x6f, 0x4f, 0x68, 0x4b, 0x55, 0x6e, 0x7a, 0x73, 0x55, 0x3d, 0x22, 0x5d, - 0x7d, -}; - -static const uint8 kCRLSetThawteSerialBlocked[] = { - 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xb1, 0x12, 0x41, 0x42, 0xa5, 0xa1, - 0xa5, 0xa2, 0x88, 0x19, 0xc7, 0x35, 0x34, 0x0e, 0xff, 0x8c, 0x9e, 0x2f, 0x81, - 0x68, 0xfe, 0xe3, 0xba, 0x18, 0x7f, 0x25, 0x3b, 0xc1, 0xa3, 0x92, 0xd7, 0xe2, - // Note that this is actually blocking two serial numbers because on XP and - // Vista, CryptoAPI finds a different Thawte certificate. - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x30, 0x00, 0x00, 0x02, - 0x04, 0x30, 0x00, 0x00, 0x06, -}; - -static const uint8 kCRLSetGoogleSerialBlocked[] = { - 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xe9, 0x7e, 0x8c, 0xc5, 0x1e, 0xd7, - 0xa4, 0xc4, 0x0a, 0xc4, 0x80, 0x3d, 0x3e, 0x3e, 0xbb, 0xeb, 0xcb, 0xed, 0x52, - 0x49, 0x33, 0x1f, 0x2c, 0xc0, 0xa2, 0x6a, 0x0e, 0x84, 0xa5, 0x27, 0xce, 0xc5, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x4f, 0x9d, 0x96, 0xd9, 0x66, 0xb0, 0x99, 0x2b, - 0x54, 0xc2, 0x95, 0x7c, 0xb4, 0x15, 0x7d, 0x4d, -}; - -// Test that CRLSets are effective in making a certificate appear to be -// revoked. -TEST_F(CertVerifyProcTest, CRLSet) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), - "googlenew.chain.pem", - X509Certificate::FORMAT_PEM_CERT_SEQUENCE); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(certs[1]->os_cert_handle()); - - scoped_refptr<X509Certificate> google_full_chain = - X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), - intermediates); - - CertVerifyResult verify_result; - int error = Verify(google_full_chain, "www.google.com", 0, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - - // First test blocking by SPKI. - base::StringPiece crl_set_bytes( - reinterpret_cast<const char*>(kCRLSetThawteSPKIBlocked), - sizeof(kCRLSetThawteSPKIBlocked)); - scoped_refptr<CRLSet> crl_set; - ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); - - error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(), - empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_REVOKED, error); - - // Second, test revocation by serial number of a cert directly under the - // root. - crl_set_bytes = base::StringPiece( - reinterpret_cast<const char*>(kCRLSetThawteSerialBlocked), - sizeof(kCRLSetThawteSerialBlocked)); - ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); - - error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(), - empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_REVOKED, error); - - // Lastly, test revocation by serial number of a certificate not under the - // root. - crl_set_bytes = base::StringPiece( - reinterpret_cast<const char*>(kCRLSetGoogleSerialBlocked), - sizeof(kCRLSetGoogleSerialBlocked)); - ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); - - error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(), - empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_REVOKED, error); -} -#endif - -struct WeakDigestTestData { - const char* root_cert_filename; - const char* intermediate_cert_filename; - const char* ee_cert_filename; - bool expected_has_md5; - bool expected_has_md4; - bool expected_has_md2; - bool expected_has_md5_ca; - bool expected_has_md2_ca; -}; - -// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how -// to output the parameter that was passed. Without this, it will simply -// attempt to print out the first twenty bytes of the object, which depending -// on platform and alignment, may result in an invalid read. -void PrintTo(const WeakDigestTestData& data, std::ostream* os) { - *os << "root: " - << (data.root_cert_filename ? data.root_cert_filename : "none") - << "; intermediate: " << data.intermediate_cert_filename - << "; end-entity: " << data.ee_cert_filename; -} - -class CertVerifyProcWeakDigestTest - : public CertVerifyProcTest, - public testing::WithParamInterface<WeakDigestTestData> { - public: - CertVerifyProcWeakDigestTest() {} - virtual ~CertVerifyProcWeakDigestTest() {} -}; - -TEST_P(CertVerifyProcWeakDigestTest, Verify) { - WeakDigestTestData data = GetParam(); - base::FilePath certs_dir = GetTestCertsDirectory(); - - ScopedTestRoot test_root; - 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); - test_root.Reset(root_cert); - } - - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, data.intermediate_cert_filename); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - scoped_refptr<X509Certificate> ee_cert = - ImportCertFromFile(certs_dir, data.ee_cert_filename); - ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - - scoped_refptr<X509Certificate> ee_chain = - X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), - intermediates); - ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain); - - int flags = 0; - CertVerifyResult verify_result; - int rv = Verify(ee_chain, "127.0.0.1", flags, NULL, - empty_cert_list_, &verify_result); - EXPECT_EQ(data.expected_has_md5, verify_result.has_md5); - EXPECT_EQ(data.expected_has_md4, verify_result.has_md4); - EXPECT_EQ(data.expected_has_md2, verify_result.has_md2); - EXPECT_EQ(data.expected_has_md5_ca, verify_result.has_md5_ca); - EXPECT_EQ(data.expected_has_md2_ca, verify_result.has_md2_ca); - EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); - - // Ensure that MD4 and MD2 are tagged as invalid. - if (data.expected_has_md4 || data.expected_has_md2) { - EXPECT_EQ(CERT_STATUS_INVALID, - verify_result.cert_status & CERT_STATUS_INVALID); - } - - // Ensure that MD5 is flagged as weak. - if (data.expected_has_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_has_md4 || data.expected_has_md2) { - EXPECT_EQ(ERR_CERT_INVALID, rv); - } else if (data.expected_has_md5) { - EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv); - } else { - EXPECT_EQ(OK, rv); - } - } -} - -// Unlike TEST/TEST_F, which are macros that expand to further macros, -// INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that -// stringizes the arguments. As a result, macros passed as parameters (such as -// prefix or test_case_name) will not be expanded by the preprocessor. To work -// around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the -// pre-processor will expand macros such as MAYBE_test_name before -// instantiating the test. -#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ - INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) - -// The signature algorithm of the root CA should not matter. -const WeakDigestTestData kVerifyRootCATestData[] = { - { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_sha1_ee.pem", false, false, false, false, false }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_sha1_ee.pem", false, false, false, false, false }, -#endif - { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_sha1_ee.pem", false, false, false, false, false }, -}; -INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyRootCATestData)); - -// The signature algorithm of intermediates should be properly detected. -const WeakDigestTestData kVerifyIntermediateCATestData[] = { - { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", - "weak_digest_sha1_ee.pem", true, false, false, true, false }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", - "weak_digest_sha1_ee.pem", false, true, false, false, false }, -#endif - { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", - "weak_digest_sha1_ee.pem", false, false, true, false, true }, -}; -// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled. -#if defined(USE_NSS) || defined(OS_IOS) -#define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate -#else -#define MAYBE_VerifyIntermediate VerifyIntermediate -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_VerifyIntermediate, - CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyIntermediateCATestData)); - -// The signature algorithm of end-entity should be properly detected. -const WeakDigestTestData kVerifyEndEntityTestData[] = { - { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_md5_ee.pem", true, false, false, false, false }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_md4_ee.pem", false, true, false, false, false }, -#endif - { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", - "weak_digest_md2_ee.pem", false, false, true, false, false }, -}; -// Disabled on NSS - NSS caches chains/signatures in such a way that cannot -// be cleared until NSS is cleanly shutdown, which is not presently supported -// in Chromium. -#if defined(USE_NSS) || defined(OS_IOS) -#define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity -#else -#define MAYBE_VerifyEndEntity VerifyEndEntity -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity, - CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyEndEntityTestData)); - -// Incomplete chains should still report the status of the intermediate. -const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = { - { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem", - true, false, false, true, false }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem", - false, true, false, false, false }, -#endif - { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem", - false, false, true, false, true }, -}; -// Disabled on NSS - libpkix does not return constructed chains on error, -// preventing us from detecting/inspecting the verified chain. -#if defined(USE_NSS) || defined(OS_IOS) -#define MAYBE_VerifyIncompleteIntermediate \ - DISABLED_VerifyIncompleteIntermediate -#else -#define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_VerifyIncompleteIntermediate, - CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyIncompleteIntermediateTestData)); - -// Incomplete chains should still report the status of the end-entity. -const WeakDigestTestData kVerifyIncompleteEETestData[] = { - { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem", - true, false, false, false, false }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem", - false, true, false, false, false }, -#endif - { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem", - false, false, true, false, false }, -}; -// Disabled on NSS - libpkix does not return constructed chains on error, -// preventing us from detecting/inspecting the verified chain. -#if defined(USE_NSS) || defined(OS_IOS) -#define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity -#else -#define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_VerifyIncompleteEndEntity, - CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyIncompleteEETestData)); - -// Differing algorithms between the intermediate and the EE should still be -// reported. -const WeakDigestTestData kVerifyMixedTestData[] = { - { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", - "weak_digest_md2_ee.pem", true, false, true, true, false }, - { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", - "weak_digest_md5_ee.pem", true, false, true, false, true }, -#if defined(USE_OPENSSL) || defined(OS_WIN) - // MD4 is not supported by OS X / NSS - { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", - "weak_digest_md2_ee.pem", false, true, true, false, false }, -#endif -}; -// NSS does not support MD4 and does not enable MD2 by default, making all -// permutations invalid. -#if defined(USE_NSS) || defined(OS_IOS) -#define MAYBE_VerifyMixed DISABLED_VerifyMixed -#else -#define MAYBE_VerifyMixed VerifyMixed -#endif -WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_VerifyMixed, - CertVerifyProcWeakDigestTest, - testing::ValuesIn(kVerifyMixedTestData)); - -} // namespace net diff --git a/net/base/cert_verify_proc_win.cc b/net/base/cert_verify_proc_win.cc deleted file mode 100644 index 5a1de37..0000000 --- a/net/base/cert_verify_proc_win.cc +++ /dev/null @@ -1,755 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_proc_win.h" - -#include <string> -#include <vector> - -#include "base/memory/scoped_ptr.h" -#include "base/sha1.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "crypto/capi_util.h" -#include "crypto/scoped_capi_types.h" -#include "crypto/sha2.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crl_set.h" -#include "net/base/ev_root_ca_metadata.h" -#include "net/base/net_errors.h" -#include "net/base/test_root_certs.h" -#include "net/base/x509_certificate.h" -#include "net/base/x509_certificate_known_roots_win.h" - -#pragma comment(lib, "crypt32.lib") - -#if !defined(CERT_TRUST_HAS_WEAK_SIGNATURE) -// This was introduced in Windows 8 / Windows Server 2012, but retroactively -// ported as far back as Windows XP via system update. -#define CERT_TRUST_HAS_WEAK_SIGNATURE 0x00100000 -#endif - -namespace net { - -namespace { - -struct FreeChainEngineFunctor { - void operator()(HCERTCHAINENGINE engine) const { - if (engine) - CertFreeCertificateChainEngine(engine); - } -}; - -struct FreeCertChainContextFunctor { - void operator()(PCCERT_CHAIN_CONTEXT chain_context) const { - if (chain_context) - CertFreeCertificateChain(chain_context); - } -}; - -struct FreeCertContextFunctor { - void operator()(PCCERT_CONTEXT context) const { - if (context) - CertFreeCertificateContext(context); - } -}; - -typedef crypto::ScopedCAPIHandle<HCERTCHAINENGINE, FreeChainEngineFunctor> - ScopedHCERTCHAINENGINE; - -typedef scoped_ptr_malloc<const CERT_CHAIN_CONTEXT, - FreeCertChainContextFunctor> - ScopedPCCERT_CHAIN_CONTEXT; - -typedef scoped_ptr_malloc<const CERT_CONTEXT, - FreeCertContextFunctor> ScopedPCCERT_CONTEXT; - -//----------------------------------------------------------------------------- - -int MapSecurityError(SECURITY_STATUS err) { - // There are numerous security error codes, but these are the ones we thus - // far find interesting. - switch (err) { - case SEC_E_WRONG_PRINCIPAL: // Schannel - case CERT_E_CN_NO_MATCH: // CryptoAPI - return ERR_CERT_COMMON_NAME_INVALID; - case SEC_E_UNTRUSTED_ROOT: // Schannel - case CERT_E_UNTRUSTEDROOT: // CryptoAPI - return ERR_CERT_AUTHORITY_INVALID; - case SEC_E_CERT_EXPIRED: // Schannel - case CERT_E_EXPIRED: // CryptoAPI - return ERR_CERT_DATE_INVALID; - case CRYPT_E_NO_REVOCATION_CHECK: - return ERR_CERT_NO_REVOCATION_MECHANISM; - case CRYPT_E_REVOCATION_OFFLINE: - return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; - case CRYPT_E_REVOKED: // Schannel and CryptoAPI - return ERR_CERT_REVOKED; - case SEC_E_CERT_UNKNOWN: - case CERT_E_ROLE: - return ERR_CERT_INVALID; - case CERT_E_WRONG_USAGE: - // TODO(wtc): Should we add ERR_CERT_WRONG_USAGE? - return ERR_CERT_INVALID; - // We received an unexpected_message or illegal_parameter alert message - // from the server. - case SEC_E_ILLEGAL_MESSAGE: - return ERR_SSL_PROTOCOL_ERROR; - case SEC_E_ALGORITHM_MISMATCH: - return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; - case SEC_E_INVALID_HANDLE: - return ERR_UNEXPECTED; - case SEC_E_OK: - return OK; - default: - LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; - return ERR_FAILED; - } -} - -// Map the errors in the chain_context->TrustStatus.dwErrorStatus returned by -// CertGetCertificateChain to our certificate status flags. -int MapCertChainErrorStatusToCertStatus(DWORD error_status) { - CertStatus cert_status = 0; - - // We don't include CERT_TRUST_IS_NOT_TIME_NESTED because it's obsolete and - // we wouldn't consider it an error anyway - const DWORD kDateInvalidErrors = CERT_TRUST_IS_NOT_TIME_VALID | - CERT_TRUST_CTL_IS_NOT_TIME_VALID; - if (error_status & kDateInvalidErrors) - cert_status |= CERT_STATUS_DATE_INVALID; - - const DWORD kAuthorityInvalidErrors = CERT_TRUST_IS_UNTRUSTED_ROOT | - CERT_TRUST_IS_EXPLICIT_DISTRUST | - CERT_TRUST_IS_PARTIAL_CHAIN; - if (error_status & kAuthorityInvalidErrors) - cert_status |= CERT_STATUS_AUTHORITY_INVALID; - - if ((error_status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) && - !(error_status & CERT_TRUST_IS_OFFLINE_REVOCATION)) - cert_status |= CERT_STATUS_NO_REVOCATION_MECHANISM; - - if (error_status & CERT_TRUST_IS_OFFLINE_REVOCATION) - cert_status |= CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; - - if (error_status & CERT_TRUST_IS_REVOKED) - cert_status |= CERT_STATUS_REVOKED; - - const DWORD kWrongUsageErrors = CERT_TRUST_IS_NOT_VALID_FOR_USAGE | - CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE; - if (error_status & kWrongUsageErrors) { - // TODO(wtc): Should we add CERT_STATUS_WRONG_USAGE? - cert_status |= CERT_STATUS_INVALID; - } - - if (error_status & CERT_TRUST_IS_NOT_SIGNATURE_VALID) { - // Check for a signature that does not meet the OS criteria for strong - // signatures. - // Note: These checks may be more restrictive than the current weak key - // criteria implemented within CertVerifier, such as excluding SHA-1 or - // excluding RSA keys < 2048 bits. However, if the user has configured - // these more stringent checks, respect that configuration and err on the - // more restrictive criteria. - if (error_status & CERT_TRUST_HAS_WEAK_SIGNATURE) { - cert_status |= CERT_STATUS_WEAK_KEY; - } else { - cert_status |= CERT_STATUS_INVALID; - } - } - - // The rest of the errors. - const DWORD kCertInvalidErrors = - CERT_TRUST_IS_CYCLIC | - CERT_TRUST_INVALID_EXTENSION | - CERT_TRUST_INVALID_POLICY_CONSTRAINTS | - CERT_TRUST_INVALID_BASIC_CONSTRAINTS | - CERT_TRUST_INVALID_NAME_CONSTRAINTS | - CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID | - CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT | - CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | - CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT | - CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT | - CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY | - CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT; - if (error_status & kCertInvalidErrors) - cert_status |= CERT_STATUS_INVALID; - - return cert_status; -} - -// Returns true if any common name in the certificate's Subject field contains -// a NULL character. -bool CertSubjectCommonNameHasNull(PCCERT_CONTEXT cert) { - CRYPT_DECODE_PARA decode_para; - decode_para.cbSize = sizeof(decode_para); - decode_para.pfnAlloc = crypto::CryptAlloc; - decode_para.pfnFree = crypto::CryptFree; - CERT_NAME_INFO* name_info = NULL; - DWORD name_info_size = 0; - BOOL rv; - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - X509_NAME, - cert->pCertInfo->Subject.pbData, - cert->pCertInfo->Subject.cbData, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &name_info, - &name_info_size); - if (rv) { - scoped_ptr_malloc<CERT_NAME_INFO> scoped_name_info(name_info); - - // The Subject field may have multiple common names. According to the - // "PKI Layer Cake" paper, CryptoAPI uses every common name in the - // Subject field, so we inspect every common name. - // - // From RFC 5280: - // X520CommonName ::= CHOICE { - // teletexString TeletexString (SIZE (1..ub-common-name)), - // printableString PrintableString (SIZE (1..ub-common-name)), - // universalString UniversalString (SIZE (1..ub-common-name)), - // utf8String UTF8String (SIZE (1..ub-common-name)), - // bmpString BMPString (SIZE (1..ub-common-name)) } - // - // We also check IA5String and VisibleString. - for (DWORD i = 0; i < name_info->cRDN; ++i) { - PCERT_RDN rdn = &name_info->rgRDN[i]; - for (DWORD j = 0; j < rdn->cRDNAttr; ++j) { - PCERT_RDN_ATTR rdn_attr = &rdn->rgRDNAttr[j]; - if (strcmp(rdn_attr->pszObjId, szOID_COMMON_NAME) == 0) { - switch (rdn_attr->dwValueType) { - // After the CryptoAPI ASN.1 security vulnerabilities described in - // http://www.microsoft.com/technet/security/Bulletin/MS09-056.mspx - // were patched, we get CERT_RDN_ENCODED_BLOB for a common name - // that contains a NULL character. - case CERT_RDN_ENCODED_BLOB: - break; - // Array of 8-bit characters. - case CERT_RDN_PRINTABLE_STRING: - case CERT_RDN_TELETEX_STRING: - case CERT_RDN_IA5_STRING: - case CERT_RDN_VISIBLE_STRING: - for (DWORD k = 0; k < rdn_attr->Value.cbData; ++k) { - if (rdn_attr->Value.pbData[k] == '\0') - return true; - } - break; - // Array of 16-bit characters. - case CERT_RDN_BMP_STRING: - case CERT_RDN_UTF8_STRING: { - DWORD num_wchars = rdn_attr->Value.cbData / 2; - wchar_t* common_name = - reinterpret_cast<wchar_t*>(rdn_attr->Value.pbData); - for (DWORD k = 0; k < num_wchars; ++k) { - if (common_name[k] == L'\0') - return true; - } - break; - } - // Array of ints (32-bit). - case CERT_RDN_UNIVERSAL_STRING: { - DWORD num_ints = rdn_attr->Value.cbData / 4; - int* common_name = - reinterpret_cast<int*>(rdn_attr->Value.pbData); - for (DWORD k = 0; k < num_ints; ++k) { - if (common_name[k] == 0) - return true; - } - break; - } - default: - NOTREACHED(); - break; - } - } - } - } - } - return false; -} - -// IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA -// which we recognise as a standard root. -// static -bool IsIssuedByKnownRoot(PCCERT_CHAIN_CONTEXT chain_context) { - PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0]; - int num_elements = first_chain->cElement; - if (num_elements < 1) - return false; - PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; - PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext; - - SHA1HashValue hash = X509Certificate::CalculateFingerprint(cert); - return IsSHA1HashInSortedArray( - hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes)); -} - -// Saves some information about the certificate chain |chain_context| in -// |*verify_result|. The caller MUST initialize |*verify_result| before -// calling this function. -void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context, - CertVerifyResult* verify_result) { - if (chain_context->cChain == 0) - return; - - PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0]; - int num_elements = first_chain->cElement; - PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; - - PCCERT_CONTEXT verified_cert = NULL; - std::vector<PCCERT_CONTEXT> verified_chain; - - bool has_root_ca = num_elements > 1 && - !(chain_context->TrustStatus.dwErrorStatus & - CERT_TRUST_IS_PARTIAL_CHAIN); - - // Each chain starts with the end entity certificate (i = 0) and ends with - // either the root CA certificate or the last available intermediate. If a - // root CA certificate is present, do not inspect the signature algorithm of - // the root CA certificate because the signature on the trust anchor is not - // important. - if (has_root_ca) { - // If a full chain was constructed, regardless of whether it was trusted, - // don't inspect the root's signature algorithm. - num_elements -= 1; - } - - for (int i = 0; i < num_elements; ++i) { - PCCERT_CONTEXT cert = element[i]->pCertContext; - if (i == 0) { - verified_cert = cert; - } else { - verified_chain.push_back(cert); - } - - const char* algorithm = cert->pCertInfo->SignatureAlgorithm.pszObjId; - if (strcmp(algorithm, szOID_RSA_MD5RSA) == 0) { - // md5WithRSAEncryption: 1.2.840.113549.1.1.4 - verify_result->has_md5 = true; - if (i != 0) - verify_result->has_md5_ca = true; - } else if (strcmp(algorithm, szOID_RSA_MD2RSA) == 0) { - // md2WithRSAEncryption: 1.2.840.113549.1.1.2 - verify_result->has_md2 = true; - if (i != 0) - verify_result->has_md2_ca = true; - } else if (strcmp(algorithm, szOID_RSA_MD4RSA) == 0) { - // md4WithRSAEncryption: 1.2.840.113549.1.1.3 - verify_result->has_md4 = true; - } - } - - if (verified_cert) { - // Add the root certificate, if present, as it was not added above. - if (has_root_ca) - verified_chain.push_back(element[num_elements]->pCertContext); - verify_result->verified_cert = - X509Certificate::CreateFromHandle(verified_cert, verified_chain); - } -} - -// Decodes the cert's certificatePolicies extension into a CERT_POLICIES_INFO -// structure and stores it in *output. -void GetCertPoliciesInfo(PCCERT_CONTEXT cert, - scoped_ptr_malloc<CERT_POLICIES_INFO>* output) { - PCERT_EXTENSION extension = CertFindExtension(szOID_CERT_POLICIES, - cert->pCertInfo->cExtension, - cert->pCertInfo->rgExtension); - if (!extension) - return; - - CRYPT_DECODE_PARA decode_para; - decode_para.cbSize = sizeof(decode_para); - decode_para.pfnAlloc = crypto::CryptAlloc; - decode_para.pfnFree = crypto::CryptFree; - CERT_POLICIES_INFO* policies_info = NULL; - DWORD policies_info_size = 0; - BOOL rv; - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_CERT_POLICIES, - extension->Value.pbData, - extension->Value.cbData, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &policies_info, - &policies_info_size); - if (rv) - output->reset(policies_info); -} - -bool CheckRevocationWithCRLSet(PCCERT_CHAIN_CONTEXT chain, - CRLSet* crl_set) { - if (chain->cChain == 0) - return true; - - const PCERT_SIMPLE_CHAIN first_chain = chain->rgpChain[0]; - const PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; - - const int num_elements = first_chain->cElement; - if (num_elements == 0) - return true; - - // We iterate from the root certificate down to the leaf, keeping track of - // the issuer's SPKI at each step. - std::string issuer_spki_hash; - for (int i = num_elements - 1; i >= 0; i--) { - PCCERT_CONTEXT cert = element[i]->pCertContext; - - base::StringPiece der_bytes( - reinterpret_cast<const char*>(cert->pbCertEncoded), - cert->cbCertEncoded); - - base::StringPiece spki; - if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) { - NOTREACHED(); - continue; - } - - const std::string spki_hash = crypto::SHA256HashString(spki); - - const CRYPT_INTEGER_BLOB* serial_blob = &cert->pCertInfo->SerialNumber; - scoped_array<uint8> serial_bytes(new uint8[serial_blob->cbData]); - // The bytes of the serial number are stored little-endian. - for (unsigned j = 0; j < serial_blob->cbData; j++) - serial_bytes[j] = serial_blob->pbData[serial_blob->cbData - j - 1]; - base::StringPiece serial(reinterpret_cast<const char*>(serial_bytes.get()), - serial_blob->cbData); - - CRLSet::Result result = crl_set->CheckSPKI(spki_hash); - - if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) - result = crl_set->CheckSerial(serial, issuer_spki_hash); - - issuer_spki_hash = spki_hash; - - switch (result) { - case CRLSet::REVOKED: - return false; - case CRLSet::UNKNOWN: - case CRLSet::GOOD: - continue; - default: - NOTREACHED(); - continue; - } - } - - return true; -} - -void AppendPublicKeyHashes(PCCERT_CHAIN_CONTEXT chain, - HashValueVector* hashes) { - if (chain->cChain == 0) - return; - - PCERT_SIMPLE_CHAIN first_chain = chain->rgpChain[0]; - PCERT_CHAIN_ELEMENT* const element = first_chain->rgpElement; - - const DWORD num_elements = first_chain->cElement; - for (DWORD i = 0; i < num_elements; i++) { - PCCERT_CONTEXT cert = element[i]->pCertContext; - - base::StringPiece der_bytes( - reinterpret_cast<const char*>(cert->pbCertEncoded), - cert->cbCertEncoded); - base::StringPiece spki_bytes; - if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) - continue; - - HashValue sha1(HASH_VALUE_SHA1); - base::SHA1HashBytes(reinterpret_cast<const uint8*>(spki_bytes.data()), - spki_bytes.size(), sha1.data()); - hashes->push_back(sha1); - - HashValue sha256(HASH_VALUE_SHA256); - crypto::SHA256HashString(spki_bytes, sha1.data(), crypto::kSHA256Length); - hashes->push_back(sha256); - } -} - -// Returns true if the certificate is an extended-validation certificate. -// -// This function checks the certificatePolicies extensions of the -// certificates in the certificate chain according to Section 7 (pp. 11-12) -// of the EV Certificate Guidelines Version 1.0 at -// http://cabforum.org/EV_Certificate_Guidelines.pdf. -bool CheckEV(PCCERT_CHAIN_CONTEXT chain_context, - bool rev_checking_enabled, - const char* policy_oid) { - DCHECK_NE(static_cast<DWORD>(0), chain_context->cChain); - // If the cert doesn't match any of the policies, the - // CERT_TRUST_IS_NOT_VALID_FOR_USAGE bit (0x10) in - // chain_context->TrustStatus.dwErrorStatus is set. - DWORD error_status = chain_context->TrustStatus.dwErrorStatus; - - if (!rev_checking_enabled) { - // If online revocation checking is disabled then we will have still - // requested that the revocation cache be checked. However, that will often - // cause the following two error bits to be set. These error bits mean that - // the local OCSP/CRL is stale or missing entries for these certificates. - // Since they are expected, we mask them away. - error_status &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | - CERT_TRUST_REVOCATION_STATUS_UNKNOWN); - } - if (!chain_context->cChain || error_status != CERT_TRUST_NO_ERROR) - return false; - - // Check the end certificate simple chain (chain_context->rgpChain[0]). - // If the end certificate's certificatePolicies extension contains the - // EV policy OID of the root CA, return true. - PCERT_CHAIN_ELEMENT* element = chain_context->rgpChain[0]->rgpElement; - int num_elements = chain_context->rgpChain[0]->cElement; - if (num_elements < 2) - return false; - - // Look up the EV policy OID of the root CA. - PCCERT_CONTEXT root_cert = element[num_elements - 1]->pCertContext; - SHA1HashValue fingerprint = - X509Certificate::CalculateFingerprint(root_cert); - EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); - return metadata->HasEVPolicyOID(fingerprint, policy_oid); -} - -} // namespace - -CertVerifyProcWin::CertVerifyProcWin() {} - -CertVerifyProcWin::~CertVerifyProcWin() {} - -bool CertVerifyProcWin::SupportsAdditionalTrustAnchors() const { - return false; -} - -int CertVerifyProcWin::VerifyInternal( - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) { - PCCERT_CONTEXT cert_handle = cert->os_cert_handle(); - if (!cert_handle) - return ERR_UNEXPECTED; - - // Build and validate certificate chain. - CERT_CHAIN_PARA chain_para; - memset(&chain_para, 0, sizeof(chain_para)); - chain_para.cbSize = sizeof(chain_para); - // ExtendedKeyUsage. - // We still need to request szOID_SERVER_GATED_CRYPTO and szOID_SGC_NETSCAPE - // today because some certificate chains need them. IE also requests these - // two usages. - static const LPSTR usage[] = { - szOID_PKIX_KP_SERVER_AUTH, - szOID_SERVER_GATED_CRYPTO, - szOID_SGC_NETSCAPE - }; - chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; - chain_para.RequestedUsage.Usage.cUsageIdentifier = arraysize(usage); - chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = - const_cast<LPSTR*>(usage); - - // Get the certificatePolicies extension of the certificate. - scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; - LPSTR ev_policy_oid = NULL; - if (flags & CertVerifier::VERIFY_EV_CERT) { - GetCertPoliciesInfo(cert_handle, &policies_info); - if (policies_info.get()) { - EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); - for (DWORD i = 0; i < policies_info->cPolicyInfo; ++i) { - LPSTR policy_oid = policies_info->rgPolicyInfo[i].pszPolicyIdentifier; - if (metadata->IsEVPolicyOID(policy_oid)) { - ev_policy_oid = policy_oid; - chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_AND; - chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 1; - chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = - &ev_policy_oid; - break; - } - } - } - } - - // We can set CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS to get more chains. - DWORD chain_flags = CERT_CHAIN_CACHE_END_CERT | - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; - const bool rev_checking_enabled = - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) || - (ev_policy_oid != NULL && - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY)); - - if (rev_checking_enabled) { - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - } else { - chain_flags |= CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; - } - - // For non-test scenarios, use the default HCERTCHAINENGINE, NULL, which - // corresponds to HCCE_CURRENT_USER and is is initialized as needed by - // crypt32. However, when testing, it is necessary to create a new - // HCERTCHAINENGINE and use that instead. This is because each - // HCERTCHAINENGINE maintains a cache of information about certificates - // encountered, and each test run may modify the trust status of a - // certificate. - ScopedHCERTCHAINENGINE chain_engine(NULL); - if (TestRootCerts::HasInstance()) - chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); - - ScopedPCCERT_CONTEXT cert_list(cert->CreateOSCertChainForCert()); - PCCERT_CHAIN_CONTEXT chain_context; - // IE passes a non-NULL pTime argument that specifies the current system - // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the - // chain_flags argument. - if (!CertGetCertificateChain( - chain_engine, - cert_list.get(), - NULL, // current system time - cert_list->hCertStore, - &chain_para, - chain_flags, - NULL, // reserved - &chain_context)) { - verify_result->cert_status |= CERT_STATUS_INVALID; - return MapSecurityError(GetLastError()); - } - - if (chain_context->TrustStatus.dwErrorStatus & - CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { - ev_policy_oid = NULL; - chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 0; - chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL; - CertFreeCertificateChain(chain_context); - if (!CertGetCertificateChain( - chain_engine, - cert_list.get(), - NULL, // current system time - cert_list->hCertStore, - &chain_para, - chain_flags, - NULL, // reserved - &chain_context)) { - verify_result->cert_status |= CERT_STATUS_INVALID; - return MapSecurityError(GetLastError()); - } - } - - ScopedPCCERT_CHAIN_CONTEXT scoped_chain_context(chain_context); - - GetCertChainInfo(chain_context, verify_result); - verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( - chain_context->TrustStatus.dwErrorStatus); - - // Flag certificates that have a Subject common name with a NULL character. - if (CertSubjectCommonNameHasNull(cert_handle)) - verify_result->cert_status |= CERT_STATUS_INVALID; - - if (crl_set && !CheckRevocationWithCRLSet(chain_context, crl_set)) - verify_result->cert_status |= CERT_STATUS_REVOKED; - - std::wstring wstr_hostname = ASCIIToWide(hostname); - - SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para; - memset(&extra_policy_para, 0, sizeof(extra_policy_para)); - extra_policy_para.cbSize = sizeof(extra_policy_para); - extra_policy_para.dwAuthType = AUTHTYPE_SERVER; - extra_policy_para.fdwChecks = 0; - extra_policy_para.pwszServerName = - const_cast<wchar_t*>(wstr_hostname.c_str()); - - CERT_CHAIN_POLICY_PARA policy_para; - memset(&policy_para, 0, sizeof(policy_para)); - policy_para.cbSize = sizeof(policy_para); - policy_para.dwFlags = 0; - policy_para.pvExtraPolicyPara = &extra_policy_para; - - CERT_CHAIN_POLICY_STATUS policy_status; - memset(&policy_status, 0, sizeof(policy_status)); - policy_status.cbSize = sizeof(policy_status); - - if (!CertVerifyCertificateChainPolicy( - CERT_CHAIN_POLICY_SSL, - chain_context, - &policy_para, - &policy_status)) { - return MapSecurityError(GetLastError()); - } - - if (policy_status.dwError) { - verify_result->cert_status |= MapNetErrorToCertStatus( - MapSecurityError(policy_status.dwError)); - - // CertVerifyCertificateChainPolicy reports only one error (in - // policy_status.dwError) if the certificate has multiple errors. - // CertGetCertificateChain doesn't report certificate name mismatch, so - // CertVerifyCertificateChainPolicy is the only function that can report - // certificate name mismatch. - // - // To prevent a potential certificate name mismatch from being hidden by - // some other certificate error, if we get any other certificate error, - // we call CertVerifyCertificateChainPolicy again, ignoring all other - // certificate errors. Both extra_policy_para.fdwChecks and - // policy_para.dwFlags allow us to ignore certificate errors, so we set - // them both. - if (policy_status.dwError != CERT_E_CN_NO_MATCH) { - const DWORD extra_ignore_flags = - 0x00000080 | // SECURITY_FLAG_IGNORE_REVOCATION - 0x00000100 | // SECURITY_FLAG_IGNORE_UNKNOWN_CA - 0x00002000 | // SECURITY_FLAG_IGNORE_CERT_DATE_INVALID - 0x00000200; // SECURITY_FLAG_IGNORE_WRONG_USAGE - extra_policy_para.fdwChecks = extra_ignore_flags; - const DWORD ignore_flags = - CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS | - CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG | - CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG | - CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG | - CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG | - CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG | - CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS | - CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG | - CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG | - CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG | - CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG; - policy_para.dwFlags = ignore_flags; - if (!CertVerifyCertificateChainPolicy( - CERT_CHAIN_POLICY_SSL, - chain_context, - &policy_para, - &policy_status)) { - return MapSecurityError(GetLastError()); - } - if (policy_status.dwError) { - verify_result->cert_status |= MapNetErrorToCertStatus( - MapSecurityError(policy_status.dwError)); - } - } - } - - // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be - // compatible with WinHTTP, which doesn't report this error (bug 3004). - verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; - - if (!rev_checking_enabled) { - // If we didn't do online revocation checking then Windows will report - // CERT_UNABLE_TO_CHECK_REVOCATION unless it had cached OCSP or CRL - // information for every certificate. We only want to put up revoked - // statuses from the offline checks so we squash this error. - verify_result->cert_status &= ~CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; - } - - AppendPublicKeyHashes(chain_context, &verify_result->public_key_hashes); - verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(chain_context); - - if (IsCertStatusError(verify_result->cert_status)) - return MapCertStatusToNetError(verify_result->cert_status); - - if (ev_policy_oid && - CheckEV(chain_context, rev_checking_enabled, ev_policy_oid)) { - verify_result->cert_status |= CERT_STATUS_IS_EV; - } - return OK; -} - -} // namespace net diff --git a/net/base/cert_verify_proc_win.h b/net/base/cert_verify_proc_win.h deleted file mode 100644 index 1db81db..0000000 --- a/net/base/cert_verify_proc_win.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_PROC_WIN_H_ -#define NET_BASE_CERT_VERIFY_PROC_WIN_H_ - -#include "net/base/cert_verify_proc.h" - -namespace net { - -// Performs certificate path construction and validation using Windows' -// CryptoAPI. -class CertVerifyProcWin : public CertVerifyProc { - public: - CertVerifyProcWin(); - - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE; - - protected: - virtual ~CertVerifyProcWin(); - - private: - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_PROC_WIN_H_ diff --git a/net/base/cert_verify_result.cc b/net/base/cert_verify_result.cc deleted file mode 100644 index 028011ee..0000000 --- a/net/base/cert_verify_result.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/cert_verify_result.h" - -#include "net/base/x509_certificate.h" - -namespace net { - -CertVerifyResult::CertVerifyResult() { - Reset(); -} - -CertVerifyResult::~CertVerifyResult() { -} - -void CertVerifyResult::Reset() { - verified_cert = NULL; - cert_status = 0; - has_md5 = false; - has_md2 = false; - has_md4 = false; - has_md5_ca = false; - has_md2_ca = false; - is_issued_by_known_root = false; - is_issued_by_additional_trust_anchor = false; - - public_key_hashes.clear(); -} - -} // namespace net diff --git a/net/base/cert_verify_result.h b/net/base/cert_verify_result.h deleted file mode 100644 index 8758d01..0000000 --- a/net/base/cert_verify_result.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CERT_VERIFY_RESULT_H_ -#define NET_BASE_CERT_VERIFY_RESULT_H_ - -#include <vector> - -#include "net/base/cert_status_flags.h" -#include "net/base/net_export.h" -#include "base/memory/ref_counted.h" -#include "net/base/x509_cert_types.h" - -namespace net { - -class X509Certificate; - -// The result of certificate verification. -class NET_EXPORT CertVerifyResult { - public: - CertVerifyResult(); - ~CertVerifyResult(); - - void Reset(); - - // The certificate and chain that was constructed during verification. - // Note that the though the verified certificate will match the originally - // supplied certificate, the intermediate certificates stored within may - // be substantially different. In the event of a verification failure, this - // will contain the chain as supplied by the server. This may be NULL if - // running within the sandbox. - scoped_refptr<X509Certificate> verified_cert; - - // Bitmask of CERT_STATUS_* from net/base/cert_status_flags.h. Note that - // these status flags apply to the certificate chain returned in - // |verified_cert|, rather than the originally supplied certificate - // chain. - CertStatus cert_status; - - // Properties of the certificate chain. - bool has_md5; - bool has_md2; - bool has_md4; - bool has_md5_ca; - bool has_md2_ca; - - // If the certificate was successfully verified then this contains the - // hashes, in several hash algorithms, of the SubjectPublicKeyInfos of the - // chain. - HashValueVector public_key_hashes; - - // is_issued_by_known_root is true if we recognise the root CA as a standard - // root. If it isn't then it's probably the case that this certificate was - // generated by a MITM proxy whose root has been installed locally. This is - // meaningless if the certificate was not trusted. - bool is_issued_by_known_root; - - // is_issued_by_additional_trust_anchor is true if the root CA used for this - // verification came from the list of additional trust anchors. - bool is_issued_by_additional_trust_anchor; -}; - -} // namespace net - -#endif // NET_BASE_CERT_VERIFY_RESULT_H_ diff --git a/net/base/crl_set.cc b/net/base/crl_set.cc deleted file mode 100644 index 735bb5e..0000000 --- a/net/base/crl_set.cc +++ /dev/null @@ -1,593 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/base64.h" -#include "base/format_macros.h" -#include "base/json/json_reader.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/string_util.h" -#include "base/stringprintf.h" -#include "base/time.h" -#include "base/values.h" -#include "crypto/sha2.h" -#include "net/base/crl_set.h" -#include "third_party/zlib/zlib.h" - -namespace net { - -// Decompress zlib decompressed |in| into |out|. |out_len| is the number of -// bytes at |out| and must be exactly equal to the size of the decompressed -// data. -static bool DecompressZlib(uint8* out, int out_len, base::StringPiece in) { - z_stream z; - memset(&z, 0, sizeof(z)); - - z.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(in.data())); - z.avail_in = in.size(); - z.next_out = reinterpret_cast<Bytef*>(out); - z.avail_out = out_len; - - if (inflateInit(&z) != Z_OK) - return false; - bool ret = false; - int r = inflate(&z, Z_FINISH); - if (r != Z_STREAM_END) - goto err; - if (z.avail_in || z.avail_out) - goto err; - ret = true; - - err: - inflateEnd(&z); - return ret; -} - -CRLSet::CRLSet() - : sequence_(0), - not_after_(0) { -} - -CRLSet::~CRLSet() { -} - -// CRLSet format: -// -// uint16le header_len -// byte[header_len] header_bytes -// repeated { -// byte[32] parent_spki_sha256 -// uint32le num_serials -// [num_serials] { -// uint8 serial_length; -// byte[serial_length] serial; -// } -// -// header_bytes consists of a JSON dictionary with the following keys: -// Version (int): currently 0 -// ContentType (string): "CRLSet" or "CRLSetDelta" (magic value) -// DeltaFrom (int32): if this is a delta update (see below), then this -// contains the sequence number of the base CRLSet. -// Sequence (int32): the monotonic sequence number of this CRL set. -// -// A delta CRLSet is similar to a CRLSet: -// -// struct CompressedChanges { -// uint32le uncompressed_size -// uint32le compressed_size -// byte[compressed_size] zlib_data -// } -// -// uint16le header_len -// byte[header_len] header_bytes -// CompressedChanges crl_changes -// [crl_changes.uncompressed_size] { -// switch (crl_changes[i]) { -// case 0: -// // CRL is the same -// case 1: -// // New CRL inserted -// // See CRL structure from the non-delta format -// case 2: -// // CRL deleted -// case 3: -// // CRL changed -// CompressedChanges serials_changes -// [serials_changes.uncompressed_size] { -// switch (serials_changes[i]) { -// case 0: -// // the serial is the same -// case 1: -// // serial inserted -// uint8 serial_length -// byte[serial_length] serial -// case 2: -// // serial deleted -// } -// } -// } -// } -// -// A delta CRLSet applies to a specific CRL set as given in the -// header's "DeltaFrom" value. The delta describes the changes to each CRL -// in turn with a zlib compressed array of options: either the CRL is the same, -// a new CRL is inserted, the CRL is deleted or the CRL is updated. In the case -// of an update, the serials in the CRL are considered in the same fashion -// except there is no delta update of a serial number: they are either -// inserted, deleted or left the same. - -// ReadHeader reads the header (including length prefix) from |data| and -// updates |data| to remove the header on return. Caller takes ownership of the -// returned pointer. -static base::DictionaryValue* ReadHeader(base::StringPiece* data) { - if (data->size() < 2) - return NULL; - uint16 header_len; - memcpy(&header_len, data->data(), 2); // assumes little-endian. - data->remove_prefix(2); - - if (data->size() < header_len) - return NULL; - - const base::StringPiece header_bytes(data->data(), header_len); - data->remove_prefix(header_len); - - scoped_ptr<Value> header(base::JSONReader::Read( - header_bytes, base::JSON_ALLOW_TRAILING_COMMAS)); - if (header.get() == NULL) - return NULL; - - if (!header->IsType(Value::TYPE_DICTIONARY)) - return NULL; - return reinterpret_cast<base::DictionaryValue*>(header.release()); -} - -// kCurrentFileVersion is the version of the CRLSet file format that we -// currently implement. -static const int kCurrentFileVersion = 0; - -static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, - std::vector<std::string>* out_serials) { - if (data->size() < crypto::kSHA256Length) - return false; - *out_parent_spki_hash = std::string(data->data(), crypto::kSHA256Length); - data->remove_prefix(crypto::kSHA256Length); - - if (data->size() < sizeof(uint32)) - return false; - uint32 num_serials; - memcpy(&num_serials, data->data(), sizeof(uint32)); // assumes little endian - data->remove_prefix(sizeof(uint32)); - - for (uint32 i = 0; i < num_serials; ++i) { - uint8 serial_length; - if (data->size() < sizeof(uint8)) - return false; - memcpy(&serial_length, data->data(), sizeof(uint8)); - data->remove_prefix(sizeof(uint8)); - - if (data->size() < serial_length) - return false; - std::string serial(data->data(), serial_length); - data->remove_prefix(serial_length); - out_serials->push_back(serial); - } - - return true; -} - -bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) { - ListValue* blocked_spkis_list = NULL; - if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { - // BlockedSPKIs is optional, so it's fine if we don't find it. - return true; - } - - blocked_spkis_.clear(); - - for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { - std::string spki_sha256_base64, spki_sha256; - if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) - return false; - if (!base::Base64Decode(spki_sha256_base64, &spki_sha256)) - return false; - blocked_spkis_.push_back(spki_sha256); - } - - return true; -} - -// static -bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { - // Other parts of Chrome assume that we're little endian, so we don't lose - // anything by doing this. -#if defined(__BYTE_ORDER) - // Linux check - COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); -#elif defined(__BIG_ENDIAN__) - // Mac check - #error assumes little endian -#endif - - scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); - if (!header_dict.get()) - return false; - - std::string contents; - if (!header_dict->GetString("ContentType", &contents)) - return false; - if (contents != "CRLSet") - return false; - - int version; - if (!header_dict->GetInteger("Version", &version) || - version != kCurrentFileVersion) { - return false; - } - - int sequence; - if (!header_dict->GetInteger("Sequence", &sequence)) - return false; - - double not_after; - if (!header_dict->GetDouble("NotAfter", ¬_after)) { - // NotAfter is optional for now. - not_after = 0; - } - if (not_after < 0) - return false; - - scoped_refptr<CRLSet> crl_set(new CRLSet); - crl_set->sequence_ = static_cast<uint32>(sequence); - crl_set->not_after_ = static_cast<uint64>(not_after); - - for (size_t crl_index = 0; !data.empty(); crl_index++) { - std::string parent_spki_sha256; - std::vector<std::string> serials; - if (!ReadCRL(&data, &parent_spki_sha256, &serials)) - return false; - - crl_set->crls_.push_back(std::make_pair(parent_spki_sha256, serials)); - crl_set->crls_index_by_issuer_[parent_spki_sha256] = crl_index; - } - - if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) - return false; - - *out_crl_set = crl_set; - return true; -} - -// kMaxUncompressedChangesLength is the largest changes array that we'll -// accept. This bounds the number of CRLs in the CRLSet as well as the number -// of serial numbers in a given CRL. -static const unsigned kMaxUncompressedChangesLength = 1024 * 1024; - -static bool ReadChanges(base::StringPiece* data, - std::vector<uint8>* out_changes) { - uint32 uncompressed_size, compressed_size; - if (data->size() < 2 * sizeof(uint32)) - return false; - // assumes little endian. - memcpy(&uncompressed_size, data->data(), sizeof(uint32)); - data->remove_prefix(4); - memcpy(&compressed_size, data->data(), sizeof(uint32)); - data->remove_prefix(4); - - if (uncompressed_size > kMaxUncompressedChangesLength) - return false; - if (data->size() < compressed_size) - return false; - - out_changes->clear(); - if (uncompressed_size == 0) - return true; - - out_changes->resize(uncompressed_size); - base::StringPiece compressed(data->data(), compressed_size); - data->remove_prefix(compressed_size); - return DecompressZlib(&(*out_changes)[0], uncompressed_size, compressed); -} - -// These are the range coder symbols used in delta updates. -enum { - SYMBOL_SAME = 0, - SYMBOL_INSERT = 1, - SYMBOL_DELETE = 2, - SYMBOL_CHANGED = 3, -}; - -bool ReadDeltaCRL(base::StringPiece* data, - const std::vector<std::string>& old_serials, - std::vector<std::string>* out_serials) { - std::vector<uint8> changes; - if (!ReadChanges(data, &changes)) - return false; - - size_t i = 0; - for (std::vector<uint8>::const_iterator k = changes.begin(); - k != changes.end(); ++k) { - if (*k == SYMBOL_SAME) { - if (i >= old_serials.size()) - return false; - out_serials->push_back(old_serials[i]); - i++; - } else if (*k == SYMBOL_INSERT) { - uint8 serial_length; - if (data->size() < sizeof(uint8)) - return false; - memcpy(&serial_length, data->data(), sizeof(uint8)); - data->remove_prefix(sizeof(uint8)); - - if (data->size() < serial_length) - return false; - const std::string serial(data->data(), serial_length); - data->remove_prefix(serial_length); - - out_serials->push_back(serial); - } else if (*k == SYMBOL_DELETE) { - if (i >= old_serials.size()) - return false; - i++; - } else { - NOTREACHED(); - return false; - } - } - - if (i != old_serials.size()) - return false; - return true; -} - -bool CRLSet::ApplyDelta(const base::StringPiece& in_data, - scoped_refptr<CRLSet>* out_crl_set) { - base::StringPiece data(in_data); - scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); - if (!header_dict.get()) - return false; - - std::string contents; - if (!header_dict->GetString("ContentType", &contents)) - return false; - if (contents != "CRLSetDelta") - return false; - - int version; - if (!header_dict->GetInteger("Version", &version) || - version != kCurrentFileVersion) { - return false; - } - - int sequence, delta_from; - if (!header_dict->GetInteger("Sequence", &sequence) || - !header_dict->GetInteger("DeltaFrom", &delta_from) || - delta_from < 0 || - static_cast<uint32>(delta_from) != sequence_) { - return false; - } - - double not_after; - if (!header_dict->GetDouble("NotAfter", ¬_after)) { - // NotAfter is optional for now. - not_after = 0; - } - if (not_after < 0) - return false; - - scoped_refptr<CRLSet> crl_set(new CRLSet); - crl_set->sequence_ = static_cast<uint32>(sequence); - crl_set->not_after_ = static_cast<uint64>(not_after); - - if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) - return false; - - std::vector<uint8> crl_changes; - - if (!ReadChanges(&data, &crl_changes)) - return false; - - size_t i = 0, j = 0; - for (std::vector<uint8>::const_iterator k = crl_changes.begin(); - k != crl_changes.end(); ++k) { - if (*k == SYMBOL_SAME) { - if (i >= crls_.size()) - return false; - crl_set->crls_.push_back(crls_[i]); - crl_set->crls_index_by_issuer_[crls_[i].first] = j; - i++; - j++; - } else if (*k == SYMBOL_INSERT) { - std::string parent_spki_hash; - std::vector<std::string> serials; - if (!ReadCRL(&data, &parent_spki_hash, &serials)) - return false; - crl_set->crls_.push_back(std::make_pair(parent_spki_hash, serials)); - crl_set->crls_index_by_issuer_[parent_spki_hash] = j; - j++; - } else if (*k == SYMBOL_DELETE) { - if (i >= crls_.size()) - return false; - i++; - } else if (*k == SYMBOL_CHANGED) { - if (i >= crls_.size()) - return false; - std::vector<std::string> serials; - if (!ReadDeltaCRL(&data, crls_[i].second, &serials)) - return false; - crl_set->crls_.push_back(std::make_pair(crls_[i].first, serials)); - crl_set->crls_index_by_issuer_[crls_[i].first] = j; - i++; - j++; - } else { - NOTREACHED(); - return false; - } - } - - if (!data.empty()) - return false; - if (i != crls_.size()) - return false; - - *out_crl_set = crl_set; - return true; -} - -// static -bool CRLSet::GetIsDeltaUpdate(const base::StringPiece& in_data, - bool* is_delta) { - base::StringPiece data(in_data); - scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); - if (!header_dict.get()) - return false; - - std::string contents; - if (!header_dict->GetString("ContentType", &contents)) - return false; - - if (contents == "CRLSet") { - *is_delta = false; - } else if (contents == "CRLSetDelta") { - *is_delta = true; - } else { - return false; - } - - return true; -} - -std::string CRLSet::Serialize() const { - std::string header = base::StringPrintf( - "{" - "\"Version\":0," - "\"ContentType\":\"CRLSet\"," - "\"Sequence\":%u," - "\"DeltaFrom\":0," - "\"NumParents\":%u," - "\"BlockedSPKIs\":[", - static_cast<unsigned>(sequence_), - static_cast<unsigned>(crls_.size())); - - for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin(); - i != blocked_spkis_.end(); ++i) { - std::string spki_hash_base64; - base::Base64Encode(*i, &spki_hash_base64); - - if (i != blocked_spkis_.begin()) - header += ","; - header += "\"" + spki_hash_base64 + "\""; - } - header += "]"; - if (not_after_ != 0) - header += base::StringPrintf(",\"NotAfter\":%" PRIu64, not_after_); - header += "}"; - - size_t len = 2 /* header len */ + header.size(); - - for (CRLList::const_iterator i = crls_.begin(); i != crls_.end(); ++i) { - len += i->first.size() + 4 /* num serials */; - for (std::vector<std::string>::const_iterator j = i->second.begin(); - j != i->second.end(); ++j) { - len += 1 /* serial length */ + j->size(); - } - } - - std::string ret; - char* out = WriteInto(&ret, len + 1 /* to include final NUL */); - size_t off = 0; - out[off++] = header.size(); - out[off++] = header.size() >> 8; - memcpy(out + off, header.data(), header.size()); - off += header.size(); - - for (CRLList::const_iterator i = crls_.begin(); i != crls_.end(); ++i) { - memcpy(out + off, i->first.data(), i->first.size()); - off += i->first.size(); - const uint32 num_serials = i->second.size(); - memcpy(out + off, &num_serials, sizeof(num_serials)); - off += sizeof(num_serials); - - for (std::vector<std::string>::const_iterator j = i->second.begin(); - j != i->second.end(); ++j) { - out[off++] = j->size(); - memcpy(out + off, j->data(), j->size()); - off += j->size(); - } - } - - CHECK_EQ(off, len); - return ret; -} - -CRLSet::Result CRLSet::CheckSPKI(const base::StringPiece& spki_hash) const { - for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin(); - i != blocked_spkis_.end(); ++i) { - if (spki_hash.size() == i->size() && - memcmp(spki_hash.data(), i->data(), i->size()) == 0) { - return REVOKED; - } - } - - return GOOD; -} - -CRLSet::Result CRLSet::CheckSerial( - const base::StringPiece& serial_number, - const base::StringPiece& issuer_spki_hash) const { - base::StringPiece serial(serial_number); - - if (!serial.empty() && (serial[0] & 0x80) != 0) { - // This serial number is negative but the process which generates CRL sets - // will reject any certificates with negative serial numbers as invalid. - return UNKNOWN; - } - - // Remove any leading zero bytes. - while (serial.size() > 1 && serial[0] == 0x00) - serial.remove_prefix(1); - - std::map<std::string, size_t>::const_iterator i = - crls_index_by_issuer_.find(issuer_spki_hash.as_string()); - if (i == crls_index_by_issuer_.end()) - return UNKNOWN; - const std::vector<std::string>& serials = crls_[i->second].second; - - for (std::vector<std::string>::const_iterator i = serials.begin(); - i != serials.end(); ++i) { - if (base::StringPiece(*i) == serial) - return REVOKED; - } - - return GOOD; -} - -bool CRLSet::IsExpired() const { - if (not_after_ == 0) - return false; - - uint64 now = base::Time::Now().ToTimeT(); - return now > not_after_; -} - -uint32 CRLSet::sequence() const { - return sequence_; -} - -const CRLSet::CRLList& CRLSet::crls() const { - return crls_; -} - -// static -CRLSet* CRLSet::EmptyCRLSetForTesting() { - return new CRLSet; -} - -CRLSet* CRLSet::ExpiredCRLSetForTesting() { - CRLSet* crl_set = new CRLSet; - crl_set->not_after_ = 1; - return crl_set; -} - -} // namespace net diff --git a/net/base/crl_set.h b/net/base/crl_set.h deleted file mode 100644 index cb37934..0000000 --- a/net/base/crl_set.h +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_CRL_SET_H_ -#define NET_BASE_CRL_SET_H_ - -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include "base/memory/ref_counted.h" -#include "base/string_piece.h" -#include "net/base/net_export.h" - -namespace base { -class DictionaryValue; -} - -namespace net { - -// A CRLSet is a structure that lists the serial numbers of revoked -// certificates from a number of issuers where issuers are identified by the -// SHA256 of their SubjectPublicKeyInfo. -class NET_EXPORT CRLSet : public base::RefCountedThreadSafe<CRLSet> { - public: - enum Result { - REVOKED, // the certificate should be rejected. - UNKNOWN, // the CRL for the certificate is not included in the set. - GOOD, // the certificate is not listed. - }; - - // Parse parses the bytes in |data| and, on success, puts a new CRLSet in - // |out_crl_set| and returns true. - static bool Parse(base::StringPiece data, - scoped_refptr<CRLSet>* out_crl_set); - - // CheckSPKI checks whether the given SPKI has been listed as blocked. - // spki_hash: the SHA256 of the SubjectPublicKeyInfo of the certificate. - Result CheckSPKI(const base::StringPiece& spki_hash) const; - - // CheckSerial returns the information contained in the set for a given - // certificate: - // serial_number: the serial number of the certificate - // issuer_spki_hash: the SHA256 of the SubjectPublicKeyInfo of the CRL - // signer - Result CheckSerial( - const base::StringPiece& serial_number, - const base::StringPiece& issuer_spki_hash) const; - - // IsExpired returns true iff the current time is past the NotAfter time - // specified in the CRLSet. - bool IsExpired() const; - - // ApplyDelta returns a new CRLSet in |out_crl_set| that is the result of - // updating the current CRL set with the delta information in |delta_bytes|. - bool ApplyDelta(const base::StringPiece& delta_bytes, - scoped_refptr<CRLSet>* out_crl_set); - - // GetIsDeltaUpdate extracts the header from |bytes|, sets *is_delta to - // whether |bytes| is a delta CRL set or not and returns true. In the event - // of a parse error, it returns false. - static bool GetIsDeltaUpdate(const base::StringPiece& bytes, bool *is_delta); - - // Serialize returns a string of bytes suitable for passing to Parse. Parsing - // and serializing a CRLSet is a lossless operation - the resulting bytes - // will be equal. - std::string Serialize() const; - - // sequence returns the sequence number of this CRL set. CRL sets generated - // by the same source are given strictly monotonically increasing sequence - // numbers. - uint32 sequence() const; - - // CRLList contains a list of (issuer SPKI hash, revoked serial numbers) - // pairs. - typedef std::vector< std::pair<std::string, std::vector<std::string> > > - CRLList; - - // crls returns the internal state of this CRLSet. It should only be used in - // testing. - const CRLList& crls() const; - - // EmptyCRLSetForTesting returns a valid, but empty, CRLSet for unit tests. - static CRLSet* EmptyCRLSetForTesting(); - - // ExpiredCRLSetForTesting returns a expired, empty CRLSet for unit tests. - static CRLSet* ExpiredCRLSetForTesting(); - - private: - CRLSet(); - ~CRLSet(); - - friend class base::RefCountedThreadSafe<CRLSet>; - - // CopyBlockedSPKIsFromHeader sets |blocked_spkis_| to the list of values - // from "BlockedSPKIs" in |header_dict|. - bool CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict); - - uint32 sequence_; - CRLList crls_; - // not_after_ contains the time, in UNIX epoch seconds, after which the - // CRLSet should be considered stale, or 0 if no such time was given. - uint64 not_after_; - // crls_index_by_issuer_ maps from issuer SPKI hashes to the index in |crls_| - // where the information for that issuer can be found. We have both |crls_| - // and |crls_index_by_issuer_| because, when applying a delta update, we need - // to identify a CRL by index. - std::map<std::string, size_t> crls_index_by_issuer_; - // blocked_spkis_ contains the SHA256 hashes of SPKIs which are to be blocked - // no matter where in a certificate chain they might appear. - std::vector<std::string> blocked_spkis_; -}; - -} // namespace net - -#endif // NET_BASE_CRL_SET_H_ diff --git a/net/base/crl_set_unittest.cc b/net/base/crl_set_unittest.cc deleted file mode 100644 index 42fa82a..0000000 --- a/net/base/crl_set_unittest.cc +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/crl_set.h" -#include "testing/gtest/include/gtest/gtest.h" - -// These data blocks were generated using a lot of code that is still in -// development. For now, if you need to update them, you have to contact agl. -static const uint8 kGIACRLSet[] = { - 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xb6, 0xb9, 0x54, 0x32, 0xab, 0xae, - 0x57, 0xfe, 0x02, 0x0c, 0xb2, 0xb7, 0x4f, 0x4f, 0x9f, 0x91, 0x73, 0xc8, 0xc7, - 0x08, 0xaf, 0xc9, 0xe7, 0x32, 0xac, 0xe2, 0x32, 0x79, 0x04, 0x7c, 0x6d, 0x05, - 0x0d, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, - 0x23, 0xb0, 0x0a, 0x10, 0x0e, 0x37, 0x06, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb1, - 0x0a, 0x16, 0x25, 0x42, 0x54, 0x00, 0x03, 0x00, 0x00, 0x14, 0x51, 0x0a, 0x16, - 0x69, 0xd1, 0xd7, 0x00, 0x03, 0x00, 0x00, 0x14, 0x52, 0x0a, 0x16, 0x70, 0x8c, - 0x22, 0x00, 0x03, 0x00, 0x00, 0x14, 0x53, 0x0a, 0x16, 0x71, 0x31, 0x2c, 0x00, - 0x03, 0x00, 0x00, 0x14, 0x54, 0x0a, 0x16, 0x7d, 0x75, 0x9d, 0x00, 0x03, 0x00, - 0x00, 0x14, 0x55, 0x0a, 0x1f, 0xee, 0xf9, 0x49, 0x00, 0x03, 0x00, 0x00, 0x23, - 0xae, 0x0a, 0x1f, 0xfc, 0xd1, 0x89, 0x00, 0x03, 0x00, 0x00, 0x23, 0xaf, 0x0a, - 0x61, 0xdd, 0xc7, 0x48, 0x00, 0x03, 0x00, 0x00, 0x18, 0x0e, 0x0a, 0x61, 0xe6, - 0x12, 0x64, 0x00, 0x03, 0x00, 0x00, 0x18, 0x0f, 0x0a, 0x61, 0xe9, 0x46, 0x56, - 0x00, 0x03, 0x00, 0x00, 0x18, 0x10, 0x0a, 0x64, 0x63, 0x49, 0xd2, 0x00, 0x03, - 0x00, 0x00, 0x1d, 0x77, -}; - -static const uint8 kNoopDeltaCRL[] = { - 0xc3, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x22, 0x2c, 0x22, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x31, 0x31, 0x32, 0x33, 0x37, 0x39, - 0x33, 0x2c, 0x22, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, 0x65, 0x63, 0x73, - 0x22, 0x3a, 0x34, 0x33, 0x32, 0x30, 0x30, 0x2c, 0x22, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x75, 0x6d, - 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x53, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x53, 0x69, 0x67, 0x6e, 0x69, - 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3a, 0x22, - 0x22, 0x7d, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x78, 0x9c, 0x62, - 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, -}; - -static const uint8 kAddCRLDelta[] = { - 0xc3, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x22, 0x2c, 0x22, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x31, 0x31, 0x32, 0x35, 0x39, 0x34, - 0x38, 0x2c, 0x22, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, 0x65, 0x63, 0x73, - 0x22, 0x3a, 0x34, 0x33, 0x32, 0x30, 0x30, 0x2c, 0x22, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x75, 0x6d, - 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x53, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x53, 0x69, 0x67, 0x6e, 0x69, - 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3a, 0x22, - 0x22, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x78, 0x9c, 0x62, - 0x60, 0x04, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0x00, 0x02, 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, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03, 0x01, - 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09, 0x01, 0x2f, - 0x01, 0x30, 0x01, 0x31, 0x01, 0x32, -}; - -static const uint8 kRemoveCRLDelta[] = { - 0xc3, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x22, 0x2c, 0x22, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x31, 0x31, 0x32, 0x36, 0x31, 0x31, - 0x36, 0x2c, 0x22, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, 0x65, 0x63, 0x73, - 0x22, 0x3a, 0x34, 0x33, 0x32, 0x30, 0x30, 0x2c, 0x22, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x75, 0x6d, - 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x53, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x53, 0x69, 0x67, 0x6e, 0x69, - 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3a, 0x22, - 0x22, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x78, 0x9c, 0x62, - 0x60, 0x02, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x04, 0x00, 0x03, -}; - -static const uint8 kUpdateSerialsDelta[] = { - 0xc3, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x22, 0x2c, 0x22, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x22, 0x3a, 0x31, 0x33, 0x31, 0x31, 0x31, 0x32, 0x36, 0x34, 0x36, - 0x31, 0x2c, 0x22, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, 0x65, 0x63, 0x73, - 0x22, 0x3a, 0x34, 0x33, 0x32, 0x30, 0x30, 0x2c, 0x22, 0x44, 0x65, 0x6c, 0x74, - 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x4e, 0x75, 0x6d, - 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x53, - 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x53, 0x69, 0x67, 0x6e, 0x69, - 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3a, 0x22, - 0x22, 0x7d, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x78, 0x9c, 0x62, - 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x04, 0x00, 0x04, 0x2d, 0x00, 0x00, - 0x00, 0x15, 0x00, 0x00, 0x00, 0x78, 0x9c, 0x62, 0x80, 0x00, 0x46, 0x2c, 0x00, - 0x45, 0x14, 0xac, 0x08, 0x10, 0x00, 0x00, 0xff, 0xff, 0x02, 0xe1, 0x00, 0x21, - 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, - 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, - 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, - 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, - 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, - 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, - 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, - 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, - 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, - 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, - 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, - 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, - 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, - 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, - 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, - 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, - 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, - 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, - 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, - 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, - 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, - 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, - 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, - 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, - 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, - 0x03, 0x00, 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, - 0x00, 0x23, 0xb0, 0x0a, 0x10, 0x0d, 0x7f, 0x30, 0x00, 0x03, 0x00, 0x00, 0x23, - 0xb0, -}; - -static const uint8 kBlockedSPKICRLSet[] = { - 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x34, 0x37, 0x44, 0x45, 0x51, 0x70, 0x6a, - 0x38, 0x48, 0x42, 0x53, 0x61, 0x2b, 0x2f, 0x54, 0x49, 0x6d, 0x57, 0x2b, 0x35, - 0x4a, 0x43, 0x65, 0x75, 0x51, 0x65, 0x52, 0x6b, 0x6d, 0x35, 0x4e, 0x4d, 0x70, - 0x4a, 0x57, 0x5a, 0x47, 0x33, 0x68, 0x53, 0x75, 0x46, 0x55, 0x3d, 0x22, 0x5d, - 0x7d, -}; - -static const uint8 kExpiredCRLSet[] = { - 0x6d, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x31, 0x2c, 0x22, - 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, - 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, - 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, - 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x2c, 0x22, 0x4e, 0x6f, 0x74, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x22, 0x3a, 0x31, 0x7d, -}; - -// kGIASPKISHA256 is the SHA256 digest the Google Internet Authority's -// SubjectPublicKeyInfo. -static const uint8 kGIASPKISHA256[32] = { - 0xb6, 0xb9, 0x54, 0x32, 0xab, 0xae, 0x57, 0xfe, 0x02, 0x0c, 0xb2, 0xb7, 0x4f, - 0x4f, 0x9f, 0x91, 0x73, 0xc8, 0xc7, 0x08, 0xaf, 0xc9, 0xe7, 0x32, 0xac, 0xe2, - 0x32, 0x79, 0x04, 0x7c, 0x6d, 0x05, -}; - -TEST(CRLSetTest, Parse) { - base::StringPiece s(reinterpret_cast<const char*>(kGIACRLSet), - sizeof(kGIACRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - const net::CRLSet::CRLList& crls = set->crls(); - ASSERT_EQ(1u, crls.size()); - const std::vector<std::string>& serials = crls[0].second; - static const unsigned kExpectedNumSerials = 13; - ASSERT_EQ(kExpectedNumSerials, serials.size()); - EXPECT_EQ(std::string("\x10\x0D\x7F\x30\x00\x03\x00\x00\x23\xB0", 10), - serials[0]); - EXPECT_EQ(std::string("\x64\x63\x49\xD2\x00\x03\x00\x00\x1D\x77", 10), - serials[kExpectedNumSerials - 1]); - - const std::string gia_spki_hash( - reinterpret_cast<const char*>(kGIASPKISHA256), - sizeof(kGIASPKISHA256)); - EXPECT_EQ(net::CRLSet::REVOKED, set->CheckSerial( - std::string("\x16\x7D\x75\x9D\x00\x03\x00\x00\x14\x55", 10), - gia_spki_hash)); - EXPECT_EQ(net::CRLSet::GOOD, set->CheckSerial( - std::string("\x47\x54\x3E\x79\x00\x03\x00\x00\x14\xF5", 10), - gia_spki_hash)); - - EXPECT_FALSE(set->IsExpired()); -} - -TEST(CRLSetTest, NoOpDeltaUpdate) { - base::StringPiece s(reinterpret_cast<const char*>(kGIACRLSet), - sizeof(kGIACRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - scoped_refptr<net::CRLSet> delta_set; - base::StringPiece delta(reinterpret_cast<const char*>(kNoopDeltaCRL), - sizeof(kNoopDeltaCRL)); - EXPECT_TRUE(set->ApplyDelta(delta, &delta_set)); - ASSERT_TRUE(delta_set.get() != NULL); - - std::string out = delta_set->Serialize(); - EXPECT_EQ(s.as_string(), out); -} - -TEST(CRLSetTest, AddCRLDelta) { - base::StringPiece s(reinterpret_cast<const char*>(kGIACRLSet), - sizeof(kGIACRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - scoped_refptr<net::CRLSet> delta_set; - base::StringPiece delta(reinterpret_cast<const char*>(kAddCRLDelta), - sizeof(kAddCRLDelta)); - EXPECT_TRUE(set->ApplyDelta(delta, &delta_set)); - ASSERT_TRUE(delta_set.get() != NULL); - - const net::CRLSet::CRLList& crls = delta_set->crls(); - ASSERT_EQ(2u, crls.size()); - const std::vector<std::string>& serials = crls[1].second; - ASSERT_EQ(12u, serials.size()); - EXPECT_EQ(std::string("\x02", 1), serials[0]); - EXPECT_EQ(std::string("\x03", 1), serials[1]); - EXPECT_EQ(std::string("\x04", 1), serials[2]); -} - -TEST(CRLSetTest, AddRemoveCRLDelta) { - base::StringPiece s(reinterpret_cast<const char*>(kGIACRLSet), - sizeof(kGIACRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - scoped_refptr<net::CRLSet> delta_set; - base::StringPiece delta(reinterpret_cast<const char*>(kAddCRLDelta), - sizeof(kAddCRLDelta)); - EXPECT_TRUE(set->ApplyDelta(delta, &delta_set)); - ASSERT_TRUE(delta_set.get() != NULL); - - scoped_refptr<net::CRLSet> delta2_set; - base::StringPiece delta2(reinterpret_cast<const char*>(kRemoveCRLDelta), - sizeof(kRemoveCRLDelta)); - EXPECT_TRUE(delta_set->ApplyDelta(delta2, &delta2_set)); - ASSERT_TRUE(delta2_set.get() != NULL); - - const net::CRLSet::CRLList& crls = delta2_set->crls(); - ASSERT_EQ(1u, crls.size()); - const std::vector<std::string>& serials = crls[0].second; - ASSERT_EQ(13u, serials.size()); -} - -TEST(CRLSetTest, UpdateSerialsDelta) { - base::StringPiece s(reinterpret_cast<const char*>(kGIACRLSet), - sizeof(kGIACRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - scoped_refptr<net::CRLSet> delta_set; - base::StringPiece delta(reinterpret_cast<const char*>(kUpdateSerialsDelta), - sizeof(kUpdateSerialsDelta)); - EXPECT_TRUE(set->ApplyDelta(delta, &delta_set)); - ASSERT_TRUE(delta_set.get() != NULL); - - const net::CRLSet::CRLList& crls = delta_set->crls(); - ASSERT_EQ(1u, crls.size()); - const std::vector<std::string>& serials = crls[0].second; - EXPECT_EQ(45u, serials.size()); -} - -TEST(CRLSetTest, BlockedSPKIs) { - base::StringPiece s(reinterpret_cast<const char*>(kBlockedSPKICRLSet), - sizeof(kBlockedSPKICRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - const uint8 spki_hash[] = { - 227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, - 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85, - 0, - }; - - EXPECT_EQ(net::CRLSet::GOOD, set->CheckSPKI("")); - EXPECT_EQ(net::CRLSet::REVOKED, set->CheckSPKI( - reinterpret_cast<const char*>(spki_hash))); -} - -TEST(CRLSetTest, Expired) { - // This CRLSet has an expiry value set to one second past midnight, 1st Jan, - // 1970. - base::StringPiece s(reinterpret_cast<const char*>(kExpiredCRLSet), - sizeof(kExpiredCRLSet)); - scoped_refptr<net::CRLSet> set; - EXPECT_TRUE(net::CRLSet::Parse(s, &set)); - ASSERT_TRUE(set.get() != NULL); - - EXPECT_TRUE(set->IsExpired()); -} diff --git a/net/base/ev_root_ca_metadata.cc b/net/base/ev_root_ca_metadata.cc deleted file mode 100644 index 5c617d7..0000000 --- a/net/base/ev_root_ca_metadata.cc +++ /dev/null @@ -1,553 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/ev_root_ca_metadata.h" - -#if defined(USE_NSS) || defined(OS_IOS) -#include <cert.h> -#include <pkcs11n.h> -#include <secerr.h> -#include <secoid.h> -#elif defined(OS_WIN) -#include <stdlib.h> -#endif - -#include "base/lazy_instance.h" -#include "base/logging.h" -#if defined(USE_NSS) || defined(OS_IOS) -#include "crypto/nss_util.h" -#endif - -namespace net { - -// Raw metadata. -struct EVMetadata { - // kMaxOIDsPerCA is the number of OIDs that we can support per root CA. At - // least one CA has different EV policies for businuss vs government - // entities and, in the case of cross-signing, we might need to list another - // CA's policy OID under the cross-signing root. - static const size_t kMaxOIDsPerCA = 2; - // This is the maximum length of an OID string (including the trailing NUL). - static const size_t kMaxOIDLength = 32; - - // The SHA-1 fingerprint of the root CA certificate, used as a unique - // identifier for a root CA certificate. - SHA1HashValue fingerprint; - - // The EV policy OIDs of the root CA. - const char policy_oids[kMaxOIDsPerCA][kMaxOIDLength]; -}; - -static const EVMetadata ev_root_ca_metadata[] = { - // AC Camerfirma S.A. Chambers of Commerce Root - 2008 - // https://www.camerfirma.com - { { { 0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a, - 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c } }, - { // AC Camerfirma uses the last two arcs to track how the private key is - // managed - the effective verification policy is the same. - "1.3.6.1.4.1.17326.10.14.2.1.2", - "1.3.6.1.4.1.17326.10.14.2.2.2", }, - }, - // AC Camerfirma S.A. Global Chambersign Root - 2008 - // https://server2.camerfirma.com:8082 - { { { 0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae, - 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c } }, - { // AC Camerfirma uses the last two arcs to track how the private key is - // managed - the effective verification policy is the same. - "1.3.6.1.4.1.17326.10.8.12.1.2", - "1.3.6.1.4.1.17326.10.8.12.2.2", }, - }, - // AddTrust External CA Root - // https://addtrustexternalcaroot-ev.comodoca.com - { { { 0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78, - 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68 } }, - { - "1.3.6.1.4.1.6449.1.2.1.5.1", - // This is the Network Solutions EV OID. However, this root - // cross-certifies NetSol and so we need it here too. - "1.3.6.1.4.1.782.1.2.1.8.1", - }, - }, - // AffirmTrust Commercial - // https://commercial.affirmtrust.com/ - { { { 0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57, - 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7 } }, - {"1.3.6.1.4.1.34697.2.1", ""}, - }, - // AffirmTrust Networking - // https://networking.affirmtrust.com:4431 - { { { 0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66, - 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f } }, - {"1.3.6.1.4.1.34697.2.2", ""}, - }, - // AffirmTrust Premium - // https://premium.affirmtrust.com:4432/ - { { { 0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6, - 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27 } }, - {"1.3.6.1.4.1.34697.2.3", ""}, - }, - // AffirmTrust Premium ECC - // https://premiumecc.affirmtrust.com:4433/ - { { { 0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01, - 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb } }, - {"1.3.6.1.4.1.34697.2.4", ""}, - }, - // CertPlus Class 2 Primary CA (KEYNECTIS) - // https://www.keynectis.com/ - { { { 0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79, - 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb } }, - {"1.3.6.1.4.1.22234.2.5.2.3.1", ""}, - }, - // Certum Trusted Network CA - // https://juice.certum.pl/ - { { { 0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f, - 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e } }, - {"1.2.616.1.113527.2.5.1.1", ""}, - }, - // COMODO Certification Authority - // https://secure.comodo.com/ - { { { 0x66, 0x31, 0xbf, 0x9e, 0xf7, 0x4f, 0x9e, 0xb6, 0xc9, 0xd5, - 0xa6, 0x0c, 0xba, 0x6a, 0xbe, 0xd1, 0xf7, 0xbd, 0xef, 0x7b } }, - {"1.3.6.1.4.1.6449.1.2.1.5.1", ""}, - }, - // COMODO Certification Authority (reissued certificate with NotBefore of Jan - // 1 00:00:00 2011 GMT) - // https://secure.comodo.com/ - { { { 0xee, 0x86, 0x93, 0x87, 0xff, 0xfd, 0x83, 0x49, 0xab, 0x5a, - 0xd1, 0x43, 0x22, 0x58, 0x87, 0x89, 0xa4, 0x57, 0xb0, 0x12 } }, - {"1.3.6.1.4.1.6449.1.2.1.5.1", ""}, - }, - // COMODO ECC Certification Authority - // https://comodoecccertificationauthority-ev.comodoca.com/ - { { { 0x9f, 0x74, 0x4e, 0x9f, 0x2b, 0x4d, 0xba, 0xec, 0x0f, 0x31, - 0x2c, 0x50, 0xb6, 0x56, 0x3b, 0x8e, 0x2d, 0x93, 0xc3, 0x11 } }, - {"1.3.6.1.4.1.6449.1.2.1.5.1", ""}, - }, - // Cybertrust Global Root - // https://evup.cybertrust.ne.jp/ctj-ev-upgrader/evseal.gif - { { { 0x5f, 0x43, 0xe5, 0xb1, 0xbf, 0xf8, 0x78, 0x8c, 0xac, 0x1c, - 0xc7, 0xca, 0x4a, 0x9a, 0xc6, 0x22, 0x2b, 0xcc, 0x34, 0xc6 } }, - {"1.3.6.1.4.1.6334.1.100.1", ""}, - }, - // DigiCert High Assurance EV Root CA - // https://www.digicert.com - { { { 0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c, - 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25 } }, - {"2.16.840.1.114412.2.1", ""}, - }, - // D-TRUST Root Class 3 CA 2 EV 2009 - // https://certdemo-ev-valid.ssl.d-trust.net/ - { { { 0x96, 0xc9, 0x1b, 0x0b, 0x95, 0xb4, 0x10, 0x98, 0x42, 0xfa, - 0xd0, 0xd8, 0x22, 0x79, 0xfe, 0x60, 0xfa, 0xb9, 0x16, 0x83 } }, - {"1.3.6.1.4.1.4788.2.202.1", ""}, - }, - // Entrust.net Secure Server Certification Authority - // https://www.entrust.net/ - { { { 0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b, - 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39 } }, - {"2.16.840.1.114028.10.1.2", ""}, - }, - // Entrust Root Certification Authority - // https://www.entrust.net/ - { { { 0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda, - 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9 } }, - {"2.16.840.1.114028.10.1.2", ""}, - }, - // Equifax Secure Certificate Authority (GeoTrust) - // https://www.geotrust.com/ - { { { 0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74, - 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a } }, - {"1.3.6.1.4.1.14370.1.6", ""}, - }, - // GeoTrust Primary Certification Authority - // https://www.geotrust.com/ - { { { 0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54, - 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96 } }, - {"1.3.6.1.4.1.14370.1.6", ""}, - }, - // GeoTrust Primary Certification Authority - G2 - { { { 0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70, - 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0 } }, - {"1.3.6.1.4.1.14370.1.6", ""}, - }, - // GeoTrust Primary Certification Authority - G3 - { { { 0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53, - 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd } }, - {"1.3.6.1.4.1.14370.1.6", ""}, - }, - // GlobalSign Root CA - R2 - // https://www.globalsign.com/ - { { { 0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04, - 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe } }, - {"1.3.6.1.4.1.4146.1.1", ""}, - }, - // GlobalSign Root CA - { { { 0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8, - 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c } }, - {"1.3.6.1.4.1.4146.1.1", ""}, - }, - // GlobalSign Root CA - R3 - // https://2029.globalsign.com/ - { { { 0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45, - 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad } }, - {"1.3.6.1.4.1.4146.1.1", ""}, - }, - // Go Daddy Class 2 Certification Authority - // https://www.godaddy.com/ - { { { 0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26, - 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4 } }, - {"2.16.840.1.114413.1.7.23.3", ""}, - }, - // GTE CyberTrust Global Root - // https://www.cybertrust.ne.jp/ - { { { 0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34, - 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74 } }, - {"1.3.6.1.4.1.6334.1.100.1", ""}, - }, - // Izenpe.com - SHA256 root - // The first OID is for businesses and the second for government entities. - // These are the test sites, respectively: - // https://servicios.izenpe.com - // https://servicios1.izenpe.com - { { { 0x2f, 0x78, 0x3d, 0x25, 0x52, 0x18, 0xa7, 0x4a, 0x65, 0x39, - 0x71, 0xb5, 0x2c, 0xa2, 0x9c, 0x45, 0x15, 0x6f, 0xe9, 0x19} }, - {"1.3.6.1.4.1.14777.6.1.1", "1.3.6.1.4.1.14777.6.1.2"}, - }, - // Izenpe.com - SHA1 root - // Windows XP finds this, SHA1, root instead. The policy OIDs are the same as - // for the SHA256 root, above. - { { { 0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a, - 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd} }, - {"1.3.6.1.4.1.14777.6.1.1", "1.3.6.1.4.1.14777.6.1.2"}, - }, - // Network Solutions Certificate Authority - // https://www.networksolutions.com/website-packages/index.jsp - { { { 0x74, 0xf8, 0xa3, 0xc3, 0xef, 0xe7, 0xb3, 0x90, 0x06, 0x4b, - 0x83, 0x90, 0x3c, 0x21, 0x64, 0x60, 0x20, 0xe5, 0xdf, 0xce } }, - {"1.3.6.1.4.1.782.1.2.1.8.1", ""}, - }, - // Network Solutions Certificate Authority (reissued certificate with - // NotBefore of Jan 1 00:00:00 2011 GMT). - // https://www.networksolutions.com/website-packages/index.jsp - { { { 0x71, 0x89, 0x9a, 0x67, 0xbf, 0x33, 0xaf, 0x31, 0xbe, 0xfd, - 0xc0, 0x71, 0xf8, 0xf7, 0x33, 0xb1, 0x83, 0x85, 0x63, 0x32 } }, - {"1.3.6.1.4.1.782.1.2.1.8.1", ""}, - }, - // QuoVadis Root CA 2 - // https://www.quovadis.bm/ - { { { 0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2, - 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7 } }, - {"1.3.6.1.4.1.8024.0.2.100.1.2", ""}, - }, - // SecureTrust CA, SecureTrust Corporation - // https://www.securetrust.com - // https://www.trustwave.com/ - { { { 0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96, - 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11 } }, - {"2.16.840.1.114404.1.1.2.4.1", ""}, - }, - // Secure Global CA, SecureTrust Corporation - { { { 0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86, - 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b } }, - {"2.16.840.1.114404.1.1.2.4.1", ""}, - }, - // Security Communication RootCA1 - // https://www.secomtrust.net/contact/form.html - { { { 0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e, - 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7 } }, - {"1.2.392.200091.100.721.1", ""}, - }, - // Security Communication EV RootCA1 - // https://www.secomtrust.net/contact/form.html - { { { 0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae, - 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d } }, - {"1.2.392.200091.100.721.1", ""}, - }, - // StartCom Certification Authority - // https://www.startssl.com/ - { { { 0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6, - 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f } }, - {"1.3.6.1.4.1.23223.1.1.1", ""}, - }, - // Starfield Class 2 Certification Authority - // https://www.starfieldtech.com/ - { { { 0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03, - 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a } }, - {"2.16.840.1.114414.1.7.23.3", ""}, - }, - // SwissSign Gold CA - G2 - // https://testevg2.swisssign.net/ - { { { 0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4, - 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61 } }, - {"2.16.756.1.89.1.2.1.1", ""}, - }, - // Thawte Premium Server CA - // https://www.thawte.com/ - { { { 0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d, - 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a } }, - {"2.16.840.1.113733.1.7.48.1", ""}, - }, - // thawte Primary Root CA - // https://www.thawte.com/ - { { { 0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5, - 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81 } }, - {"2.16.840.1.113733.1.7.48.1", ""}, - }, - // thawte Primary Root CA - G2 - { { { 0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27, - 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12 } }, - {"2.16.840.1.113733.1.7.48.1", ""}, - }, - // thawte Primary Root CA - G3 - { { { 0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0, - 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2 } }, - {"2.16.840.1.113733.1.7.48.1", ""}, - }, - // TWCA Root Certification Authority - // https://evssldemo.twca.com.tw/index.html - { { { 0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97, - 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48 } }, - {"1.3.6.1.4.1.40869.1.1.22.3", ""}, - }, - // T-TeleSec GlobalRoot Class 3 - // http://www.telesec.de/ / https://root-class3.test.telesec.de/ - { { { 0x55, 0xa6, 0x72, 0x3e, 0xcb, 0xf2, 0xec, 0xcd, 0xc3, 0x23, - 0x74, 0x70, 0x19, 0x9d, 0x2a, 0xbe, 0x11, 0xe3, 0x81, 0xd1 } }, - {"1.3.6.1.4.1.7879.13.24.1", "" }, - }, - // UTN - DATACorp SGC - { { { 0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd, - 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4 } }, - {"1.3.6.1.4.1.6449.1.2.1.5.1", ""}, - }, - // UTN-USERFirst-Hardware - { { { 0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87, - 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7 } }, - { - "1.3.6.1.4.1.6449.1.2.1.5.1", - // This is the Network Solutions EV OID. However, this root - // cross-certifies NetSol and so we need it here too. - "1.3.6.1.4.1.782.1.2.1.8.1", - }, - }, - // ValiCert Class 2 Policy Validation Authority - { { { 0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1, - 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6 } }, - {"2.16.840.1.114413.1.7.23.3", "2.16.840.1.114414.1.7.23.3"}, - }, - // VeriSign Class 3 Public Primary Certification Authority - // https://www.verisign.com/ - { { { 0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45, - 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2 } }, - {"2.16.840.1.113733.1.7.23.6", ""}, - }, - // VeriSign Class 3 Public Primary Certification Authority - G4 - { { { 0x22, 0xD5, 0xD8, 0xDF, 0x8F, 0x02, 0x31, 0xD1, 0x8D, 0xF7, - 0x9D, 0xB7, 0xCF, 0x8A, 0x2D, 0x64, 0xC9, 0x3F, 0x6C, 0x3A } }, - {"2.16.840.1.113733.1.7.23.6", ""}, - }, - // VeriSign Class 3 Public Primary Certification Authority - G5 - // https://www.verisign.com/ - { { { 0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, - 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5 } }, - {"2.16.840.1.113733.1.7.23.6", ""}, - }, - // VeriSign Universal Root Certification Authority - { { { 0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30, - 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54 } }, - {"2.16.840.1.113733.1.7.23.6", ""}, - }, - // Wells Fargo WellsSecure Public Root Certificate Authority - // https://nerys.wellsfargo.com/test.html - { { { 0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e, - 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee } }, - {"2.16.840.1.114171.500.9", ""}, - }, - // XRamp Global Certification Authority - { { { 0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04, - 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6 } }, - {"2.16.840.1.114404.1.1.2.4.1", ""}, - } -}; - -static base::LazyInstance<EVRootCAMetadata>::Leaky - g_ev_root_ca_metadata = LAZY_INSTANCE_INITIALIZER; - -// static -EVRootCAMetadata* EVRootCAMetadata::GetInstance() { - return g_ev_root_ca_metadata.Pointer(); -} - -#if defined(USE_NSS) || defined(OS_IOS) -bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const { - return policy_oids_.find(policy_oid) != policy_oids_.end(); -} - -bool EVRootCAMetadata::HasEVPolicyOID( - const SHA1HashValue& fingerprint, - PolicyOID policy_oid) const { - PolicyOIDMap::const_iterator iter = ev_policy_.find(fingerprint); - if (iter == ev_policy_.end()) - return false; - for (std::vector<PolicyOID>::const_iterator - j = iter->second.begin(); j != iter->second.end(); ++j) { - if (*j == policy_oid) - return true; - } - return false; -} - -bool EVRootCAMetadata::AddEVCA(const SHA1HashValue& fingerprint, - const char* policy) { - if (ev_policy_.find(fingerprint) != ev_policy_.end()) - return false; - - PolicyOID oid; - if (!RegisterOID(policy, &oid)) - return false; - - ev_policy_[fingerprint].push_back(oid); - policy_oids_.insert(oid); - - return true; -} - -bool EVRootCAMetadata::RemoveEVCA(const SHA1HashValue& fingerprint) { - PolicyOIDMap::iterator it = ev_policy_.find(fingerprint); - if (it == ev_policy_.end()) - return false; - PolicyOID oid = it->second[0]; - ev_policy_.erase(it); - policy_oids_.erase(oid); - return true; -} - -// static -bool EVRootCAMetadata::RegisterOID(const char* policy, - PolicyOID* out) { - PRUint8 buf[64]; - SECItem oid_item; - oid_item.data = buf; - oid_item.len = sizeof(buf); - SECStatus status = SEC_StringToOID(NULL, &oid_item, policy, 0); - if (status != SECSuccess) - return false; - - // Register the OID. - SECOidData od; - od.oid.len = oid_item.len; - od.oid.data = oid_item.data; - od.offset = SEC_OID_UNKNOWN; - od.desc = policy; - od.mechanism = CKM_INVALID_MECHANISM; - od.supportedExtension = INVALID_CERT_EXTENSION; - *out = SECOID_AddEntry(&od); - return *out != SEC_OID_UNKNOWN; -} - -#elif defined(OS_WIN) - -bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const { - for (size_t i = 0; i < arraysize(ev_root_ca_metadata); i++) { - for (size_t j = 0; j < arraysize(ev_root_ca_metadata[i].policy_oids); j++) { - if (ev_root_ca_metadata[i].policy_oids[j][0] == '\0') - break; - if (strcmp(policy_oid, ev_root_ca_metadata[i].policy_oids[j]) == 0) - return true; - } - } - - for (ExtraEVCAMap::const_iterator i = extra_cas_.begin(); - i != extra_cas_.end(); i++) { - if (i->second == policy_oid) - return true; - } - - return false; -} - -bool EVRootCAMetadata::HasEVPolicyOID(const SHA1HashValue& fingerprint, - PolicyOID policy_oid) const { - for (size_t i = 0; i < arraysize(ev_root_ca_metadata); i++) { - if (!fingerprint.Equals(ev_root_ca_metadata[i].fingerprint)) - continue; - for (size_t j = 0; j < arraysize(ev_root_ca_metadata[i].policy_oids); j++) { - if (ev_root_ca_metadata[i].policy_oids[j][0] == '\0') - break; - if (strcmp(policy_oid, ev_root_ca_metadata[i].policy_oids[j]) == 0) - return true; - } - return false; - } - - ExtraEVCAMap::const_iterator it = extra_cas_.find(fingerprint); - return it != extra_cas_.end() && it->second == policy_oid; -} - -bool EVRootCAMetadata::AddEVCA(const SHA1HashValue& fingerprint, - const char* policy) { - for (size_t i = 0; i < arraysize(ev_root_ca_metadata); i++) { - if (fingerprint.Equals(ev_root_ca_metadata[i].fingerprint)) - return false; - } - - if (extra_cas_.find(fingerprint) != extra_cas_.end()) - return false; - - extra_cas_[fingerprint] = policy; - return true; -} - -bool EVRootCAMetadata::RemoveEVCA(const SHA1HashValue& fingerprint) { - ExtraEVCAMap::iterator it = extra_cas_.find(fingerprint); - if (it == extra_cas_.end()) - return false; - extra_cas_.erase(it); - return true; -} - -#else - -// These are just stub functions for platforms where we don't use this EV -// metadata. - -bool EVRootCAMetadata::AddEVCA(const SHA1HashValue& fingerprint, - const char* policy) { - return true; -} - -bool EVRootCAMetadata::RemoveEVCA(const SHA1HashValue& fingerprint) { - return true; -} - -#endif - -EVRootCAMetadata::EVRootCAMetadata() { - // Constructs the object from the raw metadata in ev_root_ca_metadata. -#if defined(USE_NSS) || defined(OS_IOS) - crypto::EnsureNSSInit(); - - for (size_t i = 0; i < arraysize(ev_root_ca_metadata); i++) { - const EVMetadata& metadata = ev_root_ca_metadata[i]; - for (size_t j = 0; j < arraysize(metadata.policy_oids); j++) { - if (metadata.policy_oids[j][0] == '\0') - break; - const char* policy_oid = metadata.policy_oids[j]; - - PolicyOID policy; - if (!RegisterOID(policy_oid, &policy)) { - LOG(ERROR) << "Failed to register OID: " << policy_oid; - continue; - } - - ev_policy_[metadata.fingerprint].push_back(policy); - policy_oids_.insert(policy); - } - } -#endif -} - -EVRootCAMetadata::~EVRootCAMetadata() { } - -} // namespace net diff --git a/net/base/ev_root_ca_metadata.h b/net/base/ev_root_ca_metadata.h deleted file mode 100644 index 292c5ea..0000000 --- a/net/base/ev_root_ca_metadata.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_EV_ROOT_CA_METADATA_H_ -#define NET_BASE_EV_ROOT_CA_METADATA_H_ - -#include "build/build_config.h" - -#if defined(USE_NSS) || defined(OS_IOS) -#include <secoidt.h> -#endif - -#include <map> -#include <set> -#include <string> -#include <vector> - -#include "net/base/net_export.h" -#include "net/base/x509_certificate.h" - -namespace base { -template <typename T> -struct DefaultLazyInstanceTraits; -} // namespace base - -namespace net { - -// A singleton. This class stores the meta data of the root CAs that issue -// extended-validation (EV) certificates. -class NET_EXPORT_PRIVATE EVRootCAMetadata { - public: -#if defined(USE_NSS) || defined(OS_IOS) - typedef SECOidTag PolicyOID; -#elif defined(OS_WIN) - typedef const char* PolicyOID; -#endif - - static EVRootCAMetadata* GetInstance(); - -#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS) - // Returns true if policy_oid is an EV policy OID of some root CA. - bool IsEVPolicyOID(PolicyOID policy_oid) const; - - // Returns true if the root CA with the given certificate fingerprint has - // the EV policy OID policy_oid. - bool HasEVPolicyOID(const SHA1HashValue& fingerprint, - PolicyOID policy_oid) const; -#endif - - // AddEVCA adds an EV CA to the list of known EV CAs with the given policy. - // |policy| is expressed as a string of dotted numbers. It returns true on - // success. - bool AddEVCA(const SHA1HashValue& fingerprint, const char* policy); - - // RemoveEVCA removes an EV CA that was previously added by AddEVCA. It - // returns true on success. - bool RemoveEVCA(const SHA1HashValue& fingerprint); - - private: - friend struct base::DefaultLazyInstanceTraits<EVRootCAMetadata>; - - EVRootCAMetadata(); - ~EVRootCAMetadata(); - -#if defined(USE_NSS) || defined(OS_IOS) - typedef std::map<SHA1HashValue, std::vector<PolicyOID>, - SHA1HashValueLessThan> PolicyOIDMap; - - // RegisterOID registers |policy|, a policy OID in dotted string form, and - // writes the memoized form to |*out|. It returns true on success. - static bool RegisterOID(const char* policy, PolicyOID* out); - - PolicyOIDMap ev_policy_; - std::set<PolicyOID> policy_oids_; -#elif defined(OS_WIN) - typedef std::map<SHA1HashValue, std::string, - SHA1HashValueLessThan> ExtraEVCAMap; - - // extra_cas_ contains any EV CA metadata that was added at runtime. - ExtraEVCAMap extra_cas_; -#endif - - DISALLOW_COPY_AND_ASSIGN(EVRootCAMetadata); -}; - -} // namespace net - -#endif // NET_BASE_EV_ROOT_CA_METADATA_H_ diff --git a/net/base/ev_root_ca_metadata_unittest.cc b/net/base/ev_root_ca_metadata_unittest.cc deleted file mode 100644 index 0389b7d..0000000 --- a/net/base/ev_root_ca_metadata_unittest.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/ev_root_ca_metadata.h" - -#include "net/base/cert_test_util.h" -#include "net/base/x509_cert_types.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(USE_NSS) -#include "crypto/scoped_nss_types.h" -#endif - -namespace net { - -namespace { - -static const char kVerisignPolicy[] = "2.16.840.1.113733.1.7.23.6"; -static const char kThawtePolicy[] = "2.16.840.1.113733.1.7.48.1"; -static const char kFakePolicy[] = "2.16.840.1.42"; -static const SHA1HashValue kVerisignFingerprint = - { { 0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45, - 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2 } }; -static const SHA1HashValue kFakeFingerprint = - { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 } }; - -#if defined(USE_NSS) || defined(OS_WIN) -class EVOidData { - public: - EVOidData(); - bool Init(); - - EVRootCAMetadata::PolicyOID verisign_policy; - EVRootCAMetadata::PolicyOID thawte_policy; - EVRootCAMetadata::PolicyOID fake_policy; -}; - -#endif // defined(USE_NSS) || defined(OS_WIN) - -#if defined(USE_NSS) - -SECOidTag RegisterOID(PLArenaPool* arena, const char* oid_string) { - SECOidData oid_data; - memset(&oid_data, 0, sizeof(oid_data)); - oid_data.offset = SEC_OID_UNKNOWN; - oid_data.desc = oid_string; - oid_data.mechanism = CKM_INVALID_MECHANISM; - oid_data.supportedExtension = INVALID_CERT_EXTENSION; - - SECStatus rv = SEC_StringToOID(arena, &oid_data.oid, oid_string, 0); - if (rv != SECSuccess) - return SEC_OID_UNKNOWN; - - return SECOID_AddEntry(&oid_data); -} - -EVOidData::EVOidData() - : verisign_policy(SEC_OID_UNKNOWN), - thawte_policy(SEC_OID_UNKNOWN), - fake_policy(SEC_OID_UNKNOWN) { -} - -bool EVOidData::Init() { - crypto::ScopedPLArenaPool pool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - if (!pool.get()) - return false; - - verisign_policy = RegisterOID(pool.get(), kVerisignPolicy); - thawte_policy = RegisterOID(pool.get(), kThawtePolicy); - fake_policy = RegisterOID(pool.get(), kFakePolicy); - - return verisign_policy != SEC_OID_UNKNOWN && - thawte_policy != SEC_OID_UNKNOWN && - fake_policy != SEC_OID_UNKNOWN; -} - -#elif defined(OS_WIN) - -EVOidData::EVOidData() - : verisign_policy(kVerisignPolicy), - thawte_policy(kThawtePolicy), - fake_policy(kFakePolicy) { -} - -bool EVOidData::Init() { - return true; -} - -#endif - -#if defined(USE_NSS) || defined(OS_WIN) - -class EVRootCAMetadataTest : public testing::Test { - protected: - virtual void SetUp() OVERRIDE { - ASSERT_TRUE(ev_oid_data.Init()); - } - - EVOidData ev_oid_data; -}; - -TEST_F(EVRootCAMetadataTest, Basic) { - EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance()); - - EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.verisign_policy)); - EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy)); - EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint, - ev_oid_data.verisign_policy)); - EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint, - ev_oid_data.verisign_policy)); - EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint, - ev_oid_data.fake_policy)); - EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint, - ev_oid_data.thawte_policy)); -} - -TEST_F(EVRootCAMetadataTest, AddRemove) { - EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance()); - - EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy)); - EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint, - ev_oid_data.fake_policy)); - - { - ScopedTestEVPolicy test_ev_policy(ev_metadata, kFakeFingerprint, - kFakePolicy); - - EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy)); - EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kFakeFingerprint, - ev_oid_data.fake_policy)); - } - - EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy)); - EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint, - ev_oid_data.fake_policy)); -} - -#endif // defined(USE_NSS) || defined(OS_WIN) - -} // namespace - -} // namespace net diff --git a/net/base/mock_cert_verifier.cc b/net/base/mock_cert_verifier.cc deleted file mode 100644 index 9006374..0000000 --- a/net/base/mock_cert_verifier.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/mock_cert_verifier.h" - -#include "base/memory/ref_counted.h" -#include "base/string_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verify_result.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -struct MockCertVerifier::Rule { - Rule(X509Certificate* cert, - const std::string& hostname, - const CertVerifyResult& result, - int rv) - : cert(cert), - hostname(hostname), - result(result), - rv(rv) { - DCHECK(cert); - DCHECK(result.verified_cert); - } - - scoped_refptr<X509Certificate> cert; - std::string hostname; - CertVerifyResult result; - int rv; -}; - -MockCertVerifier::MockCertVerifier() : default_result_(ERR_CERT_INVALID) {} - -MockCertVerifier::~MockCertVerifier() {} - -int MockCertVerifier::Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - RequestHandle* out_req, - const BoundNetLog& net_log) { - RuleList::const_iterator it; - for (it = rules_.begin(); it != rules_.end(); ++it) { - // Check just the server cert. Intermediates will be ignored. - if (!it->cert->Equals(cert)) - continue; - if (!MatchPattern(hostname, it->hostname)) - continue; - *verify_result = it->result; - return it->rv; - } - - // Fall through to the default. - verify_result->verified_cert = cert; - verify_result->cert_status = MapNetErrorToCertStatus(default_result_); - return default_result_; -} - -void MockCertVerifier::CancelRequest(RequestHandle req) { - NOTIMPLEMENTED(); -} - -void MockCertVerifier::AddResultForCert(X509Certificate* cert, - const CertVerifyResult& verify_result, - int rv) { - AddResultForCertAndHost(cert, "*", verify_result, rv); -} - -void MockCertVerifier::AddResultForCertAndHost( - X509Certificate* cert, - const std::string& host_pattern, - const CertVerifyResult& verify_result, - int rv) { - Rule rule(cert, host_pattern, verify_result, rv); - rules_.push_back(rule); -} - -} // namespace net diff --git a/net/base/mock_cert_verifier.h b/net/base/mock_cert_verifier.h deleted file mode 100644 index d0537c1..0000000 --- a/net/base/mock_cert_verifier.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_MOCK_CERT_VERIFIER_H_ -#define NET_BASE_MOCK_CERT_VERIFIER_H_ - -#include <list> - -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" - -namespace net { - -class MockCertVerifier : public CertVerifier { - public: - // Creates a new MockCertVerifier. By default, any call to Verify() will - // result in the cert status being flagged as CERT_STATUS_INVALID and return - // an ERR_CERT_INVALID network error code. This behaviour can be overridden - // by calling set_default_result() to change the default return value for - // Verify() or by calling one of the AddResult*() methods to specifically - // handle a certificate or certificate and host. - MockCertVerifier(); - - virtual ~MockCertVerifier(); - - // CertVerifier implementation - virtual int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - RequestHandle* out_req, - const BoundNetLog& net_log) OVERRIDE; - virtual void CancelRequest(RequestHandle req) OVERRIDE; - - // Sets the default return value for Verify() for certificates/hosts that do - // not have explicit results added via the AddResult*() methods. - void set_default_result(int default_result) { - default_result_ = default_result; - } - - // Adds a rule that will cause any call to Verify() for |cert| to return rv, - // copying |verify_result| into the verified result. - // Note: Only the primary certificate of |cert| is checked. Any intermediate - // certificates will be ignored. - void AddResultForCert(X509Certificate* cert, - const CertVerifyResult& verify_result, - int rv); - - // Same as AddResultForCert(), but further restricts it to only return for - // hostnames that match |host_pattern|. - void AddResultForCertAndHost(X509Certificate* cert, - const std::string& host_pattern, - const CertVerifyResult& verify_result, - int rv); - - private: - struct Rule; - typedef std::list<Rule> RuleList; - - int default_result_; - RuleList rules_; -}; - -} // namespace net - -#endif // NET_BASE_MOCK_CERT_VERIFIER_H_ diff --git a/net/base/multi_threaded_cert_verifier.cc b/net/base/multi_threaded_cert_verifier.cc deleted file mode 100644 index dc01c0e..0000000 --- a/net/base/multi_threaded_cert_verifier.cc +++ /dev/null @@ -1,554 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/multi_threaded_cert_verifier.h" - -#include <algorithm> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "base/metrics/histogram.h" -#include "base/stl_util.h" -#include "base/synchronization/lock.h" -#include "base/time.h" -#include "base/threading/worker_pool.h" -#include "net/base/cert_trust_anchor_provider.h" -#include "net/base/cert_verify_proc.h" -#include "net/base/crl_set.h" -#include "net/base/net_errors.h" -#include "net/base/net_log.h" -#include "net/base/x509_certificate.h" -#include "net/base/x509_certificate_net_log_param.h" - -#if defined(USE_NSS) || defined(OS_IOS) -#include <private/pprthred.h> // PR_DetachThread -#endif - -namespace net { - -//////////////////////////////////////////////////////////////////////////// - -// Life of a request: -// -// MultiThreadedCertVerifier CertVerifierJob CertVerifierWorker Request -// | (origin loop) (worker loop) -// | -// Verify() -// |---->-------------------------------------<creates> -// | -// |---->-------------------<creates> -// | -// |---->-------------------------------------------------------<creates> -// | -// |---->---------------------------------------Start -// | | -// | PostTask -// | -// | <starts verifying> -// |---->-------------------AddRequest | -// | -// | -// | -// Finish -// | -// PostTask -// -// | -// DoReply -// |----<-----------------------------------------| -// HandleResult -// | -// |---->------------------HandleResult -// | -// |------>---------------------------Post -// -// -// -// On a cache hit, MultiThreadedCertVerifier::Verify() returns synchronously -// without posting a task to a worker thread. - -namespace { - -// The default value of max_cache_entries_. -const unsigned kMaxCacheEntries = 256; - -// The number of seconds for which we'll cache a cache entry. -const unsigned kTTLSecs = 1800; // 30 minutes. - -} // namespace - -MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} - -MultiThreadedCertVerifier::CachedResult::~CachedResult() {} - -MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( - const base::Time& now) - : verification_time(now), - expiration_time(now) { -} - -MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( - const base::Time& now, - const base::Time& expiration) - : verification_time(now), - expiration_time(expiration) { -} - -bool MultiThreadedCertVerifier::CacheExpirationFunctor::operator()( - const CacheValidityPeriod& now, - const CacheValidityPeriod& expiration) const { - // Ensure this functor is being used for expiration only, and not strict - // weak ordering/sorting. |now| should only ever contain a single - // base::Time. - // Note: DCHECK_EQ is not used due to operator<< overloading requirements. - DCHECK(now.verification_time == now.expiration_time); - - // |now| contains only a single time (verification_time), while |expiration| - // contains the validity range - both when the certificate was verified and - // when the verification result should expire. - // - // If the user receives a "not yet valid" message, and adjusts their clock - // foward to the correct time, this will (typically) cause - // now.verification_time to advance past expiration.expiration_time, thus - // treating the cached result as an expired entry and re-verifying. - // If the user receives a "expired" message, and adjusts their clock - // backwards to the correct time, this will cause now.verification_time to - // be less than expiration_verification_time, thus treating the cached - // result as an expired entry and re-verifying. - // If the user receives either of those messages, and does not adjust their - // clock, then the result will be (typically) be cached until the expiration - // TTL. - // - // This algorithm is only problematic if the user consistently keeps - // adjusting their clock backwards in increments smaller than the expiration - // TTL, in which case, cached elements continue to be added. However, - // because the cache has a fixed upper bound, if no entries are expired, a - // 'random' entry will be, thus keeping the memory constraints bounded over - // time. - return now.verification_time >= expiration.verification_time && - now.verification_time < expiration.expiration_time; -}; - - -// Represents the output and result callback of a request. -class CertVerifierRequest { - public: - CertVerifierRequest(const CompletionCallback& callback, - CertVerifyResult* verify_result, - const BoundNetLog& net_log) - : callback_(callback), - verify_result_(verify_result), - net_log_(net_log) { - net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); - } - - ~CertVerifierRequest() { - } - - // Ensures that the result callback will never be made. - void Cancel() { - callback_.Reset(); - verify_result_ = NULL; - net_log_.AddEvent(NetLog::TYPE_CANCELLED); - net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); - } - - // Copies the contents of |verify_result| to the caller's - // CertVerifyResult and calls the callback. - void Post(const MultiThreadedCertVerifier::CachedResult& verify_result) { - if (!callback_.is_null()) { - net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); - *verify_result_ = verify_result.result; - callback_.Run(verify_result.error); - } - delete this; - } - - bool canceled() const { return callback_.is_null(); } - - const BoundNetLog& net_log() const { return net_log_; } - - private: - CompletionCallback callback_; - CertVerifyResult* verify_result_; - const BoundNetLog net_log_; -}; - - -// CertVerifierWorker runs on a worker thread and takes care of the blocking -// process of performing the certificate verification. Deletes itself -// eventually if Start() succeeds. -class CertVerifierWorker { - public: - CertVerifierWorker(CertVerifyProc* verify_proc, - X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - MultiThreadedCertVerifier* cert_verifier) - : verify_proc_(verify_proc), - cert_(cert), - hostname_(hostname), - flags_(flags), - crl_set_(crl_set), - additional_trust_anchors_(additional_trust_anchors), - origin_loop_(MessageLoop::current()), - cert_verifier_(cert_verifier), - canceled_(false), - error_(ERR_FAILED) { - } - - // Returns the certificate being verified. May only be called /before/ - // Start() is called. - X509Certificate* certificate() const { return cert_; } - - bool Start() { - DCHECK_EQ(MessageLoop::current(), origin_loop_); - - return base::WorkerPool::PostTask( - FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), - true /* task is slow */); - } - - // Cancel is called from the origin loop when the MultiThreadedCertVerifier is - // getting deleted. - void Cancel() { - DCHECK_EQ(MessageLoop::current(), origin_loop_); - base::AutoLock locked(lock_); - canceled_ = true; - } - - private: - void Run() { - // Runs on a worker thread. - error_ = verify_proc_->Verify(cert_, hostname_, flags_, crl_set_, - additional_trust_anchors_, &verify_result_); -#if defined(USE_NSS) || defined(OS_IOS) - // Detach the thread from NSPR. - // Calling NSS functions attaches the thread to NSPR, which stores - // the NSPR thread ID in thread-specific data. - // The threads in our thread pool terminate after we have called - // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets - // segfaults on shutdown when the threads' thread-specific data - // destructors run. - PR_DetachThread(); -#endif - Finish(); - } - - // DoReply runs on the origin thread. - void DoReply() { - DCHECK_EQ(MessageLoop::current(), origin_loop_); - { - // We lock here because the worker thread could still be in Finished, - // after the PostTask, but before unlocking |lock_|. If we do not lock in - // this case, we will end up deleting a locked Lock, which can lead to - // memory leaks or worse errors. - base::AutoLock locked(lock_); - if (!canceled_) { - cert_verifier_->HandleResult(cert_, hostname_, flags_, - additional_trust_anchors_, error_, - verify_result_); - } - } - delete this; - } - - void Finish() { - // Runs on the worker thread. - // We assume that the origin loop outlives the MultiThreadedCertVerifier. If - // the MultiThreadedCertVerifier is deleted, it will call Cancel on us. If - // it does so before the Acquire, we'll delete ourselves and return. If it's - // trying to do so concurrently, then it'll block on the lock and we'll call - // PostTask while the MultiThreadedCertVerifier (and therefore the - // MessageLoop) is still alive. - // If it does so after this function, we assume that the MessageLoop will - // process pending tasks. In which case we'll notice the |canceled_| flag - // in DoReply. - - bool canceled; - { - base::AutoLock locked(lock_); - canceled = canceled_; - if (!canceled) { - origin_loop_->PostTask( - FROM_HERE, base::Bind( - &CertVerifierWorker::DoReply, base::Unretained(this))); - } - } - - if (canceled) - delete this; - } - - scoped_refptr<CertVerifyProc> verify_proc_; - scoped_refptr<X509Certificate> cert_; - const std::string hostname_; - const int flags_; - scoped_refptr<CRLSet> crl_set_; - const CertificateList additional_trust_anchors_; - MessageLoop* const origin_loop_; - MultiThreadedCertVerifier* const cert_verifier_; - - // lock_ protects canceled_. - base::Lock lock_; - - // If canceled_ is true, - // * origin_loop_ cannot be accessed by the worker thread, - // * cert_verifier_ cannot be accessed by any thread. - bool canceled_; - - int error_; - CertVerifyResult verify_result_; - - DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker); -}; - -// A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It -// lives only on the CertVerifier's origin message loop. -class CertVerifierJob { - public: - CertVerifierJob(CertVerifierWorker* worker, - const BoundNetLog& net_log) - : start_time_(base::TimeTicks::Now()), - worker_(worker), - net_log_(net_log) { - net_log_.BeginEvent( - NetLog::TYPE_CERT_VERIFIER_JOB, - base::Bind(&NetLogX509CertificateCallback, - base::Unretained(worker_->certificate()))); - } - - ~CertVerifierJob() { - if (worker_) { - net_log_.AddEvent(NetLog::TYPE_CANCELLED); - net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); - worker_->Cancel(); - DeleteAllCanceled(); - } - } - - void AddRequest(CertVerifierRequest* request) { - request->net_log().AddEvent( - NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, - net_log_.source().ToEventParametersCallback()); - - requests_.push_back(request); - } - - void HandleResult( - const MultiThreadedCertVerifier::CachedResult& verify_result) { - worker_ = NULL; - net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); - UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", - base::TimeTicks::Now() - start_time_, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMinutes(10), - 100); - PostAll(verify_result); - } - - private: - void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) { - std::vector<CertVerifierRequest*> requests; - requests_.swap(requests); - - for (std::vector<CertVerifierRequest*>::iterator - i = requests.begin(); i != requests.end(); i++) { - (*i)->Post(verify_result); - // Post() causes the CertVerifierRequest to delete itself. - } - } - - void DeleteAllCanceled() { - for (std::vector<CertVerifierRequest*>::iterator - i = requests_.begin(); i != requests_.end(); i++) { - if ((*i)->canceled()) { - delete *i; - } else { - LOG(DFATAL) << "CertVerifierRequest leaked!"; - } - } - } - - const base::TimeTicks start_time_; - std::vector<CertVerifierRequest*> requests_; - CertVerifierWorker* worker_; - const BoundNetLog net_log_; -}; - -MultiThreadedCertVerifier::MultiThreadedCertVerifier( - CertVerifyProc* verify_proc) - : cache_(kMaxCacheEntries), - requests_(0), - cache_hits_(0), - inflight_joins_(0), - verify_proc_(verify_proc), - trust_anchor_provider_(NULL) { - CertDatabase::GetInstance()->AddObserver(this); -} - -MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { - STLDeleteValues(&inflight_); - CertDatabase::GetInstance()->RemoveObserver(this); -} - -void MultiThreadedCertVerifier::SetCertTrustAnchorProvider( - CertTrustAnchorProvider* trust_anchor_provider) { - DCHECK(CalledOnValidThread()); - trust_anchor_provider_ = trust_anchor_provider; -} - -int MultiThreadedCertVerifier::Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - RequestHandle* out_req, - const BoundNetLog& net_log) { - DCHECK(CalledOnValidThread()); - - if (callback.is_null() || !verify_result || hostname.empty()) { - *out_req = NULL; - return ERR_INVALID_ARGUMENT; - } - - requests_++; - - const CertificateList empty_cert_list; - const CertificateList& additional_trust_anchors = - trust_anchor_provider_ ? - trust_anchor_provider_->GetAdditionalTrustAnchors() : empty_cert_list; - - const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), - hostname, flags, additional_trust_anchors); - const CertVerifierCache::value_type* cached_entry = - cache_.Get(key, CacheValidityPeriod(base::Time::Now())); - if (cached_entry) { - ++cache_hits_; - *out_req = NULL; - *verify_result = cached_entry->result; - return cached_entry->error; - } - - // No cache hit. See if an identical request is currently in flight. - CertVerifierJob* job; - std::map<RequestParams, CertVerifierJob*>::const_iterator j; - j = inflight_.find(key); - if (j != inflight_.end()) { - // An identical request is in flight already. We'll just attach our - // callback. - inflight_joins_++; - job = j->second; - } else { - // Need to make a new request. - CertVerifierWorker* worker = - new CertVerifierWorker(verify_proc_, cert, hostname, flags, crl_set, - additional_trust_anchors, this); - job = new CertVerifierJob( - worker, - BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); - if (!worker->Start()) { - delete job; - delete worker; - *out_req = NULL; - // TODO(wtc): log to the NetLog. - LOG(ERROR) << "CertVerifierWorker couldn't be started."; - return ERR_INSUFFICIENT_RESOURCES; // Just a guess. - } - inflight_.insert(std::make_pair(key, job)); - } - - CertVerifierRequest* request = - new CertVerifierRequest(callback, verify_result, net_log); - job->AddRequest(request); - *out_req = request; - return ERR_IO_PENDING; -} - -void MultiThreadedCertVerifier::CancelRequest(RequestHandle req) { - DCHECK(CalledOnValidThread()); - CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req); - request->Cancel(); -} - -MultiThreadedCertVerifier::RequestParams::RequestParams( - const SHA1HashValue& cert_fingerprint_arg, - const SHA1HashValue& ca_fingerprint_arg, - const std::string& hostname_arg, - int flags_arg, - const CertificateList& additional_trust_anchors) - : hostname(hostname_arg), - flags(flags_arg) { - hash_values.reserve(2 + additional_trust_anchors.size()); - hash_values.push_back(cert_fingerprint_arg); - hash_values.push_back(ca_fingerprint_arg); - for (size_t i = 0; i < additional_trust_anchors.size(); ++i) - hash_values.push_back(additional_trust_anchors[i]->fingerprint()); -} - -MultiThreadedCertVerifier::RequestParams::~RequestParams() {} - -bool MultiThreadedCertVerifier::RequestParams::operator<( - const RequestParams& other) const { - // |flags| is compared before |cert_fingerprint|, |ca_fingerprint|, and - // |hostname| under assumption that integer comparisons are faster than - // memory and string comparisons. - if (flags != other.flags) - return flags < other.flags; - if (hostname != other.hostname) - return hostname < other.hostname; - return std::lexicographical_compare( - hash_values.begin(), hash_values.end(), - other.hash_values.begin(), other.hash_values.end(), - net::SHA1HashValueLessThan()); -} - -// HandleResult is called by CertVerifierWorker on the origin message loop. -// It deletes CertVerifierJob. -void MultiThreadedCertVerifier::HandleResult( - X509Certificate* cert, - const std::string& hostname, - int flags, - const CertificateList& additional_trust_anchors, - int error, - const CertVerifyResult& verify_result) { - DCHECK(CalledOnValidThread()); - - const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), - hostname, flags, additional_trust_anchors); - - CachedResult cached_result; - cached_result.error = error; - cached_result.result = verify_result; - base::Time now = base::Time::Now(); - cache_.Put( - key, cached_result, CacheValidityPeriod(now), - CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs))); - - std::map<RequestParams, CertVerifierJob*>::iterator j; - j = inflight_.find(key); - if (j == inflight_.end()) { - NOTREACHED(); - return; - } - CertVerifierJob* job = j->second; - inflight_.erase(j); - - job->HandleResult(cached_result); - delete job; -} - -void MultiThreadedCertVerifier::OnCertTrustChanged( - const X509Certificate* cert) { - DCHECK(CalledOnValidThread()); - - ClearCache(); -} - -} // namespace net diff --git a/net/base/multi_threaded_cert_verifier.h b/net/base/multi_threaded_cert_verifier.h deleted file mode 100644 index bee577c..0000000 --- a/net/base/multi_threaded_cert_verifier.h +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_MULTI_THREADED_CERT_VERIFIER_H_ -#define NET_BASE_MULTI_THREADED_CERT_VERIFIER_H_ - -#include <map> -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" -#include "base/threading/non_thread_safe.h" -#include "net/base/cert_database.h" -#include "net/base/cert_verifier.h" -#include "net/base/cert_verify_result.h" -#include "net/base/completion_callback.h" -#include "net/base/expiring_cache.h" -#include "net/base/hash_value.h" -#include "net/base/net_export.h" -#include "net/base/x509_cert_types.h" - -namespace net { - -class CertTrustAnchorProvider; -class CertVerifierJob; -class CertVerifierRequest; -class CertVerifierWorker; -class CertVerifyProc; - -// MultiThreadedCertVerifier is a CertVerifier implementation that runs -// synchronous CertVerifier implementations on worker threads. -class NET_EXPORT_PRIVATE MultiThreadedCertVerifier - : public CertVerifier, - NON_EXPORTED_BASE(public base::NonThreadSafe), - public CertDatabase::Observer { - public: - explicit MultiThreadedCertVerifier(CertVerifyProc* verify_proc); - - // When the verifier is destroyed, all certificate verifications requests are - // canceled, and their completion callbacks will not be called. - virtual ~MultiThreadedCertVerifier(); - - // Configures a source of additional certificates that should be treated as - // trust anchors during verification, provided that the underlying - // CertVerifyProc supports additional trust beyond the default implementation. - // The CertTrustAnchorProvider will only be accessed on the same - // thread that Verify() is called on; that is, it will not be - // accessed from worker threads. - // It must outlive the MultiThreadedCertVerifier. - void SetCertTrustAnchorProvider( - CertTrustAnchorProvider* trust_anchor_provider); - - // CertVerifier implementation - virtual int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - CertVerifier::RequestHandle* out_req, - const BoundNetLog& net_log) OVERRIDE; - - virtual void CancelRequest(CertVerifier::RequestHandle req) OVERRIDE; - - private: - friend class CertVerifierWorker; // Calls HandleResult. - friend class CertVerifierRequest; - friend class CertVerifierJob; - friend class MultiThreadedCertVerifierTest; - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CacheHit); - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, DifferentCACerts); - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, InflightJoin); - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CancelRequest); - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, - RequestParamsComparators); - FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, - CertTrustAnchorProvider); - - // Input parameters of a certificate verification request. - struct NET_EXPORT_PRIVATE RequestParams { - RequestParams(const SHA1HashValue& cert_fingerprint_arg, - const SHA1HashValue& ca_fingerprint_arg, - const std::string& hostname_arg, - int flags_arg, - const CertificateList& additional_trust_anchors); - ~RequestParams(); - - bool operator<(const RequestParams& other) const; - - std::string hostname; - int flags; - std::vector<SHA1HashValue> hash_values; - }; - - // CachedResult contains the result of a certificate verification. - struct CachedResult { - CachedResult(); - ~CachedResult(); - - int error; // The return value of CertVerifier::Verify. - CertVerifyResult result; // The output of CertVerifier::Verify. - }; - - // Rather than having a single validity point along a monotonically increasing - // timeline, certificate verification is based on falling within a range of - // the certificate's NotBefore and NotAfter and based on what the current - // system clock says (which may advance forwards or backwards as users correct - // clock skew). CacheValidityPeriod and CacheExpirationFunctor are helpers to - // ensure that expiration is measured both by the 'general' case (now + cache - // TTL) and by whether or not significant enough clock skew was introduced - // since the last verification. - struct CacheValidityPeriod { - explicit CacheValidityPeriod(const base::Time& now); - CacheValidityPeriod(const base::Time& now, const base::Time& expiration); - - base::Time verification_time; - base::Time expiration_time; - }; - - struct CacheExpirationFunctor { - // Returns true iff |now| is within the validity period of |expiration|. - bool operator()(const CacheValidityPeriod& now, - const CacheValidityPeriod& expiration) const; - }; - - typedef ExpiringCache<RequestParams, CachedResult, CacheValidityPeriod, - CacheExpirationFunctor> CertVerifierCache; - - void HandleResult(X509Certificate* cert, - const std::string& hostname, - int flags, - const CertificateList& additional_trust_anchors, - int error, - const CertVerifyResult& verify_result); - - // CertDatabase::Observer methods: - virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE; - - // For unit testing. - void ClearCache() { cache_.Clear(); } - size_t GetCacheSize() const { return cache_.size(); } - uint64 cache_hits() const { return cache_hits_; } - uint64 requests() const { return requests_; } - uint64 inflight_joins() const { return inflight_joins_; } - - // cache_ maps from a request to a cached result. - CertVerifierCache cache_; - - // inflight_ maps from a request to an active verification which is taking - // place. - std::map<RequestParams, CertVerifierJob*> inflight_; - - uint64 requests_; - uint64 cache_hits_; - uint64 inflight_joins_; - - scoped_refptr<CertVerifyProc> verify_proc_; - - CertTrustAnchorProvider* trust_anchor_provider_; - - DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier); -}; - -} // namespace net - -#endif // NET_BASE_MULTI_THREADED_CERT_VERIFIER_H_ diff --git a/net/base/multi_threaded_cert_verifier_unittest.cc b/net/base/multi_threaded_cert_verifier_unittest.cc deleted file mode 100644 index 8dea596..0000000 --- a/net/base/multi_threaded_cert_verifier_unittest.cc +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/multi_threaded_cert_verifier.h" - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/format_macros.h" -#include "base/stringprintf.h" -#include "net/base/cert_test_util.h" -#include "net/base/cert_trust_anchor_provider.h" -#include "net/base/cert_verify_proc.h" -#include "net/base/cert_verify_result.h" -#include "net/base/net_errors.h" -#include "net/base/net_log.h" -#include "net/base/test_completion_callback.h" -#include "net/base/test_data_directory.h" -#include "net/base/x509_certificate.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::Mock; -using testing::ReturnRef; - -namespace net { - -namespace { - -void FailTest(int /* result */) { - FAIL(); -} - -class MockCertVerifyProc : public CertVerifyProc { - public: - MockCertVerifyProc() {} - - private: - virtual ~MockCertVerifyProc() {} - - // CertVerifyProc implementation - virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { - return false; - } - - virtual int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) OVERRIDE { - verify_result->Reset(); - verify_result->verified_cert = cert; - verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID; - return ERR_CERT_COMMON_NAME_INVALID; - } -}; - -class MockCertTrustAnchorProvider : public CertTrustAnchorProvider { - public: - MockCertTrustAnchorProvider() {} - virtual ~MockCertTrustAnchorProvider() {} - - MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&()); -}; - -} // namespace - -class MultiThreadedCertVerifierTest : public ::testing::Test { - public: - MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} - virtual ~MultiThreadedCertVerifierTest() {} - - protected: - MultiThreadedCertVerifier verifier_; -}; - -TEST_F(MultiThreadedCertVerifierTest, CacheHit) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(certs_dir, "ok_cert.pem")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); - - int error; - CertVerifyResult verify_result; - TestCompletionCallback callback; - CertVerifier::RequestHandle request_handle; - - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - ASSERT_TRUE(IsCertificateError(error)); - ASSERT_EQ(1u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - ASSERT_EQ(0u, verifier_.inflight_joins()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); - - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - // Synchronous completion. - ASSERT_NE(ERR_IO_PENDING, error); - ASSERT_TRUE(IsCertificateError(error)); - ASSERT_TRUE(request_handle == NULL); - ASSERT_EQ(2u, verifier_.requests()); - ASSERT_EQ(1u, verifier_.cache_hits()); - ASSERT_EQ(0u, verifier_.inflight_joins()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); -} - -// Tests the same server certificate with different intermediate CA -// certificates. These should be treated as different certificate chains even -// though the two X509Certificate objects contain the same server certificate. -TEST_F(MultiThreadedCertVerifierTest, DifferentCACerts) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "salesforce_com_test.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - scoped_refptr<X509Certificate> intermediate_cert1 = - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1); - - scoped_refptr<X509Certificate> intermediate_cert2 = - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert1->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain1 = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - intermediates.clear(); - intermediates.push_back(intermediate_cert2->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain2 = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - int error; - CertVerifyResult verify_result; - TestCompletionCallback callback; - CertVerifier::RequestHandle request_handle; - - error = verifier_.Verify(cert_chain1, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - ASSERT_TRUE(IsCertificateError(error)); - ASSERT_EQ(1u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - ASSERT_EQ(0u, verifier_.inflight_joins()); - ASSERT_EQ(1u, verifier_.GetCacheSize()); - - error = verifier_.Verify(cert_chain2, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - ASSERT_TRUE(IsCertificateError(error)); - ASSERT_EQ(2u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - ASSERT_EQ(0u, verifier_.inflight_joins()); - ASSERT_EQ(2u, verifier_.GetCacheSize()); -} - -// Tests an inflight join. -TEST_F(MultiThreadedCertVerifierTest, InflightJoin) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(certs_dir, "ok_cert.pem")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); - - int error; - CertVerifyResult verify_result; - TestCompletionCallback callback; - CertVerifier::RequestHandle request_handle; - CertVerifyResult verify_result2; - TestCompletionCallback callback2; - CertVerifier::RequestHandle request_handle2; - - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = verifier_.Verify( - test_cert, "www.example.com", 0, NULL, &verify_result2, - callback2.callback(), &request_handle2, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle2 != NULL); - error = callback.WaitForResult(); - ASSERT_TRUE(IsCertificateError(error)); - error = callback2.WaitForResult(); - ASSERT_TRUE(IsCertificateError(error)); - ASSERT_EQ(2u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - ASSERT_EQ(1u, verifier_.inflight_joins()); -} - -// Tests that the callback of a canceled request is never made. -TEST_F(MultiThreadedCertVerifierTest, CancelRequest) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(certs_dir, "ok_cert.pem")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); - - int error; - CertVerifyResult verify_result; - CertVerifier::RequestHandle request_handle; - - error = verifier_.Verify( - test_cert, "www.example.com", 0, NULL, &verify_result, - base::Bind(&FailTest), &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - verifier_.CancelRequest(request_handle); - - // Issue a few more requests to the worker pool and wait for their - // completion, so that the task of the canceled request (which runs on a - // worker thread) is likely to complete by the end of this test. - TestCompletionCallback callback; - for (int i = 0; i < 5; ++i) { - error = verifier_.Verify( - test_cert, "www2.example.com", 0, NULL, &verify_result, - callback.callback(), &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - verifier_.ClearCache(); - } -} - -// Tests that a canceled request is not leaked. -TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(certs_dir, "ok_cert.pem")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); - - int error; - CertVerifyResult verify_result; - TestCompletionCallback callback; - CertVerifier::RequestHandle request_handle; - - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - verifier_.CancelRequest(request_handle); - // Destroy |verifier| by going out of scope. -} - -TEST_F(MultiThreadedCertVerifierTest, RequestParamsComparators) { - SHA1HashValue a_key; - memset(a_key.data, 'a', sizeof(a_key.data)); - - SHA1HashValue z_key; - memset(z_key.data, 'z', sizeof(z_key.data)); - - const CertificateList empty_list; - CertificateList test_list; - test_list.push_back( - ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); - - struct { - // Keys to test - MultiThreadedCertVerifier::RequestParams key1; - MultiThreadedCertVerifier::RequestParams key2; - - // Expectation: - // -1 means key1 is less than key2 - // 0 means key1 equals key2 - // 1 means key1 is greater than key2 - int expected_result; - } tests[] = { - { // Test for basic equivalence. - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - 0, - }, - { // Test that different certificates but with the same CA and for - // the same host are different validation keys. - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - MultiThreadedCertVerifier::RequestParams(z_key, a_key, "www.example.test", - 0, test_list), - -1, - }, - { // Test that the same EE certificate for the same host, but with - // different chains are different validation keys. - MultiThreadedCertVerifier::RequestParams(a_key, z_key, "www.example.test", - 0, test_list), - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - 1, - }, - { // The same certificate, with the same chain, but for different - // hosts are different validation keys. - MultiThreadedCertVerifier::RequestParams(a_key, a_key, - "www1.example.test", 0, - test_list), - MultiThreadedCertVerifier::RequestParams(a_key, a_key, - "www2.example.test", 0, - test_list), - -1, - }, - { // The same certificate, chain, and host, but with different flags - // are different validation keys. - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - CertVerifier::VERIFY_EV_CERT, - test_list), - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - 1, - }, - { // Different additional_trust_anchors. - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, empty_list), - MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", - 0, test_list), - -1, - }, - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { - SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i)); - - const MultiThreadedCertVerifier::RequestParams& key1 = tests[i].key1; - const MultiThreadedCertVerifier::RequestParams& key2 = tests[i].key2; - - switch (tests[i].expected_result) { - case -1: - EXPECT_TRUE(key1 < key2); - EXPECT_FALSE(key2 < key1); - break; - case 0: - EXPECT_FALSE(key1 < key2); - EXPECT_FALSE(key2 < key1); - break; - case 1: - EXPECT_FALSE(key1 < key2); - EXPECT_TRUE(key2 < key1); - break; - default: - FAIL() << "Invalid expectation. Can be only -1, 0, 1"; - } - } -} - -TEST_F(MultiThreadedCertVerifierTest, CertTrustAnchorProvider) { - MockCertTrustAnchorProvider trust_provider; - verifier_.SetCertTrustAnchorProvider(&trust_provider); - - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); - ASSERT_TRUE(test_cert); - - const CertificateList empty_cert_list; - CertificateList cert_list; - cert_list.push_back(test_cert); - - // Check that Verify() asks the |trust_provider| for the current list of - // additional trust anchors. - int error; - CertVerifyResult verify_result; - TestCompletionCallback callback; - CertVerifier::RequestHandle request_handle; - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) - .WillOnce(ReturnRef(empty_cert_list)); - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - Mock::VerifyAndClearExpectations(&trust_provider); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle); - error = callback.WaitForResult(); - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); - ASSERT_EQ(1u, verifier_.requests()); - ASSERT_EQ(0u, verifier_.cache_hits()); - - // The next Verify() uses the cached result. - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) - .WillOnce(ReturnRef(empty_cert_list)); - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - Mock::VerifyAndClearExpectations(&trust_provider); - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); - EXPECT_FALSE(request_handle); - ASSERT_EQ(2u, verifier_.requests()); - ASSERT_EQ(1u, verifier_.cache_hits()); - - // Another Verify() for the same certificate but with a different list of - // trust anchors will not reuse the cache. - EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) - .WillOnce(ReturnRef(cert_list)); - error = verifier_.Verify(test_cert, "www.example.com", 0, NULL, - &verify_result, callback.callback(), - &request_handle, BoundNetLog()); - Mock::VerifyAndClearExpectations(&trust_provider); - ASSERT_EQ(ERR_IO_PENDING, error); - ASSERT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); - ASSERT_EQ(3u, verifier_.requests()); - ASSERT_EQ(1u, verifier_.cache_hits()); -} - -} // namespace net diff --git a/net/base/nss_cert_database.cc b/net/base/nss_cert_database.cc deleted file mode 100644 index 1cfb212..0000000 --- a/net/base/nss_cert_database.cc +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/nss_cert_database.h" - -#include <cert.h> -#include <certdb.h> -#include <keyhi.h> -#include <pk11pub.h> -#include <secmod.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/singleton.h" -#include "base/observer_list_threadsafe.h" -#include "crypto/nss_util.h" -#include "crypto/nss_util_internal.h" -#include "net/base/cert_database.h" -#include "net/base/crypto_module.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" -#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" -#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h" - -// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use -// the new name of the macro. -#if !defined(CERTDB_TERMINAL_RECORD) -#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER -#endif - -// PSM = Mozilla's Personal Security Manager. -namespace psm = mozilla_security_manager; - -namespace net { - -NSSCertDatabase::ImportCertFailure::ImportCertFailure( - X509Certificate* cert, int err) - : certificate(cert), - net_error(err) {} - -NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {} - -// static -NSSCertDatabase* NSSCertDatabase::GetInstance() { - return Singleton<NSSCertDatabase>::get(); -} - -NSSCertDatabase::NSSCertDatabase() - : observer_list_(new ObserverListThreadSafe<Observer>) { - crypto::EnsureNSSInit(); - psm::EnsurePKCS12Init(); -} - -NSSCertDatabase::~NSSCertDatabase() {} - -void NSSCertDatabase::ListCerts(CertificateList* certs) { - certs->clear(); - - CERTCertList* cert_list = PK11_ListCerts(PK11CertListUnique, NULL); - CERTCertListNode* node; - for (node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(node, cert_list); - node = CERT_LIST_NEXT(node)) { - certs->push_back(X509Certificate::CreateFromHandle( - node->cert, X509Certificate::OSCertHandles())); - } - CERT_DestroyCertList(cert_list); -} - -CryptoModule* NSSCertDatabase::GetPublicModule() const { - CryptoModule* module = - CryptoModule::CreateFromHandle(crypto::GetPublicNSSKeySlot()); - // The module is already referenced when returned from - // GetPublicNSSKeySlot, so we need to deref it once. - PK11_FreeSlot(module->os_module_handle()); - - return module; -} - -CryptoModule* NSSCertDatabase::GetPrivateModule() const { - CryptoModule* module = - CryptoModule::CreateFromHandle(crypto::GetPrivateNSSKeySlot()); - // The module is already referenced when returned from - // GetPrivateNSSKeySlot, so we need to deref it once. - PK11_FreeSlot(module->os_module_handle()); - - return module; -} - -void NSSCertDatabase::ListModules(CryptoModuleList* modules, - bool need_rw) const { - modules->clear(); - - PK11SlotList* slot_list = NULL; - // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. - slot_list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, - need_rw ? PR_TRUE : PR_FALSE, // needRW - PR_TRUE, // loadCerts (unused) - NULL); // wincx - if (!slot_list) { - LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError(); - return; - } - - PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list); - while (slot_element) { - modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot)); - slot_element = PK11_GetNextSafe(slot_list, slot_element, - PR_FALSE); // restart - } - - PK11_FreeSlotList(slot_list); -} - -int NSSCertDatabase::ImportFromPKCS12( - CryptoModule* module, - const std::string& data, - const base::string16& password, - bool is_extractable, - net::CertificateList* imported_certs) { - int result = psm::nsPKCS12Blob_Import(module->os_module_handle(), - data.data(), data.size(), - password, - is_extractable, - imported_certs); - if (result == net::OK) - NotifyObserversOfCertAdded(NULL); - - return result; -} - -int NSSCertDatabase::ExportToPKCS12( - const CertificateList& certs, - const base::string16& password, - std::string* output) const { - return psm::nsPKCS12Blob_Export(output, certs, password); -} - -X509Certificate* NSSCertDatabase::FindRootInList( - const CertificateList& certificates) const { - DCHECK_GT(certificates.size(), 0U); - - if (certificates.size() == 1) - return certificates[0].get(); - - X509Certificate* cert0 = certificates[0]; - X509Certificate* cert1 = certificates[1]; - X509Certificate* certn_2 = certificates[certificates.size() - 2]; - X509Certificate* certn_1 = certificates[certificates.size() - 1]; - - if (CERT_CompareName(&cert1->os_cert_handle()->issuer, - &cert0->os_cert_handle()->subject) == SECEqual) - return cert0; - if (CERT_CompareName(&certn_2->os_cert_handle()->issuer, - &certn_1->os_cert_handle()->subject) == SECEqual) - return certn_1; - - VLOG(1) << "certificate list is not a hierarchy"; - return cert0; -} - -bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported) { - X509Certificate* root = FindRootInList(certificates); - bool success = psm::ImportCACerts(certificates, root, trust_bits, - not_imported); - if (success) - NotifyObserversOfCertTrustChanged(NULL); - - return success; -} - -bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported) { - return psm::ImportServerCert(certificates, trust_bits, not_imported); -} - -NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust( - const X509Certificate* cert, - CertType type) const { - CERTCertTrust trust; - SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust); - if (srv != SECSuccess) { - LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); - return TRUST_DEFAULT; - } - // We define our own more "friendly" TrustBits, which means we aren't able to - // round-trip all possible NSS trust flag combinations. We try to map them in - // a sensible way. - switch (type) { - case CA_CERT: { - const unsigned kTrustedCA = CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; - const unsigned kCAFlags = kTrustedCA | CERTDB_TERMINAL_RECORD; - - TrustBits trust_bits = TRUST_DEFAULT; - if ((trust.sslFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) - trust_bits |= DISTRUSTED_SSL; - else if (trust.sslFlags & kTrustedCA) - trust_bits |= TRUSTED_SSL; - - if ((trust.emailFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) - trust_bits |= DISTRUSTED_EMAIL; - else if (trust.emailFlags & kTrustedCA) - trust_bits |= TRUSTED_EMAIL; - - if ((trust.objectSigningFlags & kCAFlags) == CERTDB_TERMINAL_RECORD) - trust_bits |= DISTRUSTED_OBJ_SIGN; - else if (trust.objectSigningFlags & kTrustedCA) - trust_bits |= TRUSTED_OBJ_SIGN; - - return trust_bits; - } - case SERVER_CERT: - if (trust.sslFlags & CERTDB_TERMINAL_RECORD) { - if (trust.sslFlags & CERTDB_TRUSTED) - return TRUSTED_SSL; - return DISTRUSTED_SSL; - } - return TRUST_DEFAULT; - default: - return TRUST_DEFAULT; - } -} - -bool NSSCertDatabase::IsUntrusted(const X509Certificate* cert) const { - CERTCertTrust nsstrust; - SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust); - if (rv != SECSuccess) { - LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError(); - return false; - } - - // The CERTCertTrust structure contains three trust records: - // sslFlags, emailFlags, and objectSigningFlags. The three - // trust records are independent of each other. - // - // If the CERTDB_TERMINAL_RECORD bit in a trust record is set, - // then that trust record is a terminal record. A terminal - // record is used for explicit trust and distrust of an - // end-entity or intermediate CA cert. - // - // In a terminal record, if neither CERTDB_TRUSTED_CA nor - // CERTDB_TRUSTED is set, then the terminal record means - // explicit distrust. On the other hand, if the terminal - // record has either CERTDB_TRUSTED_CA or CERTDB_TRUSTED bit - // set, then the terminal record means explicit trust. - // - // For a root CA, the trust record does not have - // the CERTDB_TERMINAL_RECORD bit set. - - static const unsigned int kTrusted = CERTDB_TRUSTED_CA | CERTDB_TRUSTED; - if ((nsstrust.sslFlags & CERTDB_TERMINAL_RECORD) != 0 && - (nsstrust.sslFlags & kTrusted) == 0) { - return true; - } - if ((nsstrust.emailFlags & CERTDB_TERMINAL_RECORD) != 0 && - (nsstrust.emailFlags & kTrusted) == 0) { - return true; - } - if ((nsstrust.objectSigningFlags & CERTDB_TERMINAL_RECORD) != 0 && - (nsstrust.objectSigningFlags & kTrusted) == 0) { - return true; - } - - // Self-signed certificates that don't have any trust bits set are untrusted. - // Other certificates that don't have any trust bits set may still be trusted - // if they chain up to a trust anchor. - if (CERT_CompareName(&cert->os_cert_handle()->issuer, - &cert->os_cert_handle()->subject) == SECEqual) { - return (nsstrust.sslFlags & kTrusted) == 0 && - (nsstrust.emailFlags & kTrusted) == 0 && - (nsstrust.objectSigningFlags & kTrusted) == 0; - } - - return false; -} - -bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert, - CertType type, - TrustBits trust_bits) { - bool success = psm::SetCertTrust(cert, type, trust_bits); - if (success) - NotifyObserversOfCertTrustChanged(cert); - - return success; -} - -bool NSSCertDatabase::DeleteCertAndKey(const X509Certificate* cert) { - // For some reason, PK11_DeleteTokenCertAndKey only calls - // SEC_DeletePermCertificate if the private key is found. So, we check - // whether a private key exists before deciding which function to call to - // delete the cert. - SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert->os_cert_handle(), - NULL); - if (privKey) { - SECKEY_DestroyPrivateKey(privKey); - if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) { - LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError(); - return false; - } - } else { - if (SEC_DeletePermCertificate(cert->os_cert_handle())) { - LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError(); - return false; - } - } - - NotifyObserversOfCertRemoved(cert); - - return true; -} - -bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const { - PK11SlotInfo* slot = cert->os_cert_handle()->slot; - return slot && PK11_IsReadOnly(slot); -} - -void NSSCertDatabase::AddObserver(Observer* observer) { - observer_list_->AddObserver(observer); -} - -void NSSCertDatabase::RemoveObserver(Observer* observer) { - observer_list_->RemoveObserver(observer); -} - -void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) { - observer_list_->Notify(&Observer::OnCertAdded, make_scoped_refptr(cert)); -} - -void NSSCertDatabase::NotifyObserversOfCertRemoved( - const X509Certificate* cert) { - observer_list_->Notify(&Observer::OnCertRemoved, make_scoped_refptr(cert)); -} - -void NSSCertDatabase::NotifyObserversOfCertTrustChanged( - const X509Certificate* cert) { - observer_list_->Notify( - &Observer::OnCertTrustChanged, make_scoped_refptr(cert)); -} - -} // namespace net diff --git a/net/base/nss_cert_database.h b/net/base/nss_cert_database.h deleted file mode 100644 index ae8c155..0000000 --- a/net/base/nss_cert_database.h +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_NSS_CERT_DATABASE_H_ -#define NET_BASE_NSS_CERT_DATABASE_H_ - -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/string16.h" -#include "net/base/cert_type.h" -#include "net/base/net_export.h" -#include "net/base/x509_certificate.h" - -template <typename T> struct DefaultSingletonTraits; -template <class ObserverType> class ObserverListThreadSafe; - -namespace net { - -class CryptoModule; -typedef std::vector<scoped_refptr<CryptoModule> > CryptoModuleList; - -// Provides functions to manipulate the NSS certificate stores. -class NET_EXPORT NSSCertDatabase { - public: - - class NET_EXPORT Observer { - 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 certificate's trust is changed. - // Called with |cert| == NULL after importing a list of certificates - // in ImportCACerts(). - virtual void OnCertTrustChanged(const X509Certificate* cert) {} - - protected: - Observer() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Observer); - }; - - // Stores per-certificate error codes for import failures. - struct NET_EXPORT ImportCertFailure { - public: - ImportCertFailure(X509Certificate* cert, int err); - ~ImportCertFailure(); - - scoped_refptr<X509Certificate> certificate; - int net_error; - }; - typedef std::vector<ImportCertFailure> ImportCertFailureList; - - // Constants that define which usages a certificate is trusted for. - // They are used in combination with CertType to specify trust for each type - // of certificate. - // For a CA_CERT, they specify that the CA is trusted for issuing server and - // client certs of each type. - // For SERVER_CERT, only TRUSTED_SSL makes sense, and specifies the cert is - // trusted as a server. - // For EMAIL_CERT, only TRUSTED_EMAIL makes sense, and specifies the cert is - // trusted for email. - // DISTRUSTED_* specifies that the cert should not be trusted for the given - // usage, regardless of whether it would otherwise inherit trust from the - // issuer chain. - // Use TRUST_DEFAULT to inherit trust as normal. - // NOTE: The actual constants are defined using an enum instead of static - // consts due to compilation/linkage constraints with template functions. - typedef uint32 TrustBits; - enum { - TRUST_DEFAULT = 0, - TRUSTED_SSL = 1 << 0, - TRUSTED_EMAIL = 1 << 1, - TRUSTED_OBJ_SIGN = 1 << 2, - DISTRUSTED_SSL = 1 << 3, - DISTRUSTED_EMAIL = 1 << 4, - DISTRUSTED_OBJ_SIGN = 1 << 5, - }; - - static NSSCertDatabase* GetInstance(); - - // Get a list of unique certificates in the certificate database (one - // instance of all certificates). - void ListCerts(CertificateList* certs); - - // Get the default module for public key data. - // The returned pointer must be stored in a scoped_refptr<CryptoModule>. - CryptoModule* GetPublicModule() const; - - // Get the default module for private key or mixed private/public key data. - // The returned pointer must be stored in a scoped_refptr<CryptoModule>. - CryptoModule* GetPrivateModule() const; - - // Get all modules. - // If |need_rw| is true, only writable modules will be returned. - void ListModules(CryptoModuleList* modules, bool need_rw) const; - - // Import certificates and private keys from PKCS #12 blob into the module. - // If |is_extractable| is false, mark the private key as being unextractable - // from the module. - // Returns OK or a network error code such as ERR_PKCS12_IMPORT_BAD_PASSWORD - // or ERR_PKCS12_IMPORT_ERROR. |imported_certs|, if non-NULL, returns a list - // of certs that were imported. - int ImportFromPKCS12(CryptoModule* module, - const std::string& data, - const base::string16& password, - bool is_extractable, - CertificateList* imported_certs); - - // Export the given certificates and private keys into a PKCS #12 blob, - // storing into |output|. - // Returns the number of certificates successfully exported. - int ExportToPKCS12(const CertificateList& certs, - const base::string16& password, - std::string* output) const; - - // Uses similar logic to nsNSSCertificateDB::handleCACertDownload to find the - // root. Assumes the list is an ordered hierarchy with the root being either - // the first or last element. - // TODO(mattm): improve this to handle any order. - X509Certificate* FindRootInList(const CertificateList& certificates) const; - - // Import CA certificates. - // Tries to import all the certificates given. The root will be trusted - // according to |trust_bits|. Any certificates that could not be imported - // will be listed in |not_imported|. - // Returns false if there is an internal error, otherwise true is returned and - // |not_imported| should be checked for any certificates that were not - // imported. - bool ImportCACerts(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported); - - // Import server certificate. The first cert should be the server cert. Any - // additional certs should be intermediate/CA certs and will be imported but - // not given any trust. - // Any certificates that could not be imported will be listed in - // |not_imported|. - // |trust_bits| can be set to explicitly trust or distrust the certificate, or - // use TRUST_DEFAULT to inherit trust as normal. - // Returns false if there is an internal error, otherwise true is returned and - // |not_imported| should be checked for any certificates that were not - // imported. - bool ImportServerCert(const CertificateList& certificates, - TrustBits trust_bits, - ImportCertFailureList* not_imported); - - // Get trust bits for certificate. - TrustBits GetCertTrust(const X509Certificate* cert, CertType type) const; - - // IsUntrusted returns true if |cert| is specifically untrusted. These - // certificates are stored in the database for the specific purpose of - // rejecting them. - bool IsUntrusted(const X509Certificate* cert) const; - - // Set trust values for certificate. - // Returns true on success or false on failure. - bool SetCertTrust(const X509Certificate* cert, - CertType type, - TrustBits trust_bits); - - // Delete certificate and associated private key (if one exists). - // |cert| is still valid when this function returns. Returns true on - // success. - bool DeleteCertAndKey(const X509Certificate* cert); - - // Check whether cert is stored in a readonly slot. - bool IsReadOnly(const X509Certificate* cert) const; - - // 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. - void AddObserver(Observer* observer); - - // Unregisters |observer| from receiving notifications. This must be called - // on the same thread on which AddObserver() was called. - void RemoveObserver(Observer* observer); - - private: - friend struct DefaultSingletonTraits<NSSCertDatabase>; - - NSSCertDatabase(); - ~NSSCertDatabase(); - - // Broadcasts notifications to all registered observers. - void NotifyObserversOfCertAdded(const X509Certificate* cert); - void NotifyObserversOfCertRemoved(const X509Certificate* cert); - void NotifyObserversOfCertTrustChanged(const X509Certificate* cert); - - const scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_; - - DISALLOW_COPY_AND_ASSIGN(NSSCertDatabase); -}; - -} // namespace net - -#endif // NET_BASE_NSS_CERT_DATABASE_H_ diff --git a/net/base/nss_cert_database_unittest.cc b/net/base/nss_cert_database_unittest.cc deleted file mode 100644 index 8564ec7..0000000 --- a/net/base/nss_cert_database_unittest.cc +++ /dev/null @@ -1,929 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <cert.h> -#include <certdb.h> -#include <pk11pub.h> - -#include <algorithm> - -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/lazy_instance.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "crypto/nss_util.h" -#include "crypto/nss_util_internal.h" -#include "crypto/scoped_nss_types.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_test_util.h" -#include "net/base/cert_verify_proc_nss.h" -#include "net/base/cert_verify_result.h" -#include "net/base/crypto_module.h" -#include "net/base/net_errors.h" -#include "net/base/nss_cert_database.h" -#include "net/base/test_data_directory.h" -#include "net/base/x509_certificate.h" -#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" -#include "testing/gtest/include/gtest/gtest.h" - -// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use -// the new name of the macro. -#if !defined(CERTDB_TERMINAL_RECORD) -#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER -#endif - -namespace net { - -class CertDatabaseNSSTest : public testing::Test { - public: - virtual void SetUp() { - ASSERT_TRUE(test_nssdb_.is_open()); - cert_db_ = NSSCertDatabase::GetInstance(); - slot_ = cert_db_->GetPublicModule(); - - // Test db should be empty at start of test. - EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); - } - - virtual void TearDown() { - // Don't try to cleanup if the setup failed. - ASSERT_TRUE(slot_->os_module_handle()); - - EXPECT_TRUE(CleanupSlotContents()); - - // Run the message loop to process any observer callbacks (e.g. for the - // ClientSocketFactory singleton) so that the scoped ref ptrs created in - // NSSCertDatabase::NotifyObservers* get released. - MessageLoop::current()->RunUntilIdle(); - - EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); - } - - protected: - static std::string ReadTestFile(const std::string& name) { - std::string result; - base::FilePath cert_path = GetTestCertsDirectory().AppendASCII(name); - EXPECT_TRUE(file_util::ReadFileToString(cert_path, &result)); - return result; - } - - static bool ReadCertIntoList(const std::string& name, - CertificateList* certs) { - scoped_refptr<X509Certificate> cert( - ImportCertFromFile(GetTestCertsDirectory(), name)); - if (!cert.get()) - return false; - - certs->push_back(cert); - return true; - } - - static CertificateList ListCertsInSlot(PK11SlotInfo* slot) { - CertificateList result; - CERTCertList* cert_list = PK11_ListCertsInSlot(slot); - for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(node, cert_list); - node = CERT_LIST_NEXT(node)) { - result.push_back(X509Certificate::CreateFromHandle( - node->cert, X509Certificate::OSCertHandles())); - } - CERT_DestroyCertList(cert_list); - - // Sort the result so that test comparisons can be deterministic. - std::sort(result.begin(), result.end(), X509Certificate::LessThan()); - return result; - } - - scoped_refptr<CryptoModule> slot_; - NSSCertDatabase* cert_db_; - const CertificateList empty_cert_list_; - - private: - bool CleanupSlotContents() { - bool ok = true; - CertificateList certs = ListCertsInSlot(slot_->os_module_handle()); - CERTCertTrust default_trust = {0}; - for (size_t i = 0; i < certs.size(); ++i) { - // Reset cert trust values to defaults before deleting. Otherwise NSS - // somehow seems to remember the trust which can break following tests. - SECStatus srv = CERT_ChangeCertTrust( - CERT_GetDefaultCertDB(), certs[i]->os_cert_handle(), &default_trust); - if (srv != SECSuccess) - ok = false; - - if (!cert_db_->DeleteCertAndKey(certs[i])) - ok = false; - } - return ok; - } - - crypto::ScopedTestNSSDB test_nssdb_; -}; - -TEST_F(CertDatabaseNSSTest, ListCerts) { - // This test isn't terribly useful, though it will at least let valgrind test - // for leaks. - CertificateList certs; - cert_db_->ListCerts(&certs); - // The test DB is empty, but let's assume there will always be something in - // the other slots. - EXPECT_LT(0U, certs.size()); -} - -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) { - std::string pkcs12_data = ReadTestFile("client.p12"); - - EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD, - cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - base::string16(), - true, // is_extractable - NULL)); - - // Test db should still be empty. - EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); -} - -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) { - std::string pkcs12_data = ReadTestFile("client.p12"); - - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - - EXPECT_EQ("testusercert", - cert->subject().common_name); - - // TODO(mattm): move export test to separate test case? - std::string exported_data; - EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); - ASSERT_LT(0U, exported_data.size()); - // TODO(mattm): further verification of exported data? -} - -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) { - std::string pkcs12_data = ReadTestFile("client.p12"); - - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); - EXPECT_EQ(1U, ListCertsInSlot(slot_->os_module_handle()).size()); - - // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like - // it's ever used. This test verifies that. - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); - EXPECT_EQ(1U, ListCertsInSlot(slot_->os_module_handle()).size()); -} - -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) { - std::string pkcs12_data = ReadTestFile("client.p12"); - - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - false, // is_extractable - NULL)); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - - EXPECT_EQ("testusercert", - cert->subject().common_name); - - std::string exported_data; - EXPECT_EQ(0, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); -} - -// Importing a PKCS#12 file with a certificate but no corresponding -// private key should not mark an existing private key as unextractable. -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) { - std::string pkcs12_data = ReadTestFile("client.p12"); - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - true, // is_extractable - NULL)); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - - // Now import a PKCS#12 file with just a certificate but no private key. - pkcs12_data = ReadTestFile("client-nokey.p12"); - EXPECT_EQ(OK, cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - ASCIIToUTF16("12345"), - false, // is_extractable - NULL)); - - cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - - // Make sure the imported private key is still extractable. - std::string exported_data; - EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"), - &exported_data)); - ASSERT_LT(0U, exported_data.size()); -} - -TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) { - std::string pkcs12_data = "Foobarbaz"; - - EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE, - cert_db_->ImportFromPKCS12(slot_, - pkcs12_data, - base::string16(), - true, // is_extractable - NULL)); - - // Test db should still be empty. - EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); -} - -TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - EXPECT_EQ("Test CA", cert->subject().common_name); - - EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL, - cert_db_->GetCertTrust(cert.get(), CA_CERT)); - - EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | - CERTDB_TRUSTED_CLIENT_CA), - cert->os_cert_handle()->trust->sslFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->emailFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->objectSigningFlags); -} - -TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_EMAIL, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - EXPECT_EQ("Test CA", cert->subject().common_name); - - EXPECT_EQ(NSSCertDatabase::TRUSTED_EMAIL, - cert_db_->GetCertTrust(cert.get(), CA_CERT)); - - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->sslFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | - CERTDB_TRUSTED_CLIENT_CA), - cert->os_cert_handle()->trust->emailFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->objectSigningFlags); -} - -TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_OBJ_SIGN, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> cert(cert_list[0]); - EXPECT_EQ("Test CA", cert->subject().common_name); - - EXPECT_EQ(NSSCertDatabase::TRUSTED_OBJ_SIGN, - cert_db_->GetCertTrust(cert.get(), CA_CERT)); - - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->sslFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - cert->os_cert_handle()->trust->emailFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | - CERTDB_TRUSTED_CLIENT_CA), - cert->os_cert_handle()->trust->objectSigningFlags); -} - -TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "google.single.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - EXPECT_FALSE(certs[0]->os_cert_handle()->isperm); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - ASSERT_EQ(1U, failed.size()); - // Note: this compares pointers directly. It's okay in this case because - // ImportCACerts returns the same pointers that were passed in. In the - // general case IsSameOSCert should be used. - EXPECT_EQ(certs[0], failed[0].certificate); - EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[0].net_error); - - EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); -} - -TEST_F(CertDatabaseNSSTest, ImportCACertHierarchy) { - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs)); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - // Have to specify email trust for the cert verification of the child cert to - // work (see - // http://mxr.mozilla.org/mozilla/source/security/nss/lib/certhigh/certvfy.c#752 - // "XXX This choice of trustType seems arbitrary.") - EXPECT_TRUE(cert_db_->ImportCACerts( - certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, - &failed)); - - ASSERT_EQ(2U, failed.size()); - EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[0].net_error); // The certificate expired. - EXPECT_EQ("www.us.army.mil", failed[1].certificate->subject().common_name); - EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[1].net_error); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name); -} - -TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) { - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs)); - - // First import just the root. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts( - certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, - &failed)); - - EXPECT_EQ(0U, failed.size()); - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name); - - ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs)); - - // Now import with the other certs in the list too. Even though the root is - // already present, we should still import the rest. - failed.clear(); - EXPECT_TRUE(cert_db_->ImportCACerts( - certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, - &failed)); - - ASSERT_EQ(3U, failed.size()); - EXPECT_EQ("DoD Root CA 2", failed[0].certificate->subject().common_name); - EXPECT_EQ(ERR_IMPORT_CERT_ALREADY_EXISTS, failed[0].net_error); - EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[1].net_error); // The certificate expired. - EXPECT_EQ("www.us.army.mil", failed[2].certificate->subject().common_name); - EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[2].net_error); - - cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name); -} - -TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyUntrusted) { - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUST_DEFAULT, - &failed)); - - ASSERT_EQ(1U, failed.size()); - EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name); - // TODO(mattm): should check for net error equivalent of - // SEC_ERROR_UNTRUSTED_ISSUER - EXPECT_EQ(ERR_FAILED, failed[0].net_error); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name); -} - -TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyTree) { - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts( - certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL, - &failed)); - - EXPECT_EQ(2U, failed.size()); - EXPECT_EQ("DOD CA-13", failed[0].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[0].net_error); // The certificate expired. - EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[1].net_error); // The certificate expired. - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name); -} - -TEST_F(CertDatabaseNSSTest, ImportCACertNotHierarchy) { - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs)); - ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs)); - - // Import it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts( - certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL | - NSSCertDatabase::TRUSTED_OBJ_SIGN, &failed)); - - ASSERT_EQ(2U, failed.size()); - // TODO(mattm): should check for net error equivalent of - // SEC_ERROR_UNKNOWN_ISSUER - EXPECT_EQ("DOD CA-13", failed[0].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[0].net_error); - EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name); - EXPECT_EQ(ERR_FAILED, failed[1].net_error); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - EXPECT_EQ("Test CA", cert_list[0]->subject().common_name); -} - -// http://crbug.com/108009 - Disabled, as google.chain.pem is an expired -// certificate. -TEST_F(CertDatabaseNSSTest, DISABLED_ImportServerCert) { - // Need to import intermediate cert for the verify of google cert, otherwise - // it will try to fetch it automatically with cert_pi_useAIACertFetch, which - // will cause OCSPCreateSession on the main thread, which is not allowed. - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "google.chain.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(2U, certs.size()); - - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(2U, cert_list.size()); - scoped_refptr<X509Certificate> goog_cert(cert_list[0]); - scoped_refptr<X509Certificate> thawte_cert(cert_list[1]); - EXPECT_EQ("www.google.com", goog_cert->subject().common_name); - EXPECT_EQ("Thawte SGC CA", thawte_cert->subject().common_name); - - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(goog_cert.get(), SERVER_CERT)); - - EXPECT_EQ(0U, goog_cert->os_cert_handle()->trust->sslFlags); - - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(goog_cert, "www.google.com", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); -} - -TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) { - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("punycodetest.der", &certs)); - - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> puny_cert(cert_list[0]); - - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT)); - EXPECT_EQ(0U, puny_cert->os_cert_handle()->trust->sslFlags); - - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(puny_cert, "xn--wgv71a119e.com", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); - EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); -} - -TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned_Trusted) { - // When using CERT_PKIXVerifyCert (which we do), server trust only works from - // 3.13.4 onwards. See https://bugzilla.mozilla.org/show_bug.cgi?id=647364. - if (!NSS_VersionCheck("3.13.4")) { - LOG(INFO) << "test skipped on NSS < 3.13.4"; - return; - } - - CertificateList certs; - ASSERT_TRUE(ReadCertIntoList("punycodetest.der", &certs)); - - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - - EXPECT_EQ(0U, failed.size()); - - CertificateList cert_list = ListCertsInSlot(slot_->os_module_handle()); - ASSERT_EQ(1U, cert_list.size()); - scoped_refptr<X509Certificate> puny_cert(cert_list[0]); - - EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL, - cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT)); - EXPECT_EQ(unsigned(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD), - puny_cert->os_cert_handle()->trust->sslFlags); - - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(puny_cert, "xn--wgv71a119e.com", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); -} - -TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert) { - CertificateList ca_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_certs.size()); - - // Import CA cert and trust it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "ok_cert.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert with default trust. - EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT, - &failed)); - EXPECT_EQ(0U, failed.size()); - - // Server cert should verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); -} - -TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert_DistrustServer) { - // Explicit distrust only works starting in NSS 3.13. - if (!NSS_VersionCheck("3.13")) { - LOG(INFO) << "test skipped on NSS < 3.13"; - return; - } - - CertificateList ca_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "root_ca_cert.crt", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_certs.size()); - - // Import CA cert and trust it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "ok_cert.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert without inheriting trust from issuer (explicit - // distrust). - EXPECT_TRUE(cert_db_->ImportServerCert( - certs, NSSCertDatabase::DISTRUSTED_SSL, &failed)); - EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(NSSCertDatabase::DISTRUSTED_SSL, - cert_db_->GetCertTrust(certs[0], SERVER_CERT)); - - EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD), - certs[0]->os_cert_handle()->trust->sslFlags); - - // Server cert should fail to verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_REVOKED, error); - EXPECT_EQ(CERT_STATUS_REVOKED, verify_result.cert_status); -} - -TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) { - CertificateList ca_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-root.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_certs.size()); - - // Import Root CA cert and distrust it. - NSSCertDatabase::ImportCertFailureList failed; - EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::DISTRUSTED_SSL, - &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList intermediate_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, intermediate_certs.size()); - - // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, - NSSCertDatabase::TRUSTED_SSL, &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert with default trust. - EXPECT_TRUE(cert_db_->ImportServerCert( - certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); - EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(certs[0], SERVER_CERT)); - - // Server cert should verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - - // Explicit distrust only works starting in NSS 3.13. - if (!NSS_VersionCheck("3.13")) { - LOG(INFO) << "test partially skipped on NSS < 3.13"; - return; - } - - // Trust the root cert and distrust the intermediate. - EXPECT_TRUE(cert_db_->SetCertTrust( - ca_certs[0], CA_CERT, NSSCertDatabase::TRUSTED_SSL)); - EXPECT_TRUE(cert_db_->SetCertTrust( - intermediate_certs[0], CA_CERT, NSSCertDatabase::DISTRUSTED_SSL)); - EXPECT_EQ( - unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA), - ca_certs[0]->os_cert_handle()->trust->sslFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - ca_certs[0]->os_cert_handle()->trust->emailFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - ca_certs[0]->os_cert_handle()->trust->objectSigningFlags); - EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD), - intermediate_certs[0]->os_cert_handle()->trust->sslFlags); - EXPECT_EQ(unsigned(CERTDB_VALID_CA), - intermediate_certs[0]->os_cert_handle()->trust->emailFlags); - EXPECT_EQ( - unsigned(CERTDB_VALID_CA), - intermediate_certs[0]->os_cert_handle()->trust->objectSigningFlags); - - // Server cert should fail to verify. - CertVerifyResult verify_result2; - error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result2); - EXPECT_EQ(ERR_CERT_REVOKED, error); - EXPECT_EQ(CERT_STATUS_REVOKED, verify_result2.cert_status); -} - -TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) { - NSSCertDatabase::ImportCertFailureList failed; - - CertificateList intermediate_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, intermediate_certs.size()); - - // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, - NSSCertDatabase::TRUSTED_SSL, &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert with default trust. - EXPECT_TRUE(cert_db_->ImportServerCert( - certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); - EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(certs[0], SERVER_CERT)); - - // Server cert should verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - - // Without explicit trust of the intermediate, verification should fail. - EXPECT_TRUE(cert_db_->SetCertTrust( - intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); - - // Server cert should fail to verify. - CertVerifyResult verify_result2; - error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result2); - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); - EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status); -} - -TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) { - NSSCertDatabase::ImportCertFailureList failed; - - CertificateList ca_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-root.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_certs.size()); - - // Import Root CA cert and default trust it. - EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUST_DEFAULT, - &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList intermediate_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, intermediate_certs.size()); - - // Import Intermediate CA cert and trust it. - EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs, - NSSCertDatabase::TRUSTED_SSL, &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert with default trust. - EXPECT_TRUE(cert_db_->ImportServerCert( - certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); - EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(certs[0], SERVER_CERT)); - - // Server cert should verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result.cert_status); - - // Without explicit trust of the intermediate, verification should fail. - EXPECT_TRUE(cert_db_->SetCertTrust( - intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); - - // Server cert should fail to verify. - CertVerifyResult verify_result2; - error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result2); - EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); - EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status); -} - -TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) { - // Explicit distrust only works starting in NSS 3.13. - if (!NSS_VersionCheck("3.13")) { - LOG(INFO) << "test skipped on NSS < 3.13"; - return; - } - - NSSCertDatabase::ImportCertFailureList failed; - - CertificateList ca_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-root.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, ca_certs.size()); - - // Import Root CA cert and trust it. - EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL, - &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList intermediate_certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, intermediate_certs.size()); - - // Import Intermediate CA cert and distrust it. - EXPECT_TRUE(cert_db_->ImportCACerts( - intermediate_certs, NSSCertDatabase::DISTRUSTED_SSL, &failed)); - EXPECT_EQ(0U, failed.size()); - - CertificateList certs = CreateCertificateListFromFile( - GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem", - X509Certificate::FORMAT_AUTO); - ASSERT_EQ(1U, certs.size()); - - // Import server cert with default trust. - EXPECT_TRUE(cert_db_->ImportServerCert( - certs, NSSCertDatabase::TRUST_DEFAULT, &failed)); - EXPECT_EQ(0U, failed.size()); - EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT, - cert_db_->GetCertTrust(certs[0], SERVER_CERT)); - - // Server cert should not verify. - scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS()); - int flags = 0; - CertVerifyResult verify_result; - int error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result); - EXPECT_EQ(ERR_CERT_REVOKED, error); - EXPECT_EQ(CERT_STATUS_REVOKED, verify_result.cert_status); - - // Without explicit distrust of the intermediate, verification should succeed. - EXPECT_TRUE(cert_db_->SetCertTrust( - intermediate_certs[0], CA_CERT, NSSCertDatabase::TRUST_DEFAULT)); - - // Server cert should verify. - CertVerifyResult verify_result2; - error = verify_proc->Verify(certs[0], "127.0.0.1", flags, - NULL, empty_cert_list_, &verify_result2); - EXPECT_EQ(OK, error); - EXPECT_EQ(0U, verify_result2.cert_status); -} - -} // namespace net diff --git a/net/base/openssl_client_key_store.cc b/net/base/openssl_client_key_store.cc index 5cae6c5..426a4c2 100644 --- a/net/base/openssl_client_key_store.cc +++ b/net/base/openssl_client_key_store.cc @@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" -#include "net/base/x509_certificate.h" +#include "net/cert/x509_certificate.h" namespace net { diff --git a/net/base/openssl_client_key_store_unittest.cc b/net/base/openssl_client_key_store_unittest.cc index 0b6506a..89db51e 100644 --- a/net/base/openssl_client_key_store_unittest.cc +++ b/net/base/openssl_client_key_store_unittest.cc @@ -5,8 +5,8 @@ #include "net/base/openssl_client_key_store.h" #include "base/memory/ref_counted.h" -#include "net/base/cert_test_util.h" #include "net/base/test_data_directory.h" +#include "net/test/cert_test_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/net/base/pem_tokenizer.cc b/net/base/pem_tokenizer.cc deleted file mode 100644 index c79eec1..0000000 --- a/net/base/pem_tokenizer.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/pem_tokenizer.h" - -#include "base/base64.h" -#include "base/string_util.h" -#include "base/stringprintf.h" - -namespace { - -const char kPEMSearchBlock[] = "-----BEGIN "; -const char kPEMBeginBlock[] = "-----BEGIN %s-----"; -const char kPEMEndBlock[] = "-----END %s-----"; - -} // namespace - -namespace net { - -using base::StringPiece; - -struct PEMTokenizer::PEMType { - std::string type; - std::string header; - std::string footer; -}; - -PEMTokenizer::PEMTokenizer( - const StringPiece& str, - const std::vector<std::string>& allowed_block_types) { - Init(str, allowed_block_types); -} - -PEMTokenizer::~PEMTokenizer() { -} - -bool PEMTokenizer::GetNext() { - while (pos_ != StringPiece::npos) { - // Scan for the beginning of the next PEM encoded block. - pos_ = str_.find(kPEMSearchBlock, pos_); - if (pos_ == StringPiece::npos) - return false; // No more PEM blocks - - std::vector<PEMType>::const_iterator it; - // Check to see if it is of an acceptable block type. - for (it = block_types_.begin(); it != block_types_.end(); ++it) { - if (!str_.substr(pos_).starts_with(it->header)) - continue; - - // Look for a footer matching the header. If none is found, then all - // data following this point is invalid and should not be parsed. - StringPiece::size_type footer_pos = str_.find(it->footer, pos_); - if (footer_pos == StringPiece::npos) { - pos_ = StringPiece::npos; - return false; - } - - // Chop off the header and footer and parse the data in between. - StringPiece::size_type data_begin = pos_ + it->header.size(); - pos_ = footer_pos + it->footer.size(); - block_type_ = it->type; - - StringPiece encoded = str_.substr(data_begin, - footer_pos - data_begin); - if (!base::Base64Decode(CollapseWhitespaceASCII(encoded.as_string(), - true), &data_)) { - // The most likely cause for a decode failure is a datatype that - // includes PEM headers, which are not supported. - break; - } - - return true; - } - - // If the block did not match any acceptable type, move past it and - // continue the search. Otherwise, |pos_| has been updated to the most - // appropriate search position to continue searching from and should not - // be adjusted. - if (it == block_types_.end()) - pos_ += sizeof(kPEMSearchBlock); - } - - return false; -} - -void PEMTokenizer::Init( - const StringPiece& str, - const std::vector<std::string>& allowed_block_types) { - str_ = str; - pos_ = 0; - - // Construct PEM header/footer strings for all the accepted types, to - // reduce parsing later. - for (std::vector<std::string>::const_iterator it = - allowed_block_types.begin(); it != allowed_block_types.end(); ++it) { - PEMType allowed_type; - allowed_type.type = *it; - allowed_type.header = base::StringPrintf(kPEMBeginBlock, it->c_str()); - allowed_type.footer = base::StringPrintf(kPEMEndBlock, it->c_str()); - block_types_.push_back(allowed_type); - } -} - -} // namespace net diff --git a/net/base/pem_tokenizer.h b/net/base/pem_tokenizer.h deleted file mode 100644 index ea1fae9..0000000 --- a/net/base/pem_tokenizer.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_PEM_TOKENIZER_H_ -#define NET_BASE_PEM_TOKENIZER_H_ - -#include <string> -#include <vector> - -#include "base/string_piece.h" -#include "net/base/net_export.h" - -namespace net { - -// PEMTokenizer is a utility class for the parsing of data encapsulated -// using RFC 1421, Privacy Enhancement for Internet Electronic Mail. It -// does not implement the full specification, most notably it does not -// support the Encapsulated Header Portion described in Section 4.4. -class NET_EXPORT_PRIVATE PEMTokenizer { - public: - // Create a new PEMTokenizer that iterates through |str| searching for - // instances of PEM encoded blocks that are of the |allowed_block_types|. - // |str| must remain valid for the duration of the PEMTokenizer. - PEMTokenizer(const base::StringPiece& str, - const std::vector<std::string>& allowed_block_types); - ~PEMTokenizer(); - - // Attempts to decode the next PEM block in the string. Returns false if no - // PEM blocks can be decoded. The decoded PEM block will be available via - // data(). - bool GetNext(); - - // Returns the PEM block type (eg: CERTIFICATE) of the last successfully - // decoded PEM block. - // GetNext() must have returned true before calling this method. - const std::string& block_type() const { return block_type_; } - - // Returns the raw, Base64-decoded data of the last successfully decoded - // PEM block. - // GetNext() must have returned true before calling this method. - const std::string& data() const { return data_; } - - private: - void Init(const base::StringPiece& str, - const std::vector<std::string>& allowed_block_types); - - // A simple cache of the allowed PEM header and footer for a given PEM - // block type, so that it is only computed once. - struct PEMType; - - // The string to search, which must remain valid for as long as this class - // is around. - base::StringPiece str_; - - // The current position within |str_| that searching should begin from, - // or StringPiece::npos if iteration is complete - base::StringPiece::size_type pos_; - - // The type of data that was encoded, as indicated in the PEM - // Pre-Encapsulation Boundary (eg: CERTIFICATE, PKCS7, or - // PRIVACY-ENHANCED MESSAGE). - std::string block_type_; - - // The types of PEM blocks that are allowed. PEM blocks that are not of - // one of these types will be skipped. - std::vector<PEMType> block_types_; - - // The raw (Base64-decoded) data of the last successfully decoded block. - std::string data_; - - DISALLOW_COPY_AND_ASSIGN(PEMTokenizer); -}; - -} // namespace net - -#endif // NET_BASE_PEM_TOKENIZER_H_ diff --git a/net/base/pem_tokenizer_unittest.cc b/net/base/pem_tokenizer_unittest.cc deleted file mode 100644 index af2446c..0000000 --- a/net/base/pem_tokenizer_unittest.cc +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/pem_tokenizer.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -TEST(PEMTokenizerTest, BasicParsing) { - const char data[] = - "-----BEGIN EXPECTED-BLOCK-----\n" - "TWF0Y2hlc0FjY2VwdGVkQmxvY2tUeXBl\n" - "-----END EXPECTED-BLOCK-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("EXPECTED-BLOCK"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("EXPECTED-BLOCK", tokenizer.block_type()); - EXPECT_EQ("MatchesAcceptedBlockType", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, CarriageReturnLineFeeds) { - const char data[] = - "-----BEGIN EXPECTED-BLOCK-----\r\n" - "TWF0Y2hlc0FjY2VwdGVkQmxvY2tUeXBl\r\n" - "-----END EXPECTED-BLOCK-----\r\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("EXPECTED-BLOCK"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("EXPECTED-BLOCK", tokenizer.block_type()); - EXPECT_EQ("MatchesAcceptedBlockType", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, NoAcceptedBlockTypes) { - const char data[] = - "-----BEGIN UNEXPECTED-BLOCK-----\n" - "SWdub3Jlc1JlamVjdGVkQmxvY2tUeXBl\n" - "-----END UNEXPECTED-BLOCK-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("EXPECTED-BLOCK"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, MultipleAcceptedBlockTypes) { - const char data[] = - "-----BEGIN BLOCK-ONE-----\n" - "RW5jb2RlZERhdGFPbmU=\n" - "-----END BLOCK-ONE-----\n" - "-----BEGIN BLOCK-TWO-----\n" - "RW5jb2RlZERhdGFUd28=\n" - "-----END BLOCK-TWO-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("BLOCK-ONE"); - accepted_types.push_back("BLOCK-TWO"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("BLOCK-ONE", tokenizer.block_type()); - EXPECT_EQ("EncodedDataOne", tokenizer.data()); - - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("BLOCK-TWO", tokenizer.block_type()); - EXPECT_EQ("EncodedDataTwo", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, MissingFooter) { - const char data[] = - "-----BEGIN MISSING-FOOTER-----\n" - "RW5jb2RlZERhdGFPbmU=\n" - "-----END MISSING-FOOTER-----\n" - "-----BEGIN MISSING-FOOTER-----\n" - "RW5jb2RlZERhdGFUd28=\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("MISSING-FOOTER"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("MISSING-FOOTER", tokenizer.block_type()); - EXPECT_EQ("EncodedDataOne", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, NestedEncoding) { - const char data[] = - "-----BEGIN BLOCK-ONE-----\n" - "RW5jb2RlZERhdGFPbmU=\n" - "-----BEGIN BLOCK-TWO-----\n" - "RW5jb2RlZERhdGFUd28=\n" - "-----END BLOCK-TWO-----\n" - "-----END BLOCK-ONE-----\n" - "-----BEGIN BLOCK-ONE-----\n" - "RW5jb2RlZERhdGFUaHJlZQ==\n" - "-----END BLOCK-ONE-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("BLOCK-ONE"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("BLOCK-ONE", tokenizer.block_type()); - EXPECT_EQ("EncodedDataThree", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, EmptyAcceptedTypes) { - const char data[] = - "-----BEGIN BLOCK-ONE-----\n" - "RW5jb2RlZERhdGFPbmU=\n" - "-----END BLOCK-ONE-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_FALSE(tokenizer.GetNext()); -} - -TEST(PEMTokenizerTest, BlockWithHeader) { - const char data[] = - "-----BEGIN BLOCK-ONE-----\n" - "Header-One: Data data data\n" - "Header-Two: \n" - " continuation\n" - "Header-Three: Mix-And,Match\n" - "\n" - "RW5jb2RlZERhdGFPbmU=\n" - "-----END BLOCK-ONE-----\n" - "-----BEGIN BLOCK-ONE-----\n" - "RW5jb2RlZERhdGFUd28=\n" - "-----END BLOCK-ONE-----\n"; - base::StringPiece string_piece(data); - std::vector<std::string> accepted_types; - accepted_types.push_back("BLOCK-ONE"); - - PEMTokenizer tokenizer(string_piece, accepted_types); - EXPECT_TRUE(tokenizer.GetNext()); - - EXPECT_EQ("BLOCK-ONE", tokenizer.block_type()); - EXPECT_EQ("EncodedDataTwo", tokenizer.data()); - - EXPECT_FALSE(tokenizer.GetNext()); -} - -} // namespace net diff --git a/net/base/single_request_cert_verifier.cc b/net/base/single_request_cert_verifier.cc deleted file mode 100644 index 1777945..0000000 --- a/net/base/single_request_cert_verifier.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/single_request_cert_verifier.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "net/base/net_errors.h" -#include "net/base/x509_certificate.h" - -namespace net { - -SingleRequestCertVerifier::SingleRequestCertVerifier( - CertVerifier* cert_verifier) - : cert_verifier_(cert_verifier), - cur_request_(NULL) { - DCHECK(cert_verifier_ != NULL); -} - -SingleRequestCertVerifier::~SingleRequestCertVerifier() { - if (cur_request_) { - cert_verifier_->CancelRequest(cur_request_); - cur_request_ = NULL; - } -} - -int SingleRequestCertVerifier::Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - const BoundNetLog& net_log) { - // Should not be already in use. - DCHECK(!cur_request_ && cur_request_callback_.is_null()); - - CertVerifier::RequestHandle request = NULL; - - // We need to be notified of completion before |callback| is called, so that - // we can clear out |cur_request_*|. - int rv = cert_verifier_->Verify( - cert, hostname, flags, crl_set, verify_result, - base::Bind(&SingleRequestCertVerifier::OnVerifyCompletion, - base::Unretained(this)), - &request, net_log); - - if (rv == ERR_IO_PENDING) { - // Cleared in OnVerifyCompletion(). - cur_request_ = request; - cur_request_callback_ = callback; - } - - return rv; -} - -void SingleRequestCertVerifier::OnVerifyCompletion(int result) { - DCHECK(cur_request_ && !cur_request_callback_.is_null()); - - CompletionCallback callback = cur_request_callback_; - - // Clear the outstanding request information. - cur_request_ = NULL; - cur_request_callback_.Reset(); - - // Call the user's original callback. - callback.Run(result); -} - -} // namespace net diff --git a/net/base/single_request_cert_verifier.h b/net/base/single_request_cert_verifier.h deleted file mode 100644 index 29d9f04..0000000 --- a/net/base/single_request_cert_verifier.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_SINGLE_REQUEST_CERT_VERIFIER_H_ -#define NET_BASE_SINGLE_REQUEST_CERT_VERIFIER_H_ - -#include "net/base/cert_verifier.h" - -namespace net { - -// This class represents the task of verifying a certificate. It wraps -// CertVerifier to verify only a single certificate at a time and cancels this -// request when going out of scope. -class SingleRequestCertVerifier { - public: - // |cert_verifier| must remain valid for the lifetime of |this|. - explicit SingleRequestCertVerifier(CertVerifier* cert_verifier); - - // If a completion callback is pending when the verifier is destroyed, the - // certificate verification is canceled, and the completion callback will - // not be called. - ~SingleRequestCertVerifier(); - - // Verifies the given certificate, filling out the |verify_result| object - // upon success. See CertVerifier::Verify() for details. - int Verify(X509Certificate* cert, - const std::string& hostname, - int flags, - CRLSet* crl_set, - CertVerifyResult* verify_result, - const CompletionCallback& callback, - const BoundNetLog& net_log); - - private: - // Callback for when the request to |cert_verifier_| completes, so we - // dispatch to the user's callback. - void OnVerifyCompletion(int result); - - // The actual certificate verifier that will handle the request. - CertVerifier* const cert_verifier_; - - // The current request (if any). - CertVerifier::RequestHandle cur_request_; - CompletionCallback cur_request_callback_; - - DISALLOW_COPY_AND_ASSIGN(SingleRequestCertVerifier); -}; - -} // namespace net - -#endif // NET_BASE_SINGLE_REQUEST_CERT_VERIFIER_H_ diff --git a/net/base/test_certificate_data.h b/net/base/test_certificate_data.h deleted file mode 100644 index edbbc36..0000000 --- a/net/base/test_certificate_data.h +++ /dev/null @@ -1,843 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -namespace { - -// This is the SHA1 hash of the SubjectPublicKeyInfo of nist.der. -static const char kNistSPKIHash[] = - "\x15\x60\xde\x65\x4e\x03\x9f\xd0\x08\x82" - "\xa9\x6a\xc4\x65\x8e\x6f\x92\x06\x84\x35"; - -// kCertSESPKIs contains the SHA1 hashes of the SPKIs of the certse.pem -// certificate chain, in order. -static const char kCertSESPKIs[3][21] = { - "\x3f\x6c\xf3\xf1\xc9\xdf\xb6\x63\xa8\x05" - "\x44\x75\x9a\xac\x21\x4a\x74\xb2\xa5\xa4", - "\xae\x4a\xd7\xf9\xb3\x80\xe1\x12\x93\x32" - "\xbb\x52\xde\x5a\x09\x0c\x52\x1b\x33\xd0", - "\xb1\x81\x08\x1a\x19\xa4\xc0\x94\x1f\xfa" - "\xe8\x95\x28\xc1\x24\xc9\x9b\x34\xac\xc7", -}; - -// Certificates for test data. They're obtained with: -// -// $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null -// $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der -// $ xxd -i /tmp/host.der -// -// TODO(wtc): move these certificates to data files in the -// src/net/data/ssl/certificates directory. - -// The linux compiler is nitty about unused variables. Declaring variables -// in headers is not generally a good idea, but for our test data it is not -// a big deal. Mark these as potentially unused so that the compiler won't -// complain. -#ifdef __GNUC__ -#define VARIABLE_IS_NOT_USED __attribute__ ((unused)) -#else -#define VARIABLE_IS_NOT_USED -#endif - -// Google's cert. - -unsigned char VARIABLE_IS_NOT_USED google_der[] = { - 0x30, 0x82, 0x03, 0x21, 0x30, 0x82, 0x02, 0x8a, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x01, 0x2a, 0x39, 0x76, 0x0d, 0x3f, 0x4f, 0xc9, 0x0b, - 0xe7, 0xbd, 0x2b, 0xcf, 0x95, 0x2e, 0x7a, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a, - 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, - 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20, - 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x47, - 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x33, - 0x32, 0x37, 0x32, 0x32, 0x32, 0x30, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x31, - 0x30, 0x30, 0x33, 0x32, 0x37, 0x32, 0x32, 0x32, 0x30, 0x30, 0x37, 0x5a, - 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x4d, - 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x17, 0x30, - 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0e, 0x77, 0x77, 0x77, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, - 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, - 0x81, 0x81, 0x00, 0xd6, 0xb9, 0xe1, 0xad, 0xb8, 0x61, 0x0b, 0x1f, 0x4e, - 0xb6, 0x3c, 0x09, 0x3d, 0xab, 0xe8, 0xe3, 0x2b, 0xb6, 0xe8, 0xa4, 0x3a, - 0x78, 0x2f, 0xd3, 0x51, 0x20, 0x22, 0x45, 0x95, 0xd8, 0x00, 0x91, 0x33, - 0x9a, 0xa7, 0xa2, 0x48, 0xea, 0x30, 0x57, 0x26, 0x97, 0x66, 0xc7, 0x5a, - 0xef, 0xf1, 0x9b, 0x0c, 0x3f, 0xe1, 0xb9, 0x7f, 0x7b, 0xc3, 0xc7, 0xcc, - 0xaf, 0x9c, 0xd0, 0x1f, 0x3c, 0x81, 0x15, 0x10, 0x58, 0xfc, 0x06, 0xb3, - 0xbf, 0xbc, 0x9c, 0x02, 0xb9, 0x51, 0xdc, 0xfb, 0xa6, 0xb9, 0x17, 0x42, - 0xe6, 0x46, 0xe7, 0x22, 0xcf, 0x6c, 0x27, 0x10, 0xfe, 0x54, 0xe6, 0x92, - 0x6c, 0x0c, 0x60, 0x76, 0x9a, 0xce, 0xf8, 0x7f, 0xac, 0xb8, 0x5a, 0x08, - 0x4a, 0xdc, 0xb1, 0x64, 0xbd, 0xa0, 0x74, 0x41, 0xb2, 0xac, 0x8f, 0x86, - 0x9d, 0x1a, 0xde, 0x58, 0x09, 0xfd, 0x6c, 0x0a, 0x25, 0xe0, 0x79, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x28, - 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, - 0xf8, 0x42, 0x04, 0x01, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, - 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, - 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, - 0x77, 0x74, 0x65, 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, - 0x30, 0x72, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x04, 0x66, 0x30, 0x64, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x02, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x5f, 0x53, 0x47, - 0x43, 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0c, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x39, 0xb6, 0xfb, 0x11, 0xbc, 0x33, 0x2c, - 0xc3, 0x90, 0x48, 0xe3, 0x6e, 0xc3, 0x9b, 0x38, 0xb1, 0x42, 0xd1, 0x00, - 0x09, 0x58, 0x63, 0xa0, 0xe1, 0x98, 0x1c, 0x85, 0xf2, 0xef, 0x10, 0x1d, - 0x60, 0x4e, 0x51, 0x09, 0x62, 0xf5, 0x05, 0xbd, 0x9d, 0x4f, 0x87, 0x6c, - 0x98, 0x72, 0x07, 0x80, 0xc3, 0x59, 0x48, 0x14, 0xe2, 0xd6, 0xef, 0xd0, - 0x8f, 0x33, 0x6a, 0x68, 0x31, 0xfa, 0xb7, 0xbb, 0x85, 0xcc, 0xf7, 0xc7, - 0x47, 0x7b, 0x67, 0x93, 0x3c, 0xc3, 0x16, 0x51, 0x9b, 0x6f, 0x87, 0x20, - 0xfd, 0x67, 0x4c, 0x2b, 0xea, 0x6a, 0x49, 0xdb, 0x11, 0xd1, 0xbd, 0xd7, - 0x95, 0x22, 0x43, 0x7a, 0x06, 0x7b, 0x4e, 0xf6, 0x37, 0x8e, 0xa2, 0xb9, - 0xcf, 0x1f, 0xa5, 0xd2, 0xbd, 0x3b, 0x04, 0x97, 0x39, 0xb3, 0x0f, 0xfa, - 0x38, 0xb5, 0xaf, 0x55, 0x20, 0x88, 0x60, 0x93, 0xf2, 0xde, 0xdb, 0xff, - 0xdf -}; - -// webkit.org's cert. - -unsigned char VARIABLE_IS_NOT_USED webkit_der[] = { - 0x30, 0x82, 0x05, 0x0d, 0x30, 0x82, 0x03, 0xf5, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x43, 0xdd, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xca, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, - 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, - 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x27, - 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x05, - 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 0x30, 0x1e, - 0x17, 0x0d, 0x30, 0x38, 0x30, 0x33, 0x31, 0x38, 0x32, 0x33, 0x33, 0x35, - 0x31, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x33, 0x31, 0x38, 0x32, - 0x33, 0x33, 0x35, 0x31, 0x39, 0x5a, 0x30, 0x79, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, - 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, - 0x6e, 0x6f, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x61, - 0x63, 0x20, 0x4f, 0x53, 0x20, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x31, 0x15, - 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0c, 0x2a, 0x2e, 0x77, - 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x81, 0x9f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, - 0x81, 0x00, 0xa7, 0x62, 0x79, 0x41, 0xda, 0x28, 0xf2, 0xc0, 0x4f, 0xe0, - 0x25, 0xaa, 0xa1, 0x2e, 0x3b, 0x30, 0x94, 0xb5, 0xc9, 0x26, 0x3a, 0x1b, - 0xe2, 0xd0, 0xcc, 0xa2, 0x95, 0xe2, 0x91, 0xc0, 0xf0, 0x40, 0x9e, 0x27, - 0x6e, 0xbd, 0x6e, 0xde, 0x7c, 0xb6, 0x30, 0x5c, 0xb8, 0x9b, 0x01, 0x2f, - 0x92, 0x04, 0xa1, 0xef, 0x4a, 0xb1, 0x6c, 0xb1, 0x7e, 0x8e, 0xcd, 0xa6, - 0xf4, 0x40, 0x73, 0x1f, 0x2c, 0x96, 0xad, 0xff, 0x2a, 0x6d, 0x0e, 0xba, - 0x52, 0x84, 0x83, 0xb0, 0x39, 0xee, 0xc9, 0x39, 0xdc, 0x1e, 0x34, 0xd0, - 0xd8, 0x5d, 0x7a, 0x09, 0xac, 0xa9, 0xee, 0xca, 0x65, 0xf6, 0x85, 0x3a, - 0x6b, 0xee, 0xe4, 0x5c, 0x5e, 0xf8, 0xda, 0xd1, 0xce, 0x88, 0x47, 0xcd, - 0x06, 0x21, 0xe0, 0xb9, 0x4b, 0xe4, 0x07, 0xcb, 0x57, 0xdc, 0xca, 0x99, - 0x54, 0xf7, 0x0e, 0xd5, 0x17, 0x95, 0x05, 0x2e, 0xe9, 0xb1, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xce, 0x30, 0x82, 0x01, 0xca, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x57, 0x06, 0x03, 0x55, 0x1d, - 0x1f, 0x04, 0x50, 0x30, 0x4e, 0x30, 0x4c, 0xa0, 0x4a, 0xa0, 0x48, 0x86, - 0x46, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, - 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x6f, 0x64, 0x61, - 0x64, 0x64, 0x79, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x69, - 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x52, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4b, 0x30, 0x49, 0x30, 0x47, - 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, 0x01, 0x07, 0x17, - 0x02, 0x30, 0x38, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, - 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, - 0x7f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x73, 0x30, 0x71, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x48, 0xdf, 0x60, 0x32, 0xcc, - 0x89, 0x01, 0xb6, 0xdc, 0x2f, 0xe3, 0x73, 0xb5, 0x9c, 0x16, 0x58, 0x32, - 0x68, 0xa9, 0xc3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, - 0xe2, 0xee, 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, - 0x30, 0x23, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x1c, 0x30, 0x1a, 0x82, - 0x0c, 0x2a, 0x2e, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2e, 0x6f, 0x72, - 0x67, 0x82, 0x0a, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2e, 0x6f, 0x72, - 0x67, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x1e, 0x6a, 0xe7, - 0xe0, 0x4f, 0xe7, 0x4d, 0xd0, 0x69, 0x7c, 0xf8, 0x8f, 0x99, 0xb4, 0x18, - 0x95, 0x36, 0x24, 0x0f, 0x0e, 0xa3, 0xea, 0x34, 0x37, 0xf4, 0x7d, 0xd5, - 0x92, 0x35, 0x53, 0x72, 0x76, 0x3f, 0x69, 0xf0, 0x82, 0x56, 0xe3, 0x94, - 0x7a, 0x1d, 0x1a, 0x81, 0xaf, 0x9f, 0xc7, 0x43, 0x01, 0x64, 0xd3, 0x7c, - 0x0d, 0xc8, 0x11, 0x4e, 0x4a, 0xe6, 0x1a, 0xc3, 0x01, 0x74, 0xe8, 0x35, - 0x87, 0x5c, 0x61, 0xaa, 0x8a, 0x46, 0x06, 0xbe, 0x98, 0x95, 0x24, 0x9e, - 0x01, 0xe3, 0xe6, 0xa0, 0x98, 0xee, 0x36, 0x44, 0x56, 0x8d, 0x23, 0x9c, - 0x65, 0xea, 0x55, 0x6a, 0xdf, 0x66, 0xee, 0x45, 0xe8, 0xa0, 0xe9, 0x7d, - 0x9a, 0xba, 0x94, 0xc5, 0xc8, 0xc4, 0x4b, 0x98, 0xff, 0x9a, 0x01, 0x31, - 0x6d, 0xf9, 0x2b, 0x58, 0xe7, 0xe7, 0x2a, 0xc5, 0x4d, 0xbb, 0xbb, 0xcd, - 0x0d, 0x70, 0xe1, 0xad, 0x03, 0xf5, 0xfe, 0xf4, 0x84, 0x71, 0x08, 0xd2, - 0xbc, 0x04, 0x7b, 0x26, 0x1c, 0xa8, 0x0f, 0x9c, 0xd8, 0x12, 0x6a, 0x6f, - 0x2b, 0x67, 0xa1, 0x03, 0x80, 0x9a, 0x11, 0x0b, 0xe9, 0xe0, 0xb5, 0xb3, - 0xb8, 0x19, 0x4e, 0x0c, 0xa4, 0xd9, 0x2b, 0x3b, 0xc2, 0xca, 0x20, 0xd3, - 0x0c, 0xa4, 0xff, 0x93, 0x13, 0x1f, 0xfc, 0xba, 0x94, 0x93, 0x8c, 0x64, - 0x15, 0x2e, 0x28, 0xa9, 0x55, 0x8c, 0x2c, 0x48, 0xd3, 0xd3, 0xc1, 0x50, - 0x69, 0x19, 0xe8, 0x34, 0xd3, 0xf1, 0x04, 0x9f, 0x0a, 0x7a, 0x21, 0x87, - 0xbf, 0xb9, 0x59, 0x37, 0x2e, 0xf4, 0x71, 0xa5, 0x3e, 0xbe, 0xcd, 0x70, - 0x83, 0x18, 0xf8, 0x8a, 0x72, 0x85, 0x45, 0x1f, 0x08, 0x01, 0x6f, 0x37, - 0xf5, 0x2b, 0x7b, 0xea, 0xb9, 0x8b, 0xa3, 0xcc, 0xfd, 0x35, 0x52, 0xdd, - 0x66, 0xde, 0x4f, 0x30, 0xc5, 0x73, 0x81, 0xb6, 0xe8, 0x3c, 0xd8, 0x48, - 0x8a -}; - -// thawte.com's cert (it's EV-licious!). -unsigned char VARIABLE_IS_NOT_USED thawte_der[] = { - 0x30, 0x82, 0x04, 0xa5, 0x30, 0x82, 0x03, 0x8d, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x17, 0x76, 0x05, 0x88, 0x95, 0x58, 0xee, 0xbb, 0x00, - 0xda, 0x10, 0xe5, 0xf0, 0xf3, 0x9c, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, - 0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, - 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x74, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, - 0x30, 0x38, 0x31, 0x31, 0x31, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x31, 0x31, 0x37, 0x32, 0x33, 0x35, - 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xc7, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01, 0x03, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x19, 0x30, 0x17, 0x06, 0x0b, 0x2b, 0x06, - 0x01, 0x04, 0x01, 0x82, 0x37, 0x3c, 0x02, 0x01, 0x02, 0x14, 0x08, 0x44, - 0x65, 0x6c, 0x61, 0x77, 0x61, 0x72, 0x65, 0x31, 0x1b, 0x30, 0x19, 0x06, - 0x03, 0x55, 0x04, 0x0f, 0x13, 0x12, 0x56, 0x31, 0x2e, 0x30, 0x2c, 0x20, - 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x35, 0x2e, 0x28, 0x62, 0x29, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x0a, 0x54, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x10, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x07, 0x33, 0x38, 0x39, 0x38, - 0x32, 0x36, 0x31, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, - 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x14, 0x0d, - 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, - 0x77, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x0e, - 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xe7, 0x89, 0x68, 0xb5, 0x6e, - 0x1d, 0x38, 0x19, 0xf6, 0x2d, 0x61, 0xc2, 0x00, 0xba, 0x6e, 0xab, 0x66, - 0x92, 0xd6, 0x85, 0x87, 0x2d, 0xd5, 0xa8, 0x58, 0xa9, 0x7a, 0x75, 0x27, - 0x9d, 0xed, 0x9e, 0xfe, 0x06, 0x71, 0x70, 0x2d, 0x21, 0x70, 0x4c, 0x3e, - 0x9c, 0xb6, 0xd5, 0x5d, 0x44, 0x92, 0xb4, 0xe0, 0xee, 0x7c, 0x0a, 0x50, - 0x4c, 0x0d, 0x67, 0x98, 0xaa, 0x01, 0x0e, 0x37, 0xa3, 0x2a, 0xef, 0xe6, - 0xe0, 0x11, 0x7b, 0xee, 0xb0, 0xa2, 0xb4, 0x32, 0x64, 0xa7, 0x0d, 0xda, - 0x6c, 0x15, 0xf8, 0xc5, 0xa5, 0x5a, 0x2c, 0xfc, 0xc9, 0xa6, 0x3c, 0x88, - 0x88, 0xbf, 0xdf, 0xa7, 0x38, 0xf0, 0x78, 0xed, 0x81, 0x93, 0x29, 0x0c, - 0xae, 0xc7, 0xab, 0x51, 0x21, 0x5e, 0xca, 0x95, 0xe5, 0x48, 0x52, 0x41, - 0xb6, 0x18, 0x60, 0x04, 0x19, 0x6f, 0x3d, 0x80, 0x14, 0xd3, 0xaf, 0x23, - 0x03, 0x10, 0x95, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49, - 0x30, 0x82, 0x01, 0x45, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x39, 0x06, 0x03, 0x55, 0x1d, - 0x1f, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0xa0, 0x2c, 0xa0, 0x2a, 0x86, - 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, - 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x45, 0x56, 0x43, 0x41, 0x32, 0x30, 0x30, - 0x36, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x45, 0x01, 0x07, 0x30, 0x01, 0x30, 0x28, 0x30, 0x26, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, - 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, - 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xcd, 0x32, 0xe2, - 0xf2, 0x5d, 0x25, 0x47, 0x02, 0xaa, 0x8f, 0x79, 0x4b, 0x32, 0xee, 0x03, - 0x99, 0xfd, 0x30, 0x49, 0xd1, 0x30, 0x76, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x6a, 0x30, 0x68, 0x30, 0x22, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x42, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x36, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, - 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x54, 0x68, 0x61, 0x77, - 0x74, 0x65, 0x5f, 0x45, 0x56, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x30, - 0x36, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0xb2, 0xa0, 0x96, 0xdd, 0xec, 0x04, 0x38, 0x6b, 0xc3, 0x7a, 0xad, - 0x23, 0x44, 0x91, 0xe5, 0x62, 0x8c, 0xb1, 0xf6, 0x9c, 0x03, 0x21, 0x1f, - 0xef, 0x03, 0xd9, 0xca, 0x63, 0xb2, 0xf8, 0xdb, 0x5a, 0x93, 0xc2, 0xcc, - 0xf1, 0x7c, 0x6f, 0xeb, 0x0f, 0x51, 0x7b, 0x4b, 0xe7, 0xb5, 0xfc, 0xbc, - 0x9b, 0x87, 0x48, 0xcc, 0x5b, 0xf9, 0xc8, 0x66, 0xa4, 0x40, 0xac, 0xe9, - 0x42, 0x5d, 0xed, 0xf3, 0x53, 0x13, 0xe7, 0xbd, 0x6e, 0x7f, 0x50, 0x53, - 0x64, 0xb3, 0x95, 0xf1, 0x42, 0x4f, 0x36, 0x54, 0xb4, 0x1e, 0x7f, 0x18, - 0x37, 0x39, 0x3b, 0x06, 0x5b, 0xe5, 0x13, 0xd9, 0x57, 0xbc, 0xd5, 0x68, - 0xe3, 0x71, 0x5f, 0x5f, 0x2b, 0xf5, 0xa6, 0xc2, 0x8f, 0x67, 0x81, 0x3a, - 0x44, 0x63, 0x8c, 0x36, 0xfa, 0xa8, 0xed, 0xfd, 0xd7, 0x5e, 0xa2, 0x9f, - 0xb0, 0x9d, 0x47, 0x86, 0xfb, 0x71, 0x60, 0x8e, 0xc8, 0xd3, 0x45, 0x19, - 0xb7, 0xda, 0xcd, 0x9e, 0xea, 0x70, 0x10, 0x87, 0x37, 0x10, 0xdd, 0x2c, - 0x11, 0xdf, 0xee, 0x02, 0x21, 0xa6, 0x75, 0xe6, 0xd6, 0x9f, 0x54, 0x72, - 0x61, 0xe6, 0x5c, 0x1e, 0x6e, 0x16, 0xf6, 0x8e, 0xb8, 0xfc, 0x47, 0x80, - 0x05, 0x4b, 0xf7, 0x2d, 0x02, 0xee, 0x50, 0x26, 0xd1, 0x48, 0x01, 0x60, - 0xdc, 0x3c, 0xa7, 0xdb, 0xeb, 0xca, 0x8b, 0xa6, 0xff, 0x9e, 0x47, 0x5d, - 0x87, 0x40, 0xf8, 0xd2, 0x82, 0xd7, 0x13, 0x64, 0x0e, 0xd4, 0xb3, 0x29, - 0x22, 0xa7, 0xe0, 0xc8, 0xcd, 0x8c, 0x4d, 0xf5, 0x11, 0x21, 0x26, 0x02, - 0x43, 0x33, 0x8e, 0xa9, 0x3f, 0x91, 0xd4, 0x05, 0x97, 0xc9, 0xd3, 0x42, - 0x6b, 0x05, 0x99, 0xf6, 0x16, 0x71, 0x67, 0x65, 0xc7, 0x96, 0xdf, 0x2a, - 0xd7, 0x54, 0x63, 0x25, 0xc0, 0x28, 0xf7, 0x1c, 0xee, 0xcd, 0x8b, 0xe4, - 0x9d, 0x32, 0xa3, 0x81, 0x55 -}; - -// A certificate for www.paypal.com with a NULL byte in the common name. -// From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 -unsigned char VARIABLE_IS_NOT_USED paypal_null_der[] = { - 0x30, 0x82, 0x06, 0x44, 0x30, 0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x82, 0x01, - 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x12, - 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61, 0x72, - 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, - 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, - 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, - 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36, 0x32, 0x32, 0x31, 0x30, 0x36, 0x39, - 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x25, - 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, - 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, - 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, - 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, - 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x32, 0x34, - 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x30, 0x81, 0x94, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, - 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20, 0x46, - 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x0b, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, - 0x74, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, - 0x77, 0x77, 0x77, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6d, 0x00, 0x73, 0x73, 0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69, 0xfa, 0x6f, 0x3a, - 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19, 0xb2, 0xc4, - 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e, 0x3c, - 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29, - 0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, - 0x41, 0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, - 0x26, 0xce, 0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, - 0xba, 0xa3, 0x96, 0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, - 0x14, 0xa4, 0xf4, 0xe2, 0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, - 0x2f, 0x7a, 0xe5, 0xb6, 0x10, 0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, - 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49, 0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, - 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x21, - 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, - 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, - 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, 0x0b, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8, 0x30, - 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, - 0x55, 0x14, 0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, - 0x25, 0xbc, 0x6e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, - 0x5d, 0x90, 0x7b, 0x23, 0xc8, 0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x02, 0x30, 0x00, 0x30, - 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04, 0x15, 0x30, 0x13, 0x81, 0x11, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, - 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63, 0x4f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, - 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, - 0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, - 0x2e, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, - 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, - 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, - 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, - 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, - 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x46, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, - 0x04, 0x39, 0x16, 0x37, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, - 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x4c, - 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, - 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x07, - 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, - 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, - 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, - 0x32, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, - 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, - 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, - 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, - 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, - 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, - 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, - 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, - 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, - 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, - 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x69, - 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b, 0xef, - 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa, - 0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, - 0x9e, 0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, - 0x90, 0x1d, 0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, - 0x41, 0x5b, 0xf7, 0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, - 0x1e, 0x45, 0x38, 0xa1, 0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, - 0x07, 0xba, 0x44, 0xcc, 0xe5, 0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, - 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07, 0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, - 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e, 0xc8, 0x64, 0x8c, 0xb5, 0x50, - 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43, 0x96, 0x07, 0xa8, 0xbb -}; - -// DER-encoded X.509 DistinguishedNames. -// -// To output the subject or issuer of a certificate: -// -// openssl asn1parse -i -inform DER -in <cert> -// -// The output will contain -// SEQUENCE [This is the issuer name] -// ... -// SEQUENCE [This is the validity period] -// UTCTIME (or GENERALTIME) -// UTCTIME -// SEQUENCE [This is the subject] -// ... -// -// The OFFSET is the first column before the column, e.g. for '21:d=2', the -// offset is 21 for the SEQUENCE you're interested in. -// The LENGTH is 'hl + l'. -// -// To generate the table, then use the following for a DER-encoded -// certificate: -// -// xxd -i -s $OFFSET -l $LENGTH <cert> -// -// For PEM certificates, convert them to DER before, as in: -// -// openssl x509 -inform PEM -outform DER -in <cert> | -// xxd -i -s $OFFSET -l $LENGTH -// - -// 0:d=0 hl=2 l= 95 cons: SEQUENCE -// 2:d=1 hl=2 l= 11 cons: SET -// 4:d=2 hl=2 l= 9 cons: SEQUENCE -// 6:d=3 hl=2 l= 3 prim: OBJECT :countryName -// 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US -// 15:d=1 hl=2 l= 23 cons: SET -// 17:d=2 hl=2 l= 21 cons: SEQUENCE -// 19:d=3 hl=2 l= 3 prim: OBJECT :organizationName -// 24:d=3 hl=2 l= 14 prim: PRINTABLESTRING :VeriSign, Inc. -// 40:d=1 hl=2 l= 55 cons: SET -// 42:d=2 hl=2 l= 53 cons: SEQUENCE -// 44:d=3 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 49:d=3 hl=2 l= 46 prim: PRINTABLESTRING : -// Class 1 Public Primary Certification Authority -const uint8 VARIABLE_IS_NOT_USED VerisignDN[] = { - 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x31, 0x20, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79 -}; - -// 0:d=0 hl=2 l= 125 cons: SEQUENCE -// 2:d=1 hl=2 l= 11 cons: SET -// 4:d=2 hl=2 l= 9 cons: SEQUENCE -// 6:d=3 hl=2 l= 3 prim: OBJECT :countryName -// 11:d=3 hl=2 l= 2 prim: PRINTABLESTRING :IL -// 15:d=1 hl=2 l= 22 cons: SET -// 17:d=2 hl=2 l= 20 cons: SEQUENCE -// 19:d=3 hl=2 l= 3 prim: OBJECT :organizationName -// 24:d=3 hl=2 l= 13 prim: PRINTABLESTRING :StartCom Ltd. -// 39:d=1 hl=2 l= 43 cons: SET -// 41:d=2 hl=2 l= 41 cons: SEQUENCE -// 43:d=3 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 48:d=3 hl=2 l= 34 prim: PRINTABLESTRING : -// Secure Digital Certificate Signing -// 84:d=1 hl=2 l= 41 cons: SET -// 86:d=2 hl=2 l= 39 cons: SEQUENCE -// 88:d=3 hl=2 l= 3 prim: OBJECT :commonName -// 93:d=3 hl=2 l= 32 prim: PRINTABLESTRING : -// StartCom Certification Authority -const uint8 VARIABLE_IS_NOT_USED StartComDN[] = { - 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, - 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, - 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79 -}; - -// 0:d=0 hl=3 l= 174 cons: SEQUENCE -// 3:d=1 hl=2 l= 11 cons: SET -// 5:d=2 hl=2 l= 9 cons: SEQUENCE -// 7:d=3 hl=2 l= 3 prim: OBJECT :countryName -// 12:d=3 hl=2 l= 2 prim: PRINTABLESTRING :US -// 16:d=1 hl=2 l= 11 cons: SET -// 18:d=2 hl=2 l= 9 cons: SEQUENCE -// 20:d=3 hl=2 l= 3 prim: OBJECT :stateOrProvinceName -// 25:d=3 hl=2 l= 2 prim: PRINTABLESTRING :UT -// 29:d=1 hl=2 l= 23 cons: SET -// 31:d=2 hl=2 l= 21 cons: SEQUENCE -// 33:d=3 hl=2 l= 3 prim: OBJECT :localityName -// 38:d=3 hl=2 l= 14 prim: PRINTABLESTRING :Salt Lake City -// 54:d=1 hl=2 l= 30 cons: SET -// 56:d=2 hl=2 l= 28 cons: SEQUENCE -// 58:d=3 hl=2 l= 3 prim: OBJECT :organizationName -// 63:d=3 hl=2 l= 21 prim: PRINTABLESTRING :The USERTRUST Network -// 86:d=1 hl=2 l= 33 cons: SET -// 88:d=2 hl=2 l= 31 cons: SEQUENCE -// 90:d=3 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 95:d=3 hl=2 l= 24 prim: PRINTABLESTRING :http://www.usertrust.com -//121:d=1 hl=2 l= 54 cons: SET -//123:d=2 hl=2 l= 52 cons: SEQUENCE -//125:d=3 hl=2 l= 3 prim: OBJECT :commonName -//130:d=3 hl=2 l= 45 prim: PRINTABLESTRING : -// UTN-USERFirst-Client Authentication and Email -const uint8 VARIABLE_IS_NOT_USED UserTrustDN[] = { - 0x30, 0x81, 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, - 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, - 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, - 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, - 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c -}; - -// 0:d=0 hl=3 l= 190 cons: SEQUENCE -// 3:d=1 hl=2 l= 63 cons: SET -// 5:d=2 hl=2 l= 61 cons: SEQUENCE -// 7:d=3 hl=2 l= 3 prim: OBJECT :commonName -// 12:d=3 hl=2 l= 54 prim: UTF8STRING : -// TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı -// 68:d=1 hl=2 l= 11 cons: SET -// 70:d=2 hl=2 l= 9 cons: SEQUENCE -// 72:d=3 hl=2 l= 3 prim: OBJECT :countryName -// 77:d=3 hl=2 l= 2 prim: PRINTABLESTRING :TR -// 81:d=1 hl=2 l= 15 cons: SET -// 83:d=2 hl=2 l= 13 cons: SEQUENCE -// 85:d=3 hl=2 l= 3 prim: OBJECT :localityName -// 90:d=3 hl=2 l= 6 prim: UTF8STRING :Ankara -// 98:d=1 hl=2 l= 93 cons: SET -//100:d=2 hl=2 l= 91 cons: SEQUENCE -//102:d=3 hl=2 l= 3 prim: OBJECT :organizationName -//107:d=3 hl=2 l= 84 prim: UTF8STRING : -// TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. -// (c) Kasım 2005 -const uint8 VARIABLE_IS_NOT_USED TurkTrustDN[] = { - 0x30, 0x81, 0xbe, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x36, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54, - 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x6b, 0x20, - 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x69, - 0x7a, 0x6d, 0x65, 0x74, 0x20, 0x53, 0x61, 0xc4, 0x9f, 0x6c, 0x61, 0x79, - 0xc4, 0xb1, 0x63, 0xc4, 0xb1, 0x73, 0xc4, 0xb1, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x52, 0x31, 0x0f, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x41, 0x6e, 0x6b, 0x61, - 0x72, 0x61, 0x31, 0x5d, 0x30, 0x5b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, - 0x54, 0x54, 0xc3, 0x9c, 0x52, 0x4b, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, - 0x42, 0x69, 0x6c, 0x67, 0x69, 0x20, 0xc4, 0xb0, 0x6c, 0x65, 0x74, 0x69, - 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x76, 0x65, 0x20, 0x42, 0x69, 0x6c, 0x69, - 0xc5, 0x9f, 0x69, 0x6d, 0x20, 0x47, 0xc3, 0xbc, 0x76, 0x65, 0x6e, 0x6c, - 0x69, 0xc4, 0x9f, 0x69, 0x20, 0x48, 0x69, 0x7a, 0x6d, 0x65, 0x74, 0x6c, - 0x65, 0x72, 0x69, 0x20, 0x41, 0x2e, 0xc5, 0x9e, 0x2e, 0x20, 0x28, 0x63, - 0x29, 0x20, 0x4b, 0x61, 0x73, 0xc4, 0xb1, 0x6d, 0x20, 0x32, 0x30, 0x30, - 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x31, 0x31, 0x30, 0x37, 0x31, - 0x30, 0x30, 0x37, 0x35, 0x37 -}; - -// 33:d=2 hl=3 l= 207 cons: SEQUENCE -// 36:d=3 hl=2 l= 11 cons: SET -// 38:d=4 hl=2 l= 9 cons: SEQUENCE -// 40:d=5 hl=2 l= 3 prim: OBJECT :countryName -// 45:d=5 hl=2 l= 2 prim: PRINTABLESTRING :AT -// 49:d=3 hl=3 l= 139 cons: SET -// 52:d=4 hl=3 l= 136 cons: SEQUENCE -// 55:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 60:d=5 hl=3 l= 128 prim: BMPSTRING : -// A-Trust Ges. für Sicherheitssysteme im elektr. Datenverkehr GmbH -//191:d=3 hl=2 l= 24 cons: SET -//193:d=4 hl=2 l= 22 cons: SEQUENCE -//195:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -//200:d=5 hl=2 l= 15 prim: PRINTABLESTRING :A-Trust-Qual-01 -//217:d=3 hl=2 l= 24 cons: SET -//219:d=4 hl=2 l= 22 cons: SEQUENCE -//221:d=5 hl=2 l= 3 prim: OBJECT :commonName -//226:d=5 hl=2 l= 15 prim: PRINTABLESTRING :A-Trust-Qual-01 -const uint8 VARIABLE_IS_NOT_USED ATrustQual01DN[] = { - 0x30, 0x81, 0xcf, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x41, 0x54, 0x31, 0x81, 0x8b, 0x30, 0x81, 0x88, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x1e, 0x81, 0x80, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x54, - 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20, 0x00, 0x47, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x66, 0x00, 0xfc, - 0x00, 0x72, 0x00, 0x20, 0x00, 0x53, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x68, 0x00, 0x65, 0x00, 0x69, 0x00, 0x74, - 0x00, 0x73, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, - 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x20, - 0x00, 0x65, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x6b, 0x00, 0x74, 0x00, 0x72, - 0x00, 0x2e, 0x00, 0x20, 0x00, 0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x65, - 0x00, 0x68, 0x00, 0x72, 0x00, 0x20, 0x00, 0x47, 0x00, 0x6d, 0x00, 0x62, - 0x00, 0x48, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51, 0x75, 0x61, - 0x6c, 0x2d, 0x30, 0x31, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x0f, 0x41, 0x2d, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2d, 0x51, - 0x75, 0x61, 0x6c, 0x2d, 0x30, 0x31, 0x30, 0x1e, 0x17 -}; - -// 34:d=2 hl=3 l= 180 cons: SEQUENCE -// 37:d=3 hl=2 l= 20 cons: SET -// 39:d=4 hl=2 l= 18 cons: SEQUENCE -// 41:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 46:d=5 hl=2 l= 11 prim: PRINTABLESTRING :Entrust.net -// 59:d=3 hl=2 l= 64 cons: SET -// 61:d=4 hl=2 l= 62 cons: SEQUENCE -// 63:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 68:d=5 hl=2 l= 55 prim: T61STRING : -// www.entrust.net/CPS_2048 incorp. by ref. (limits liab.) -//125:d=3 hl=2 l= 37 cons: SET -//127:d=4 hl=2 l= 35 cons: SEQUENCE -//129:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -//134:d=5 hl=2 l= 28 prim: PRINTABLESTRING : -// (c) 1999 Entrust.net Limited -//164:d=3 hl=2 l= 51 cons: SET -//166:d=4 hl=2 l= 49 cons: SEQUENCE -//168:d=5 hl=2 l= 3 prim: OBJECT :commonName -//173:d=5 hl=2 l= 42 prim: PRINTABLESTRING : -// Entrust.net Certification Authority (2048) -const uint8 VARIABLE_IS_NOT_USED EntrustDN[] = { - 0x30, 0x81, 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0b, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, - 0x74, 0x31, 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37, - 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38, - 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, - 0x72, 0x65, 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, - 0x20, 0x6c, 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, - 0x39, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, - 0x65, 0x74, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, - 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, - 0x34, 0x38, 0x29 -}; - -// 46:d=2 hl=2 l= 76 cons: SEQUENCE -// 48:d=3 hl=2 l= 11 cons: SET -// 50:d=4 hl=2 l= 9 cons: SEQUENCE -// 52:d=5 hl=2 l= 3 prim: OBJECT :countryName -// 57:d=5 hl=2 l= 2 prim: PRINTABLESTRING :ZA -// 61:d=3 hl=2 l= 37 cons: SET -// 63:d=4 hl=2 l= 35 cons: SEQUENCE -// 65:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 70:d=5 hl=2 l= 28 prim: PRINTABLESTRING : -// Thawte Consulting (Pty) Ltd. -// 100:d=3 hl=2 l= 22 cons: SET -// 102:d=4 hl=2 l= 20 cons: SEQUENCE -// 104:d=5 hl=2 l= 3 prim: OBJECT :commonName -// 109:d=5 hl=2 l= 13 prim: PRINTABLESTRING :Thawte SGC CA -const uint8 VARIABLE_IS_NOT_USED ThawteDN[] = { - 0x30, 0x4C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x5A, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, - 0x13, 0x1C, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6F, 0x6E, - 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, - 0x29, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x0D, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, - 0x53, 0x47, 0x43, 0x20, 0x43, 0x41 -}; - -// 47:d=2 hl=2 l= 108 cons: SEQUENCE -// 49:d=3 hl=2 l= 11 cons: SET -// 51:d=4 hl=2 l= 9 cons: SEQUENCE -// 53:d=5 hl=2 l= 3 prim: OBJECT :countryName -// 58:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US -// 62:d=3 hl=2 l= 22 cons: SET -// 64:d=4 hl=2 l= 20 cons: SEQUENCE -// 66:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName -// 71:d=5 hl=2 l= 13 prim: PRINTABLESTRING :Massachusetts -// 86:d=3 hl=2 l= 46 cons: SET -// 88:d=4 hl=2 l= 44 cons: SEQUENCE -// 90:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 95:d=5 hl=2 l= 37 prim: PRINTABLESTRING : -// Massachusetts Institute of Technology -// 134:d=3 hl=2 l= 21 cons: SET -// 136:d=4 hl=2 l= 19 cons: SEQUENCE -// 138:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 143:d=5 hl=2 l= 12 prim: PRINTABLESTRING :Client CA v1 -const uint8 VARIABLE_IS_NOT_USED MITDN[] = { - 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0D, 0x4D, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, 0x73, 0x65, - 0x74, 0x74, 0x73, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x0A, - 0x13, 0x25, 0x4D, 0x61, 0x73, 0x73, 0x61, 0x63, 0x68, 0x75, 0x73, 0x65, - 0x74, 0x74, 0x73, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, - 0x65, 0x20, 0x6F, 0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, - 0x6F, 0x67, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0B, - 0x13, 0x0C, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x43, 0x41, 0x20, - 0x76, 0x31 -}; - -// 31:d=2 hl=2 l= 91 cons: SEQUENCE -// 33:d=3 hl=2 l= 11 cons: SET -// 35:d=4 hl=2 l= 9 cons: SEQUENCE -// 37:d=5 hl=2 l= 3 prim: OBJECT :countryName -// 42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US -// 46:d=3 hl=2 l= 24 cons: SET -// 48:d=4 hl=2 l= 22 cons: SEQUENCE -// 50:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 55:d=5 hl=2 l= 15 prim: PRINTABLESTRING :U.S. Government -// 72:d=3 hl=2 l= 12 cons: SET -// 74:d=4 hl=2 l= 10 cons: SEQUENCE -// 76:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 81:d=5 hl=2 l= 3 prim: PRINTABLESTRING :DoD -// 86:d=3 hl=2 l= 12 cons: SET -// 88:d=4 hl=2 l= 10 cons: SEQUENCE -// 90:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 95:d=5 hl=2 l= 3 prim: PRINTABLESTRING :PKI -// 100:d=3 hl=2 l= 22 cons: SET -// 102:d=4 hl=2 l= 20 cons: SEQUENCE -// 104:d=5 hl=2 l= 3 prim: OBJECT :commonName -// 109:d=5 hl=2 l= 13 prim: PRINTABLESTRING :DoD Root CA 2 -const uint8 VARIABLE_IS_NOT_USED DodRootCA2DN[] = { - 0x30, 0x5b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0f, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x47, 0x6f, 0x76, 0x65, 0x72, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x03, 0x44, 0x6f, 0x44, 0x31, 0x0c, 0x30, 0x0a, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x50, 0x4b, 0x49, 0x31, 0x16, 0x30, - 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x44, 0x6f, 0x44, 0x20, - 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 -}; - -// 33:d=2 hl=2 l= 87 cons: SEQUENCE -// 35:d=3 hl=2 l= 11 cons: SET -// 37:d=4 hl=2 l= 9 cons: SEQUENCE -// 39:d=5 hl=2 l= 3 prim: OBJECT :countryName -// 44:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US -// 48:d=3 hl=2 l= 24 cons: SET -// 50:d=4 hl=2 l= 22 cons: SEQUENCE -// 52:d=5 hl=2 l= 3 prim: OBJECT :organizationName -// 57:d=5 hl=2 l= 15 prim: PRINTABLESTRING :U.S. Government -// 74:d=3 hl=2 l= 12 cons: SET -// 76:d=4 hl=2 l= 10 cons: SEQUENCE -// 78:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 83:d=5 hl=2 l= 3 prim: PRINTABLESTRING :DoD -// 88:d=3 hl=2 l= 12 cons: SET -// 90:d=4 hl=2 l= 10 cons: SEQUENCE -// 92:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName -// 97:d=5 hl=2 l= 3 prim: PRINTABLESTRING :PKI -// 102:d=3 hl=2 l= 18 cons: SET -// 104:d=4 hl=2 l= 16 cons: SEQUENCE -// 106:d=5 hl=2 l= 3 prim: OBJECT :commonName -// 111:d=5 hl=2 l= 9 prim: PRINTABLESTRING :DOD CA-17 -const uint8 VARIABLE_IS_NOT_USED DodCA17DN[] = { - 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0f, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x47, 0x6f, 0x76, 0x65, 0x72, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x03, 0x44, 0x6f, 0x44, 0x31, 0x0c, 0x30, 0x0a, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x50, 0x4b, 0x49, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x44, 0x4f, 0x44, 0x20, - 0x43, 0x41, 0x2d, 0x31, 0x37 -}; - -} // namespace diff --git a/net/base/test_root_certs.cc b/net/base/test_root_certs.cc deleted file mode 100644 index 084bbef..0000000 --- a/net/base/test_root_certs.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/test_root_certs.h" - -#include <string> - -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -bool g_has_instance = false; - -base::LazyInstance<TestRootCerts>::Leaky - g_test_root_certs = LAZY_INSTANCE_INITIALIZER; - -CertificateList LoadCertificates(const base::FilePath& filename) { - std::string raw_cert; - if (!file_util::ReadFileToString(filename, &raw_cert)) { - LOG(ERROR) << "Can't load certificate " << filename.value(); - return CertificateList(); - } - - return X509Certificate::CreateCertificateListFromBytes( - raw_cert.data(), raw_cert.length(), X509Certificate::FORMAT_AUTO); -} - -} // namespace - -// static -TestRootCerts* TestRootCerts::GetInstance() { - return g_test_root_certs.Pointer(); -} - -bool TestRootCerts::HasInstance() { - return g_has_instance; -} - -bool TestRootCerts::AddFromFile(const base::FilePath& file) { - CertificateList root_certs = LoadCertificates(file); - if (root_certs.empty() || root_certs.size() > 1) - return false; - - return Add(root_certs.front()); -} - -TestRootCerts::TestRootCerts() { - Init(); - g_has_instance = true; -} - -ScopedTestRoot::ScopedTestRoot() {} - -ScopedTestRoot::ScopedTestRoot(X509Certificate* cert) { - Reset(cert); -} - -ScopedTestRoot::~ScopedTestRoot() { - Reset(NULL); -} - -void ScopedTestRoot::Reset(X509Certificate* cert) { - if (cert_) - TestRootCerts::GetInstance()->Clear(); - if (cert) - TestRootCerts::GetInstance()->Add(cert); - cert_ = cert; -} - -} // namespace net diff --git a/net/base/test_root_certs.h b/net/base/test_root_certs.h deleted file mode 100644 index a7c7cde..0000000 --- a/net/base/test_root_certs.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_TEST_ROOT_CERTS_H_ -#define NET_BASE_TEST_ROOT_CERTS_H_ - -#include "base/lazy_instance.h" -#include "base/memory/ref_counted.h" -#include "build/build_config.h" -#include "net/base/net_export.h" - -#if defined(USE_NSS) || defined(OS_IOS) -#include <list> -#elif defined(OS_WIN) -#include <windows.h> -#include <wincrypt.h> -#elif defined(OS_MACOSX) -#include <CoreFoundation/CFArray.h> -#include <Security/SecTrust.h> -#include "base/mac/scoped_cftyperef.h" -#endif - -namespace base { -class FilePath; -} - -namespace net { - -class X509Certificate; - -// TestRootCerts is a helper class for unit tests that is used to -// artificially mark a certificate as trusted, independent of the local -// machine configuration. -class NET_EXPORT_PRIVATE TestRootCerts { - public: - // Obtains the Singleton instance to the trusted certificates. - static TestRootCerts* GetInstance(); - - // Returns true if an instance exists, without forcing an initialization. - static bool HasInstance(); - - // Marks |certificate| as trusted for X509Certificate::Verify(). Returns - // false if the certificate could not be marked trusted. - bool Add(X509Certificate* certificate); - - // Reads a single certificate from |file| and marks it as trusted. Returns - // false if an error is encountered, such as being unable to read |file| - // or more than one certificate existing in |file|. - bool AddFromFile(const base::FilePath& file); - - // Clears the trusted status of any certificates that were previously - // marked trusted via Add(). - void Clear(); - - // Returns true if there are no certificates that have been marked trusted. - bool IsEmpty() const; - -#if defined(OS_MACOSX) && !defined(OS_IOS) - CFArrayRef temporary_roots() const { return temporary_roots_; } - - // Modifies the root certificates of |trust_ref| to include the - // certificates stored in |temporary_roots_|. If IsEmpty() is true, this - // does not modify |trust_ref|. - OSStatus FixupSecTrustRef(SecTrustRef trust_ref) const; -#elif defined(OS_WIN) - HCERTSTORE temporary_roots() const { return temporary_roots_; } - - // Returns an HCERTCHAINENGINE suitable to be used for certificate - // validation routines, or NULL to indicate that the default system chain - // engine is appropriate. The caller is responsible for freeing the - // returned HCERTCHAINENGINE. - HCERTCHAINENGINE GetChainEngine() const; -#endif - - private: - friend struct base::DefaultLazyInstanceTraits<TestRootCerts>; - - TestRootCerts(); - ~TestRootCerts(); - - // Performs platform-dependent initialization. - void Init(); - -#if defined(USE_NSS) || defined(OS_IOS) - // 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_; -#elif defined(OS_WIN) - HCERTSTORE temporary_roots_; -#elif defined(OS_MACOSX) - base::mac::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots_; -#endif - -#if defined(OS_WIN) || defined(USE_OPENSSL) - // True if there are no temporarily trusted root certificates. - bool empty_; -#endif - - DISALLOW_COPY_AND_ASSIGN(TestRootCerts); -}; - -// Scoped helper for unittests to handle safely managing trusted roots. -class NET_EXPORT_PRIVATE ScopedTestRoot { - public: - ScopedTestRoot(); - // Creates a ScopedTestRoot that will adds|cert| to the TestRootCerts store. - explicit ScopedTestRoot(X509Certificate* cert); - ~ScopedTestRoot(); - - // Assigns |cert| to be the new test root cert. If |cert| is NULL, undoes - // any work the ScopedTestRoot may have previously done. - // If |cert_| contains a certificate (due to a prior call to Reset or due to - // a cert being passed at construction), the existing TestRootCerts store is - // cleared. - void Reset(X509Certificate* cert); - - private: - scoped_refptr<X509Certificate> cert_; - - DISALLOW_COPY_AND_ASSIGN(ScopedTestRoot); -}; - -} // namespace net - -#endif // NET_BASE_TEST_ROOT_CERTS_H_ diff --git a/net/base/test_root_certs_android.cc b/net/base/test_root_certs_android.cc deleted file mode 100644 index 5ad185f..0000000 --- a/net/base/test_root_certs_android.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/test_root_certs.h" - -#include "base/location.h" -#include "base/logging.h" -#include "net/android/network_library.h" -#include "net/base/x509_certificate.h" - -namespace net { - -bool TestRootCerts::Add(X509Certificate* certificate) { - std::string cert_bytes; - if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(), - &cert_bytes)) - return false; - android::AddTestRootCertificate( - reinterpret_cast<const uint8*>(cert_bytes.data()), cert_bytes.size()); - return true; -} - -void TestRootCerts::Clear() { - if (empty_) - return; - - android::ClearTestRootCertificates(); - empty_ = true; -} - -bool TestRootCerts::IsEmpty() const { - return empty_; -} - -TestRootCerts::~TestRootCerts() {} - -void TestRootCerts::Init() { - empty_ = true; -} - -} // namespace net diff --git a/net/base/test_root_certs_mac.cc b/net/base/test_root_certs_mac.cc deleted file mode 100644 index a2bb5b8..0000000 --- a/net/base/test_root_certs_mac.cc +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/test_root_certs.h" - -#include <Security/Security.h> - -#include "base/logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -typedef OSStatus (*SecTrustSetAnchorCertificatesOnlyFuncPtr)(SecTrustRef, - Boolean); - -Boolean OurSecCertificateEqual(const void* value1, const void* value2) { - if (CFGetTypeID(value1) != SecCertificateGetTypeID() || - CFGetTypeID(value2) != SecCertificateGetTypeID()) - return CFEqual(value1, value2); - return X509Certificate::IsSameOSCert( - reinterpret_cast<SecCertificateRef>(const_cast<void*>(value1)), - reinterpret_cast<SecCertificateRef>(const_cast<void*>(value2))); -} - -const void* RetainWrapper(CFAllocatorRef unused, const void* value) { - return CFRetain(value); -} - -void ReleaseWrapper(CFAllocatorRef unused, const void* value) { - CFRelease(value); -} - -// CFEqual prior to 10.6 only performed pointer checks on SecCertificateRefs, -// rather than checking if they were the same (logical) certificate, so a -// custom structure is used for the array callbacks. -const CFArrayCallBacks kCertArrayCallbacks = { - 0, // version - RetainWrapper, - ReleaseWrapper, - CFCopyDescription, - OurSecCertificateEqual, -}; - -} // namespace - -bool TestRootCerts::Add(X509Certificate* certificate) { - if (CFArrayContainsValue(temporary_roots_, - CFRangeMake(0, CFArrayGetCount(temporary_roots_)), - certificate->os_cert_handle())) - return true; - CFArrayAppendValue(temporary_roots_, certificate->os_cert_handle()); - return true; -} - -void TestRootCerts::Clear() { - CFArrayRemoveAllValues(temporary_roots_); -} - -bool TestRootCerts::IsEmpty() const { - return CFArrayGetCount(temporary_roots_) == 0; -} - -OSStatus TestRootCerts::FixupSecTrustRef(SecTrustRef trust_ref) const { - if (IsEmpty()) - return noErr; - - CFBundleRef bundle = - CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); - SecTrustSetAnchorCertificatesOnlyFuncPtr set_anchor_certificates_only = NULL; - if (bundle) { - set_anchor_certificates_only = - reinterpret_cast<SecTrustSetAnchorCertificatesOnlyFuncPtr>( - CFBundleGetFunctionPointerForName(bundle, - CFSTR("SecTrustSetAnchorCertificatesOnly"))); - } - - OSStatus status = noErr; - if (set_anchor_certificates_only) { - // OS X 10.6 includes a function where the system trusts can be - // preserved while appending application trusts. This is preferable, - // because it preserves any user trust settings (explicit distrust), - // which the naive copy in 10.5 does not. Unfortunately, though the - // function pointer may be available, it is not always implemented. If it - // returns errSecUnimplemented, fall through to the 10.5 behaviour. - status = SecTrustSetAnchorCertificates(trust_ref, temporary_roots_); - if (status) - return status; - status = set_anchor_certificates_only(trust_ref, false); - if (status != errSecUnimplemented) - return status; - - // Restore the original settings before falling back. - status = SecTrustSetAnchorCertificates(trust_ref, NULL); - if (status) - return status; - } - - // On 10.5, the system certificates have to be copied and merged into - // the application trusts, and may override any user trust settings. - CFArrayRef system_roots = NULL; - status = SecTrustCopyAnchorCertificates(&system_roots); - if (status) - return status; - - base::mac::ScopedCFTypeRef<CFArrayRef> scoped_system_roots(system_roots); - base::mac::ScopedCFTypeRef<CFMutableArrayRef> scoped_roots( - CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, - scoped_system_roots)); - DCHECK(scoped_roots.get()); - - CFArrayAppendArray(scoped_roots, temporary_roots_, - CFRangeMake(0, CFArrayGetCount(temporary_roots_))); - return SecTrustSetAnchorCertificates(trust_ref, scoped_roots); -} - -TestRootCerts::~TestRootCerts() {} - -void TestRootCerts::Init() { - temporary_roots_.reset(CFArrayCreateMutable(kCFAllocatorDefault, 0, - &kCertArrayCallbacks)); -} - -} // namespace net diff --git a/net/base/test_root_certs_nss.cc b/net/base/test_root_certs_nss.cc deleted file mode 100644 index 039b790..0000000 --- a/net/base/test_root_certs_nss.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/test_root_certs.h" - -#include <cert.h> - -#include "base/logging.h" -#include "base/stl_util.h" -#include "crypto/nss_util.h" -#include "net/base/x509_certificate.h" - -#if defined(OS_IOS) -#include "net/base/x509_util_ios.h" -#endif - -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) - : certificate_(CERT_DupCertificate(certificate)), - trust_(trust) { -} - -TestRootCerts::TrustEntry::~TrustEntry() { - CERT_DestroyCertificate(certificate_); -} - -bool TestRootCerts::Add(X509Certificate* certificate) { -#if defined(OS_IOS) - x509_util_ios::NSSCertificate nss_certificate(certificate->os_cert_handle()); - CERTCertificate* cert_handle = nss_certificate.cert_handle(); -#else - CERTCertificate* cert_handle = certificate->os_cert_handle(); -#endif - // Preserve the original trust bits so that they can be restored when - // the certificate is removed. - CERTCertTrust original_trust; - SECStatus rv = CERT_GetCertTrust(cert_handle, &original_trust); - if (rv != SECSuccess) { - // CERT_GetCertTrust will fail if the certificate does not have any - // particular trust settings associated with it, and attempts to use - // |original_trust| later to restore the original trust settings will not - // cause the trust settings to be revoked. If the certificate has no - // particular trust settings associated with it, mark the certificate as - // a valid CA certificate with no specific trust. - rv = CERT_DecodeTrustString(&original_trust, "c,c,c"); - } - - // Change the trust bits to unconditionally trust this certificate. - CERTCertTrust new_trust; - rv = CERT_DecodeTrustString(&new_trust, "TCu,Cu,Tu"); - if (rv != SECSuccess) { - LOG(ERROR) << "Cannot decode certificate trust string."; - return false; - } - - rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert_handle, &new_trust); - if (rv != SECSuccess) { - LOG(ERROR) << "Cannot change certificate trust."; - return false; - } - - trust_cache_.push_back(new TrustEntry(cert_handle, original_trust)); - return true; -} - -void TestRootCerts::Clear() { - // Restore the certificate trusts to what they were originally, before - // Add() was called. Work from the rear first, since if a certificate was - // 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) { - CERTCertTrust original_trust = (*it)->trust(); - SECStatus rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), - (*it)->certificate(), - &original_trust); - // DCHECK(), rather than LOG(), as a failure to restore the original - // trust can cause flake or hard-to-trace errors in any unit tests that - // occur after Clear() has been called. - DCHECK_EQ(SECSuccess, rv) << "Cannot restore certificate trust."; - } - STLDeleteElements(&trust_cache_); -} - -bool TestRootCerts::IsEmpty() const { - return trust_cache_.empty(); -} - -TestRootCerts::~TestRootCerts() { - Clear(); -} - -void TestRootCerts::Init() { - crypto::EnsureNSSInit(); -} - -} // namespace net diff --git a/net/base/test_root_certs_openssl.cc b/net/base/test_root_certs_openssl.cc deleted file mode 100644 index e01d5c9..0000000 --- a/net/base/test_root_certs_openssl.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/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/base/x509_certificate.h" - -namespace net { - -bool TestRootCerts::Add(X509Certificate* certificate) { - if (!X509_STORE_add_cert(X509Certificate::cert_store(), - certificate->os_cert_handle())) { - unsigned long error_code = ERR_peek_error(); - if (ERR_GET_LIB(error_code) != ERR_LIB_X509 || - ERR_GET_REASON(error_code) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { - crypto::ClearOpenSSLERRStack(FROM_HERE); - return false; - } - ERR_clear_error(); - } - - empty_ = false; - return true; -} - -void TestRootCerts::Clear() { - if (empty_) - return; - - X509Certificate::ResetCertStore(); - empty_ = true; -} - -bool TestRootCerts::IsEmpty() const { - return empty_; -} - -TestRootCerts::~TestRootCerts() {} - -void TestRootCerts::Init() { - empty_ = true; -} - -} // namespace net diff --git a/net/base/test_root_certs_win.cc b/net/base/test_root_certs_win.cc deleted file mode 100644 index 05f3d4a..0000000 --- a/net/base/test_root_certs_win.cc +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/test_root_certs.h" - -#include <windows.h> -#include <wincrypt.h> - -#include "base/basictypes.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/win/win_util.h" -#include "base/win/windows_version.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -// Provides a CertDllOpenStoreProv callback provider function, to be called -// by CertOpenStore when the CERT_STORE_PROV_SYSTEM_W store is opened. See -// http://msdn.microsoft.com/en-us/library/aa376043(VS.85).aspx. -BOOL WINAPI InterceptedOpenStoreW(LPCSTR store_provider, - DWORD encoding, - HCRYPTPROV crypt_provider, - DWORD flags, - const void* extra, - HCERTSTORE memory_store, - PCERT_STORE_PROV_INFO store_info); - -// CryptoAPIInjector is used to inject a store provider function for system -// certificate stores before the one provided internally by Crypt32.dll. -// Once injected, there is no way to remove, so every call to open a system -// store will be redirected to the injected function. -struct CryptoAPIInjector { - // The previous default function for opening system stores. For most - // configurations, this should point to Crypt32's internal - // I_CertDllOpenSystemStoreProvW function. - PFN_CERT_DLL_OPEN_STORE_PROV_FUNC original_function; - - // The handle that CryptoAPI uses to ensure the DLL implementing - // |original_function| remains loaded in memory. - HCRYPTOIDFUNCADDR original_handle; - - private: - friend struct base::DefaultLazyInstanceTraits<CryptoAPIInjector>; - - CryptoAPIInjector() - : original_function(NULL), - original_handle(NULL) { - HCRYPTOIDFUNCSET registered_functions = - CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0); - - // Preserve the original handler function in |original_function|. If other - // functions are overridden, they will also need to be preserved. - BOOL ok = CryptGetOIDFunctionAddress( - registered_functions, 0, CERT_STORE_PROV_SYSTEM_W, 0, - reinterpret_cast<void**>(&original_function), &original_handle); - DCHECK(ok); - - // For now, intercept only the numeric form of the system store - // function, CERT_STORE_PROV_SYSTEM_W (0x0A), which is what Crypt32 - // functionality uses exclusively. Depending on the machine that tests - // are being run on, it may prove necessary to also intercept - // sz_CERT_STORE_PROV_SYSTEM_[A/W] and CERT_STORE_PROV_SYSTEM_A, based - // on whether or not any third-party CryptoAPI modules have been - // installed. - const CRYPT_OID_FUNC_ENTRY kFunctionToIntercept = - { CERT_STORE_PROV_SYSTEM_W, &InterceptedOpenStoreW }; - - // Inject kFunctionToIntercept at the front of the linked list that - // crypt32 uses when CertOpenStore is called, replacing the existing - // registered function. - ok = CryptInstallOIDFunctionAddress(NULL, 0, - CRYPT_OID_OPEN_STORE_PROV_FUNC, 1, - &kFunctionToIntercept, - CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG); - DCHECK(ok); - } - - // This is never called, because this object is intentionally leaked. - // Certificate verification happens on a non-joinable worker thread, which - // may still be running when ~AtExitManager is called, so the LazyInstance - // must be leaky. - ~CryptoAPIInjector() { - original_function = NULL; - CryptFreeOIDFunctionAddress(original_handle, NULL); - } -}; - -base::LazyInstance<CryptoAPIInjector>::Leaky - g_capi_injector = LAZY_INSTANCE_INITIALIZER; - -BOOL WINAPI InterceptedOpenStoreW(LPCSTR store_provider, - DWORD encoding, - HCRYPTPROV crypt_provider, - DWORD flags, - const void* store_name, - HCERTSTORE memory_store, - PCERT_STORE_PROV_INFO store_info) { - // If the high word is all zeroes, then |store_provider| is a numeric ID. - // Otherwise, it's a pointer to a null-terminated ASCII string. See the - // documentation for CryptGetOIDFunctionAddress for more information. - uint32 store_as_uint = reinterpret_cast<uint32>(store_provider); - if (store_as_uint > 0xFFFF || store_provider != CERT_STORE_PROV_SYSTEM_W || - !g_capi_injector.Get().original_function) - return FALSE; - - BOOL ok = g_capi_injector.Get().original_function(store_provider, encoding, - crypt_provider, flags, - store_name, memory_store, - store_info); - // Only the Root store should have certificates injected. If - // CERT_SYSTEM_STORE_RELOCATE_FLAG is set, then |store_name| points to a - // CERT_SYSTEM_STORE_RELOCATE_PARA structure, rather than a - // NULL-terminated wide string, so check before making a string - // comparison. - if (!ok || TestRootCerts::GetInstance()->IsEmpty() || - (flags & CERT_SYSTEM_STORE_RELOCATE_FLAG) || - lstrcmpiW(reinterpret_cast<LPCWSTR>(store_name), L"root")) - return ok; - - // The result of CertOpenStore with CERT_STORE_PROV_SYSTEM_W is documented - // to be a collection store, and that appears to hold for |memory_store|. - // Attempting to add an individual certificate to |memory_store| causes - // the request to be forwarded to the first physical store in the - // collection that accepts modifications, which will cause a secure - // confirmation dialog to be displayed, confirming the user wishes to - // trust the certificate. However, appending a store to the collection - // will merely modify the temporary collection store, and will not persist - // any changes to the underlying physical store. When the |memory_store| is - // searched to see if a certificate is in the Root store, all the - // underlying stores in the collection will be searched, and any certificate - // in temporary_roots() will be found and seen as trusted. - return CertAddStoreToCollection( - memory_store, TestRootCerts::GetInstance()->temporary_roots(), 0, 0); -} - -} // namespace - -bool TestRootCerts::Add(X509Certificate* certificate) { - // Ensure that the default CryptoAPI functionality has been intercepted. - // If a test certificate is never added, then no interception should - // happen. - g_capi_injector.Get(); - - BOOL ok = CertAddCertificateContextToStore( - temporary_roots_, certificate->os_cert_handle(), - CERT_STORE_ADD_NEW, NULL); - if (!ok) { - // If the certificate is already added, return successfully. - return GetLastError() == CRYPT_E_EXISTS; - } - - empty_ = false; - return true; -} - -void TestRootCerts::Clear() { - empty_ = true; - - PCCERT_CONTEXT prev_cert = NULL; - while (prev_cert = CertEnumCertificatesInStore(temporary_roots_, NULL)) - CertDeleteCertificateFromStore(prev_cert); -} - -bool TestRootCerts::IsEmpty() const { - return empty_; -} - -HCERTCHAINENGINE TestRootCerts::GetChainEngine() const { - if (IsEmpty()) - return NULL; // Default chain engine will suffice. - - // Windows versions before 7 don't accept the struct size for later versions. - // We report the size of the old struct since we don't need the new members. - static const DWORD kSizeofCertChainEngineConfig = - SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER( - CERT_CHAIN_ENGINE_CONFIG, CycleDetectionModulus); - - // Each HCERTCHAINENGINE caches both the configured system stores and - // information about each chain that has been built. In order to ensure - // that changes to |temporary_roots_| are properly propagated and that the - // various caches are flushed, when at least one certificate is added, - // return a new chain engine for every call. Each chain engine creation - // should re-open the root store, ensuring the most recent changes are - // visible. - CERT_CHAIN_ENGINE_CONFIG engine_config = { - kSizeofCertChainEngineConfig - }; - engine_config.dwFlags = - CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE | - CERT_CHAIN_ENABLE_SHARE_STORE; - HCERTCHAINENGINE chain_engine = NULL; - BOOL ok = CertCreateCertificateChainEngine(&engine_config, &chain_engine); - DCHECK(ok); - return chain_engine; -} - -TestRootCerts::~TestRootCerts() { - CertCloseStore(temporary_roots_, 0); -} - -void TestRootCerts::Init() { - empty_ = true; - temporary_roots_ = CertOpenStore( - CERT_STORE_PROV_MEMORY, 0, NULL, - CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL); - DCHECK(temporary_roots_); -} - -} // namespace net diff --git a/net/base/x509_cert_types.cc b/net/base/x509_cert_types.cc deleted file mode 100644 index 643454f..0000000 --- a/net/base/x509_cert_types.cc +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_cert_types.h" - -#include <cstdlib> -#include <cstring> - -#include "base/logging.h" -#include "base/string_number_conversions.h" -#include "base/string_piece.h" -#include "base/time.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -// Helper for ParseCertificateDate. |*field| must contain at least -// |field_len| characters. |*field| will be advanced by |field_len| on exit. -// |*ok| is set to false if there is an error in parsing the number, but left -// untouched otherwise. Returns the parsed integer. -int ParseIntAndAdvance(const char** field, size_t field_len, bool* ok) { - int result = 0; - *ok &= base::StringToInt(base::StringPiece(*field, field_len), &result); - *field += field_len; - return result; -} - -} - -CertPrincipal::CertPrincipal() { -} - -CertPrincipal::CertPrincipal(const std::string& name) : common_name(name) {} - -CertPrincipal::~CertPrincipal() { -} - -std::string CertPrincipal::GetDisplayName() const { - if (!common_name.empty()) - return common_name; - if (!organization_names.empty()) - return organization_names[0]; - if (!organization_unit_names.empty()) - return organization_unit_names[0]; - - return std::string(); -} - -CertPolicy::CertPolicy() { -} - -CertPolicy::~CertPolicy() { -} - -CertPolicy::Judgment CertPolicy::Check( - X509Certificate* cert) const { - // It shouldn't matter which set we check first, but we check denied first - // in case something strange has happened. - - if (denied_.find(cert->fingerprint()) != denied_.end()) { - // DCHECK that the order didn't matter. - DCHECK(allowed_.find(cert->fingerprint()) == allowed_.end()); - return DENIED; - } - - if (allowed_.find(cert->fingerprint()) != allowed_.end()) { - // DCHECK that the order didn't matter. - DCHECK(denied_.find(cert->fingerprint()) == denied_.end()); - return ALLOWED; - } - - // We don't have a policy for this cert. - return UNKNOWN; -} - -void CertPolicy::Allow(X509Certificate* cert) { - // Put the cert in the allowed set and (maybe) remove it from the denied set. - denied_.erase(cert->fingerprint()); - allowed_.insert(cert->fingerprint()); -} - -void CertPolicy::Deny(X509Certificate* cert) { - // Put the cert in the denied set and (maybe) remove it from the allowed set. - allowed_.erase(cert->fingerprint()); - denied_.insert(cert->fingerprint()); -} - -bool CertPolicy::HasAllowedCert() const { - return !allowed_.empty(); -} - -bool CertPolicy::HasDeniedCert() const { - return !denied_.empty(); -} - -bool ParseCertificateDate(const base::StringPiece& raw_date, - CertDateFormat format, - base::Time* time) { - size_t year_length = format == CERT_DATE_FORMAT_UTC_TIME ? 2 : 4; - - if (raw_date.length() < 11 + year_length) - return false; - - const char* field = raw_date.data(); - bool valid = true; - base::Time::Exploded exploded = {0}; - - exploded.year = ParseIntAndAdvance(&field, year_length, &valid); - exploded.month = ParseIntAndAdvance(&field, 2, &valid); - exploded.day_of_month = ParseIntAndAdvance(&field, 2, &valid); - exploded.hour = ParseIntAndAdvance(&field, 2, &valid); - exploded.minute = ParseIntAndAdvance(&field, 2, &valid); - exploded.second = ParseIntAndAdvance(&field, 2, &valid); - if (valid && year_length == 2) - exploded.year += exploded.year < 50 ? 2000 : 1900; - - valid &= exploded.HasValidValues(); - - if (!valid) - return false; - - *time = base::Time::FromUTCExploded(exploded); - return true; -} - -} // namespace net diff --git a/net/base/x509_cert_types.h b/net/base/x509_cert_types.h deleted file mode 100644 index 8ebc477..0000000 --- a/net/base/x509_cert_types.h +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_CERT_TYPES_H_ -#define NET_BASE_X509_CERT_TYPES_H_ - -#include <string.h> - -#include <set> -#include <string> -#include <vector> - -#include "base/logging.h" -#include "base/string_piece.h" -#include "build/build_config.h" -#include "net/base/hash_value.h" -#include "net/base/net_export.h" - -#if defined(OS_MACOSX) && !defined(OS_IOS) -#include <Security/x509defs.h> -#endif - -namespace base { -class Time; -} // namespace base - -namespace net { - -class X509Certificate; - -// CertPrincipal represents the issuer or subject field of an X.509 certificate. -struct NET_EXPORT CertPrincipal { - CertPrincipal(); - explicit CertPrincipal(const std::string& name); - ~CertPrincipal(); - -#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) - // Parses a BER-format DistinguishedName. - bool ParseDistinguishedName(const void* ber_name_data, size_t length); -#endif - -#if defined(OS_MACOSX) - // Compare this CertPrincipal with |against|, returning true if they're - // equal enough to be a possible match. This should NOT be used for any - // security relevant decisions. - // TODO(rsleevi): Remove once Mac client auth uses NSS for name comparison. - bool Matches(const CertPrincipal& against) const; -#endif - - // Returns a name that can be used to represent the issuer. It tries in this - // order: CN, O and OU and returns the first non-empty one found. - std::string GetDisplayName() const; - - // The different attributes for a principal, stored in UTF-8. They may be "". - // Note that some of them can have several values. - - std::string common_name; - std::string locality_name; - std::string state_or_province_name; - std::string country_name; - - std::vector<std::string> street_addresses; - std::vector<std::string> organization_names; - std::vector<std::string> organization_unit_names; - std::vector<std::string> domain_components; -}; - -// This class is useful for maintaining policies about which certificates are -// permitted or forbidden for a particular purpose. -class NET_EXPORT CertPolicy { - public: - // The judgments this policy can reach. - enum Judgment { - // We don't have policy information for this certificate. - UNKNOWN, - - // This certificate is allowed. - ALLOWED, - - // This certificate is denied. - DENIED, - }; - - CertPolicy(); - ~CertPolicy(); - - // Returns the judgment this policy makes about this certificate. - Judgment Check(X509Certificate* cert) const; - - // Causes the policy to allow this certificate. - void Allow(X509Certificate* cert); - - // Causes the policy to deny this certificate. - void Deny(X509Certificate* cert); - - // Returns true if this policy has allowed at least one certificate. - bool HasAllowedCert() const; - - // Returns true if this policy has denied at least one certificate. - bool HasDeniedCert() const; - - private: - // The set of fingerprints of allowed certificates. - std::set<SHA1HashValue, SHA1HashValueLessThan> allowed_; - - // The set of fingerprints of denied certificates. - std::set<SHA1HashValue, SHA1HashValueLessThan> denied_; -}; - -#if defined(OS_MACOSX) && !defined(OS_IOS) -// Compares two OIDs by value. -inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { - return oid1->Length == oid2->Length && - (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); -} -#endif - -// A list of ASN.1 date/time formats that ParseCertificateDate() supports, -// encoded in the canonical forms specified in RFC 2459/3280/5280. -enum CertDateFormat { - // UTCTime: Format is YYMMDDHHMMSSZ - CERT_DATE_FORMAT_UTC_TIME, - - // GeneralizedTime: Format is YYYYMMDDHHMMSSZ - CERT_DATE_FORMAT_GENERALIZED_TIME, -}; - -// Attempts to parse |raw_date|, an ASN.1 date/time string encoded as -// |format|, and writes the result into |*time|. If an invalid date is -// specified, or if parsing fails, returns false, and |*time| will not be -// updated. -bool ParseCertificateDate(const base::StringPiece& raw_date, - CertDateFormat format, - base::Time* time); -} // namespace net - -#endif // NET_BASE_X509_CERT_TYPES_H_ diff --git a/net/base/x509_cert_types_mac.cc b/net/base/x509_cert_types_mac.cc deleted file mode 100644 index a3eec5e..0000000 --- a/net/base/x509_cert_types_mac.cc +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_cert_types.h" - -#include <CoreServices/CoreServices.h> -#include <Security/Security.h> -#include <Security/SecAsn1Coder.h> - -#include "base/logging.h" -#include "base/i18n/icu_string_conversions.h" -#include "base/mac/mac_logging.h" -#include "base/utf_string_conversions.h" - -namespace net { - -namespace { - -// The BER encoding of 0.9.2342.19200300.100.1.25. -// On 10.6 and later this is available as CSSMOID_DomainComponent, which is an -// external symbol from Security.framework. However, it appears that Apple's -// implementation improperly encoded this on 10.6+, and even still is -// unavailable on 10.5, so simply including the raw BER here. -// -// Note: CSSM is allowed to store CSSM_OIDs in any arbitrary format desired, -// as long as the symbols are properly exposed. The fact that Apple's -// implementation stores it in BER is an internal implementation detail -// observed by studying libsecurity_cssm. -const uint8 kDomainComponentData[] = { - 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 -}; - -const CSSM_OID kDomainComponentOID = { - arraysize(kDomainComponentData), - const_cast<uint8*>(kDomainComponentData) -}; - -const CSSM_OID* kOIDs[] = { - &CSSMOID_CommonName, - &CSSMOID_LocalityName, - &CSSMOID_StateProvinceName, - &CSSMOID_CountryName, - &CSSMOID_StreetAddress, - &CSSMOID_OrganizationName, - &CSSMOID_OrganizationalUnitName, - &kDomainComponentOID, -}; - -// The following structs and templates work with Apple's very arcane and under- -// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1 -// decoder: -// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html - -// These are used to parse the contents of a raw -// BER DistinguishedName structure. - -const SecAsn1Template kStringValueTemplate[] = { - { SEC_ASN1_CHOICE, offsetof(CSSM_X509_TYPE_VALUE_PAIR, valueType), }, - { SEC_ASN1_PRINTABLE_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_PRINTABLE_STRING }, - { SEC_ASN1_IA5_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_IA5_STRING }, - { SEC_ASN1_T61_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_T61_STRING }, - { SEC_ASN1_UTF8_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_PKIX_UTF8_STRING }, - { SEC_ASN1_BMP_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_PKIX_BMP_STRING }, - { SEC_ASN1_UNIVERSAL_STRING, - offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, - BER_TAG_PKIX_UNIVERSAL_STRING }, - { 0, } -}; - -const SecAsn1Template kKeyValuePairTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CSSM_X509_TYPE_VALUE_PAIR) }, - { SEC_ASN1_OBJECT_ID, offsetof(CSSM_X509_TYPE_VALUE_PAIR, type), }, - { SEC_ASN1_INLINE, 0, &kStringValueTemplate, }, - { 0, } -}; - -struct KeyValuePairs { - CSSM_X509_TYPE_VALUE_PAIR* pairs; -}; - -const SecAsn1Template kKeyValuePairSetTemplate[] = { - { SEC_ASN1_SET_OF, offsetof(KeyValuePairs, pairs), - kKeyValuePairTemplate, sizeof(KeyValuePairs) } -}; - -struct X509Name { - KeyValuePairs** pairs_list; -}; - -const SecAsn1Template kNameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name, pairs_list), - kKeyValuePairSetTemplate, sizeof(X509Name) } -}; - -// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.) -std::string DataToString(CSSM_DATA data) { - return std::string( - reinterpret_cast<std::string::value_type*>(data.Data), - data.Length); -} - -// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8. -std::string Latin1DataToUTF8String(CSSM_DATA data) { - base::string16 utf16; - if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1, - base::OnStringConversionError::FAIL, &utf16)) - return ""; - return UTF16ToUTF8(utf16); -} - -// Converts big-endian UTF-16 to UTF-8 in a std::string. -// Note: The byte-order flipping is done in place on the input buffer! -bool UTF16BigEndianToUTF8(char16* chars, size_t length, - std::string* out_string) { - for (size_t i = 0; i < length; i++) - chars[i] = EndianU16_BtoN(chars[i]); - return UTF16ToUTF8(chars, length, out_string); -} - -// Converts big-endian UTF-32 to UTF-8 in a std::string. -// Note: The byte-order flipping is done in place on the input buffer! -bool UTF32BigEndianToUTF8(char32* chars, size_t length, - std::string* out_string) { - for (size_t i = 0; i < length; ++i) - chars[i] = EndianS32_BtoN(chars[i]); -#if defined(WCHAR_T_IS_UTF32) - return WideToUTF8(reinterpret_cast<const wchar_t*>(chars), - length, out_string); -#else -#error This code doesn't handle 16-bit wchar_t. -#endif -} - -// Adds a type+value pair to the appropriate vector from a C array. -// The array is keyed by the matching OIDs from kOIDS[]. -void AddTypeValuePair(const CSSM_OID type, - const std::string& value, - std::vector<std::string>* values[]) { - for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { - if (CSSMOIDEqual(&type, kOIDs[oid])) { - values[oid]->push_back(value); - break; - } - } -} - -// Stores the first string of the vector, if any, to *single_value. -void SetSingle(const std::vector<std::string>& values, - std::string* single_value) { - // We don't expect to have more than one CN, L, S, and C. - LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values"; - if (!values.empty()) - *single_value = values[0]; -} - -bool match(const std::string& str, const std::string& against) { - // TODO(snej): Use the full matching rules specified in RFC 5280 sec. 7.1 - // including trimming and case-folding: <http://www.ietf.org/rfc/rfc5280.txt>. - return against == str; -} - -bool match(const std::vector<std::string>& rdn1, - const std::vector<std::string>& rdn2) { - // "Two relative distinguished names RDN1 and RDN2 match if they have the - // same number of naming attributes and for each naming attribute in RDN1 - // there is a matching naming attribute in RDN2." --RFC 5280 sec. 7.1. - if (rdn1.size() != rdn2.size()) - return false; - for (unsigned i1 = 0; i1 < rdn1.size(); ++i1) { - unsigned i2; - for (i2 = 0; i2 < rdn2.size(); ++i2) { - if (match(rdn1[i1], rdn2[i2])) - break; - } - if (i2 == rdn2.size()) - return false; - } - return true; -} - -} // namespace - -bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, - size_t length) { - DCHECK(ber_name_data); - - // First parse the BER |name_data| into the above structs. - SecAsn1CoderRef coder = NULL; - SecAsn1CoderCreate(&coder); - DCHECK(coder); - X509Name* name = NULL; - OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate, - &name); - if (err) { - OSSTATUS_LOG(ERROR, err) << "SecAsn1Decode"; - SecAsn1CoderRelease(coder); - return false; - } - - // Now scan the structs and add the values to my string vectors. - // I don't store multiple common/locality/state/country names, so use - // temporary vectors for those. - std::vector<std::string> common_names, locality_names, state_names, - country_names; - std::vector<std::string>* values[] = { - &common_names, &locality_names, - &state_names, &country_names, - &this->street_addresses, - &this->organization_names, - &this->organization_unit_names, - &this->domain_components - }; - DCHECK(arraysize(kOIDs) == arraysize(values)); - - for (int rdn = 0; name[rdn].pairs_list; ++rdn) { - CSSM_X509_TYPE_VALUE_PAIR* pair; - for (int pair_index = 0; - NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs); - ++pair_index) { - switch (pair->valueType) { - case BER_TAG_IA5_STRING: // ASCII (that means 7-bit!) - case BER_TAG_PRINTABLE_STRING: // a subset of ASCII - case BER_TAG_PKIX_UTF8_STRING: // UTF-8 - AddTypeValuePair(pair->type, DataToString(pair->value), values); - break; - case BER_TAG_T61_STRING: // T61, pretend it's Latin-1 - AddTypeValuePair(pair->type, - Latin1DataToUTF8String(pair->value), - values); - break; - case BER_TAG_PKIX_BMP_STRING: { // UTF-16, big-endian - std::string value; - UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data), - pair->value.Length / sizeof(char16), - &value); - AddTypeValuePair(pair->type, value, values); - break; - } - case BER_TAG_PKIX_UNIVERSAL_STRING: { // UTF-32, big-endian - std::string value; - UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data), - pair->value.Length / sizeof(char32), - &value); - AddTypeValuePair(pair->type, value, values); - break; - } - default: - DCHECK_EQ(pair->valueType, BER_TAG_UNKNOWN); - // We don't know what data type this is, but we'll store it as a blob. - // Displaying the string may not work, but at least it can be compared - // byte-for-byte by a Matches() call. - AddTypeValuePair(pair->type, DataToString(pair->value), values); - break; - } - } - } - - SetSingle(common_names, &this->common_name); - SetSingle(locality_names, &this->locality_name); - SetSingle(state_names, &this->state_or_province_name); - SetSingle(country_names, &this->country_name); - - // Releasing |coder| frees all the memory pointed to via |name|. - SecAsn1CoderRelease(coder); - return true; -} - -bool CertPrincipal::Matches(const CertPrincipal& against) const { - return match(common_name, against.common_name) && - match(locality_name, against.locality_name) && - match(state_or_province_name, against.state_or_province_name) && - match(country_name, against.country_name) && - match(street_addresses, against.street_addresses) && - match(organization_names, against.organization_names) && - match(organization_unit_names, against.organization_unit_names) && - match(domain_components, against.domain_components); -} - -} // namespace net diff --git a/net/base/x509_cert_types_unittest.cc b/net/base/x509_cert_types_unittest.cc deleted file mode 100644 index 5e66267..0000000 --- a/net/base/x509_cert_types_unittest.cc +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/basictypes.h" -#include "net/base/test_certificate_data.h" -#include "net/base/x509_cert_types.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -#if defined(OS_MACOSX) -TEST(X509TypesTest, Matching) { - CertPrincipal spamco; - spamco.common_name = "SpamCo Dept. Of Certificization"; - spamco.country_name = "EB"; - spamco.organization_names.push_back("SpamCo Holding Company, LLC"); - spamco.organization_names.push_back("SpamCo Evil Masterminds"); - spamco.organization_unit_names.push_back("Class Z Obfuscation Authority"); - ASSERT_TRUE(spamco.Matches(spamco)); - - CertPrincipal bogus; - EXPECT_FALSE(bogus.Matches(spamco)); - EXPECT_FALSE(spamco.Matches(bogus)); - - bogus = spamco; - EXPECT_TRUE(bogus.Matches(spamco)); - EXPECT_TRUE(spamco.Matches(bogus)); - - bogus.organization_names.erase(bogus.organization_names.begin(), - bogus.organization_names.end()); - EXPECT_FALSE(bogus.Matches(spamco)); - EXPECT_FALSE(spamco.Matches(bogus)); - - bogus.organization_names.push_back("SpamCo Holding Company, LLC"); - bogus.organization_names.push_back("SpamCo Evil Masterminds"); - EXPECT_TRUE(bogus.Matches(spamco)); - EXPECT_TRUE(spamco.Matches(bogus)); - - bogus.locality_name = "Elbosdorf"; - EXPECT_FALSE(bogus.Matches(spamco)); - EXPECT_FALSE(spamco.Matches(bogus)); - - bogus.locality_name = ""; - bogus.organization_unit_names.push_back("Q Division"); - EXPECT_FALSE(bogus.Matches(spamco)); - EXPECT_FALSE(spamco.Matches(bogus)); -} -#endif - -TEST(X509TypesTest, ParseDNVerisign) { - CertPrincipal verisign; - EXPECT_TRUE(verisign.ParseDistinguishedName(VerisignDN, sizeof(VerisignDN))); - EXPECT_EQ("", verisign.common_name); - EXPECT_EQ("US", verisign.country_name); - ASSERT_EQ(1U, verisign.organization_names.size()); - EXPECT_EQ("VeriSign, Inc.", verisign.organization_names[0]); - ASSERT_EQ(1U, verisign.organization_unit_names.size()); - EXPECT_EQ("Class 1 Public Primary Certification Authority", - verisign.organization_unit_names[0]); -} - -TEST(X509TypesTest, ParseDNStartcom) { - CertPrincipal startcom; - EXPECT_TRUE(startcom.ParseDistinguishedName(StartComDN, sizeof(StartComDN))); - EXPECT_EQ("StartCom Certification Authority", startcom.common_name); - EXPECT_EQ("IL", startcom.country_name); - ASSERT_EQ(1U, startcom.organization_names.size()); - EXPECT_EQ("StartCom Ltd.", startcom.organization_names[0]); - ASSERT_EQ(1U, startcom.organization_unit_names.size()); - EXPECT_EQ("Secure Digital Certificate Signing", - startcom.organization_unit_names[0]); -} - -TEST(X509TypesTest, ParseDNUserTrust) { - CertPrincipal usertrust; - EXPECT_TRUE(usertrust.ParseDistinguishedName(UserTrustDN, - sizeof(UserTrustDN))); - EXPECT_EQ("UTN-USERFirst-Client Authentication and Email", - usertrust.common_name); - EXPECT_EQ("US", usertrust.country_name); - EXPECT_EQ("UT", usertrust.state_or_province_name); - EXPECT_EQ("Salt Lake City", usertrust.locality_name); - ASSERT_EQ(1U, usertrust.organization_names.size()); - EXPECT_EQ("The USERTRUST Network", usertrust.organization_names[0]); - ASSERT_EQ(1U, usertrust.organization_unit_names.size()); - EXPECT_EQ("http://www.usertrust.com", - usertrust.organization_unit_names[0]); -} - -TEST(X509TypesTest, ParseDNTurkTrust) { - // Note: This tests parsing UTF8STRINGs. - CertPrincipal turktrust; - EXPECT_TRUE(turktrust.ParseDistinguishedName(TurkTrustDN, - sizeof(TurkTrustDN))); - EXPECT_EQ("TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı", - turktrust.common_name); - EXPECT_EQ("TR", turktrust.country_name); - EXPECT_EQ("Ankara", turktrust.locality_name); - ASSERT_EQ(1U, turktrust.organization_names.size()); - EXPECT_EQ("TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. (c) Kasım 2005", - turktrust.organization_names[0]); -} - -TEST(X509TypesTest, ParseDNATrust) { - // Note: This tests parsing 16-bit BMPSTRINGs. - CertPrincipal atrust; - EXPECT_TRUE(atrust.ParseDistinguishedName(ATrustQual01DN, - sizeof(ATrustQual01DN))); - EXPECT_EQ("A-Trust-Qual-01", - atrust.common_name); - EXPECT_EQ("AT", atrust.country_name); - ASSERT_EQ(1U, atrust.organization_names.size()); - EXPECT_EQ("A-Trust Ges. für Sicherheitssysteme im elektr. Datenverkehr GmbH", - atrust.organization_names[0]); - ASSERT_EQ(1U, atrust.organization_unit_names.size()); - EXPECT_EQ("A-Trust-Qual-01", - atrust.organization_unit_names[0]); -} - -TEST(X509TypesTest, ParseDNEntrust) { - // Note: This tests parsing T61STRINGs and fields with multiple values. - CertPrincipal entrust; - EXPECT_TRUE(entrust.ParseDistinguishedName(EntrustDN, - sizeof(EntrustDN))); - EXPECT_EQ("Entrust.net Certification Authority (2048)", - entrust.common_name); - EXPECT_EQ("", entrust.country_name); - ASSERT_EQ(1U, entrust.organization_names.size()); - EXPECT_EQ("Entrust.net", - entrust.organization_names[0]); - ASSERT_EQ(2U, entrust.organization_unit_names.size()); - EXPECT_EQ("www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)", - entrust.organization_unit_names[0]); - EXPECT_EQ("(c) 1999 Entrust.net Limited", - entrust.organization_unit_names[1]); -} - -} // namespace net diff --git a/net/base/x509_cert_types_win.cc b/net/base/x509_cert_types_win.cc deleted file mode 100644 index 0db63b1..0000000 --- a/net/base/x509_cert_types_win.cc +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_cert_types.h" - -#include <windows.h> -#include <wincrypt.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "crypto/capi_util.h" - -#pragma comment(lib, "crypt32.lib") - -namespace net { - -namespace { - -// A list of OIDs to decode. Any OID not on this list will be ignored for -// purposes of parsing. -const char* kOIDs[] = { - szOID_COMMON_NAME, - szOID_LOCALITY_NAME, - szOID_STATE_OR_PROVINCE_NAME, - szOID_COUNTRY_NAME, - szOID_STREET_ADDRESS, - szOID_ORGANIZATION_NAME, - szOID_ORGANIZATIONAL_UNIT_NAME, - szOID_DOMAIN_COMPONENT -}; - -// Converts the value for |attribute| to an UTF-8 string, storing the result -// in |value|. Returns false if the string cannot be converted. -bool GetAttributeValue(PCERT_RDN_ATTR attribute, - std::string* value) { - DWORD chars_needed = CertRDNValueToStrW(attribute->dwValueType, - &attribute->Value, NULL, 0); - if (chars_needed == 0) - return false; - if (chars_needed == 1) { - // The value is actually an empty string (chars_needed includes a single - // char for a NULL value). Don't bother converting - just clear the - // string. - value->clear(); - return true; - } - std::wstring wide_name; - DWORD chars_written = CertRDNValueToStrW( - attribute->dwValueType, &attribute->Value, - WriteInto(&wide_name, chars_needed), chars_needed); - if (chars_written <= 1) - return false; - wide_name.resize(chars_written - 1); - *value = WideToUTF8(wide_name); - return true; -} - -// Adds a type+value pair to the appropriate vector from a C array. -// The array is keyed by the matching OIDs from kOIDS[]. -bool AddTypeValuePair(PCERT_RDN_ATTR attribute, - std::vector<std::string>* values[]) { - for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { - if (strcmp(attribute->pszObjId, kOIDs[oid]) == 0) { - std::string value; - if (!GetAttributeValue(attribute, &value)) - return false; - values[oid]->push_back(value); - break; - } - } - return true; -} - -// Stores the first string of the vector, if any, to *single_value. -void SetSingle(const std::vector<std::string>& values, - std::string* single_value) { - // We don't expect to have more than one CN, L, S, and C. - LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values"; - if (!values.empty()) - *single_value = values[0]; -} - -} // namespace - -bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, - size_t length) { - DCHECK(ber_name_data); - - CRYPT_DECODE_PARA decode_para; - decode_para.cbSize = sizeof(decode_para); - decode_para.pfnAlloc = crypto::CryptAlloc; - decode_para.pfnFree = crypto::CryptFree; - CERT_NAME_INFO* name_info = NULL; - DWORD name_info_size = 0; - BOOL rv; - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - X509_NAME, - reinterpret_cast<const BYTE*>(ber_name_data), - length, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &name_info, &name_info_size); - if (!rv) - return false; - scoped_ptr_malloc<CERT_NAME_INFO> scoped_name_info(name_info); - - std::vector<std::string> common_names, locality_names, state_names, - country_names; - - std::vector<std::string>* values[] = { - &common_names, &locality_names, - &state_names, &country_names, - &this->street_addresses, - &this->organization_names, - &this->organization_unit_names, - &this->domain_components - }; - DCHECK(arraysize(kOIDs) == arraysize(values)); - - for (DWORD cur_rdn = 0; cur_rdn < name_info->cRDN; ++cur_rdn) { - PCERT_RDN rdn = &name_info->rgRDN[cur_rdn]; - for (DWORD cur_ava = 0; cur_ava < rdn->cRDNAttr; ++cur_ava) { - PCERT_RDN_ATTR ava = &rdn->rgRDNAttr[cur_ava]; - if (!AddTypeValuePair(ava, values)) - return false; - } - } - - SetSingle(common_names, &this->common_name); - SetSingle(locality_names, &this->locality_name); - SetSingle(state_names, &this->state_or_province_name); - SetSingle(country_names, &this->country_name); - return true; -} - -} // namespace net diff --git a/net/base/x509_certificate.cc b/net/base/x509_certificate.cc deleted file mode 100644 index 29b11a8..0000000 --- a/net/base/x509_certificate.cc +++ /dev/null @@ -1,701 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <stdlib.h> - -#include <algorithm> -#include <map> -#include <string> -#include <vector> - -#include "base/base64.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/memory/singleton.h" -#include "base/metrics/histogram.h" -#include "base/pickle.h" -#include "base/sha1.h" -#include "base/string_piece.h" -#include "base/string_util.h" -#include "base/synchronization/lock.h" -#include "base/time.h" -#include "googleurl/src/url_canon_ip.h" -#include "net/base/net_util.h" -#include "net/base/pem_tokenizer.h" - -namespace net { - -namespace { - -// Indicates the order to use when trying to decode binary data, which is -// based on (speculation) as to what will be most common -> least common -const X509Certificate::Format kFormatDecodePriority[] = { - X509Certificate::FORMAT_SINGLE_CERTIFICATE, - X509Certificate::FORMAT_PKCS7 -}; - -// The PEM block header used for DER certificates -const char kCertificateHeader[] = "CERTIFICATE"; -// The PEM block header used for PKCS#7 data -const char kPKCS7Header[] = "PKCS7"; - -#if !defined(USE_NSS) -// A thread-safe cache for OS certificate handles. -// -// Within each of the supported underlying crypto libraries, a certificate -// handle is represented as a ref-counted object that contains the parsed -// data for the certificate. In addition, the underlying OS handle may also -// contain a copy of the original ASN.1 DER used to constructed the handle. -// -// In order to reduce the memory usage when multiple SSL connections exist, -// with each connection storing the server's identity certificate plus any -// intermediates supplied, the certificate handles are cached. Any two -// X509Certificates that were created from the same ASN.1 DER data, -// regardless of where that data came from, will share the same underlying -// OS certificate handle. -class X509CertificateCache { - public: - // Performs a compare-and-swap like operation. If an OS certificate handle - // for the same certificate data as |*cert_handle| already exists in the - // cache, the original |*cert_handle| will be freed and |cert_handle| - // will be updated to point to a duplicated reference to the existing cached - // certificate, with the caller taking ownership of this duplicated handle. - // If an equivalent OS certificate handle is not found, a duplicated - // reference to |*cert_handle| will be added to the cache. In either case, - // upon return, the caller fully owns |*cert_handle| and is responsible for - // calling FreeOSCertHandle(), after first calling Remove(). - void InsertOrUpdate(X509Certificate::OSCertHandle* cert_handle); - - // Decrements the cache reference count for |cert_handle|, a handle that was - // previously obtained by calling InsertOrUpdate(). If this is the last - // cached reference held, this will remove the handle from the cache. The - // caller retains ownership of |cert_handle| and remains responsible for - // calling FreeOSCertHandle() to release the underlying OS certificate - void Remove(X509Certificate::OSCertHandle cert_handle); - - private: - // A single entry in the cache. Certificates will be keyed by their SHA1 - // fingerprints, but will not be considered equivalent unless the entire - // certificate data matches. - struct Entry { - Entry() : cert_handle(NULL), ref_count(0) {} - - X509Certificate::OSCertHandle cert_handle; - - // Increased by each call to InsertOrUpdate(), and balanced by each call - // to Remove(). When it equals 0, all references created by - // InsertOrUpdate() have been released, so the cache entry will be removed - // the cached OS certificate handle will be freed. - int ref_count; - }; - typedef std::map<SHA1HashValue, Entry, SHA1HashValueLessThan> CertMap; - - // Obtain an instance of X509CertificateCache via a LazyInstance. - X509CertificateCache() {} - ~X509CertificateCache() {} - friend struct base::DefaultLazyInstanceTraits<X509CertificateCache>; - - // You must acquire this lock before using any private data of this object - // You must not block while holding this lock. - base::Lock lock_; - - // The certificate cache. You must acquire |lock_| before using |cache_|. - CertMap cache_; - - DISALLOW_COPY_AND_ASSIGN(X509CertificateCache); -}; - -base::LazyInstance<X509CertificateCache>::Leaky - g_x509_certificate_cache = LAZY_INSTANCE_INITIALIZER; - -void X509CertificateCache::InsertOrUpdate( - X509Certificate::OSCertHandle* cert_handle) { - DCHECK(cert_handle); - SHA1HashValue fingerprint = - X509Certificate::CalculateFingerprint(*cert_handle); - - X509Certificate::OSCertHandle old_handle = NULL; - { - base::AutoLock lock(lock_); - CertMap::iterator pos = cache_.find(fingerprint); - if (pos == cache_.end()) { - // A cached entry was not found, so initialize a new entry. The entry - // assumes ownership of the current |*cert_handle|. - Entry cache_entry; - cache_entry.cert_handle = *cert_handle; - cache_entry.ref_count = 0; - CertMap::value_type cache_value(fingerprint, cache_entry); - pos = cache_.insert(cache_value).first; - } else { - bool is_same_cert = - X509Certificate::IsSameOSCert(*cert_handle, pos->second.cert_handle); - if (!is_same_cert) { - // Two certificates don't match, due to a SHA1 hash collision. Given - // the low probability, the simplest solution is to not cache the - // certificate, which should not affect performance too negatively. - return; - } - // A cached entry was found and will be used instead of the caller's - // handle. Ensure the caller's original handle will be freed, since - // ownership is assumed. - old_handle = *cert_handle; - } - // Whether an existing cached handle or a new handle, increment the - // cache's reference count and return a handle that the caller can own. - ++pos->second.ref_count; - *cert_handle = X509Certificate::DupOSCertHandle(pos->second.cert_handle); - } - // If the caller's handle was replaced with a cached handle, free the - // original handle now. This is done outside of the lock because - // |old_handle| may be the only handle for this particular certificate, so - // freeing it may be complex or resource-intensive and does not need to - // be guarded by the lock. - if (old_handle) { - X509Certificate::FreeOSCertHandle(old_handle); - DHISTOGRAM_COUNTS("X509CertificateReuseCount", 1); - } -} - -void X509CertificateCache::Remove(X509Certificate::OSCertHandle cert_handle) { - SHA1HashValue fingerprint = - X509Certificate::CalculateFingerprint(cert_handle); - base::AutoLock lock(lock_); - - CertMap::iterator pos = cache_.find(fingerprint); - if (pos == cache_.end()) - return; // A hash collision where the winning cert was already freed. - - bool is_same_cert = X509Certificate::IsSameOSCert(cert_handle, - pos->second.cert_handle); - if (!is_same_cert) - return; // A hash collision where the winning cert is still around. - - if (--pos->second.ref_count == 0) { - // The last reference to |cert_handle| has been removed, so release the - // Entry's OS handle and remove the Entry. The caller still holds a - // reference to |cert_handle| and is responsible for freeing it. - X509Certificate::FreeOSCertHandle(pos->second.cert_handle); - cache_.erase(pos); - } -} -#endif // !defined(USE_NSS) - -// See X509CertificateCache::InsertOrUpdate. NSS has a built-in cache, so there -// is no point in wrapping another cache around it. -void InsertOrUpdateCache(X509Certificate::OSCertHandle* cert_handle) { -#if !defined(USE_NSS) - g_x509_certificate_cache.Pointer()->InsertOrUpdate(cert_handle); -#endif -} - -// See X509CertificateCache::Remove. -void RemoveFromCache(X509Certificate::OSCertHandle cert_handle) { -#if !defined(USE_NSS) - g_x509_certificate_cache.Pointer()->Remove(cert_handle); -#endif -} - -// Utility to split |src| on the first occurrence of |c|, if any. |right| will -// either be empty if |c| was not found, or will contain the remainder of the -// string including the split character itself. -void SplitOnChar(const base::StringPiece& src, - char c, - base::StringPiece* left, - base::StringPiece* right) { - size_t pos = src.find(c); - if (pos == base::StringPiece::npos) { - *left = src; - right->clear(); - } else { - *left = src.substr(0, pos); - *right = src.substr(pos); - } -} - -} // namespace - -bool X509Certificate::LessThan::operator()(X509Certificate* lhs, - X509Certificate* rhs) const { - if (lhs == rhs) - return false; - - int rv = memcmp(lhs->fingerprint_.data, rhs->fingerprint_.data, - sizeof(lhs->fingerprint_.data)); - if (rv != 0) - return rv < 0; - - rv = memcmp(lhs->ca_fingerprint_.data, rhs->ca_fingerprint_.data, - sizeof(lhs->ca_fingerprint_.data)); - return rv < 0; -} - -X509Certificate::X509Certificate(const std::string& subject, - const std::string& issuer, - base::Time start_date, - base::Time expiration_date) - : subject_(subject), - issuer_(issuer), - valid_start_(start_date), - valid_expiry_(expiration_date), - cert_handle_(NULL) { - memset(fingerprint_.data, 0, sizeof(fingerprint_.data)); - memset(ca_fingerprint_.data, 0, sizeof(ca_fingerprint_.data)); -} - -// static -X509Certificate* X509Certificate::CreateFromHandle( - OSCertHandle cert_handle, - const OSCertHandles& intermediates) { - DCHECK(cert_handle); - return new X509Certificate(cert_handle, intermediates); -} - -// static -X509Certificate* X509Certificate::CreateFromDERCertChain( - const std::vector<base::StringPiece>& der_certs) { - if (der_certs.empty()) - return NULL; - - X509Certificate::OSCertHandles intermediate_ca_certs; - for (size_t i = 1; i < der_certs.size(); i++) { - OSCertHandle handle = CreateOSCertHandleFromBytes( - const_cast<char*>(der_certs[i].data()), der_certs[i].size()); - if (!handle) - break; - intermediate_ca_certs.push_back(handle); - } - - OSCertHandle handle = NULL; - // Return NULL if we failed to parse any of the certs. - if (der_certs.size() - 1 == intermediate_ca_certs.size()) { - handle = CreateOSCertHandleFromBytes( - const_cast<char*>(der_certs[0].data()), der_certs[0].size()); - } - - X509Certificate* cert = NULL; - if (handle) { - cert = CreateFromHandle(handle, intermediate_ca_certs); - FreeOSCertHandle(handle); - } - - for (size_t i = 0; i < intermediate_ca_certs.size(); i++) - FreeOSCertHandle(intermediate_ca_certs[i]); - - return cert; -} - -// static -X509Certificate* X509Certificate::CreateFromBytes(const char* data, - int length) { - OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length); - if (!cert_handle) - return NULL; - - X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); - FreeOSCertHandle(cert_handle); - return cert; -} - -// static -X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, - PickleIterator* pickle_iter, - PickleType type) { - if (type == PICKLETYPE_CERTIFICATE_CHAIN_V3) { - int chain_length = 0; - if (!pickle_iter->ReadLength(&chain_length)) - return NULL; - - std::vector<base::StringPiece> cert_chain; - const char* data = NULL; - int data_length = 0; - for (int i = 0; i < chain_length; ++i) { - if (!pickle_iter->ReadData(&data, &data_length)) - return NULL; - cert_chain.push_back(base::StringPiece(data, data_length)); - } - return CreateFromDERCertChain(cert_chain); - } - - // Legacy / Migration code. This should eventually be removed once - // sufficient time has passed that all pickles serialized prior to - // PICKLETYPE_CERTIFICATE_CHAIN_V3 have been removed. - OSCertHandle cert_handle = ReadOSCertHandleFromPickle(pickle_iter); - if (!cert_handle) - return NULL; - - OSCertHandles intermediates; - uint32 num_intermediates = 0; - if (type != PICKLETYPE_SINGLE_CERTIFICATE) { - if (!pickle_iter->ReadUInt32(&num_intermediates)) { - FreeOSCertHandle(cert_handle); - return NULL; - } - -#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(__x86_64__) - // On 64-bit Linux (and any other 64-bit platforms), the intermediate count - // might really be a 64-bit field since we used to use Pickle::WriteSize(), - // which writes either 32 or 64 bits depending on the architecture. Since - // x86-64 is little-endian, if that happens, the next 32 bits will be all - // zeroes (the high bits) and the 32 bits we already read above are the - // correct value (we assume there are never more than 2^32 - 1 intermediate - // certificates in a chain; in practice, more than a dozen or so is - // basically unheard of). Since it's invalid for a certificate to start with - // 32 bits of zeroes, we check for that here and skip it if we find it. We - // save a copy of the pickle iterator to restore in case we don't get 32 - // bits of zeroes. Now we always write 32 bits, so after a while, these old - // cached pickles will all get replaced. - // TODO(mdm): remove this compatibility code in April 2013 or so. - PickleIterator saved_iter = *pickle_iter; - uint32 zero_check = 0; - if (!pickle_iter->ReadUInt32(&zero_check)) { - // This may not be an error. If there are no intermediates, and we're - // reading an old 32-bit pickle, and there's nothing else after this in - // the pickle, we should report success. Note that it is technically - // possible for us to skip over zeroes that should have occurred after - // an empty certificate list; to avoid this going forward, only do this - // backward-compatibility stuff for PICKLETYPE_CERTIFICATE_CHAIN_V1 - // which comes from the pickle version number in http_response_info.cc. - if (num_intermediates) { - FreeOSCertHandle(cert_handle); - return NULL; - } - } - if (zero_check) - *pickle_iter = saved_iter; -#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && defined(__x86_64__) - - for (uint32 i = 0; i < num_intermediates; ++i) { - OSCertHandle intermediate = ReadOSCertHandleFromPickle(pickle_iter); - if (!intermediate) - break; - intermediates.push_back(intermediate); - } - } - - X509Certificate* cert = NULL; - if (intermediates.size() == num_intermediates) - cert = CreateFromHandle(cert_handle, intermediates); - FreeOSCertHandle(cert_handle); - for (size_t i = 0; i < intermediates.size(); ++i) - FreeOSCertHandle(intermediates[i]); - - return cert; -} - -// static -CertificateList X509Certificate::CreateCertificateListFromBytes( - const char* data, int length, int format) { - OSCertHandles certificates; - - // Check to see if it is in a PEM-encoded form. This check is performed - // first, as both OS X and NSS will both try to convert if they detect - // PEM encoding, except they don't do it consistently between the two. - base::StringPiece data_string(data, length); - std::vector<std::string> pem_headers; - - // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally - // valid PEM block header for any format. - pem_headers.push_back(kCertificateHeader); - if (format & FORMAT_PKCS7) - pem_headers.push_back(kPKCS7Header); - - PEMTokenizer pem_tok(data_string, pem_headers); - while (pem_tok.GetNext()) { - std::string decoded(pem_tok.data()); - - OSCertHandle handle = NULL; - if (format & FORMAT_PEM_CERT_SEQUENCE) - handle = CreateOSCertHandleFromBytes(decoded.c_str(), decoded.size()); - if (handle != NULL) { - // Parsed a DER encoded certificate. All PEM blocks that follow must - // also be DER encoded certificates wrapped inside of PEM blocks. - format = FORMAT_PEM_CERT_SEQUENCE; - certificates.push_back(handle); - continue; - } - - // If the first block failed to parse as a DER certificate, and - // formats other than PEM are acceptable, check to see if the decoded - // data is one of the accepted formats. - if (format & ~FORMAT_PEM_CERT_SEQUENCE) { - for (size_t i = 0; certificates.empty() && - i < arraysize(kFormatDecodePriority); ++i) { - if (format & kFormatDecodePriority[i]) { - certificates = CreateOSCertHandlesFromBytes(decoded.c_str(), - decoded.size(), kFormatDecodePriority[i]); - } - } - } - - // Stop parsing after the first block for any format but a sequence of - // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE - // is handled above, and continues processing until a certificate fails - // to parse. - break; - } - - // Try each of the formats, in order of parse preference, to see if |data| - // contains the binary representation of a Format, if it failed to parse - // as a PEM certificate/chain. - for (size_t i = 0; certificates.empty() && - i < arraysize(kFormatDecodePriority); ++i) { - if (format & kFormatDecodePriority[i]) - certificates = CreateOSCertHandlesFromBytes(data, length, - kFormatDecodePriority[i]); - } - - CertificateList results; - // No certificates parsed. - if (certificates.empty()) - return results; - - for (OSCertHandles::iterator it = certificates.begin(); - it != certificates.end(); ++it) { - X509Certificate* result = CreateFromHandle(*it, OSCertHandles()); - results.push_back(scoped_refptr<X509Certificate>(result)); - FreeOSCertHandle(*it); - } - - return results; -} - -void X509Certificate::Persist(Pickle* pickle) { - DCHECK(cert_handle_); - // This would be an absolutely insane number of intermediates. - if (intermediate_ca_certs_.size() > static_cast<size_t>(INT_MAX) - 1) { - NOTREACHED(); - return; - } - if (!pickle->WriteInt( - static_cast<int>(intermediate_ca_certs_.size() + 1)) || - !WriteOSCertHandleToPickle(cert_handle_, pickle)) { - NOTREACHED(); - return; - } - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { - if (!WriteOSCertHandleToPickle(intermediate_ca_certs_[i], pickle)) { - NOTREACHED(); - return; - } - } -} - -void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { - GetSubjectAltName(dns_names, NULL); - if (dns_names->empty()) - dns_names->push_back(subject_.common_name); -} - -bool X509Certificate::HasExpired() const { - return base::Time::Now() > valid_expiry(); -} - -bool X509Certificate::Equals(const X509Certificate* other) const { - return IsSameOSCert(cert_handle_, other->cert_handle_); -} - -// static -bool X509Certificate::VerifyHostname( - const std::string& hostname, - const std::string& cert_common_name, - const std::vector<std::string>& cert_san_dns_names, - const std::vector<std::string>& cert_san_ip_addrs) { - DCHECK(!hostname.empty()); - // Perform name verification following http://tools.ietf.org/html/rfc6125. - // The terminology used in this method is as per that RFC:- - // Reference identifier == the host the local user/agent is intending to - // access, i.e. the thing displayed in the URL bar. - // Presented identifier(s) == name(s) the server knows itself as, in its cert. - - // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. - const std::string host_or_ip = hostname.find(':') != std::string::npos ? - "[" + hostname + "]" : hostname; - url_canon::CanonHostInfo host_info; - std::string reference_name = CanonicalizeHost(host_or_ip, &host_info); - // CanonicalizeHost does not normalize absolute vs relative DNS names. If - // the input name was absolute (included trailing .), normalize it as if it - // was relative. - if (!reference_name.empty() && *reference_name.rbegin() == '.') - reference_name.resize(reference_name.size() - 1); - if (reference_name.empty()) - return false; - - // Allow fallback to Common name matching? - const bool common_name_fallback = cert_san_dns_names.empty() && - cert_san_ip_addrs.empty(); - - // Fully handle all cases where |hostname| contains an IP address. - if (host_info.IsIPAddress()) { - if (common_name_fallback && - host_info.family == url_canon::CanonHostInfo::IPV4) { - // Fallback to Common name matching. As this is deprecated and only - // supported for compatibility refuse it for IPv6 addresses. - return reference_name == cert_common_name; - } - base::StringPiece ip_addr_string( - reinterpret_cast<const char*>(host_info.address), - host_info.AddressLength()); - return std::find(cert_san_ip_addrs.begin(), cert_san_ip_addrs.end(), - ip_addr_string) != cert_san_ip_addrs.end(); - } - - // |reference_domain| is the remainder of |host| after the leading host - // component is stripped off, but includes the leading dot e.g. - // "www.f.com" -> ".f.com". - // If there is no meaningful domain part to |host| (e.g. it contains no dots) - // then |reference_domain| will be empty. - base::StringPiece reference_host, reference_domain; - SplitOnChar(reference_name, '.', &reference_host, &reference_domain); - bool allow_wildcards = false; - if (!reference_domain.empty()) { - DCHECK(reference_domain.starts_with(".")); - // We required at least 3 components (i.e. 2 dots) as a basic protection - // against too-broad wild-carding. - // Also we don't attempt wildcard matching on a purely numerical hostname. - allow_wildcards = reference_domain.rfind('.') != 0 && - reference_name.find_first_not_of("0123456789.") != std::string::npos; - } - - // Now step through the DNS names doing wild card comparison (if necessary) - // on each against the reference name. If subjectAltName is empty, then - // fallback to use the common name instead. - std::vector<std::string> common_name_as_vector; - const std::vector<std::string>* presented_names = &cert_san_dns_names; - if (common_name_fallback) { - // Note: there's a small possibility cert_common_name is an international - // domain name in non-standard encoding (e.g. UTF8String or BMPString - // instead of A-label). As common name fallback is deprecated we're not - // doing anything specific to deal with this. - common_name_as_vector.push_back(cert_common_name); - presented_names = &common_name_as_vector; - } - for (std::vector<std::string>::const_iterator it = - presented_names->begin(); - it != presented_names->end(); ++it) { - // Catch badly corrupt cert names up front. - if (it->empty() || it->find('\0') != std::string::npos) { - DVLOG(1) << "Bad name in cert: " << *it; - continue; - } - std::string presented_name(StringToLowerASCII(*it)); - - // Remove trailing dot, if any. - if (*presented_name.rbegin() == '.') - presented_name.resize(presented_name.length() - 1); - - // The hostname must be at least as long as the cert name it is matching, - // as we require the wildcard (if present) to match at least one character. - if (presented_name.length() > reference_name.length()) - continue; - - base::StringPiece presented_host, presented_domain; - SplitOnChar(presented_name, '.', &presented_host, &presented_domain); - - if (presented_domain != reference_domain) - continue; - - base::StringPiece pattern_begin, pattern_end; - SplitOnChar(presented_host, '*', &pattern_begin, &pattern_end); - - if (pattern_end.empty()) { // No '*' in the presented_host - if (presented_host == reference_host) - return true; - continue; - } - pattern_end.remove_prefix(1); // move past the * - - if (!allow_wildcards) - continue; - - // * must not match a substring of an IDN A label; just a whole fragment. - if (reference_host.starts_with("xn--") && - !(pattern_begin.empty() && pattern_end.empty())) - continue; - - if (reference_host.starts_with(pattern_begin) && - reference_host.ends_with(pattern_end)) - return true; - } - return false; -} - -#if !defined(USE_NSS) -bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { - std::vector<std::string> dns_names, ip_addrs; - GetSubjectAltName(&dns_names, &ip_addrs); - return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs); -} -#endif - -// static -bool X509Certificate::GetPEMEncoded(OSCertHandle cert_handle, - std::string* pem_encoded) { - std::string der_encoded; - if (!GetDEREncoded(cert_handle, &der_encoded) || der_encoded.empty()) - return false; - std::string b64_encoded; - if (!base::Base64Encode(der_encoded, &b64_encoded) || b64_encoded.empty()) - return false; - *pem_encoded = "-----BEGIN CERTIFICATE-----\n"; - - // Divide the Base-64 encoded data into 64-character chunks, as per - // 4.3.2.4 of RFC 1421. - static const size_t kChunkSize = 64; - size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize; - for (size_t i = 0, chunk_offset = 0; i < chunks; - ++i, chunk_offset += kChunkSize) { - pem_encoded->append(b64_encoded, chunk_offset, kChunkSize); - pem_encoded->append("\n"); - } - pem_encoded->append("-----END CERTIFICATE-----\n"); - return true; -} - -bool X509Certificate::GetPEMEncodedChain( - std::vector<std::string>* pem_encoded) const { - std::vector<std::string> encoded_chain; - std::string pem_data; - if (!GetPEMEncoded(os_cert_handle(), &pem_data)) - return false; - encoded_chain.push_back(pem_data); - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { - if (!GetPEMEncoded(intermediate_ca_certs_[i], &pem_data)) - return false; - encoded_chain.push_back(pem_data); - } - pem_encoded->swap(encoded_chain); - return true; -} - -X509Certificate::X509Certificate(OSCertHandle cert_handle, - const OSCertHandles& intermediates) - : cert_handle_(DupOSCertHandle(cert_handle)) { - InsertOrUpdateCache(&cert_handle_); - for (size_t i = 0; i < intermediates.size(); ++i) { - // Duplicate the incoming certificate, as the caller retains ownership - // of |intermediates|. - OSCertHandle intermediate = DupOSCertHandle(intermediates[i]); - // Update the cache, which will assume ownership of the duplicated - // handle and return a suitable equivalent, potentially from the cache. - InsertOrUpdateCache(&intermediate); - intermediate_ca_certs_.push_back(intermediate); - } - // Platform-specific initialization. - Initialize(); -} - -X509Certificate::~X509Certificate() { - if (cert_handle_) { - RemoveFromCache(cert_handle_); - FreeOSCertHandle(cert_handle_); - } - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { - RemoveFromCache(intermediate_ca_certs_[i]); - FreeOSCertHandle(intermediate_ca_certs_[i]); - } -} - -} // namespace net diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h deleted file mode 100644 index ade9655..0000000 --- a/net/base/x509_certificate.h +++ /dev/null @@ -1,510 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_CERTIFICATE_H_ -#define NET_BASE_X509_CERTIFICATE_H_ - -#include <string.h> - -#include <string> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" -#include "base/string_piece.h" -#include "base/time.h" -#include "net/base/cert_type.h" -#include "net/base/net_export.h" -#include "net/base/x509_cert_types.h" - -#if defined(OS_WIN) -#include <windows.h> -#include <wincrypt.h> -#elif defined(OS_MACOSX) -#include <CoreFoundation/CFArray.h> -#include <Security/SecBase.h> - -#elif defined(USE_OPENSSL) -// Forward declaration; real one in <x509.h> -typedef struct x509_st X509; -typedef struct x509_store_st X509_STORE; -#elif defined(USE_NSS) -// Forward declaration; real one in <cert.h> -struct CERTCertificateStr; -#endif - -class Pickle; -class PickleIterator; - -namespace crypto { -class RSAPrivateKey; -} // namespace crypto - -namespace net { - -class CRLSet; -class CertVerifyResult; - -typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; - -// X509Certificate represents a X.509 certificate, which is comprised a -// particular identity or end-entity certificate, such as an SSL server -// identity or an SSL client certificate, and zero or more intermediate -// certificates that may be used to build a path to a root certificate. -class NET_EXPORT X509Certificate - : public base::RefCountedThreadSafe<X509Certificate> { - public: - // An OSCertHandle is a handle to a certificate object in the underlying - // crypto library. We assume that OSCertHandle is a pointer type on all - // platforms and that NULL represents an invalid OSCertHandle. -#if defined(OS_WIN) - typedef PCCERT_CONTEXT OSCertHandle; -#elif defined(OS_MACOSX) - typedef SecCertificateRef OSCertHandle; -#elif defined(USE_OPENSSL) - typedef X509* OSCertHandle; -#elif defined(USE_NSS) - typedef struct CERTCertificateStr* OSCertHandle; -#else - // TODO(ericroman): not implemented - typedef void* OSCertHandle; -#endif - - typedef std::vector<OSCertHandle> OSCertHandles; - - enum PublicKeyType { - kPublicKeyTypeUnknown, - kPublicKeyTypeRSA, - kPublicKeyTypeDSA, - kPublicKeyTypeECDSA, - kPublicKeyTypeDH, - kPublicKeyTypeECDH - }; - - // Predicate functor used in maps when X509Certificate is used as the key. - class NET_EXPORT LessThan { - public: - bool operator() (X509Certificate* lhs, X509Certificate* rhs) const; - }; - - enum Format { - // The data contains a single DER-encoded certificate, or a PEM-encoded - // DER certificate with the PEM encoding block name of "CERTIFICATE". - // Any subsequent blocks will be ignored. - FORMAT_SINGLE_CERTIFICATE = 1 << 0, - - // The data contains a sequence of one or more PEM-encoded, DER - // certificates, with the PEM encoding block name of "CERTIFICATE". - // All PEM blocks will be parsed, until the first error is encountered. - FORMAT_PEM_CERT_SEQUENCE = 1 << 1, - - // The data contains a PKCS#7 SignedData structure, whose certificates - // member is to be used to initialize the certificate and intermediates. - // The data may further be encoded using PEM, specifying block names of - // either "PKCS7" or "CERTIFICATE". - FORMAT_PKCS7 = 1 << 2, - - // Automatically detect the format. - FORMAT_AUTO = FORMAT_SINGLE_CERTIFICATE | FORMAT_PEM_CERT_SEQUENCE | - FORMAT_PKCS7, - }; - - // PickleType is intended for deserializing certificates that were pickled - // by previous releases as part of a net::HttpResponseInfo. - // When serializing certificates to a new Pickle, - // PICKLETYPE_CERTIFICATE_CHAIN_V3 is always used. - enum PickleType { - // When reading a certificate from a Pickle, the Pickle only contains a - // single certificate. - PICKLETYPE_SINGLE_CERTIFICATE, - - // When reading a certificate from a Pickle, the Pickle contains the - // the certificate plus any certificates that were stored in - // |intermediate_ca_certificates_| at the time it was serialized. - // The count of certificates is stored as a size_t, which is either 32 - // or 64 bits. - PICKLETYPE_CERTIFICATE_CHAIN_V2, - - // The Pickle contains the certificate and any certificates that were - // stored in |intermediate_ca_certs_| at the time it was serialized. - // The format is [int count], [data - this certificate], - // [data - intermediate1], ... [data - intermediateN]. - // All certificates are stored in DER form. - PICKLETYPE_CERTIFICATE_CHAIN_V3, - }; - - // Creates a X509Certificate from the ground up. Used by tests that simulate - // SSL connections. - X509Certificate(const std::string& subject, const std::string& issuer, - base::Time start_date, base::Time expiration_date); - - // Create an X509Certificate from a handle to the certificate object in the - // underlying crypto library. The returned pointer must be stored in a - // scoped_refptr<X509Certificate>. - static X509Certificate* CreateFromHandle(OSCertHandle cert_handle, - const OSCertHandles& intermediates); - - // Create an X509Certificate from a chain of DER encoded certificates. The - // first certificate in the chain is the end-entity certificate to which a - // handle is returned. The other certificates in the chain are intermediate - // certificates. The returned pointer must be stored in a - // scoped_refptr<X509Certificate>. - static X509Certificate* CreateFromDERCertChain( - const std::vector<base::StringPiece>& der_certs); - - // Create an X509Certificate from the DER-encoded representation. - // Returns NULL on failure. - // - // The returned pointer must be stored in a scoped_refptr<X509Certificate>. - static X509Certificate* CreateFromBytes(const char* data, int length); - -#if defined(USE_NSS) - // Create an X509Certificate from the DER-encoded representation. - // |nickname| can be NULL if an auto-generated nickname is desired. - // Returns NULL on failure. The returned pointer must be stored in a - // scoped_refptr<X509Certificate>. - // - // This function differs from CreateFromBytes in that it takes a - // nickname that will be used when the certificate is imported into PKCS#11. - static X509Certificate* CreateFromBytesWithNickname(const char* data, - int length, - const char* nickname); - - // The default nickname of the certificate, based on the certificate type - // passed in. If this object was created using CreateFromBytesWithNickname, - // then this will return the nickname specified upon creation. - std::string GetDefaultNickname(CertType type) const; -#endif - - // Create an X509Certificate from the representation stored in the given - // pickle. The data for this object is found relative to the given - // pickle_iter, which should be passed to the pickle's various Read* methods. - // Returns NULL on failure. - // - // The returned pointer must be stored in a scoped_refptr<X509Certificate>. - static X509Certificate* CreateFromPickle(const Pickle& pickle, - PickleIterator* pickle_iter, - PickleType type); - - // Parses all of the certificates possible from |data|. |format| is a - // bit-wise OR of Format, indicating the possible formats the - // certificates may have been serialized as. If an error occurs, an empty - // collection will be returned. - static CertificateList CreateCertificateListFromBytes(const char* data, - int length, - int format); - - // Create a self-signed certificate containing the public key in |key|. - // Subject, serial number and validity period are given as parameters. - // The certificate is signed by the private key in |key|. The hashing - // algorithm for the signature is SHA-1. - // - // |subject| is a distinguished name defined in RFC4514. - // - // An example: - // CN=Michael Wong,O=FooBar Corporation,DC=foobar,DC=com - // - // SECURITY WARNING - // - // Using self-signed certificates has the following security risks: - // 1. Encryption without authentication and thus vulnerable to - // man-in-the-middle attacks. - // 2. Self-signed certificates cannot be revoked. - // - // Use this certificate only after the above risks are acknowledged. - static X509Certificate* CreateSelfSigned(crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration); - - // Appends a representation of this object to the given pickle. - void Persist(Pickle* pickle); - - // The serial number, DER encoded, possibly including a leading 00 byte. - const std::string& serial_number() const { return serial_number_; } - - // The subject of the certificate. For HTTPS server certificates, this - // represents the web server. The common name of the subject should match - // the host name of the web server. - const CertPrincipal& subject() const { return subject_; } - - // The issuer of the certificate. - const CertPrincipal& issuer() const { return issuer_; } - - // Time period during which the certificate is valid. More precisely, this - // certificate is invalid before the |valid_start| date and invalid after - // the |valid_expiry| date. - // If we were unable to parse either date from the certificate (or if the cert - // lacks either date), the date will be null (i.e., is_null() will be true). - const base::Time& valid_start() const { return valid_start_; } - const base::Time& valid_expiry() const { return valid_expiry_; } - - // The fingerprint of this certificate. - const SHA1HashValue& fingerprint() const { return fingerprint_; } - - // The fingerprint of the intermediate CA certificates. - const SHA1HashValue& ca_fingerprint() const { - return ca_fingerprint_; - } - - // Gets the DNS names in the certificate. Pursuant to RFC 2818, Section 3.1 - // Server Identity, if the certificate has a subjectAltName extension of - // type dNSName, this method gets the DNS names in that extension. - // Otherwise, it gets the common name in the subject field. - void GetDNSNames(std::vector<std::string>* dns_names) const; - - // Gets the subjectAltName extension field from the certificate, if any. - // For future extension; currently this only returns those name types that - // are required for HTTP certificate name verification - see VerifyHostname. - // Unrequired parameters may be passed as NULL. - void GetSubjectAltName(std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const; - - // Convenience method that returns whether this certificate has expired as of - // now. - bool HasExpired() const; - - // Returns true if this object and |other| represent the same certificate. - bool Equals(const X509Certificate* other) const; - - // Returns intermediate certificates added via AddIntermediateCertificate(). - // Ownership follows the "get" rule: it is the caller's responsibility to - // retain the elements of the result. - const OSCertHandles& GetIntermediateCertificates() const { - return intermediate_ca_certs_; - } - -#if defined(OS_MACOSX) - // Does this certificate's usage allow SSL client authentication? - bool SupportsSSLClientAuth() const; - - // Creates the chain of certs to use for this client identity cert. - CFArrayRef CreateClientCertificateChain() const; - - // Returns a new CFArrayRef containing this certificate and its intermediate - // certificates in the form expected by Security.framework and Keychain - // Services, or NULL on failure. - // The first item in the array will be this certificate, followed by its - // intermediates, if any. - CFArrayRef CreateOSCertChainForCert() const; -#endif - - // Do any of the given issuer names appear in this cert's chain of trust? - // |valid_issuers| is a list of DER-encoded X.509 DistinguishedNames. - bool IsIssuedByEncoded(const std::vector<std::string>& valid_issuers); - -#if defined(OS_WIN) - // Returns a new PCCERT_CONTEXT containing this certificate and its - // intermediate certificates, or NULL on failure. The returned - // PCCERT_CONTEXT *MUST NOT* be stored in an X509Certificate, as this will - // cause os_cert_handle() to return incorrect results. This function is only - // necessary if the CERT_CONTEXT.hCertStore member will be accessed or - // enumerated, which is generally true for any CryptoAPI functions involving - // certificate chains, including validation or certificate display. - // - // Remarks: - // Depending on the CryptoAPI function, Windows may need to access the - // HCERTSTORE that the passed-in PCCERT_CONTEXT belongs to, such as to - // locate additional intermediates. However, all certificate handles are added - // to a NULL HCERTSTORE, allowing the system to manage the resources. As a - // result, intermediates for |cert_handle_| cannot be located simply via - // |cert_handle_->hCertStore|, as it refers to a magic value indicating - // "only this certificate". - // - // To avoid this problems, a new in-memory HCERTSTORE is created containing - // just this certificate and its intermediates. The handle to the version of - // the current certificate in the new HCERTSTORE is then returned, with the - // PCCERT_CONTEXT's HCERTSTORE set to be automatically freed when the returned - // certificate handle is freed. - // - // This function is only needed when the HCERTSTORE of the os_cert_handle() - // will be accessed, which is generally only during certificate validation - // or display. While the returned PCCERT_CONTEXT and its HCERTSTORE can - // safely be used on multiple threads if no further modifications happen, it - // is generally preferable for each thread that needs such a context to - // obtain its own, rather than risk thread-safety issues by sharing. - // - // Because of how X509Certificate caching is implemented, attempting to - // create an X509Certificate from the returned PCCERT_CONTEXT may result in - // the original handle (and thus the originall HCERTSTORE) being returned by - // os_cert_handle(). For this reason, the returned PCCERT_CONTEXT *MUST NOT* - // be stored in an X509Certificate. - PCCERT_CONTEXT CreateOSCertChainForCert() const; -#endif - -#if defined(USE_OPENSSL) - // Returns a handle to a global, in-memory certificate store. We - // use it for test code, e.g. importing the test server's certificate. - static X509_STORE* cert_store(); -#endif - - // Verifies that |hostname| matches this certificate. - // Does not verify that the certificate is valid, only that the certificate - // matches this host. - // Returns true if it matches. - bool VerifyNameMatch(const std::string& hostname) const; - - // Obtains the DER encoded certificate data for |cert_handle|. On success, - // returns true and writes the DER encoded certificate to |*der_encoded|. - static bool GetDEREncoded(OSCertHandle cert_handle, - std::string* der_encoded); - - // Returns the PEM encoded data from an OSCertHandle. If the return value is - // true, then the PEM encoded certificate is written to |pem_encoded|. - static bool GetPEMEncoded(OSCertHandle cert_handle, - std::string* pem_encoded); - - // Encodes the entire certificate chain (this certificate and any - // intermediate certificates stored in |intermediate_ca_certs_|) as a series - // of PEM encoded strings. Returns true if all certificates were encoded, - // storig the result in |*pem_encoded|, with this certificate stored as - // the first element. - bool GetPEMEncodedChain(std::vector<std::string>* pem_encoded) const; - - // Sets |*size_bits| to be the length of the public key in bits, and sets - // |*type| to one of the |PublicKeyType| values. In case of - // |kPublicKeyTypeUnknown|, |*size_bits| will be set to 0. - static void GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type); - - // Returns the OSCertHandle of this object. Because of caching, this may - // differ from the OSCertHandle originally supplied during initialization. - // Note: On Windows, CryptoAPI may return unexpected results if this handle - // is used across multiple threads. For more details, see - // CreateOSCertChainForCert(). - OSCertHandle os_cert_handle() const { return cert_handle_; } - - // Returns true if two OSCertHandles refer to identical certificates. - static bool IsSameOSCert(OSCertHandle a, OSCertHandle b); - - // Creates an OS certificate handle from the DER-encoded representation. - // Returns NULL on failure. - static OSCertHandle CreateOSCertHandleFromBytes(const char* data, - int length); - -#if defined(USE_NSS) - // Creates an OS certificate handle from the DER-encoded representation. - // Returns NULL on failure. Sets the default nickname if |nickname| is - // non-NULL. - static OSCertHandle CreateOSCertHandleFromBytesWithNickname( - const char* data, - int length, - const char* nickname); -#endif - - // Creates all possible OS certificate handles from |data| encoded in a - // specific |format|. Returns an empty collection on failure. - static OSCertHandles CreateOSCertHandlesFromBytes( - const char* data, - int length, - Format format); - - // Duplicates (or adds a reference to) an OS certificate handle. - static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle); - - // Frees (or releases a reference to) an OS certificate handle. - static void FreeOSCertHandle(OSCertHandle cert_handle); - - // Calculates the SHA-1 fingerprint of the certificate. Returns an empty - // (all zero) fingerprint on failure. - static SHA1HashValue CalculateFingerprint(OSCertHandle cert_handle); - - // Calculates the SHA-1 fingerprint of the intermediate CA certificates. - // Returns an empty (all zero) fingerprint on failure. - static SHA1HashValue CalculateCAFingerprint( - const OSCertHandles& intermediates); - - private: - friend class base::RefCountedThreadSafe<X509Certificate>; - friend class TestRootCerts; // For unit tests - - FRIEND_TEST_ALL_PREFIXES(X509CertificateNameVerifyTest, VerifyHostname); - FRIEND_TEST_ALL_PREFIXES(X509CertificateTest, SerialNumbers); - - // Construct an X509Certificate from a handle to the certificate object - // in the underlying crypto library. - X509Certificate(OSCertHandle cert_handle, - const OSCertHandles& intermediates); - - ~X509Certificate(); - - // Common object initialization code. Called by the constructors only. - void Initialize(); - -#if defined(USE_OPENSSL) - // Resets the store returned by cert_store() to default state. Used by - // TestRootCerts to undo modifications. - static void ResetCertStore(); -#endif - - // Verifies that |hostname| matches one of the certificate names or IP - // addresses supplied, based on TLS name matching rules - specifically, - // following http://tools.ietf.org/html/rfc6125. - // |cert_common_name| is the Subject CN, e.g. from X509Certificate::subject(). - // The members of |cert_san_dns_names| and |cert_san_ipaddrs| must be filled - // from the dNSName and iPAddress components of the subject alternative name - // extension, if present. Note these IP addresses are NOT ascii-encoded: - // they must be 4 or 16 bytes of network-ordered data, for IPv4 and IPv6 - // addresses, respectively. - static bool VerifyHostname(const std::string& hostname, - const std::string& cert_common_name, - const std::vector<std::string>& cert_san_dns_names, - const std::vector<std::string>& cert_san_ip_addrs); - - // Reads a single certificate from |pickle_iter| and returns a - // platform-specific certificate handle. The format of the certificate - // stored in |pickle_iter| is not guaranteed to be the same across different - // underlying cryptographic libraries, nor acceptable to CreateFromBytes(). - // Returns an invalid handle, NULL, on failure. - // NOTE: This should not be used for any new code. It is provided for - // migration purposes and should eventually be removed. - static OSCertHandle ReadOSCertHandleFromPickle(PickleIterator* pickle_iter); - - // Writes a single certificate to |pickle| in DER form. Returns false on - // failure. - static bool WriteOSCertHandleToPickle(OSCertHandle handle, Pickle* pickle); - - // The subject of the certificate. - CertPrincipal subject_; - - // The issuer of the certificate. - CertPrincipal issuer_; - - // This certificate is not valid before |valid_start_| - base::Time valid_start_; - - // This certificate is not valid after |valid_expiry_| - base::Time valid_expiry_; - - // The fingerprint of this certificate. - SHA1HashValue fingerprint_; - - // The fingerprint of the intermediate CA certificates. - SHA1HashValue ca_fingerprint_; - - // The serial number of this certificate, DER encoded. - std::string serial_number_; - - // A handle to the certificate object in the underlying crypto library. - OSCertHandle cert_handle_; - - // Untrusted intermediate certificates associated with this certificate - // that may be needed for chain building. - OSCertHandles intermediate_ca_certs_; - -#if defined(USE_NSS) - // This stores any default nickname that has been set on the certificate - // at creation time with CreateFromBytesWithNickname. - // If this is empty, then GetDefaultNickname will return a generated name - // based on the type of the certificate. - std::string default_nickname_; -#endif - - DISALLOW_COPY_AND_ASSIGN(X509Certificate); -}; - -} // namespace net - -#endif // NET_BASE_X509_CERTIFICATE_H_ diff --git a/net/base/x509_certificate_ios.cc b/net/base/x509_certificate_ios.cc deleted file mode 100644 index 91ae799..0000000 --- a/net/base/x509_certificate_ios.cc +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <CommonCrypto/CommonDigest.h> -#include <Security/Security.h> -#include <vector> - -#include <cryptohi.h> -#include <cert.h> -#include <keyhi.h> -#include <nss.h> -#include <pk11pub.h> -#include <prerror.h> -#include <prtime.h> -#include <prtypes.h> -#include <secder.h> -#include <secerr.h> -#include <sslerr.h> - -#include "base/logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/scoped_ptr.h" -#include "base/pickle.h" -#include "base/time.h" -#include "crypto/nss_util.h" -#include "crypto/scoped_nss_types.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_status_flags.h" -#include "net/base/cert_verify_result.h" -#include "net/base/ev_root_ca_metadata.h" -#include "net/base/net_errors.h" -#include "net/base/x509_util_ios.h" -#include "net/base/x509_util_nss.h" - -using base::mac::ScopedCFTypeRef; - -namespace net { -namespace { -// Returns true if a given |cert_handle| is actually a valid X.509 certificate -// handle. -// -// SecCertificateCreateFromData() does not always force the immediate parsing of -// the certificate, and as such, may return a SecCertificateRef for an -// invalid/unparsable certificate. Force parsing to occur to ensure that the -// SecCertificateRef is correct. On later versions where -// SecCertificateCreateFromData() immediately parses, rather than lazily, this -// call is cheap, as the subject is cached. -bool IsValidOSCertHandle(SecCertificateRef cert_handle) { - ScopedCFTypeRef<CFStringRef> sanity_check( - SecCertificateCopySubjectSummary(cert_handle)); - return sanity_check != NULL; -} -} // namespace - -void X509Certificate::Initialize() { - x509_util_ios::NSSCertificate nss_cert(cert_handle_); - CERTCertificate* cert_handle = nss_cert.cert_handle(); - if (cert_handle) { - x509_util::ParsePrincipal(&cert_handle->subject, &subject_); - x509_util::ParsePrincipal(&cert_handle->issuer, &issuer_); - x509_util::ParseDate(&cert_handle->validity.notBefore, &valid_start_); - x509_util::ParseDate(&cert_handle->validity.notAfter, &valid_expiry_); - serial_number_ = x509_util::ParseSerialNumber(cert_handle); - } - fingerprint_ = CalculateFingerprint(cert_handle_); - ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); -} - -bool X509Certificate::IsIssuedByEncoded( - const std::vector<std::string>& valid_issuers) { - x509_util_ios::NSSCertChain nss_chain(this); - // Convert to scoped CERTName* list. - std::vector<CERTName*> issuers; - crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - if (!x509_util::GetIssuersFromEncodedList(valid_issuers, - arena.get(), - &issuers)) { - return false; - } - return x509_util::IsCertificateIssuedBy( - nss_chain.cert_chain(), issuers); -} - -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - DCHECK(!subject.empty()); - NOTIMPLEMENTED(); - return NULL; -} - -void X509Certificate::GetSubjectAltName( - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const { - x509_util_ios::NSSCertificate nss_cert(cert_handle_); - CERTCertificate* cert_handle = nss_cert.cert_handle(); - if (!cert_handle) { - if (dns_names) - dns_names->clear(); - if (ip_addrs) - ip_addrs->clear(); - return; - } - x509_util::GetSubjectAltName(cert_handle, dns_names, ip_addrs); -} - -// static -bool X509Certificate::GetDEREncoded(OSCertHandle cert_handle, - std::string* encoded) { - ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); - if (!der_data) - return false; - encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)), - CFDataGetLength(der_data)); - return true; -} - -// static -bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, - X509Certificate::OSCertHandle b) { - DCHECK(a && b); - if (a == b) - return true; - if (CFEqual(a, b)) - return true; - ScopedCFTypeRef<CFDataRef> a_data(SecCertificateCopyData(a)); - ScopedCFTypeRef<CFDataRef> b_data(SecCertificateCopyData(b)); - return a_data && b_data && - CFDataGetLength(a_data) == CFDataGetLength(b_data) && - memcmp(CFDataGetBytePtr(a_data), CFDataGetBytePtr(b_data), - CFDataGetLength(a_data)) == 0; -} - -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy( - kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data), length, - kCFAllocatorNull)); - if (!cert_data) - return NULL; - OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data); - if (!cert_handle) - return NULL; - if (!IsValidOSCertHandle(cert_handle)) { - CFRelease(cert_handle); - return NULL; - } - return cert_handle; -} - -// static -X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( - const char* data, - int length, - Format format) { - return x509_util::CreateOSCertHandlesFromBytes(data, length, format); -} - -// static -X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( - OSCertHandle handle) { - if (!handle) - return NULL; - return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - CFRelease(cert_handle); -} - -// static -SHA1HashValue X509Certificate::CalculateFingerprint( - OSCertHandle cert) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); - if (!cert_data) - return sha1; - DCHECK(CFDataGetBytePtr(cert_data)); - DCHECK_NE(0, CFDataGetLength(cert_data)); - CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data); - - return sha1; -} - -// static -SHA1HashValue X509Certificate::CalculateCAFingerprint( - const OSCertHandles& intermediates) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - // The CC_SHA(3cc) man page says all CC_SHA1_xxx routines return 1, so - // we don't check their return values. - CC_SHA1_CTX sha1_ctx; - CC_SHA1_Init(&sha1_ctx); - for (size_t i = 0; i < intermediates.size(); ++i) { - ScopedCFTypeRef<CFDataRef> - cert_data(SecCertificateCopyData(intermediates[i])); - if (!cert_data) - return sha1; - CC_SHA1_Update(&sha1_ctx, - CFDataGetBytePtr(cert_data), - CFDataGetLength(cert_data)); - } - CC_SHA1_Final(sha1.data, &sha1_ctx); - return sha1; -} - -// static -X509Certificate::OSCertHandle -X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { - return x509_util::ReadOSCertHandleFromPickle(pickle_iter); -} - -// static -bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, - Pickle* pickle) { - ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle)); - if (!cert_data) - return false; - - return pickle->WriteData( - reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), - CFDataGetLength(cert_data)); -} - -// static -void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type) { - x509_util_ios::NSSCertificate nss_cert(cert_handle); - x509_util::GetPublicKeyInfo(nss_cert.cert_handle(), size_bits, type); -} - -} // namespace net diff --git a/net/base/x509_certificate_known_roots_mac.h b/net/base/x509_certificate_known_roots_mac.h deleted file mode 100644 index fa2081a..0000000 --- a/net/base/x509_certificate_known_roots_mac.h +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_ -#define NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_ - -// This is the set of Apple trusted roots from OS X 10.6. -// They were taken by exporting the trusted roots from the Keychain utility. -// -// Note that these *are not* trust anchors for Chromium. They are only used to -// distinguish `real' root CAs from roots that were user-installed. -static uint8 kKnownRootCertSHA1Hashes[][20] = { - {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34, - 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f}, - {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4, - 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa}, - {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78, - 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68}, - {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87, - 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7}, - {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8, - 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43}, - {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69, - 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91}, - {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0, - 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff}, - {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f, - 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e}, - {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53, - 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16}, - {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde, - 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52}, - {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5, - 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04}, - {0x10, 0xf1, 0x93, 0xf3, 0x40, 0xac, 0x91, 0xd6, 0xde, 0x5f, - 0x1e, 0xdc, 0x00, 0x62, 0x47, 0xc4, 0xf2, 0x5d, 0x96, 0x71}, - {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2, - 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6}, - {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae, - 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85}, - {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57, - 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5}, - {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c, - 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85}, - {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1, - 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a}, - {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03, - 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c}, - {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7, - 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42}, - {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f, - 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1}, - {0x27, 0x0c, 0x50, 0x0c, 0xc6, 0xc8, 0x6e, 0xcb, 0x19, 0x80, - 0xbc, 0x13, 0x05, 0x43, 0x9e, 0xd2, 0x82, 0x48, 0x0b, 0xe3}, - {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55, - 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47}, - {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26, - 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4}, - {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66, - 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f}, - {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32, - 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d}, - {0x2a, 0xb6, 0x28, 0x48, 0x5e, 0x78, 0xfb, 0xf3, 0xad, 0x9e, - 0x79, 0x10, 0xdd, 0x6b, 0xdf, 0x99, 0x72, 0x2c, 0x96, 0xe5}, - {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf, - 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41}, - {0x2c, 0xeb, 0x05, 0x34, 0xad, 0x59, 0x27, 0x18, 0x0d, 0x34, - 0x8c, 0x5f, 0x0e, 0x05, 0x6d, 0x38, 0x2b, 0x50, 0x82, 0x87}, - {0x2d, 0xff, 0x63, 0x36, 0xe3, 0x3a, 0x48, 0x29, 0xaa, 0x00, - 0x9f, 0x01, 0xa1, 0x80, 0x1e, 0xe7, 0xeb, 0xa5, 0x82, 0xbb}, - {0x2e, 0xf6, 0x4b, 0xba, 0x77, 0xdd, 0x37, 0x79, 0xe9, 0x1f, - 0xbd, 0x5a, 0x4e, 0xee, 0x63, 0x3c, 0x8a, 0x36, 0xa5, 0xb1}, - {0x2f, 0x17, 0x3f, 0x7d, 0xe9, 0x96, 0x67, 0xaf, 0xa5, 0x7a, - 0xf8, 0x0a, 0xa2, 0xd1, 0xb1, 0x2f, 0xac, 0x83, 0x03, 0x38}, - {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a, - 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd}, - {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1, - 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6}, - {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54, - 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96}, - {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01, - 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9}, - {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6, - 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce}, - {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e, - 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7}, - {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e, - 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27}, - {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb, - 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a}, - {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18, - 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc}, - {0x3a, 0x32, 0xef, 0x7b, 0x9a, 0xb8, 0x36, 0xf8, 0x37, 0x18, - 0x1a, 0x4c, 0xef, 0xa3, 0x55, 0xc6, 0x46, 0x67, 0xac, 0xbf}, - {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86, - 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b}, - {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6, - 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f}, - {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed, - 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d}, - {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b, - 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89}, - {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f, - 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc}, - {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52, - 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54}, - {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72, - 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7}, - {0x4a, 0x65, 0xd5, 0xf4, 0x1d, 0xef, 0x39, 0xb8, 0xb8, 0x90, - 0x4a, 0x4a, 0xd3, 0x64, 0x81, 0x33, 0xcf, 0xc7, 0xa1, 0xd1}, - {0x4a, 0xd4, 0x4d, 0x4d, 0x81, 0x2e, 0x42, 0x23, 0x2f, 0xe0, - 0x38, 0x76, 0x4c, 0x7b, 0x0c, 0xeb, 0x46, 0x6e, 0xef, 0x96}, - {0x4c, 0xab, 0x31, 0xa1, 0x28, 0x34, 0x02, 0x52, 0xbc, 0xb4, - 0x67, 0xd6, 0x2a, 0x99, 0x63, 0x1b, 0x21, 0x77, 0x20, 0x50}, - {0x4d, 0x23, 0x78, 0xec, 0x91, 0x95, 0x39, 0xb5, 0x00, 0x7f, - 0x75, 0x8f, 0x03, 0x3b, 0x21, 0x1e, 0xc5, 0x4d, 0x8b, 0xcf}, - {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, - 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5}, - {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39, - 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31}, - {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e, - 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae}, - {0x51, 0xcc, 0xa0, 0x71, 0x0a, 0xf7, 0x73, 0x3d, 0x34, 0xac, - 0xdc, 0x19, 0x45, 0x09, 0x9f, 0x43, 0x5c, 0x7f, 0xc5, 0x9f}, - {0x56, 0x4b, 0x6f, 0x8c, 0x56, 0x38, 0xdc, 0x05, 0x5b, 0xba, - 0x2b, 0xa1, 0x39, 0x0f, 0x7e, 0x31, 0x95, 0x4a, 0x55, 0x50}, - {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18, - 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66}, - {0x57, 0xf0, 0x3d, 0xce, 0xfb, 0x45, 0x69, 0x4c, 0x1c, 0x25, - 0xe6, 0xee, 0xa0, 0x2c, 0x43, 0xd7, 0x52, 0x38, 0xd3, 0xc4}, - {0x58, 0x0f, 0x80, 0x47, 0x92, 0xab, 0xc6, 0x3b, 0xbb, 0x80, - 0x15, 0x4d, 0x4d, 0xfd, 0xdd, 0x8b, 0x2e, 0xf2, 0x67, 0x4e}, - {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd, - 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4}, - {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8, - 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9}, - {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07, - 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16}, - {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65, - 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1}, - {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34, - 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51}, - {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b, - 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf}, - {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c, - 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25}, - {0x61, 0x1e, 0x5b, 0x66, 0x2c, 0x59, 0x3a, 0x08, 0xff, 0x58, - 0xd1, 0x4a, 0xe2, 0x24, 0x52, 0xd1, 0x98, 0xdf, 0x6c, 0x60}, - {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92, - 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71}, - {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc, - 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11}, - {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde, - 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18}, - {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d, - 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a}, - {0x66, 0x31, 0xbf, 0x9e, 0xf7, 0x4f, 0x9e, 0xb6, 0xc9, 0xd5, - 0xa6, 0x0c, 0xba, 0x6a, 0xbe, 0xd1, 0xf7, 0xbd, 0xef, 0x7b}, - {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40, - 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0}, - {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39, - 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a}, - {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19, - 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6}, - {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e, - 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb}, - {0x6a, 0x84, 0xfe, 0x62, 0x7e, 0xcc, 0x49, 0xa1, 0xbe, 0x02, - 0xe9, 0x18, 0xfa, 0xc9, 0xe1, 0xf7, 0x32, 0x80, 0x3a, 0x62}, - {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0, - 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3}, - {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8, - 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16}, - {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84, - 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1}, - {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91, - 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62}, - {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79, - 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb}, - {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45, - 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2}, - {0x74, 0x54, 0x53, 0x5c, 0x24, 0xa3, 0xa7, 0x58, 0x20, 0x7e, - 0x3e, 0x3e, 0xd3, 0x24, 0xf8, 0x16, 0xfb, 0x21, 0x16, 0x49}, - {0x74, 0xa2, 0x66, 0xf0, 0x95, 0xa9, 0xa4, 0xeb, 0x95, 0x22, - 0x19, 0xd6, 0x05, 0xda, 0x93, 0x63, 0xf5, 0x14, 0xfa, 0xf9}, - {0x74, 0xf8, 0xa3, 0xc3, 0xef, 0xe7, 0xb3, 0x90, 0x06, 0x4b, - 0x83, 0x90, 0x3c, 0x21, 0x64, 0x60, 0x20, 0xe5, 0xdf, 0xce}, - {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04, - 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe}, - {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2, - 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9}, - {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1, - 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45}, - {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3, - 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74}, - {0x80, 0x1d, 0x62, 0xd0, 0x7b, 0x44, 0x9d, 0x5c, 0x5c, 0x03, - 0x5c, 0x98, 0xea, 0x61, 0xfa, 0x44, 0x3c, 0x2a, 0x58, 0xfe}, - {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24, - 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5}, - {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28, - 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f}, - {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58, - 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf}, - {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8, - 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84}, - {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65, - 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01}, - {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96, - 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11}, - {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3, - 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf}, - {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda, - 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f}, - {0x8c, 0x94, 0x1b, 0x34, 0xea, 0x1e, 0xa6, 0xed, 0x9a, 0xe2, - 0xbc, 0x54, 0xcf, 0x68, 0x72, 0x52, 0xb4, 0xc9, 0xb5, 0x61}, - {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee, - 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58}, - {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d, - 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88}, - {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43, - 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f}, - {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5, - 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81}, - {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc, - 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65}, - {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1, - 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87}, - {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd, - 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e}, - {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34, - 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74}, - {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b, - 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39}, - {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a, - 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb}, - {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12, - 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc}, - {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55, - 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b}, - {0xa6, 0x76, 0xdb, 0xf1, 0x92, 0x48, 0xf5, 0x2c, 0x57, 0x53, - 0xd0, 0xda, 0xc1, 0x4c, 0x53, 0xc4, 0x74, 0xa4, 0x83, 0x5e}, - {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63, - 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50}, - {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7, - 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36}, - {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f, - 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6}, - {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03, - 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a}, - {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61, - 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e}, - {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2, - 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97}, - {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02, - 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a}, - {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8, - 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c}, - {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda, - 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9}, - {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2, - 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d}, - {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7, - 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7}, - {0xb4, 0x57, 0x12, 0x1e, 0x63, 0x45, 0xff, 0x93, 0x5d, 0x6b, - 0x1c, 0xa2, 0xdd, 0xf4, 0x52, 0x3c, 0xc6, 0xd0, 0xef, 0x6b}, - {0xb6, 0xca, 0x21, 0x5b, 0x83, 0x6c, 0x35, 0x10, 0x1d, 0xaf, - 0x74, 0x63, 0x90, 0x0a, 0x93, 0x68, 0x80, 0x76, 0x7a, 0xa6}, - {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04, - 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6}, - {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01, - 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb}, - {0xc0, 0x60, 0xed, 0x44, 0xcb, 0xd8, 0x81, 0xbd, 0x0e, 0xf8, - 0x6c, 0x0b, 0xa2, 0x87, 0xdd, 0xcf, 0x81, 0x67, 0x47, 0x8c}, - {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39, - 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d}, - {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2, - 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7}, - {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e, - 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5}, - {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45, - 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36}, - {0xcc, 0xab, 0x0e, 0xa0, 0x4c, 0x23, 0x01, 0xd6, 0x69, 0x7b, - 0xdd, 0x37, 0x9f, 0xcd, 0x12, 0xeb, 0x24, 0xe3, 0x94, 0x9d}, - {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85, - 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1}, - {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97, - 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48}, - {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25, - 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49}, - {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74, - 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a}, - {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad, - 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2}, - {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a, - 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74}, - {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45, - 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad}, - {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24, - 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58}, - {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6, - 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27}, - {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4, - 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61}, - {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae, - 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41}, - {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93, - 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13}, - {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5, - 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12}, - {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60, - 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9}, - {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed, - 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa}, - {0xdf, 0xdf, 0xac, 0x89, 0x47, 0xbd, 0xf7, 0x52, 0x64, 0xa9, - 0x23, 0x3a, 0xc1, 0x0e, 0xe3, 0xd1, 0x28, 0x33, 0xda, 0xcc}, - {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30, - 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46}, - {0xe1, 0x9f, 0xe3, 0x0e, 0x8b, 0x84, 0x60, 0x9e, 0x80, 0x9b, - 0x17, 0x0d, 0x72, 0xa8, 0xc5, 0xba, 0x6e, 0x14, 0x09, 0xbd}, - {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6, - 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b}, - {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43, - 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e}, - {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3, - 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15}, - {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e, - 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee}, - {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8, - 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33}, - {0xf7, 0x4d, 0xac, 0xb2, 0x14, 0x14, 0xdc, 0xba, 0xab, 0x0b, - 0x94, 0x7c, 0x8a, 0x25, 0x7c, 0x32, 0x5c, 0xa8, 0x85, 0x50}, - {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57, - 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7}, - {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8, - 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5}, - {0xfc, 0x21, 0x9a, 0x76, 0x11, 0x2f, 0x76, 0xc1, 0xc5, 0x08, - 0x83, 0x3c, 0x9a, 0x2f, 0xa2, 0xba, 0x84, 0xac, 0x08, 0x7a}, - {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae, - 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d}, -}; - -#endif // NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_MAC_H_ diff --git a/net/base/x509_certificate_known_roots_win.h b/net/base/x509_certificate_known_roots_win.h deleted file mode 100644 index b81613c3..0000000 --- a/net/base/x509_certificate_known_roots_win.h +++ /dev/null @@ -1,655 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_ -#define NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_ - -// This is the set of 318 Microsoft trusted roots from 1st April 2011. -// Extracted from -// http://www.download.windowsupdate.com/msdownload/update/v3/ -// static/trustedr/en/authrootstl.cab -// (sha1sum: 62f2d9b91a5a0032be6795bb4b6e2b4bfeb8bbb3) -// -// Note that these *are not* trust anchors for Chromium. They are only used to -// distinguish `real' root CAs from roots that were user-installed. -static uint8 kKnownRootCertSHA1Hashes[][20] = { - {0x00, 0x48, 0xf8, 0xd3, 0x7b, 0x15, 0x3f, 0x6e, 0xa2, 0x79, - 0x8c, 0x32, 0x3e, 0xf4, 0xf3, 0x18, 0xa5, 0x62, 0x4a, 0x9e}, - {0x00, 0xea, 0x52, 0x2c, 0x8a, 0x9c, 0x06, 0xaa, 0x3e, 0xcc, - 0xe0, 0xb4, 0xfa, 0x6c, 0xdc, 0x21, 0xd9, 0x2e, 0x80, 0x99}, - {0x01, 0x68, 0x97, 0xe1, 0xa0, 0xb8, 0xf2, 0xc3, 0xb1, 0x34, - 0x66, 0x5c, 0x20, 0xa7, 0x27, 0xb7, 0xa1, 0x58, 0xe2, 0x8f}, - {0x02, 0x72, 0x68, 0x29, 0x3e, 0x5f, 0x5d, 0x17, 0xaa, 0xa4, - 0xb3, 0xc3, 0xe6, 0x36, 0x1e, 0x1f, 0x92, 0x57, 0x5e, 0xaa}, - {0x02, 0xfa, 0xf3, 0xe2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78, - 0x57, 0x69, 0x4d, 0xf5, 0xe4, 0x5b, 0x68, 0x85, 0x18, 0x68}, - {0x03, 0x9e, 0xed, 0xb8, 0x0b, 0xe7, 0xa0, 0x3c, 0x69, 0x53, - 0x89, 0x3b, 0x20, 0xd2, 0xd9, 0x32, 0x3a, 0x4c, 0x2a, 0xfd}, - {0x04, 0x09, 0x56, 0x5b, 0x77, 0xda, 0x58, 0x2e, 0x64, 0x95, - 0xac, 0x00, 0x60, 0xa7, 0x23, 0x54, 0xe6, 0x4b, 0x01, 0x92}, - {0x04, 0x46, 0xc8, 0xbb, 0x9a, 0x69, 0x83, 0xc9, 0x5c, 0x8a, - 0x2e, 0x54, 0x64, 0x68, 0x7c, 0x11, 0x15, 0xaa, 0xb7, 0x4a}, - {0x04, 0x56, 0xf2, 0x3d, 0x1e, 0x9c, 0x43, 0xae, 0xcb, 0x0d, - 0x80, 0x7f, 0x1c, 0x06, 0x47, 0x55, 0x1a, 0x05, 0xf4, 0x56}, - {0x04, 0x83, 0xed, 0x33, 0x99, 0xac, 0x36, 0x08, 0x05, 0x87, - 0x22, 0xed, 0xbc, 0x5e, 0x46, 0x00, 0xe3, 0xbe, 0xf9, 0xd7}, - {0x04, 0x98, 0x11, 0x05, 0x6a, 0xfe, 0x9f, 0xd0, 0xf5, 0xbe, - 0x01, 0x68, 0x5a, 0xac, 0xe6, 0xa5, 0xd1, 0xc4, 0x45, 0x4c}, - {0x05, 0x60, 0xa2, 0xc7, 0x38, 0xff, 0x98, 0xd1, 0x17, 0x2a, - 0x94, 0xfe, 0x45, 0xfb, 0x8a, 0x47, 0xd6, 0x65, 0x37, 0x1e}, - {0x05, 0x63, 0xb8, 0x63, 0x0d, 0x62, 0xd7, 0x5a, 0xbb, 0xc8, - 0xab, 0x1e, 0x4b, 0xdf, 0xb5, 0xa8, 0x99, 0xb2, 0x4d, 0x43}, - {0x06, 0x08, 0x3f, 0x59, 0x3f, 0x15, 0xa1, 0x04, 0xa0, 0x69, - 0xa4, 0x6b, 0xa9, 0x03, 0xd0, 0x06, 0xb7, 0x97, 0x09, 0x91}, - {0x07, 0x47, 0x22, 0x01, 0x99, 0xce, 0x74, 0xb9, 0x7c, 0xb0, - 0x3d, 0x79, 0xb2, 0x64, 0xa2, 0xc8, 0x55, 0xe9, 0x33, 0xff}, - {0x07, 0xe0, 0x32, 0xe0, 0x20, 0xb7, 0x2c, 0x3f, 0x19, 0x2f, - 0x06, 0x28, 0xa2, 0x59, 0x3a, 0x19, 0xa7, 0x0f, 0x06, 0x9e}, - {0x08, 0x64, 0x18, 0xe9, 0x06, 0xce, 0xe8, 0x9c, 0x23, 0x53, - 0xb6, 0xe2, 0x7f, 0xbd, 0x9e, 0x74, 0x39, 0xf7, 0x63, 0x16}, - {0x0b, 0x71, 0x99, 0xa1, 0xc7, 0xf3, 0xad, 0xdf, 0x7b, 0xa7, - 0xea, 0xb8, 0xeb, 0x57, 0x4a, 0xe8, 0x0d, 0x60, 0xdd, 0xde}, - {0x0b, 0x77, 0xbe, 0xbb, 0xcb, 0x7a, 0xa2, 0x47, 0x05, 0xde, - 0xcc, 0x0f, 0xbd, 0x6a, 0x02, 0xfc, 0x7a, 0xbd, 0x9b, 0x52}, - {0x0b, 0x97, 0x2c, 0x9e, 0xa6, 0xe7, 0xcc, 0x58, 0xd9, 0x3b, - 0x20, 0xbf, 0x71, 0xec, 0x41, 0x2e, 0x72, 0x09, 0xfa, 0xbf}, - {0x0c, 0xfd, 0x83, 0xdb, 0xae, 0x44, 0xb9, 0xa0, 0xc8, 0xf6, - 0x76, 0xf3, 0xb5, 0x70, 0x65, 0x0b, 0x94, 0xb6, 0x9d, 0xbf}, - {0x10, 0x1d, 0xfa, 0x3f, 0xd5, 0x0b, 0xcb, 0xbb, 0x9b, 0xb5, - 0x60, 0x0c, 0x19, 0x55, 0xa4, 0x1a, 0xf4, 0x73, 0x3a, 0x04}, - {0x11, 0xc5, 0xb5, 0xf7, 0x55, 0x52, 0xb0, 0x11, 0x66, 0x9c, - 0x2e, 0x97, 0x17, 0xde, 0x6d, 0x9b, 0xff, 0x5f, 0xa8, 0x10}, - {0x13, 0x2d, 0x0d, 0x45, 0x53, 0x4b, 0x69, 0x97, 0xcd, 0xb2, - 0xd5, 0xc3, 0x39, 0xe2, 0x55, 0x76, 0x60, 0x9b, 0x5c, 0xc6}, - {0x16, 0xd8, 0x66, 0x35, 0xaf, 0x13, 0x41, 0xcd, 0x34, 0x79, - 0x94, 0x45, 0xeb, 0x60, 0x3e, 0x27, 0x37, 0x02, 0x96, 0x5d}, - {0x18, 0xf7, 0xc1, 0xfc, 0xc3, 0x09, 0x02, 0x03, 0xfd, 0x5b, - 0xaa, 0x2f, 0x86, 0x1a, 0x75, 0x49, 0x76, 0xc8, 0xdd, 0x25}, - {0x1b, 0x4b, 0x39, 0x61, 0x26, 0x27, 0x6b, 0x64, 0x91, 0xa2, - 0x68, 0x6d, 0xd7, 0x02, 0x43, 0x21, 0x2d, 0x1f, 0x1d, 0x96}, - {0x1f, 0x49, 0x14, 0xf7, 0xd8, 0x74, 0x95, 0x1d, 0xdd, 0xae, - 0x02, 0xc0, 0xbe, 0xfd, 0x3a, 0x2d, 0x82, 0x75, 0x51, 0x85}, - {0x20, 0x42, 0x85, 0xdc, 0xf7, 0xeb, 0x76, 0x41, 0x95, 0x57, - 0x8e, 0x13, 0x6b, 0xd4, 0xb7, 0xd1, 0xe9, 0x8e, 0x46, 0xa5}, - {0x20, 0x99, 0x00, 0xb6, 0x3d, 0x95, 0x57, 0x28, 0x14, 0x0c, - 0xd1, 0x36, 0x22, 0xd8, 0xc6, 0x87, 0xa4, 0xeb, 0x00, 0x85}, - {0x20, 0xcb, 0x59, 0x4f, 0xb4, 0xed, 0xd8, 0x95, 0x76, 0x3f, - 0xd5, 0x25, 0x4e, 0x95, 0x9a, 0x66, 0x74, 0xc6, 0xee, 0xb2}, - {0x21, 0x11, 0x65, 0xca, 0x37, 0x9f, 0xbb, 0x5e, 0xd8, 0x01, - 0xe3, 0x1c, 0x43, 0x0a, 0x62, 0xaa, 0xc1, 0x09, 0xbc, 0xb4}, - {0x21, 0x6b, 0x2a, 0x29, 0xe6, 0x2a, 0x00, 0xce, 0x82, 0x01, - 0x46, 0xd8, 0x24, 0x41, 0x41, 0xb9, 0x25, 0x11, 0xb2, 0x79}, - {0x21, 0xfc, 0xbd, 0x8e, 0x7f, 0x6c, 0xaf, 0x05, 0x1b, 0xd1, - 0xb3, 0x43, 0xec, 0xa8, 0xe7, 0x61, 0x47, 0xf2, 0x0f, 0x8a}, - {0x22, 0xd5, 0xd8, 0xdf, 0x8f, 0x02, 0x31, 0xd1, 0x8d, 0xf7, - 0x9d, 0xb7, 0xcf, 0x8a, 0x2d, 0x64, 0xc9, 0x3f, 0x6c, 0x3a}, - {0x23, 0x88, 0xc9, 0xd3, 0x71, 0xcc, 0x9e, 0x96, 0x3d, 0xff, - 0x7d, 0x3c, 0xa7, 0xce, 0xfc, 0xd6, 0x25, 0xec, 0x19, 0x0d}, - {0x23, 0xe5, 0x94, 0x94, 0x51, 0x95, 0xf2, 0x41, 0x48, 0x03, - 0xb4, 0xd5, 0x64, 0xd2, 0xa3, 0xa3, 0xf5, 0xd8, 0x8b, 0x8c}, - {0x23, 0xe8, 0x33, 0x23, 0x3e, 0x7d, 0x0c, 0xc9, 0x2b, 0x7c, - 0x42, 0x79, 0xac, 0x19, 0xc2, 0xf4, 0x74, 0xd6, 0x04, 0xca}, - {0x24, 0x5c, 0x97, 0xdf, 0x75, 0x14, 0xe7, 0xcf, 0x2d, 0xf8, - 0xbe, 0x72, 0xae, 0x95, 0x7b, 0x9e, 0x04, 0x74, 0x1e, 0x85}, - {0x24, 0xa4, 0x0a, 0x1f, 0x57, 0x36, 0x43, 0xa6, 0x7f, 0x0a, - 0x4b, 0x07, 0x49, 0xf6, 0xa2, 0x2b, 0xf2, 0x8a, 0xbb, 0x6b}, - {0x24, 0xba, 0x6d, 0x6c, 0x8a, 0x5b, 0x58, 0x37, 0xa4, 0x8d, - 0xb5, 0xfa, 0xe9, 0x19, 0xea, 0x67, 0x5c, 0x94, 0xd2, 0x17}, - {0x25, 0x01, 0x90, 0x19, 0xcf, 0xfb, 0xd9, 0x99, 0x1c, 0xb7, - 0x68, 0x25, 0x74, 0x8d, 0x94, 0x5f, 0x30, 0x93, 0x95, 0x42}, - {0x25, 0x3f, 0x77, 0x5b, 0x0e, 0x77, 0x97, 0xab, 0x64, 0x5f, - 0x15, 0x91, 0x55, 0x97, 0xc3, 0x9e, 0x26, 0x36, 0x31, 0xd1}, - {0x27, 0x3e, 0xe1, 0x24, 0x57, 0xfd, 0xc4, 0xf9, 0x0c, 0x55, - 0xe8, 0x2b, 0x56, 0x16, 0x7f, 0x62, 0xf5, 0x32, 0xe5, 0x47}, - {0x27, 0x96, 0xba, 0xe6, 0x3f, 0x18, 0x01, 0xe2, 0x77, 0x26, - 0x1b, 0xa0, 0xd7, 0x77, 0x70, 0x02, 0x8f, 0x20, 0xee, 0xe4}, - {0x28, 0x90, 0x3a, 0x63, 0x5b, 0x52, 0x80, 0xfa, 0xe6, 0x77, - 0x4c, 0x0b, 0x6d, 0xa7, 0xd6, 0xba, 0xa6, 0x4a, 0xf2, 0xe8}, - {0x29, 0x36, 0x21, 0x02, 0x8b, 0x20, 0xed, 0x02, 0xf5, 0x66, - 0xc5, 0x32, 0xd1, 0xd6, 0xed, 0x90, 0x9f, 0x45, 0x00, 0x2f}, - {0x29, 0x64, 0xb6, 0x86, 0x13, 0x5b, 0x5d, 0xfd, 0xdd, 0x32, - 0x53, 0xa8, 0x9b, 0xbc, 0x24, 0xd7, 0x4b, 0x08, 0xc6, 0x4d}, - {0x2a, 0xc8, 0xd5, 0x8b, 0x57, 0xce, 0xbf, 0x2f, 0x49, 0xaf, - 0xf2, 0xfc, 0x76, 0x8f, 0x51, 0x14, 0x62, 0x90, 0x7a, 0x41}, - {0x2b, 0x8f, 0x1b, 0x57, 0x33, 0x0d, 0xbb, 0xa2, 0xd0, 0x7a, - 0x6c, 0x51, 0xf7, 0x0e, 0xe9, 0x0d, 0xda, 0xb9, 0xad, 0x8e}, - {0x2e, 0x14, 0xda, 0xec, 0x28, 0xf0, 0xfa, 0x1e, 0x8e, 0x38, - 0x9a, 0x4e, 0xab, 0xeb, 0x26, 0xc0, 0x0a, 0xd3, 0x83, 0xc3}, - {0x30, 0x70, 0xf8, 0x83, 0x3e, 0x4a, 0xa6, 0x80, 0x3e, 0x09, - 0xa6, 0x46, 0xae, 0x3f, 0x7d, 0x8a, 0xe1, 0xfd, 0x16, 0x54}, - {0x30, 0x77, 0x9e, 0x93, 0x15, 0x02, 0x2e, 0x94, 0x85, 0x6a, - 0x3f, 0xf8, 0xbc, 0xf8, 0x15, 0xb0, 0x82, 0xf9, 0xae, 0xfd}, - {0x31, 0x7a, 0x2a, 0xd0, 0x7f, 0x2b, 0x33, 0x5e, 0xf5, 0xa1, - 0xc3, 0x4e, 0x4b, 0x57, 0xe8, 0xb7, 0xd8, 0xf1, 0xfc, 0xa6}, - {0x31, 0xe2, 0xc5, 0x2c, 0xe1, 0x08, 0x9b, 0xef, 0xfd, 0xda, - 0xdb, 0x26, 0xdd, 0x7c, 0x78, 0x2e, 0xbc, 0x40, 0x37, 0xbd}, - {0x32, 0x3c, 0x11, 0x8e, 0x1b, 0xf7, 0xb8, 0xb6, 0x52, 0x54, - 0xe2, 0xe2, 0x10, 0x0d, 0xd6, 0x02, 0x90, 0x37, 0xf0, 0x96}, - {0x33, 0x9b, 0x6b, 0x14, 0x50, 0x24, 0x9b, 0x55, 0x7a, 0x01, - 0x87, 0x72, 0x84, 0xd9, 0xe0, 0x2f, 0xc3, 0xd2, 0xd8, 0xe9}, - {0x34, 0x2c, 0xd9, 0xd3, 0x06, 0x2d, 0xa4, 0x8c, 0x34, 0x69, - 0x65, 0x29, 0x7f, 0x08, 0x1e, 0xbc, 0x2e, 0xf6, 0x8f, 0xdc}, - {0x34, 0xd4, 0x99, 0x42, 0x6f, 0x9f, 0xc2, 0xbb, 0x27, 0xb0, - 0x75, 0xba, 0xb6, 0x82, 0xaa, 0xe5, 0xef, 0xfc, 0xba, 0x74}, - {0x36, 0x79, 0xca, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4d, 0x30, - 0xa5, 0xfb, 0x87, 0x3b, 0x0f, 0xa7, 0x7b, 0xb7, 0x0d, 0x54}, - {0x36, 0x86, 0x35, 0x63, 0xfd, 0x51, 0x28, 0xc7, 0xbe, 0xa6, - 0xf0, 0x05, 0xcf, 0xe9, 0xb4, 0x36, 0x68, 0x08, 0x6c, 0xce}, - {0x36, 0xb1, 0x2b, 0x49, 0xf9, 0x81, 0x9e, 0xd7, 0x4c, 0x9e, - 0xbc, 0x38, 0x0f, 0xc6, 0x56, 0x8f, 0x5d, 0xac, 0xb2, 0xf7}, - {0x37, 0x9a, 0x19, 0x7b, 0x41, 0x85, 0x45, 0x35, 0x0c, 0xa6, - 0x03, 0x69, 0xf3, 0x3c, 0x2e, 0xaf, 0x47, 0x4f, 0x20, 0x79}, - {0x37, 0xf7, 0x6d, 0xe6, 0x07, 0x7c, 0x90, 0xc5, 0xb1, 0x3e, - 0x93, 0x1a, 0xb7, 0x41, 0x10, 0xb4, 0xf2, 0xe4, 0x9a, 0x27}, - {0x39, 0x13, 0x85, 0x3e, 0x45, 0xc4, 0x39, 0xa2, 0xda, 0x71, - 0x8c, 0xdf, 0xb6, 0xf3, 0xe0, 0x33, 0xe0, 0x4f, 0xee, 0x71}, - {0x39, 0x21, 0xc1, 0x15, 0xc1, 0x5d, 0x0e, 0xca, 0x5c, 0xcb, - 0x5b, 0xc4, 0xf0, 0x7d, 0x21, 0xd8, 0x05, 0x0b, 0x56, 0x6a}, - {0x39, 0x4f, 0xf6, 0x85, 0x0b, 0x06, 0xbe, 0x52, 0xe5, 0x18, - 0x56, 0xcc, 0x10, 0xe1, 0x80, 0xe8, 0x82, 0xb3, 0x85, 0xcc}, - {0x39, 0x8e, 0xbe, 0x9c, 0x0f, 0x46, 0xc0, 0x79, 0xc3, 0xc7, - 0xaf, 0xe0, 0x7a, 0x2f, 0xdd, 0x9f, 0xae, 0x5f, 0x8a, 0x5c}, - {0x3a, 0x44, 0x73, 0x5a, 0xe5, 0x81, 0x90, 0x1f, 0x24, 0x86, - 0x61, 0x46, 0x1e, 0x3b, 0x9c, 0xc4, 0x5f, 0xf5, 0x3a, 0x1b}, - {0x3b, 0x1e, 0xfd, 0x3a, 0x66, 0xea, 0x28, 0xb1, 0x66, 0x97, - 0x39, 0x47, 0x03, 0xa7, 0x2c, 0xa3, 0x40, 0xa0, 0x5b, 0xd5}, - {0x3b, 0xc0, 0x38, 0x0b, 0x33, 0xc3, 0xf6, 0xa6, 0x0c, 0x86, - 0x15, 0x22, 0x93, 0xd9, 0xdf, 0xf5, 0x4b, 0x81, 0xc0, 0x04}, - {0x3b, 0xc4, 0x9f, 0x48, 0xf8, 0xf3, 0x73, 0xa0, 0x9c, 0x1e, - 0xbd, 0xf8, 0x5b, 0xb1, 0xc3, 0x65, 0xc7, 0xd8, 0x11, 0xb3}, - {0x3c, 0x71, 0xd7, 0x0e, 0x35, 0xa5, 0xda, 0xa8, 0xb2, 0xe3, - 0x81, 0x2d, 0xc3, 0x67, 0x74, 0x17, 0xf5, 0x99, 0x0d, 0xf3}, - {0x3e, 0x2b, 0xf7, 0xf2, 0x03, 0x1b, 0x96, 0xf3, 0x8c, 0xe6, - 0xc4, 0xd8, 0xa8, 0x5d, 0x3e, 0x2d, 0x58, 0x47, 0x6a, 0x0f}, - {0x3e, 0x42, 0xa1, 0x87, 0x06, 0xbd, 0x0c, 0x9c, 0xcf, 0x59, - 0x47, 0x50, 0xd2, 0xe4, 0xd6, 0xab, 0x00, 0x48, 0xfd, 0xc4}, - {0x3e, 0x84, 0xd3, 0xbc, 0xc5, 0x44, 0xc0, 0xf6, 0xfa, 0x19, - 0x43, 0x5c, 0x85, 0x1f, 0x3f, 0x2f, 0xcb, 0xa8, 0xe8, 0x14}, - {0x3f, 0x85, 0xf2, 0xbb, 0x4a, 0x62, 0xb0, 0xb5, 0x8b, 0xe1, - 0x61, 0x4a, 0xbb, 0x0d, 0x46, 0x31, 0xb4, 0xbe, 0xf8, 0xba}, - {0x40, 0x54, 0xda, 0x6f, 0x1c, 0x3f, 0x40, 0x74, 0xac, 0xed, - 0x0f, 0xec, 0xcd, 0xdb, 0x79, 0xd1, 0x53, 0xfb, 0x90, 0x1d}, - {0x40, 0x9d, 0x4b, 0xd9, 0x17, 0xb5, 0x5c, 0x27, 0xb6, 0x9b, - 0x64, 0xcb, 0x98, 0x22, 0x44, 0x0d, 0xcd, 0x09, 0xb8, 0x89}, - {0x40, 0xe7, 0x8c, 0x1d, 0x52, 0x3d, 0x1c, 0xd9, 0x95, 0x4f, - 0xac, 0x1a, 0x1a, 0xb3, 0xbd, 0x3c, 0xba, 0xa1, 0x5b, 0xfc}, - {0x42, 0xef, 0xdd, 0xe6, 0xbf, 0xf3, 0x5e, 0xd0, 0xba, 0xe6, - 0xac, 0xdd, 0x20, 0x4c, 0x50, 0xae, 0x86, 0xc4, 0xf4, 0xfa}, - {0x43, 0x13, 0xbb, 0x96, 0xf1, 0xd5, 0x86, 0x9b, 0xc1, 0x4e, - 0x6a, 0x92, 0xf6, 0xcf, 0xf6, 0x34, 0x69, 0x87, 0x82, 0x37}, - {0x43, 0xd9, 0xbc, 0xb5, 0x68, 0xe0, 0x39, 0xd0, 0x73, 0xa7, - 0x4a, 0x71, 0xd8, 0x51, 0x1f, 0x74, 0x76, 0x08, 0x9c, 0xc3}, - {0x43, 0xf9, 0xb1, 0x10, 0xd5, 0xba, 0xfd, 0x48, 0x22, 0x52, - 0x31, 0xb0, 0xd0, 0x08, 0x2b, 0x37, 0x2f, 0xef, 0x9a, 0x54}, - {0x44, 0x63, 0xc5, 0x31, 0xd7, 0xcc, 0xc1, 0x00, 0x67, 0x94, - 0x61, 0x2b, 0xb6, 0x56, 0xd3, 0xbf, 0x82, 0x57, 0x84, 0x6f}, - {0x47, 0xbe, 0xab, 0xc9, 0x22, 0xea, 0xe8, 0x0e, 0x78, 0x78, - 0x34, 0x62, 0xa7, 0x9f, 0x45, 0xc2, 0x54, 0xfd, 0xe6, 0x8b}, - {0x4a, 0x05, 0x8f, 0xdf, 0xd7, 0x61, 0xdb, 0x21, 0xb0, 0xc2, - 0xee, 0x48, 0x57, 0x9b, 0xe2, 0x7f, 0x42, 0xa4, 0xda, 0x1c}, - {0x4a, 0x3f, 0x8d, 0x6b, 0xdc, 0x0e, 0x1e, 0xcf, 0xcd, 0x72, - 0xe3, 0x77, 0xde, 0xf2, 0xd7, 0xff, 0x92, 0xc1, 0x9b, 0xc7}, - {0x4a, 0xbd, 0xee, 0xec, 0x95, 0x0d, 0x35, 0x9c, 0x89, 0xae, - 0xc7, 0x52, 0xa1, 0x2c, 0x5b, 0x29, 0xf6, 0xd6, 0xaa, 0x0c}, - {0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58, - 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5}, - {0x4e, 0xfc, 0xed, 0x9c, 0x6b, 0xdd, 0x0c, 0x98, 0x5c, 0xa3, - 0xc7, 0xd2, 0x53, 0x06, 0x3c, 0x5b, 0xe6, 0xfc, 0x62, 0x0c}, - {0x4f, 0x55, 0x5c, 0xe2, 0x0d, 0xcd, 0x33, 0x64, 0xe0, 0xdc, - 0x7c, 0x41, 0xef, 0xdd, 0x40, 0xf5, 0x03, 0x56, 0xc1, 0x22}, - {0x4f, 0x65, 0x56, 0x63, 0x36, 0xdb, 0x65, 0x98, 0x58, 0x1d, - 0x58, 0x4a, 0x59, 0x6c, 0x87, 0x93, 0x4d, 0x5f, 0x2a, 0xb4}, - {0x4f, 0x99, 0xaa, 0x93, 0xfb, 0x2b, 0xd1, 0x37, 0x26, 0xa1, - 0x99, 0x4a, 0xce, 0x7f, 0xf0, 0x05, 0xf2, 0x93, 0x5d, 0x1e}, - {0x50, 0x30, 0x06, 0x09, 0x1d, 0x97, 0xd4, 0xf5, 0xae, 0x39, - 0xf7, 0xcb, 0xe7, 0x92, 0x7d, 0x7d, 0x65, 0x2d, 0x34, 0x31}, - {0x51, 0xa4, 0x4c, 0x28, 0xf3, 0x13, 0xe3, 0xf9, 0xcb, 0x5e, - 0x7c, 0x0a, 0x1e, 0x0e, 0x0d, 0xd2, 0x84, 0x37, 0x58, 0xae}, - {0x54, 0xf9, 0xc1, 0x63, 0x75, 0x9f, 0x19, 0x04, 0x51, 0x21, - 0xa3, 0x19, 0xf6, 0x4c, 0x2d, 0x05, 0x55, 0xb7, 0xe0, 0x73}, - {0x55, 0xc8, 0x6f, 0x74, 0x14, 0xac, 0x8b, 0xdd, 0x68, 0x14, - 0xf4, 0xd8, 0x6a, 0xf1, 0x5f, 0x37, 0x10, 0xe1, 0x04, 0xd0}, - {0x56, 0xe0, 0xfa, 0xc0, 0x3b, 0x8f, 0x18, 0x23, 0x55, 0x18, - 0xe5, 0xd3, 0x11, 0xca, 0xe8, 0xc2, 0x43, 0x31, 0xab, 0x66}, - {0x58, 0x11, 0x9f, 0x0e, 0x12, 0x82, 0x87, 0xea, 0x50, 0xfd, - 0xd9, 0x87, 0x45, 0x6f, 0x4f, 0x78, 0xdc, 0xfa, 0xd6, 0xd4}, - {0x59, 0x22, 0xa1, 0xe1, 0x5a, 0xea, 0x16, 0x35, 0x21, 0xf8, - 0x98, 0x39, 0x6a, 0x46, 0x46, 0xb0, 0x44, 0x1b, 0x0f, 0xa9}, - {0x59, 0xaf, 0x82, 0x79, 0x91, 0x86, 0xc7, 0xb4, 0x75, 0x07, - 0xcb, 0xcf, 0x03, 0x57, 0x46, 0xeb, 0x04, 0xdd, 0xb7, 0x16}, - {0x5a, 0x4d, 0x0e, 0x8b, 0x5f, 0xdc, 0xfd, 0xf6, 0x4e, 0x72, - 0x99, 0xa3, 0x6c, 0x06, 0x0d, 0xb2, 0x22, 0xca, 0x78, 0xe4}, - {0x5a, 0x5a, 0x4d, 0xaf, 0x78, 0x61, 0x26, 0x7c, 0x4b, 0x1f, - 0x1e, 0x67, 0x58, 0x6b, 0xae, 0x6e, 0xd4, 0xfe, 0xb9, 0x3f}, - {0x5d, 0x00, 0x38, 0x60, 0xf0, 0x02, 0xed, 0x82, 0x9d, 0xea, - 0xa4, 0x18, 0x68, 0xf7, 0x88, 0x18, 0x6d, 0x62, 0x12, 0x7f}, - {0x5d, 0x98, 0x9c, 0xdb, 0x15, 0x96, 0x11, 0x36, 0x51, 0x65, - 0x64, 0x1b, 0x56, 0x0f, 0xdb, 0xea, 0x2a, 0xc2, 0x3e, 0xf1}, - {0x5f, 0x3a, 0xfc, 0x0a, 0x8b, 0x64, 0xf6, 0x86, 0x67, 0x34, - 0x74, 0xdf, 0x7e, 0xa9, 0xa2, 0xfe, 0xf9, 0xfa, 0x7a, 0x51}, - {0x5f, 0x3b, 0x8c, 0xf2, 0xf8, 0x10, 0xb3, 0x7d, 0x78, 0xb4, - 0xce, 0xec, 0x19, 0x19, 0xc3, 0x73, 0x34, 0xb9, 0xc7, 0x74}, - {0x5f, 0x43, 0xe5, 0xb1, 0xbf, 0xf8, 0x78, 0x8c, 0xac, 0x1c, - 0xc7, 0xca, 0x4a, 0x9a, 0xc6, 0x22, 0x2b, 0xcc, 0x34, 0xc6}, - {0x5f, 0x4e, 0x1f, 0xcf, 0x31, 0xb7, 0x91, 0x3b, 0x85, 0x0b, - 0x54, 0xf6, 0xe5, 0xff, 0x50, 0x1a, 0x2b, 0x6f, 0xc6, 0xcf}, - {0x5f, 0xb7, 0xee, 0x06, 0x33, 0xe2, 0x59, 0xdb, 0xad, 0x0c, - 0x4c, 0x9a, 0xe6, 0xd3, 0x8f, 0x1a, 0x61, 0xc7, 0xdc, 0x25}, - {0x60, 0xd6, 0x89, 0x74, 0xb5, 0xc2, 0x65, 0x9e, 0x8a, 0x0f, - 0xc1, 0x88, 0x7c, 0x88, 0xd2, 0x46, 0x69, 0x1b, 0x18, 0x2c}, - {0x61, 0x57, 0x3a, 0x11, 0xdf, 0x0e, 0xd8, 0x7e, 0xd5, 0x92, - 0x65, 0x22, 0xea, 0xd0, 0x56, 0xd7, 0x44, 0xb3, 0x23, 0x71}, - {0x61, 0xef, 0x43, 0xd7, 0x7f, 0xca, 0xd4, 0x61, 0x51, 0xbc, - 0x98, 0xe0, 0xc3, 0x59, 0x12, 0xaf, 0x9f, 0xeb, 0x63, 0x11}, - {0x62, 0x52, 0xdc, 0x40, 0xf7, 0x11, 0x43, 0xa2, 0x2f, 0xde, - 0x9e, 0xf7, 0x34, 0x8e, 0x06, 0x42, 0x51, 0xb1, 0x81, 0x18}, - {0x62, 0x7f, 0x8d, 0x78, 0x27, 0x65, 0x63, 0x99, 0xd2, 0x7d, - 0x7f, 0x90, 0x44, 0xc9, 0xfe, 0xb3, 0xf3, 0x3e, 0xfa, 0x9a}, - {0x63, 0x4c, 0x3b, 0x02, 0x30, 0xcf, 0x1b, 0x78, 0xb4, 0x56, - 0x9f, 0xec, 0xf2, 0xc0, 0x4a, 0x86, 0x52, 0xef, 0xef, 0x0e}, - {0x64, 0x90, 0x2a, 0xd7, 0x27, 0x7a, 0xf3, 0xe3, 0x2c, 0xd8, - 0xcc, 0x1d, 0xc7, 0x9d, 0xe1, 0xfd, 0x7f, 0x80, 0x69, 0xea}, - {0x66, 0x31, 0xbf, 0x9e, 0xf7, 0x4f, 0x9e, 0xb6, 0xc9, 0xd5, - 0xa6, 0x0c, 0xba, 0x6a, 0xbe, 0xd1, 0xf7, 0xbd, 0xef, 0x7b}, - {0x67, 0x24, 0x89, 0x80, 0xde, 0x77, 0x5d, 0x2c, 0x9b, 0x04, - 0xe4, 0x03, 0x07, 0x94, 0x0b, 0xad, 0xb3, 0x51, 0xf3, 0x95}, - {0x67, 0x65, 0x0d, 0xf1, 0x7e, 0x8e, 0x7e, 0x5b, 0x82, 0x40, - 0xa4, 0xf4, 0x56, 0x4b, 0xcf, 0xe2, 0x3d, 0x69, 0xc6, 0xf0}, - {0x67, 0x82, 0xaa, 0xe0, 0xed, 0xee, 0xe2, 0x1a, 0x58, 0x39, - 0xd3, 0xc0, 0xcd, 0x14, 0x68, 0x0a, 0x4f, 0x60, 0x14, 0x2a}, - {0x67, 0x9a, 0x4f, 0x81, 0xfc, 0x70, 0x5d, 0xde, 0xc4, 0x19, - 0x77, 0x8d, 0xd2, 0xeb, 0xd8, 0x75, 0xf4, 0xc2, 0x42, 0xc6}, - {0x67, 0xeb, 0x33, 0x7b, 0x68, 0x4c, 0xeb, 0x0e, 0xc2, 0xb0, - 0x76, 0x0a, 0xb4, 0x88, 0x27, 0x8c, 0xdd, 0x95, 0x97, 0xdd}, - {0x68, 0x8b, 0x6e, 0xb8, 0x07, 0xe8, 0xed, 0xa5, 0xc7, 0xb1, - 0x7c, 0x43, 0x93, 0xd0, 0x79, 0x5f, 0x0f, 0xae, 0x15, 0x5f}, - {0x68, 0xed, 0x18, 0xb3, 0x09, 0xcd, 0x52, 0x91, 0xc0, 0xd3, - 0x35, 0x7c, 0x1d, 0x11, 0x41, 0xbf, 0x88, 0x38, 0x66, 0xb1}, - {0x69, 0xbd, 0x8c, 0xf4, 0x9c, 0xd3, 0x00, 0xfb, 0x59, 0x2e, - 0x17, 0x93, 0xca, 0x55, 0x6a, 0xf3, 0xec, 0xaa, 0x35, 0xfb}, - {0x6a, 0x17, 0x45, 0x70, 0xa9, 0x16, 0xfb, 0xe8, 0x44, 0x53, - 0xee, 0xd3, 0xd0, 0x70, 0xa1, 0xd8, 0xda, 0x44, 0x28, 0x29}, - {0x6a, 0x6f, 0x2a, 0x8b, 0x6e, 0x26, 0x15, 0x08, 0x8d, 0xf5, - 0x9c, 0xd2, 0x4c, 0x40, 0x24, 0x18, 0xae, 0x42, 0xa3, 0xf1}, - {0x6b, 0x2f, 0x34, 0xad, 0x89, 0x58, 0xbe, 0x62, 0xfd, 0xb0, - 0x6b, 0x5c, 0xce, 0xbb, 0x9d, 0xd9, 0x4f, 0x4e, 0x39, 0xf3}, - {0x6b, 0x81, 0x44, 0x6a, 0x5c, 0xdd, 0xf4, 0x74, 0xa0, 0xf8, - 0x00, 0xff, 0xbe, 0x69, 0xfd, 0x0d, 0xb6, 0x28, 0x75, 0x16}, - {0x6e, 0x3a, 0x55, 0xa4, 0x19, 0x0c, 0x19, 0x5c, 0x93, 0x84, - 0x3c, 0xc0, 0xdb, 0x72, 0x2e, 0x31, 0x30, 0x61, 0xf0, 0xb1}, - {0x70, 0x17, 0x9b, 0x86, 0x8c, 0x00, 0xa4, 0xfa, 0x60, 0x91, - 0x52, 0x22, 0x3f, 0x9f, 0x3e, 0x32, 0xbd, 0xe0, 0x05, 0x62}, - {0x70, 0x30, 0xaa, 0xbf, 0x84, 0x32, 0xa8, 0x00, 0x66, 0x6c, - 0xcc, 0xc4, 0x2a, 0x88, 0x7e, 0x42, 0xb7, 0x55, 0x3e, 0x2b}, - {0x70, 0x5d, 0x2b, 0x45, 0x65, 0xc7, 0x04, 0x7a, 0x54, 0x06, - 0x94, 0xa7, 0x9a, 0xf7, 0xab, 0xb8, 0x42, 0xbd, 0xc1, 0x61}, - {0x72, 0x0f, 0xc1, 0x5d, 0xdc, 0x27, 0xd4, 0x56, 0xd0, 0x98, - 0xfa, 0xbf, 0x3c, 0xdd, 0x78, 0xd3, 0x1e, 0xf5, 0xa8, 0xda}, - {0x74, 0x20, 0x74, 0x41, 0x72, 0x9c, 0xdd, 0x92, 0xec, 0x79, - 0x31, 0xd8, 0x23, 0x10, 0x8d, 0xc2, 0x81, 0x92, 0xe2, 0xbb}, - {0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45, - 0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2}, - {0x74, 0x2c, 0xdf, 0x15, 0x94, 0x04, 0x9c, 0xbf, 0x17, 0xa2, - 0x04, 0x6c, 0xc6, 0x39, 0xbb, 0x38, 0x88, 0xe0, 0x2e, 0x33}, - {0x74, 0xf8, 0xa3, 0xc3, 0xef, 0xe7, 0xb3, 0x90, 0x06, 0x4b, - 0x83, 0x90, 0x3c, 0x21, 0x64, 0x60, 0x20, 0xe5, 0xdf, 0xce}, - {0x75, 0x02, 0x51, 0xb2, 0xc6, 0x32, 0x53, 0x6f, 0x9d, 0x91, - 0x72, 0x79, 0x54, 0x3c, 0x13, 0x7c, 0xd7, 0x21, 0xc6, 0xe0}, - {0x75, 0xe0, 0xab, 0xb6, 0x13, 0x85, 0x12, 0x27, 0x1c, 0x04, - 0xf8, 0x5f, 0xdd, 0xde, 0x38, 0xe4, 0xb7, 0x24, 0x2e, 0xfe}, - {0x76, 0x39, 0xc7, 0x18, 0x47, 0xe1, 0x51, 0xb5, 0xc7, 0xea, - 0x01, 0xc7, 0x58, 0xfb, 0xf1, 0x2a, 0xba, 0x29, 0x8f, 0x7a}, - {0x76, 0xb7, 0x60, 0x96, 0xdd, 0x14, 0x56, 0x29, 0xac, 0x75, - 0x85, 0xd3, 0x70, 0x63, 0xc1, 0xbc, 0x47, 0x86, 0x1c, 0x8b}, - {0x78, 0x6a, 0x74, 0xac, 0x76, 0xab, 0x14, 0x7f, 0x9c, 0x6a, - 0x30, 0x50, 0xba, 0x9e, 0xa8, 0x7e, 0xfe, 0x9a, 0xce, 0x3c}, - {0x78, 0xe9, 0xdd, 0x06, 0x50, 0x62, 0x4d, 0xb9, 0xcb, 0x36, - 0xb5, 0x07, 0x67, 0xf2, 0x09, 0xb8, 0x43, 0xbe, 0x15, 0xb3}, - {0x79, 0x98, 0xa3, 0x08, 0xe1, 0x4d, 0x65, 0x85, 0xe6, 0xc2, - 0x1e, 0x15, 0x3a, 0x71, 0x9f, 0xba, 0x5a, 0xd3, 0x4a, 0xd9}, - {0x7a, 0x74, 0x41, 0x0f, 0xb0, 0xcd, 0x5c, 0x97, 0x2a, 0x36, - 0x4b, 0x71, 0xbf, 0x03, 0x1d, 0x88, 0xa6, 0x51, 0x0e, 0x9e}, - {0x7a, 0xc5, 0xff, 0xf8, 0xdc, 0xbc, 0x55, 0x83, 0x17, 0x68, - 0x77, 0x07, 0x3b, 0xf7, 0x51, 0x73, 0x5e, 0x9b, 0xd3, 0x58}, - {0x7e, 0x20, 0x69, 0x39, 0xcc, 0x5f, 0xa8, 0x83, 0x63, 0x5f, - 0x64, 0xc7, 0x50, 0xeb, 0xf5, 0xfd, 0xa9, 0xae, 0xe6, 0x53}, - {0x7e, 0x78, 0x4a, 0x10, 0x1c, 0x82, 0x65, 0xcc, 0x2d, 0xe1, - 0xf1, 0x6d, 0x47, 0xb4, 0x40, 0xca, 0xd9, 0x0a, 0x19, 0x45}, - {0x7f, 0x88, 0xcd, 0x72, 0x23, 0xf3, 0xc8, 0x13, 0x81, 0x8c, - 0x99, 0x46, 0x14, 0xa8, 0x9c, 0x99, 0xfa, 0x3b, 0x52, 0x47}, - {0x7f, 0x8a, 0x77, 0x83, 0x6b, 0xdc, 0x6d, 0x06, 0x8f, 0x8b, - 0x07, 0x37, 0xfc, 0xc5, 0x72, 0x54, 0x13, 0x06, 0x8c, 0xa4}, - {0x7f, 0x8a, 0xb0, 0xcf, 0xd0, 0x51, 0x87, 0x6a, 0x66, 0xf3, - 0x36, 0x0f, 0x47, 0xc8, 0x8d, 0x8c, 0xd3, 0x35, 0xfc, 0x74}, - {0x7f, 0xb9, 0xe2, 0xc9, 0x95, 0xc9, 0x7a, 0x93, 0x9f, 0x9e, - 0x81, 0xa0, 0x7a, 0xea, 0x9b, 0x4d, 0x70, 0x46, 0x34, 0x96}, - {0x7f, 0xbb, 0x6a, 0xcd, 0x7e, 0x0a, 0xb4, 0x38, 0xda, 0xaf, - 0x6f, 0xd5, 0x02, 0x10, 0xd0, 0x07, 0xc6, 0xc0, 0x82, 0x9c}, - {0x80, 0x25, 0xef, 0xf4, 0x6e, 0x70, 0xc8, 0xd4, 0x72, 0x24, - 0x65, 0x84, 0xfe, 0x40, 0x3b, 0x8a, 0x8d, 0x6a, 0xdb, 0xf5}, - {0x80, 0xbf, 0x3d, 0xe9, 0xa4, 0x1d, 0x76, 0x8d, 0x19, 0x4b, - 0x29, 0x3c, 0x85, 0x63, 0x2c, 0xdb, 0xc8, 0xea, 0x8c, 0xf7}, - {0x81, 0x96, 0x8b, 0x3a, 0xef, 0x1c, 0xdc, 0x70, 0xf5, 0xfa, - 0x32, 0x69, 0xc2, 0x92, 0xa3, 0x63, 0x5b, 0xd1, 0x23, 0xd3}, - {0x82, 0x50, 0xbe, 0xd5, 0xa2, 0x14, 0x43, 0x3a, 0x66, 0x37, - 0x7c, 0xbc, 0x10, 0xef, 0x83, 0xf6, 0x69, 0xda, 0x3a, 0x67}, - {0x83, 0x8e, 0x30, 0xf7, 0x7f, 0xdd, 0x14, 0xaa, 0x38, 0x5e, - 0xd1, 0x45, 0x00, 0x9c, 0x0e, 0x22, 0x36, 0x49, 0x4f, 0xaa}, - {0x85, 0x37, 0x1c, 0xa6, 0xe5, 0x50, 0x14, 0x3d, 0xce, 0x28, - 0x03, 0x47, 0x1b, 0xde, 0x3a, 0x09, 0xe8, 0xf8, 0x77, 0x0f}, - {0x85, 0xa4, 0x08, 0xc0, 0x9c, 0x19, 0x3e, 0x5d, 0x51, 0x58, - 0x7d, 0xcd, 0xd6, 0x13, 0x30, 0xfd, 0x8c, 0xde, 0x37, 0xbf}, - {0x85, 0xb5, 0xff, 0x67, 0x9b, 0x0c, 0x79, 0x96, 0x1f, 0xc8, - 0x6e, 0x44, 0x22, 0x00, 0x46, 0x13, 0xdb, 0x17, 0x92, 0x84}, - {0x87, 0x81, 0xc2, 0x5a, 0x96, 0xbd, 0xc2, 0xfb, 0x4c, 0x65, - 0x06, 0x4f, 0xf9, 0x39, 0x0b, 0x26, 0x04, 0x8a, 0x0e, 0x01}, - {0x87, 0x82, 0xc6, 0xc3, 0x04, 0x35, 0x3b, 0xcf, 0xd2, 0x96, - 0x92, 0xd2, 0x59, 0x3e, 0x7d, 0x44, 0xd9, 0x34, 0xff, 0x11}, - {0x87, 0x9f, 0x4b, 0xee, 0x05, 0xdf, 0x98, 0x58, 0x3b, 0xe3, - 0x60, 0xd6, 0x33, 0xe7, 0x0d, 0x3f, 0xfe, 0x98, 0x71, 0xaf}, - {0x89, 0xc3, 0x2e, 0x6b, 0x52, 0x4e, 0x4d, 0x65, 0x38, 0x8b, - 0x9e, 0xce, 0xdc, 0x63, 0x71, 0x34, 0xed, 0x41, 0x93, 0xa3}, - {0x89, 0xdf, 0x74, 0xfe, 0x5c, 0xf4, 0x0f, 0x4a, 0x80, 0xf9, - 0xe3, 0x37, 0x7d, 0x54, 0xda, 0x91, 0xe1, 0x01, 0x31, 0x8e}, - {0x8b, 0x1a, 0x11, 0x06, 0xb8, 0xe2, 0x6b, 0x23, 0x29, 0x80, - 0xfd, 0x65, 0x2e, 0x61, 0x81, 0x37, 0x64, 0x41, 0xfd, 0x11}, - {0x8b, 0xaf, 0x4c, 0x9b, 0x1d, 0xf0, 0x2a, 0x92, 0xf7, 0xda, - 0x12, 0x8e, 0xb9, 0x1b, 0xac, 0xf4, 0x98, 0x60, 0x4b, 0x6f}, - {0x8c, 0x96, 0xba, 0xeb, 0xdd, 0x2b, 0x07, 0x07, 0x48, 0xee, - 0x30, 0x32, 0x66, 0xa0, 0xf3, 0x98, 0x6e, 0x7c, 0xae, 0x58}, - {0x8c, 0xc4, 0x30, 0x7b, 0xc6, 0x07, 0x55, 0xe7, 0xb2, 0x2d, - 0xd9, 0xf7, 0xfe, 0xa2, 0x45, 0x93, 0x6c, 0x7c, 0xf2, 0x88}, - {0x8c, 0xf4, 0x27, 0xfd, 0x79, 0x0c, 0x3a, 0xd1, 0x66, 0x06, - 0x8d, 0xe8, 0x1e, 0x57, 0xef, 0xbb, 0x93, 0x22, 0x72, 0xd4}, - {0x8d, 0x08, 0xfc, 0x43, 0xc0, 0x77, 0x0c, 0xa8, 0x4f, 0x4d, - 0xcc, 0xb2, 0xd4, 0x1a, 0x5d, 0x95, 0x6d, 0x78, 0x6d, 0xc4}, - {0x8d, 0x17, 0x84, 0xd5, 0x37, 0xf3, 0x03, 0x7d, 0xec, 0x70, - 0xfe, 0x57, 0x8b, 0x51, 0x9a, 0x99, 0xe6, 0x10, 0xd7, 0xb0}, - {0x8e, 0x10, 0x32, 0xe9, 0x24, 0x59, 0x44, 0xf8, 0x47, 0x91, - 0x98, 0x3e, 0xc9, 0xe8, 0x29, 0xcb, 0x10, 0x59, 0xb4, 0xd3}, - {0x8e, 0xb0, 0x3f, 0xc3, 0xcf, 0x7b, 0xb2, 0x92, 0x86, 0x62, - 0x68, 0xb7, 0x51, 0x22, 0x3d, 0xb5, 0x10, 0x34, 0x05, 0xcb}, - {0x8e, 0xfd, 0xca, 0xbc, 0x93, 0xe6, 0x1e, 0x92, 0x5d, 0x4d, - 0x1d, 0xed, 0x18, 0x1a, 0x43, 0x20, 0xa4, 0x67, 0xa1, 0x39}, - {0x90, 0x5f, 0x94, 0x2f, 0xd9, 0xf2, 0x8f, 0x67, 0x9b, 0x37, - 0x81, 0x80, 0xfd, 0x4f, 0x84, 0x63, 0x47, 0xf6, 0x45, 0xc1}, - {0x90, 0x78, 0xc5, 0xa2, 0x8f, 0x9a, 0x43, 0x25, 0xc2, 0xa7, - 0xc7, 0x38, 0x13, 0xcd, 0xfe, 0x13, 0xc2, 0x0f, 0x93, 0x4e}, - {0x90, 0xae, 0xa2, 0x69, 0x85, 0xff, 0x14, 0x80, 0x4c, 0x43, - 0x49, 0x52, 0xec, 0xe9, 0x60, 0x84, 0x77, 0xaf, 0x55, 0x6f}, - {0x90, 0xde, 0xce, 0x77, 0xf8, 0xc8, 0x25, 0x34, 0x0e, 0x62, - 0xeb, 0xd6, 0x35, 0xe1, 0xbe, 0x20, 0xcf, 0x73, 0x27, 0xdd}, - {0x90, 0xde, 0xde, 0x9e, 0x4c, 0x4e, 0x9f, 0x6f, 0xd8, 0x86, - 0x17, 0x57, 0x9d, 0xd3, 0x91, 0xbc, 0x65, 0xa6, 0x89, 0x64}, - {0x91, 0x21, 0x98, 0xee, 0xf2, 0x3d, 0xca, 0xc4, 0x09, 0x39, - 0x31, 0x2f, 0xee, 0x97, 0xdd, 0x56, 0x0b, 0xae, 0x49, 0xb1}, - {0x91, 0x58, 0xc5, 0xef, 0x98, 0x73, 0x01, 0xa8, 0x90, 0x3c, - 0xfd, 0xab, 0x03, 0xd7, 0x2d, 0xa1, 0xd8, 0x89, 0x09, 0xc9}, - {0x91, 0xc6, 0xd6, 0xee, 0x3e, 0x8a, 0xc8, 0x63, 0x84, 0xe5, - 0x48, 0xc2, 0x99, 0x29, 0x5c, 0x75, 0x6c, 0x81, 0x7b, 0x81}, - {0x92, 0x5a, 0x8f, 0x8d, 0x2c, 0x6d, 0x04, 0xe0, 0x66, 0x5f, - 0x59, 0x6a, 0xff, 0x22, 0xd8, 0x63, 0xe8, 0x25, 0x6f, 0x3f}, - {0x93, 0xe6, 0xab, 0x22, 0x03, 0x03, 0xb5, 0x23, 0x28, 0xdc, - 0xda, 0x56, 0x9e, 0xba, 0xe4, 0xd1, 0xd1, 0xcc, 0xfb, 0x65}, - {0x96, 0x56, 0xcd, 0x7b, 0x57, 0x96, 0x98, 0x95, 0xd0, 0xe1, - 0x41, 0x46, 0x68, 0x06, 0xfb, 0xb8, 0xc6, 0x11, 0x06, 0x87}, - {0x96, 0x83, 0x38, 0xf1, 0x13, 0xe3, 0x6a, 0x7b, 0xab, 0xdd, - 0x08, 0xf7, 0x77, 0x63, 0x91, 0xa6, 0x87, 0x36, 0x58, 0x2e}, - {0x96, 0x97, 0x4c, 0xd6, 0xb6, 0x63, 0xa7, 0x18, 0x45, 0x26, - 0xb1, 0xd6, 0x48, 0xad, 0x81, 0x5c, 0xf5, 0x1e, 0x80, 0x1a}, - {0x97, 0x1d, 0x34, 0x86, 0xfc, 0x1e, 0x8e, 0x63, 0x15, 0xf7, - 0xc6, 0xf2, 0xe1, 0x29, 0x67, 0xc7, 0x24, 0x34, 0x22, 0x14}, - {0x97, 0x22, 0x6a, 0xae, 0x4a, 0x7a, 0x64, 0xa5, 0x9b, 0xd1, - 0x67, 0x87, 0xf2, 0x7f, 0x84, 0x1c, 0x0a, 0x00, 0x1f, 0xd0}, - {0x97, 0x81, 0x79, 0x50, 0xd8, 0x1c, 0x96, 0x70, 0xcc, 0x34, - 0xd8, 0x09, 0xcf, 0x79, 0x44, 0x31, 0x36, 0x7e, 0xf4, 0x74}, - {0x97, 0xe2, 0xe9, 0x96, 0x36, 0xa5, 0x47, 0x55, 0x4f, 0x83, - 0x8f, 0xba, 0x38, 0xb8, 0x2e, 0x74, 0xf8, 0x9a, 0x83, 0x0a}, - {0x99, 0xa6, 0x9b, 0xe6, 0x1a, 0xfe, 0x88, 0x6b, 0x4d, 0x2b, - 0x82, 0x00, 0x7c, 0xb8, 0x54, 0xfc, 0x31, 0x7e, 0x15, 0x39}, - {0x9b, 0xaa, 0xe5, 0x9f, 0x56, 0xee, 0x21, 0xcb, 0x43, 0x5a, - 0xbe, 0x25, 0x93, 0xdf, 0xa7, 0xf0, 0x40, 0xd1, 0x1d, 0xcb}, - {0x9c, 0x61, 0x5c, 0x4d, 0x4d, 0x85, 0x10, 0x3a, 0x53, 0x26, - 0xc2, 0x4d, 0xba, 0xea, 0xe4, 0xa2, 0xd2, 0xd5, 0xcc, 0x97}, - {0x9e, 0xd1, 0x80, 0x28, 0xfb, 0x1e, 0x8a, 0x97, 0x01, 0x48, - 0x0a, 0x78, 0x90, 0xa5, 0x9a, 0xcd, 0x73, 0xdf, 0xf8, 0x71}, - {0x9f, 0x74, 0x4e, 0x9f, 0x2b, 0x4d, 0xba, 0xec, 0x0f, 0x31, - 0x2c, 0x50, 0xb6, 0x56, 0x3b, 0x8e, 0x2d, 0x93, 0xc3, 0x11}, - {0x9f, 0xad, 0x91, 0xa6, 0xce, 0x6a, 0xc6, 0xc5, 0x00, 0x47, - 0xc4, 0x4e, 0xc9, 0xd4, 0xa5, 0x0d, 0x92, 0xd8, 0x49, 0x79}, - {0x9f, 0xc7, 0x96, 0xe8, 0xf8, 0x52, 0x4f, 0x86, 0x3a, 0xe1, - 0x49, 0x6d, 0x38, 0x12, 0x42, 0x10, 0x5f, 0x1b, 0x78, 0xf5}, - {0xa0, 0x73, 0xe5, 0xc5, 0xbd, 0x43, 0x61, 0x0d, 0x86, 0x4c, - 0x21, 0x13, 0x0a, 0x85, 0x58, 0x57, 0xcc, 0x9c, 0xea, 0x46}, - {0xa0, 0xa1, 0xab, 0x90, 0xc9, 0xfc, 0x84, 0x7b, 0x3b, 0x12, - 0x61, 0xe8, 0x97, 0x7d, 0x5f, 0xd3, 0x22, 0x61, 0xd3, 0xcc}, - {0xa0, 0xf8, 0xdb, 0x3f, 0x0b, 0xf4, 0x17, 0x69, 0x3b, 0x28, - 0x2e, 0xb7, 0x4a, 0x6a, 0xd8, 0x6d, 0xf9, 0xd4, 0x48, 0xa3}, - {0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55, - 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b}, - {0xa1, 0xe7, 0xc6, 0x00, 0xaa, 0x41, 0x70, 0xe5, 0xb7, 0x4b, - 0xc9, 0x4f, 0x9b, 0x97, 0x03, 0xed, 0xc2, 0x61, 0xb4, 0xb9}, - {0xa3, 0x99, 0xf7, 0x6f, 0x0c, 0xbf, 0x4c, 0x9d, 0xa5, 0x5e, - 0x4a, 0xc2, 0x4e, 0x89, 0x60, 0x98, 0x4b, 0x29, 0x05, 0xb6}, - {0xa3, 0xe3, 0x1e, 0x20, 0xb2, 0xe4, 0x6a, 0x32, 0x85, 0x20, - 0x47, 0x2d, 0x0c, 0xde, 0x95, 0x23, 0xe7, 0x26, 0x0c, 0x6d}, - {0xa4, 0x34, 0x89, 0x15, 0x9a, 0x52, 0x0f, 0x0d, 0x93, 0xd0, - 0x32, 0xcc, 0xaf, 0x37, 0xe7, 0xfe, 0x20, 0xa8, 0xb4, 0x19}, - {0xa5, 0x9c, 0x9b, 0x10, 0xec, 0x73, 0x57, 0x51, 0x5a, 0xbb, - 0x66, 0x0c, 0x4d, 0x94, 0xf7, 0x3b, 0x9e, 0x6e, 0x92, 0x72}, - {0xa5, 0xec, 0x73, 0xd4, 0x8c, 0x34, 0xfc, 0xbe, 0xf1, 0x00, - 0x5a, 0xeb, 0x85, 0x84, 0x35, 0x24, 0xbb, 0xfa, 0xb7, 0x27}, - {0xa6, 0x9a, 0x91, 0xfd, 0x05, 0x7f, 0x13, 0x6a, 0x42, 0x63, - 0x0b, 0xb1, 0x76, 0x0d, 0x2d, 0x51, 0x12, 0x0c, 0x16, 0x50}, - {0xa7, 0xf8, 0x39, 0x0b, 0xa5, 0x77, 0x05, 0x09, 0x6f, 0xd3, - 0x69, 0x41, 0xd4, 0x2e, 0x71, 0x98, 0xc6, 0xd4, 0xd9, 0xd5}, - {0xa8, 0x98, 0x5d, 0x3a, 0x65, 0xe5, 0xe5, 0xc4, 0xb2, 0xd7, - 0xd6, 0x6d, 0x40, 0xc6, 0xdd, 0x2f, 0xb1, 0x9c, 0x54, 0x36}, - {0xa9, 0x62, 0x8f, 0x4b, 0x98, 0xa9, 0x1b, 0x48, 0x35, 0xba, - 0xd2, 0xc1, 0x46, 0x32, 0x86, 0xbb, 0x66, 0x64, 0x6a, 0x8c}, - {0xa9, 0xe9, 0x78, 0x08, 0x14, 0x37, 0x58, 0x88, 0xf2, 0x05, - 0x19, 0xb0, 0x6d, 0x2b, 0x0d, 0x2b, 0x60, 0x16, 0x90, 0x7d}, - {0xaa, 0xdb, 0xbc, 0x22, 0x23, 0x8f, 0xc4, 0x01, 0xa1, 0x27, - 0xbb, 0x38, 0xdd, 0xf4, 0x1d, 0xdb, 0x08, 0x9e, 0xf0, 0x12}, - {0xab, 0x16, 0xdd, 0x14, 0x4e, 0xcd, 0xc0, 0xfc, 0x4b, 0xaa, - 0xb6, 0x2e, 0xcf, 0x04, 0x08, 0x89, 0x6f, 0xde, 0x52, 0xb7}, - {0xab, 0x48, 0xf3, 0x33, 0xdb, 0x04, 0xab, 0xb9, 0xc0, 0x72, - 0xda, 0x5b, 0x0c, 0xc1, 0xd0, 0x57, 0xf0, 0x36, 0x9b, 0x46}, - {0xac, 0xed, 0x5f, 0x65, 0x53, 0xfd, 0x25, 0xce, 0x01, 0x5f, - 0x1f, 0x7a, 0x48, 0x3b, 0x6a, 0x74, 0x9f, 0x61, 0x78, 0xc6}, - {0xad, 0x7e, 0x1c, 0x28, 0xb0, 0x64, 0xef, 0x8f, 0x60, 0x03, - 0x40, 0x20, 0x14, 0xc3, 0xd0, 0xe3, 0x37, 0x0e, 0xb5, 0x8a}, - {0xae, 0x50, 0x83, 0xed, 0x7c, 0xf4, 0x5c, 0xbc, 0x8f, 0x61, - 0xc6, 0x21, 0xfe, 0x68, 0x5d, 0x79, 0x42, 0x21, 0x15, 0x6e}, - {0xae, 0xc5, 0xfb, 0x3f, 0xc8, 0xe1, 0xbf, 0xc4, 0xe5, 0x4f, - 0x03, 0x07, 0x5a, 0x9a, 0xe8, 0x00, 0xb7, 0xf7, 0xb6, 0xfa}, - {0xaf, 0xe5, 0xd2, 0x44, 0xa8, 0xd1, 0x19, 0x42, 0x30, 0xff, - 0x47, 0x9f, 0xe2, 0xf8, 0x97, 0xbb, 0xcd, 0x7a, 0x8c, 0xb4}, - {0xb1, 0x2e, 0x13, 0x63, 0x45, 0x86, 0xa4, 0x6f, 0x1a, 0xb2, - 0x60, 0x68, 0x37, 0x58, 0x2d, 0xc4, 0xac, 0xfd, 0x94, 0x97}, - {0xb1, 0x72, 0xb1, 0xa5, 0x6d, 0x95, 0xf9, 0x1f, 0xe5, 0x02, - 0x87, 0xe1, 0x4d, 0x37, 0xea, 0x6a, 0x44, 0x63, 0x76, 0x8a}, - {0xb1, 0x9d, 0xd0, 0x96, 0xdc, 0xd4, 0xe3, 0xe0, 0xfd, 0x67, - 0x68, 0x85, 0x50, 0x5a, 0x67, 0x2c, 0x43, 0x8d, 0x4e, 0x9c}, - {0xb1, 0xbc, 0x96, 0x8b, 0xd4, 0xf4, 0x9d, 0x62, 0x2a, 0xa8, - 0x9a, 0x81, 0xf2, 0x15, 0x01, 0x52, 0xa4, 0x1d, 0x82, 0x9c}, - {0xb1, 0xea, 0xc3, 0xe5, 0xb8, 0x24, 0x76, 0xe9, 0xd5, 0x0b, - 0x1e, 0xc6, 0x7d, 0x2c, 0xc1, 0x1e, 0x12, 0xe0, 0xb4, 0x91}, - {0xb3, 0x1e, 0xb1, 0xb7, 0x40, 0xe3, 0x6c, 0x84, 0x02, 0xda, - 0xdc, 0x37, 0xd4, 0x4d, 0xf5, 0xd4, 0x67, 0x49, 0x52, 0xf9}, - {0xb3, 0x8f, 0xec, 0xec, 0x0b, 0x14, 0x8a, 0xa6, 0x86, 0xc3, - 0xd0, 0x0f, 0x01, 0xec, 0xc8, 0x84, 0x8e, 0x80, 0x85, 0xeb}, - {0xb3, 0xea, 0xc4, 0x47, 0x76, 0xc9, 0xc8, 0x1c, 0xea, 0xf2, - 0x9d, 0x95, 0xb6, 0xcc, 0xa0, 0x08, 0x1b, 0x67, 0xec, 0x9d}, - {0xb4, 0x35, 0xd4, 0xe1, 0x11, 0x9d, 0x1c, 0x66, 0x90, 0xa7, - 0x49, 0xeb, 0xb3, 0x94, 0xbd, 0x63, 0x7b, 0xa7, 0x82, 0xb7}, - {0xb5, 0x1c, 0x06, 0x7c, 0xee, 0x2b, 0x0c, 0x3d, 0xf8, 0x55, - 0xab, 0x2d, 0x92, 0xf4, 0xfe, 0x39, 0xd4, 0xe7, 0x0f, 0x0e}, - {0xb7, 0x2f, 0xff, 0x92, 0xd2, 0xce, 0x43, 0xde, 0x0a, 0x8d, - 0x4c, 0x54, 0x8c, 0x50, 0x37, 0x26, 0xa8, 0x1e, 0x2b, 0x93}, - {0xb8, 0x01, 0x86, 0xd1, 0xeb, 0x9c, 0x86, 0xa5, 0x41, 0x04, - 0xcf, 0x30, 0x54, 0xf3, 0x4c, 0x52, 0xb7, 0xe5, 0x58, 0xc6}, - {0xb8, 0x23, 0x6b, 0x00, 0x2f, 0x1d, 0x16, 0x86, 0x53, 0x01, - 0x55, 0x6c, 0x11, 0xa4, 0x37, 0xca, 0xeb, 0xff, 0xc3, 0xbb}, - {0xb8, 0x65, 0x13, 0x0b, 0xed, 0xca, 0x38, 0xd2, 0x7f, 0x69, - 0x92, 0x94, 0x20, 0x77, 0x0b, 0xed, 0x86, 0xef, 0xbc, 0x10}, - {0xbc, 0x7b, 0x3c, 0x6f, 0xef, 0x26, 0xb9, 0xf7, 0xab, 0x10, - 0xd7, 0xa1, 0xf6, 0xb6, 0x7c, 0x5e, 0xd2, 0xa1, 0x2d, 0x3d}, - {0xbc, 0x92, 0x19, 0xdd, 0xc9, 0x8e, 0x14, 0xbf, 0x1a, 0x78, - 0x1f, 0x6e, 0x28, 0x0b, 0x04, 0xc2, 0x7f, 0x90, 0x27, 0x12}, - {0xbe, 0x36, 0xa4, 0x56, 0x2f, 0xb2, 0xee, 0x05, 0xdb, 0xb3, - 0xd3, 0x23, 0x23, 0xad, 0xf4, 0x45, 0x08, 0x4e, 0xd6, 0x56}, - {0xbe, 0xb5, 0xa9, 0x95, 0x74, 0x6b, 0x9e, 0xdf, 0x73, 0x8b, - 0x56, 0xe6, 0xdf, 0x43, 0x7a, 0x77, 0xbe, 0x10, 0x6b, 0x81}, - {0xc0, 0x60, 0xed, 0x44, 0xcb, 0xd8, 0x81, 0xbd, 0x0e, 0xf8, - 0x6c, 0x0b, 0xa2, 0x87, 0xdd, 0xcf, 0x81, 0x67, 0x47, 0x8c}, - {0xc0, 0x9a, 0xb0, 0xc8, 0xad, 0x71, 0x14, 0x71, 0x4e, 0xd5, - 0xe2, 0x1a, 0x5a, 0x27, 0x6a, 0xdc, 0xd5, 0xe7, 0xef, 0xcb}, - {0xc0, 0xdb, 0x57, 0x81, 0x57, 0xe9, 0xee, 0x82, 0xb5, 0x91, - 0x7d, 0xf0, 0xdd, 0x6d, 0x82, 0xee, 0x90, 0x39, 0xc4, 0xe2}, - {0xc1, 0x82, 0x11, 0x32, 0x8a, 0x92, 0xb3, 0xb2, 0x38, 0x09, - 0xb9, 0xb5, 0xe2, 0x74, 0x0a, 0x07, 0xfb, 0x12, 0xeb, 0x5e}, - {0xc4, 0x67, 0x4d, 0xdc, 0x6c, 0xe2, 0x96, 0x7f, 0xf9, 0xc9, - 0x2e, 0x07, 0x2e, 0xf8, 0xe8, 0xa7, 0xfb, 0xd6, 0xa1, 0x31}, - {0xc7, 0x30, 0x26, 0xe3, 0x25, 0xfe, 0x21, 0x91, 0x6b, 0x55, - 0xc4, 0xb5, 0x3a, 0x56, 0xb1, 0x3d, 0xca, 0xf3, 0xd6, 0x25}, - {0xc8, 0xec, 0x8c, 0x87, 0x92, 0x69, 0xcb, 0x4b, 0xab, 0x39, - 0xe9, 0x8d, 0x7e, 0x57, 0x67, 0xf3, 0x14, 0x95, 0x73, 0x9d}, - {0xc9, 0x32, 0x1d, 0xe6, 0xb5, 0xa8, 0x26, 0x66, 0xcf, 0x69, - 0x71, 0xa1, 0x8a, 0x56, 0xf2, 0xd3, 0xa8, 0x67, 0x56, 0x02}, - {0xca, 0x3a, 0xfb, 0xcf, 0x12, 0x40, 0x36, 0x4b, 0x44, 0xb2, - 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7c, 0xf7}, - {0xca, 0xbb, 0x51, 0x67, 0x24, 0x00, 0x58, 0x8e, 0x64, 0x19, - 0xf1, 0xd4, 0x08, 0x78, 0xd0, 0x40, 0x3a, 0xa2, 0x02, 0x64}, - {0xcb, 0x44, 0xa0, 0x97, 0x85, 0x7c, 0x45, 0xfa, 0x18, 0x7e, - 0xd9, 0x52, 0x08, 0x6c, 0xb9, 0x84, 0x1f, 0x2d, 0x51, 0xb5}, - {0xcb, 0x65, 0x82, 0x64, 0xea, 0x8c, 0xda, 0x18, 0x6e, 0x17, - 0x52, 0xfb, 0x52, 0xc3, 0x97, 0x36, 0x7e, 0xa3, 0x87, 0xbe}, - {0xcb, 0xa1, 0xc5, 0xf8, 0xb0, 0xe3, 0x5e, 0xb8, 0xb9, 0x45, - 0x12, 0xd3, 0xf9, 0x34, 0xa2, 0xe9, 0x06, 0x10, 0xd3, 0x36}, - {0xcd, 0xd4, 0xee, 0xae, 0x60, 0x00, 0xac, 0x7f, 0x40, 0xc3, - 0x80, 0x2c, 0x17, 0x1e, 0x30, 0x14, 0x80, 0x30, 0xc0, 0x72}, - {0xce, 0x6a, 0x64, 0xa3, 0x09, 0xe4, 0x2f, 0xbb, 0xd9, 0x85, - 0x1c, 0x45, 0x3e, 0x64, 0x09, 0xea, 0xe8, 0x7d, 0x60, 0xf1}, - {0xce, 0xa9, 0x89, 0x0d, 0x85, 0xd8, 0x07, 0x53, 0xa6, 0x26, - 0x28, 0x6c, 0xda, 0xd7, 0x8c, 0xb5, 0x66, 0xd7, 0x0c, 0xf2}, - {0xcf, 0x9e, 0x87, 0x6d, 0xd3, 0xeb, 0xfc, 0x42, 0x26, 0x97, - 0xa3, 0xb5, 0xa3, 0x7a, 0xa0, 0x76, 0xa9, 0x06, 0x23, 0x48}, - {0xcf, 0xde, 0xfe, 0x10, 0x2f, 0xda, 0x05, 0xbb, 0xe4, 0xc7, - 0x8d, 0x2e, 0x44, 0x23, 0x58, 0x90, 0x05, 0xb2, 0x57, 0x1d}, - {0xcf, 0xe4, 0x31, 0x3d, 0xba, 0x05, 0xb8, 0xa7, 0xc3, 0x00, - 0x63, 0x99, 0x5a, 0x9e, 0xb7, 0xc2, 0x47, 0xad, 0x8f, 0xd5}, - {0xcf, 0xf3, 0x60, 0xf5, 0x24, 0xcb, 0x20, 0xf1, 0xfe, 0xad, - 0x89, 0x00, 0x6f, 0x7f, 0x58, 0x6a, 0x28, 0x5b, 0x2d, 0x5b}, - {0xcf, 0xf8, 0x10, 0xfb, 0x2c, 0x4f, 0xfc, 0x01, 0x56, 0xbf, - 0xe1, 0xe1, 0xfa, 0xbc, 0xb4, 0x18, 0xc6, 0x8d, 0x31, 0xc5}, - {0xd1, 0xcb, 0xca, 0x5d, 0xb2, 0xd5, 0x2a, 0x7f, 0x69, 0x3b, - 0x67, 0x4d, 0xe5, 0xf0, 0x5a, 0x1d, 0x0c, 0x95, 0x7d, 0xf0}, - {0xd1, 0xeb, 0x23, 0xa4, 0x6d, 0x17, 0xd6, 0x8f, 0xd9, 0x25, - 0x64, 0xc2, 0xf1, 0xf1, 0x60, 0x17, 0x64, 0xd8, 0xe3, 0x49}, - {0xd2, 0x32, 0x09, 0xad, 0x23, 0xd3, 0x14, 0x23, 0x21, 0x74, - 0xe4, 0x0d, 0x7f, 0x9d, 0x62, 0x13, 0x97, 0x86, 0x63, 0x3a}, - {0xd2, 0x44, 0x1a, 0xa8, 0xc2, 0x03, 0xae, 0xca, 0xa9, 0x6e, - 0x50, 0x1f, 0x12, 0x4d, 0x52, 0xb6, 0x8f, 0xe4, 0xc3, 0x75}, - {0xd2, 0x9f, 0x6c, 0x98, 0xbe, 0xfc, 0x6d, 0x98, 0x65, 0x21, - 0x54, 0x3e, 0xe8, 0xbe, 0x56, 0xce, 0xbc, 0x28, 0x8c, 0xf3}, - {0xd2, 0xed, 0xf8, 0x8b, 0x41, 0xb6, 0xfe, 0x01, 0x46, 0x1d, - 0x6e, 0x28, 0x34, 0xec, 0x7c, 0x8f, 0x6c, 0x77, 0x72, 0x1e}, - {0xd3, 0xc0, 0x63, 0xf2, 0x19, 0xed, 0x07, 0x3e, 0x34, 0xad, - 0x5d, 0x75, 0x0b, 0x32, 0x76, 0x29, 0xff, 0xd5, 0x9a, 0xf2}, - {0xd4, 0xde, 0x20, 0xd0, 0x5e, 0x66, 0xfc, 0x53, 0xfe, 0x1a, - 0x50, 0x88, 0x2c, 0x78, 0xdb, 0x28, 0x52, 0xca, 0xe4, 0x74}, - {0xd6, 0x9b, 0x56, 0x11, 0x48, 0xf0, 0x1c, 0x77, 0xc5, 0x45, - 0x78, 0xc1, 0x09, 0x26, 0xdf, 0x5b, 0x85, 0x69, 0x76, 0xad}, - {0xd6, 0xbf, 0x79, 0x94, 0xf4, 0x2b, 0xe5, 0xfa, 0x29, 0xda, - 0x0b, 0xd7, 0x58, 0x7b, 0x59, 0x1f, 0x47, 0xa4, 0x4f, 0x22}, - {0xd6, 0xda, 0xa8, 0x20, 0x8d, 0x09, 0xd2, 0x15, 0x4d, 0x24, - 0xb5, 0x2f, 0xcb, 0x34, 0x6e, 0xb2, 0x58, 0xb2, 0x8a, 0x58}, - {0xd8, 0xa6, 0x33, 0x2c, 0xe0, 0x03, 0x6f, 0xb1, 0x85, 0xf6, - 0x63, 0x4f, 0x7d, 0x6a, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27}, - {0xd8, 0xc5, 0x38, 0x8a, 0xb7, 0x30, 0x1b, 0x1b, 0x6e, 0xd4, - 0x7a, 0xe6, 0x45, 0x25, 0x3a, 0x6f, 0x9f, 0x1a, 0x27, 0x61}, - {0xd9, 0x04, 0x08, 0x0a, 0x49, 0x29, 0xc8, 0x38, 0xe9, 0xf1, - 0x85, 0xec, 0xf7, 0xa2, 0x2d, 0xef, 0x99, 0x34, 0x24, 0x07}, - {0xda, 0x40, 0x18, 0x8b, 0x91, 0x89, 0xa3, 0xed, 0xee, 0xae, - 0xda, 0x97, 0xfe, 0x2f, 0x9d, 0xf5, 0xb7, 0xd1, 0x8a, 0x41}, - {0xda, 0xc9, 0x02, 0x4f, 0x54, 0xd8, 0xf6, 0xdf, 0x94, 0x93, - 0x5f, 0xb1, 0x73, 0x26, 0x38, 0xca, 0x6a, 0xd7, 0x7c, 0x13}, - {0xdb, 0xac, 0x3c, 0x7a, 0xa4, 0x25, 0x4d, 0xa1, 0xaa, 0x5c, - 0xaa, 0xd6, 0x84, 0x68, 0xcb, 0x88, 0xee, 0xdd, 0xee, 0xa8}, - {0xdd, 0x83, 0xc5, 0x19, 0xd4, 0x34, 0x81, 0xfa, 0xd4, 0xc2, - 0x2c, 0x03, 0xd7, 0x02, 0xfe, 0x9f, 0x3b, 0x22, 0xf5, 0x17}, - {0xdd, 0xe1, 0xd2, 0xa9, 0x01, 0x80, 0x2e, 0x1d, 0x87, 0x5e, - 0x84, 0xb3, 0x80, 0x7e, 0x4b, 0xb1, 0xfd, 0x99, 0x41, 0x34}, - {0xde, 0x28, 0xf4, 0xa4, 0xff, 0xe5, 0xb9, 0x2f, 0xa3, 0xc5, - 0x03, 0xd1, 0xa3, 0x49, 0xa7, 0xf9, 0x96, 0x2a, 0x82, 0x12}, - {0xde, 0x3f, 0x40, 0xbd, 0x50, 0x93, 0xd3, 0x9b, 0x6c, 0x60, - 0xf6, 0xda, 0xbc, 0x07, 0x62, 0x01, 0x00, 0x89, 0x76, 0xc9}, - {0xde, 0x99, 0x0c, 0xed, 0x99, 0xe0, 0x43, 0x1f, 0x60, 0xed, - 0xc3, 0x93, 0x7e, 0x7c, 0xd5, 0xbf, 0x0e, 0xd9, 0xe5, 0xfa}, - {0xdf, 0x64, 0x6d, 0xcb, 0x7b, 0x0f, 0xd3, 0xa9, 0x6a, 0xee, - 0x88, 0xc6, 0x4e, 0x2d, 0x67, 0x67, 0x11, 0xff, 0x9d, 0x5f}, - {0xe0, 0x92, 0x5e, 0x18, 0xc7, 0x76, 0x5e, 0x22, 0xda, 0xbd, - 0x94, 0x27, 0x52, 0x9d, 0xa6, 0xaf, 0x4e, 0x06, 0x64, 0x28}, - {0xe0, 0xab, 0x05, 0x94, 0x20, 0x72, 0x54, 0x93, 0x05, 0x60, - 0x62, 0x02, 0x36, 0x70, 0xf7, 0xcd, 0x2e, 0xfc, 0x66, 0x66}, - {0xe0, 0xb4, 0x32, 0x2e, 0xb2, 0xf6, 0xa5, 0x68, 0xb6, 0x54, - 0x53, 0x84, 0x48, 0x18, 0x4a, 0x50, 0x36, 0x87, 0x43, 0x84}, - {0xe1, 0x2d, 0xfb, 0x4b, 0x41, 0xd7, 0xd9, 0xc3, 0x2b, 0x30, - 0x51, 0x4b, 0xac, 0x1d, 0x81, 0xd8, 0x38, 0x5e, 0x2d, 0x46}, - {0xe1, 0xa4, 0x5b, 0x14, 0x1a, 0x21, 0xda, 0x1a, 0x79, 0xf4, - 0x1a, 0x42, 0xa9, 0x61, 0xd6, 0x69, 0xcd, 0x06, 0x34, 0xc1}, - {0xe3, 0x92, 0x51, 0x2f, 0x0a, 0xcf, 0xf5, 0x05, 0xdf, 0xf6, - 0xde, 0x06, 0x7f, 0x75, 0x37, 0xe1, 0x65, 0xea, 0x57, 0x4b}, - {0xe3, 0xd7, 0x36, 0x06, 0x99, 0x6c, 0xdf, 0xef, 0x61, 0xfa, - 0x04, 0xc3, 0x35, 0xe9, 0x8e, 0xa9, 0x61, 0x04, 0x26, 0x4a}, - {0xe5, 0xdf, 0x74, 0x3c, 0xb6, 0x01, 0xc4, 0x9b, 0x98, 0x43, - 0xdc, 0xab, 0x8c, 0xe8, 0x6a, 0x81, 0x10, 0x9f, 0xe4, 0x8e}, - {0xe6, 0x19, 0xd2, 0x5b, 0x38, 0x0b, 0x7b, 0x13, 0xfd, 0xa3, - 0x3e, 0x8a, 0x58, 0xcd, 0x82, 0xd8, 0xa8, 0x8e, 0x05, 0x15}, - {0xe6, 0x21, 0xf3, 0x35, 0x43, 0x79, 0x05, 0x9a, 0x4b, 0x68, - 0x30, 0x9d, 0x8a, 0x2f, 0x74, 0x22, 0x15, 0x87, 0xec, 0x79}, - {0xe7, 0x07, 0x15, 0xf6, 0xf7, 0x28, 0x36, 0x5b, 0x51, 0x90, - 0xe2, 0x71, 0xde, 0xe4, 0xc6, 0x5e, 0xbe, 0xea, 0xca, 0xf3}, - {0xe7, 0xb4, 0xf6, 0x9d, 0x61, 0xec, 0x90, 0x69, 0xdb, 0x7e, - 0x90, 0xa7, 0x40, 0x1a, 0x3c, 0xf4, 0x7d, 0x4f, 0xe8, 0xee}, - {0xec, 0x0c, 0x37, 0x16, 0xea, 0x9e, 0xdf, 0xad, 0xd3, 0x5d, - 0xfb, 0xd5, 0x56, 0x08, 0xe6, 0x0a, 0x05, 0xd3, 0xcb, 0xf3}, - {0xec, 0x93, 0xde, 0x08, 0x3c, 0x93, 0xd9, 0x33, 0xa9, 0x86, - 0xb3, 0xd5, 0xcd, 0xe2, 0x5a, 0xcb, 0x2f, 0xee, 0xcf, 0x8e}, - {0xed, 0x8d, 0xc8, 0x38, 0x6c, 0x48, 0x86, 0xae, 0xee, 0x07, - 0x91, 0x58, 0xaa, 0xc3, 0xbf, 0xe6, 0x58, 0xe3, 0x94, 0xb4}, - {0xee, 0x29, 0xd6, 0xea, 0x98, 0xe6, 0x32, 0xc6, 0xe5, 0x27, - 0xe0, 0x90, 0x6f, 0x02, 0x80, 0x68, 0x8b, 0xdf, 0x44, 0xdc}, - {0xf1, 0x7f, 0x6f, 0xb6, 0x31, 0xdc, 0x99, 0xe3, 0xa3, 0xc8, - 0x7f, 0xfe, 0x1c, 0xf1, 0x81, 0x10, 0x88, 0xd9, 0x60, 0x33}, - {0xf1, 0x8b, 0x53, 0x8d, 0x1b, 0xe9, 0x03, 0xb6, 0xa6, 0xf0, - 0x56, 0x43, 0x5b, 0x17, 0x15, 0x89, 0xca, 0xf3, 0x6b, 0xf2}, - {0xf4, 0x40, 0x95, 0xc2, 0x38, 0xac, 0x73, 0xfc, 0x4f, 0x77, - 0xbf, 0x8f, 0x98, 0xdf, 0x70, 0xf8, 0xf0, 0x91, 0xbc, 0x52}, - {0xf4, 0x8b, 0x11, 0xbf, 0xde, 0xab, 0xbe, 0x94, 0x54, 0x20, - 0x71, 0xe6, 0x41, 0xde, 0x6b, 0xbe, 0x88, 0x2b, 0x40, 0xb9}, - {0xf5, 0xc2, 0x7c, 0xf5, 0xff, 0xf3, 0x02, 0x9a, 0xcf, 0x1a, - 0x1a, 0x4b, 0xec, 0x7e, 0xe1, 0x96, 0x4c, 0x77, 0xd7, 0x84}, - {0xf9, 0xb5, 0xb6, 0x32, 0x45, 0x5f, 0x9c, 0xbe, 0xec, 0x57, - 0x5f, 0x80, 0xdc, 0xe9, 0x6e, 0x2c, 0xc7, 0xb2, 0x78, 0xb7}, - {0xf9, 0xcd, 0x0e, 0x2c, 0xda, 0x76, 0x24, 0xc1, 0x8f, 0xbd, - 0xf0, 0xf0, 0xab, 0xb6, 0x45, 0xb8, 0xf7, 0xfe, 0xd5, 0x7a}, - {0xf9, 0xdd, 0x19, 0x26, 0x6b, 0x20, 0x43, 0xf1, 0xfe, 0x4b, - 0x3d, 0xcb, 0x01, 0x90, 0xaf, 0xf1, 0x1f, 0x31, 0xa6, 0x9d}, - {0xfa, 0x08, 0x82, 0x59, 0x5f, 0x9c, 0xa6, 0xa1, 0x1e, 0xcc, - 0xbe, 0xaf, 0x65, 0xc7, 0x64, 0xc0, 0xcc, 0xc3, 0x11, 0xd0}, - {0xfa, 0xa7, 0xd9, 0xfb, 0x31, 0xb7, 0x46, 0xf2, 0x00, 0xa8, - 0x5e, 0x65, 0x79, 0x76, 0x13, 0xd8, 0x16, 0xe0, 0x63, 0xb5}, - {0xfa, 0xaa, 0x27, 0xb8, 0xca, 0xf5, 0xfd, 0xf5, 0xcd, 0xa9, - 0x8a, 0xc3, 0x37, 0x85, 0x72, 0xe0, 0x4c, 0xe8, 0xf2, 0xe0}, - {0xfa, 0xb7, 0xee, 0x36, 0x97, 0x26, 0x62, 0xfb, 0x2d, 0xb0, - 0x2a, 0xf6, 0xbf, 0x03, 0xfd, 0xe8, 0x7c, 0x4b, 0x2f, 0x9b}, - {0xfd, 0x1e, 0xd1, 0xe2, 0x02, 0x1b, 0x0b, 0x9f, 0x73, 0xe8, - 0xeb, 0x75, 0xce, 0x23, 0x43, 0x6b, 0xbc, 0xc7, 0x46, 0xeb}, - {0xfe, 0xb8, 0xc4, 0x32, 0xdc, 0xf9, 0x76, 0x9a, 0xce, 0xae, - 0x3d, 0xd8, 0x90, 0x8f, 0xfd, 0x28, 0x86, 0x65, 0x64, 0x7d}, -}; - -#endif // NET_BASE_X509_CERTIFICATE_KNOWN_ROOTS_WIN_H_ diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc deleted file mode 100644 index fb6ffa9..0000000 --- a/net/base/x509_certificate_mac.cc +++ /dev/null @@ -1,834 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <CommonCrypto/CommonDigest.h> -#include <CoreServices/CoreServices.h> -#include <Security/Security.h> -#include <time.h> - -#include <vector> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/mac/mac_logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/singleton.h" -#include "base/pickle.h" -#include "base/sha1.h" -#include "base/string_piece.h" -#include "base/strings/sys_string_conversions.h" -#include "base/synchronization/lock.h" -#include "crypto/cssm_init.h" -#include "crypto/mac_security_services_lock.h" -#include "crypto/nss_util.h" -#include "crypto/rsa_private_key.h" -#include "net/base/x509_util_mac.h" -#include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h" - -using base::mac::ScopedCFTypeRef; -using base::Time; - -namespace net { - -namespace { - -void GetCertDistinguishedName( - const x509_util::CSSMCachedCertificate& cached_cert, - const CSSM_OID* oid, - CertPrincipal* result) { - x509_util::CSSMFieldValue distinguished_name; - OSStatus status = cached_cert.GetField(oid, &distinguished_name); - if (status || !distinguished_name.field()) - return; - result->ParseDistinguishedName(distinguished_name.field()->Data, - distinguished_name.field()->Length); -} - -bool IsCertIssuerInEncodedList(X509Certificate::OSCertHandle cert_handle, - const std::vector<std::string>& issuers) { - x509_util::CSSMCachedCertificate cached_cert; - if (cached_cert.Init(cert_handle) != CSSM_OK) - return false; - - x509_util::CSSMFieldValue distinguished_name; - OSStatus status = cached_cert.GetField(&CSSMOID_X509V1IssuerNameStd, - &distinguished_name); - if (status || !distinguished_name.field()) - return false; - - base::StringPiece name_piece( - reinterpret_cast<const char*>(distinguished_name.field()->Data), - static_cast<size_t>(distinguished_name.field()->Length)); - - for (std::vector<std::string>::const_iterator it = issuers.begin(); - it != issuers.end(); ++it) { - base::StringPiece issuer_piece(*it); - if (name_piece == issuer_piece) - return true; - } - - return false; -} - -void GetCertDateForOID(const x509_util::CSSMCachedCertificate& cached_cert, - const CSSM_OID* oid, - Time* result) { - *result = Time::Time(); - - x509_util::CSSMFieldValue field; - OSStatus status = cached_cert.GetField(oid, &field); - if (status) - return; - - const CSSM_X509_TIME* x509_time = field.GetAs<CSSM_X509_TIME>(); - if (x509_time->timeType != BER_TAG_UTC_TIME && - x509_time->timeType != BER_TAG_GENERALIZED_TIME) { - LOG(ERROR) << "Unsupported date/time format " - << x509_time->timeType; - return; - } - - base::StringPiece time_string( - reinterpret_cast<const char*>(x509_time->time.Data), - x509_time->time.Length); - CertDateFormat format = x509_time->timeType == BER_TAG_UTC_TIME ? - CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; - if (!ParseCertificateDate(time_string, format, result)) - LOG(ERROR) << "Invalid certificate date/time " << time_string; -} - -std::string GetCertSerialNumber( - const x509_util::CSSMCachedCertificate& cached_cert) { - x509_util::CSSMFieldValue serial_number; - OSStatus status = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, - &serial_number); - if (status || !serial_number.field()) - return std::string(); - - return std::string( - reinterpret_cast<const char*>(serial_number.field()->Data), - serial_number.field()->Length); -} - -// Gets the issuer for a given cert, starting with the cert itself and -// including the intermediate and finally root certificates (if any). -// This function calls SecTrust but doesn't actually pay attention to the trust -// result: it shouldn't be used to determine trust, just to traverse the chain. -// Caller is responsible for releasing the value stored into *out_cert_chain. -OSStatus CopyCertChain(SecCertificateRef cert_handle, - CFArrayRef* out_cert_chain) { - DCHECK(cert_handle); - DCHECK(out_cert_chain); - - // Create an SSL policy ref configured for client cert evaluation. - SecPolicyRef ssl_policy; - OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy); - if (result) - return result; - ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); - - // Create a SecTrustRef. - ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate( - NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)), - 1, &kCFTypeArrayCallBacks)); - SecTrustRef trust_ref = NULL; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - result = SecTrustCreateWithCertificates(input_certs, ssl_policy, - &trust_ref); - } - if (result) - return result; - ScopedCFTypeRef<SecTrustRef> trust(trust_ref); - - // Evaluate trust, which creates the cert chain. - SecTrustResultType status; - CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - result = SecTrustEvaluate(trust, &status); - } - if (result) - return result; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain); - } - return result; -} - -// Returns true if |purpose| is listed as allowed in |usage|. This -// function also considers the "Any" purpose. If the attribute is -// present and empty, we return false. -bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage, - const CSSM_OID* purpose) { - for (unsigned p = 0; p < usage->numPurposes; ++p) { - if (CSSMOIDEqual(&usage->purposes[p], purpose)) - return true; - if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny)) - return true; - } - return false; -} - -// Test that a given |cert_handle| is actually a valid X.509 certificate, and -// return true if it is. -// -// On OS X, SecCertificateCreateFromData() does not return any errors if -// called with invalid data, as long as data is present. The actual decoding -// of the certificate does not happen until an API that requires a CSSM -// handle is called. While SecCertificateGetCLHandle is the most likely -// candidate, as it performs the parsing, it does not check whether the -// parsing was actually successful. Instead, SecCertificateGetSubject is -// used (supported since 10.3), as a means to check that the certificate -// parsed as a valid X.509 certificate. -bool IsValidOSCertHandle(SecCertificateRef cert_handle) { - const CSSM_X509_NAME* sanity_check = NULL; - OSStatus status = SecCertificateGetSubject(cert_handle, &sanity_check); - return status == noErr && sanity_check; -} - -// Parses |data| of length |length|, attempting to decode it as the specified -// |format|. If |data| is in the specified format, any certificates contained -// within are stored into |output|. -void AddCertificatesFromBytes(const char* data, size_t length, - SecExternalFormat format, - X509Certificate::OSCertHandles* output) { - SecExternalFormat input_format = format; - ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy( - kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length, - kCFAllocatorNull)); - - CFArrayRef items = NULL; - OSStatus status; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - status = SecKeychainItemImport(local_data, NULL, &input_format, - NULL, 0, NULL, NULL, &items); - } - - if (status) { - OSSTATUS_DLOG(WARNING, status) - << "Unable to import items from data of length " << length; - return; - } - - ScopedCFTypeRef<CFArrayRef> scoped_items(items); - CFTypeID cert_type_id = SecCertificateGetTypeID(); - - for (CFIndex i = 0; i < CFArrayGetCount(items); ++i) { - SecKeychainItemRef item = reinterpret_cast<SecKeychainItemRef>( - const_cast<void*>(CFArrayGetValueAtIndex(items, i))); - - // While inputFormat implies only certificates will be imported, if/when - // other formats (eg: PKCS#12) are supported, this may also include - // private keys or other items types, so filter appropriately. - if (CFGetTypeID(item) == cert_type_id) { - SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(item); - // OS X ignores |input_format| if it detects that |local_data| is PEM - // encoded, attempting to decode data based on internal rules for PEM - // block headers. If a PKCS#7 blob is encoded with a PEM block of - // CERTIFICATE, OS X 10.5 will return a single, invalid certificate - // based on the decoded data. If this happens, the certificate should - // not be included in |output|. Because |output| is empty, - // CreateCertificateListfromBytes will use PEMTokenizer to decode the - // data. When called again with the decoded data, OS X will honor - // |input_format|, causing decode to succeed. On OS X 10.6, the data - // is properly decoded as a PKCS#7, whether PEM or not, which avoids - // the need to fallback to internal decoding. - if (IsValidOSCertHandle(cert)) { - CFRetain(cert); - output->push_back(cert); - } - } - } -} - -struct CSSMOIDString { - const CSSM_OID* oid_; - std::string string_; -}; - -typedef std::vector<CSSMOIDString> CSSMOIDStringVector; - -bool CERTNameToCSSMOIDVector(CERTName* name, CSSMOIDStringVector* out_values) { - struct OIDCSSMMap { - SECOidTag sec_OID_; - const CSSM_OID* cssm_OID_; - }; - - const OIDCSSMMap kOIDs[] = { - { SEC_OID_AVA_COMMON_NAME, &CSSMOID_CommonName }, - { SEC_OID_AVA_COUNTRY_NAME, &CSSMOID_CountryName }, - { SEC_OID_AVA_LOCALITY, &CSSMOID_LocalityName }, - { SEC_OID_AVA_STATE_OR_PROVINCE, &CSSMOID_StateProvinceName }, - { SEC_OID_AVA_STREET_ADDRESS, &CSSMOID_StreetAddress }, - { SEC_OID_AVA_ORGANIZATION_NAME, &CSSMOID_OrganizationName }, - { SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, &CSSMOID_OrganizationalUnitName }, - { SEC_OID_AVA_DN_QUALIFIER, &CSSMOID_DNQualifier }, - { SEC_OID_RFC1274_UID, &CSSMOID_UniqueIdentifier }, - { SEC_OID_PKCS9_EMAIL_ADDRESS, &CSSMOID_EmailAddress }, - }; - - CERTRDN** rdns = name->rdns; - for (size_t rdn = 0; rdns[rdn]; ++rdn) { - CERTAVA** avas = rdns[rdn]->avas; - for (size_t pair = 0; avas[pair] != 0; ++pair) { - SECOidTag tag = CERT_GetAVATag(avas[pair]); - if (tag == SEC_OID_UNKNOWN) { - return false; - } - CSSMOIDString oidString; - bool found_oid = false; - for (size_t oid = 0; oid < ARRAYSIZE_UNSAFE(kOIDs); ++oid) { - if (kOIDs[oid].sec_OID_ == tag) { - SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value); - if (!decode_item) - return false; - - // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote. - std::string value(reinterpret_cast<char*>(decode_item->data), - decode_item->len); - oidString.oid_ = kOIDs[oid].cssm_OID_; - oidString.string_ = value; - out_values->push_back(oidString); - SECITEM_FreeItem(decode_item, PR_TRUE); - found_oid = true; - break; - } - } - if (!found_oid) { - DLOG(ERROR) << "Unrecognized OID: " << tag; - } - } - } - return true; -} - -class ScopedCertName { - public: - explicit ScopedCertName(CERTName* name) : name_(name) { } - ~ScopedCertName() { - if (name_) CERT_DestroyName(name_); - } - operator CERTName*() { return name_; } - - private: - CERTName* name_; -}; - -class ScopedEncodedCertResults { - public: - explicit ScopedEncodedCertResults(CSSM_TP_RESULT_SET* results) - : results_(results) { } - ~ScopedEncodedCertResults() { - if (results_) { - CSSM_ENCODED_CERT* encCert = - reinterpret_cast<CSSM_ENCODED_CERT*>(results_->Results); - for (uint32 i = 0; i < results_->NumberOfResults; i++) { - crypto::CSSMFree(encCert[i].CertBlob.Data); - } - } - crypto::CSSMFree(results_->Results); - crypto::CSSMFree(results_); - } - - private: - CSSM_TP_RESULT_SET* results_; -}; - -} // namespace - -void X509Certificate::Initialize() { - x509_util::CSSMCachedCertificate cached_cert; - if (cached_cert.Init(cert_handle_) == CSSM_OK) { - GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1SubjectNameStd, - &subject_); - GetCertDistinguishedName(cached_cert, &CSSMOID_X509V1IssuerNameStd, - &issuer_); - GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotBefore, - &valid_start_); - GetCertDateForOID(cached_cert, &CSSMOID_X509V1ValidityNotAfter, - &valid_expiry_); - serial_number_ = GetCertSerialNumber(cached_cert); - } - - fingerprint_ = CalculateFingerprint(cert_handle_); - ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); -} - -bool X509Certificate::IsIssuedByEncoded( - const std::vector<std::string>& valid_issuers) { - if (IsCertIssuerInEncodedList(cert_handle_, valid_issuers)) - return true; - - for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); - it != intermediate_ca_certs_.end(); ++it) { - if (IsCertIssuerInEncodedList(*it, valid_issuers)) - return true; - } - return false; -} - -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - DCHECK(!subject.empty()); - - if (valid_duration.InSeconds() > kuint32max) { - LOG(ERROR) << "valid_duration too big " << valid_duration.InSeconds(); - valid_duration = base::TimeDelta::FromSeconds(kuint32max); - } - - // There is a comment in - // http://www.opensource.apple.com/source/security_certtool/security_certtool-31828/src/CertTool.cpp - // that serial_numbers being passed into CSSM_TP_SubmitCredRequest can't have - // their high bit set. We will continue though and mask it out below. - if (serial_number & 0x80000000) - LOG(ERROR) << "serial_number has high bit set " << serial_number; - - // NSS is used to parse the subject string into a set of - // CSSM_OID/string pairs. There doesn't appear to be a system routine for - // parsing Distinguished Name strings. - crypto::EnsureNSSInit(); - - CSSMOIDStringVector subject_name_oids; - ScopedCertName subject_name( - CERT_AsciiToName(const_cast<char*>(subject.c_str()))); - if (!CERTNameToCSSMOIDVector(subject_name, &subject_name_oids)) { - DLOG(ERROR) << "Unable to generate CSSMOIDMap from " << subject; - return NULL; - } - - // Convert the map of oid/string pairs into an array of - // CSSM_APPLE_TP_NAME_OIDs. - std::vector<CSSM_APPLE_TP_NAME_OID> cssm_subject_names; - for (CSSMOIDStringVector::iterator iter = subject_name_oids.begin(); - iter != subject_name_oids.end(); ++iter) { - CSSM_APPLE_TP_NAME_OID cssm_subject_name; - cssm_subject_name.oid = iter->oid_; - cssm_subject_name.string = iter->string_.c_str(); - cssm_subject_names.push_back(cssm_subject_name); - } - - if (cssm_subject_names.empty()) { - DLOG(ERROR) << "cssm_subject_names.size() == 0. Input: " << subject; - return NULL; - } - - // Set up a certificate request. - CSSM_APPLE_TP_CERT_REQUEST certReq; - memset(&certReq, 0, sizeof(certReq)); - certReq.cspHand = crypto::GetSharedCSPHandle(); - certReq.clHand = crypto::GetSharedCLHandle(); - // See comment about serial numbers above. - certReq.serialNumber = serial_number & 0x7fffffff; - certReq.numSubjectNames = cssm_subject_names.size(); - certReq.subjectNames = &cssm_subject_names[0]; - certReq.numIssuerNames = 0; // Root. - certReq.issuerNames = NULL; - certReq.issuerNameX509 = NULL; - certReq.certPublicKey = key->public_key(); - certReq.issuerPrivateKey = key->key(); - // These are the Apple defaults. - certReq.signatureAlg = CSSM_ALGID_SHA1WithRSA; - certReq.signatureOid = CSSMOID_SHA1WithRSA; - certReq.notBefore = 0; - certReq.notAfter = static_cast<uint32>(valid_duration.InSeconds()); - certReq.numExtensions = 0; - certReq.extensions = NULL; - certReq.challengeString = NULL; - - CSSM_TP_REQUEST_SET reqSet; - reqSet.NumberOfRequests = 1; - reqSet.Requests = &certReq; - - CSSM_FIELD policyId; - memset(&policyId, 0, sizeof(policyId)); - policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN; - - CSSM_TP_CALLERAUTH_CONTEXT callerAuthContext; - memset(&callerAuthContext, 0, sizeof(callerAuthContext)); - callerAuthContext.Policy.NumberOfPolicyIds = 1; - callerAuthContext.Policy.PolicyIds = &policyId; - - CSSM_TP_HANDLE tp_handle = crypto::GetSharedTPHandle(); - CSSM_DATA refId; - memset(&refId, 0, sizeof(refId)); - sint32 estTime; - CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tp_handle, NULL, - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, &reqSet, &callerAuthContext, - &estTime, &refId); - if (crtn) { - DLOG(ERROR) << "CSSM_TP_SubmitCredRequest failed " << crtn; - return NULL; - } - - CSSM_BOOL confirmRequired; - CSSM_TP_RESULT_SET* resultSet = NULL; - crtn = CSSM_TP_RetrieveCredResult(tp_handle, &refId, NULL, &estTime, - &confirmRequired, &resultSet); - ScopedEncodedCertResults scopedResults(resultSet); - crypto::CSSMFree(refId.Data); - if (crtn) { - DLOG(ERROR) << "CSSM_TP_RetrieveCredResult failed " << crtn; - return NULL; - } - - if (confirmRequired) { - // Potential leak here of resultSet. |confirmRequired| should never be - // true. - DLOG(ERROR) << "CSSM_TP_RetrieveCredResult required confirmation"; - return NULL; - } - - if (resultSet->NumberOfResults != 1) { - DLOG(ERROR) << "Unexpected number of results: " - << resultSet->NumberOfResults; - return NULL; - } - - CSSM_ENCODED_CERT* encCert = - reinterpret_cast<CSSM_ENCODED_CERT*>(resultSet->Results); - ScopedCFTypeRef<SecCertificateRef> scoped_cert; - SecCertificateRef certificate_ref = NULL; - OSStatus os_status = - SecCertificateCreateFromData(&encCert->CertBlob, encCert->CertType, - encCert->CertEncoding, &certificate_ref); - if (os_status != 0) { - OSSTATUS_DLOG(ERROR, os_status) << "SecCertificateCreateFromData failed"; - return NULL; - } - scoped_cert.reset(certificate_ref); - - return CreateFromHandle(scoped_cert, X509Certificate::OSCertHandles()); -} - -void X509Certificate::GetSubjectAltName( - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const { - if (dns_names) - dns_names->clear(); - if (ip_addrs) - ip_addrs->clear(); - - x509_util::CSSMCachedCertificate cached_cert; - OSStatus status = cached_cert.Init(cert_handle_); - if (status) - return; - x509_util::CSSMFieldValue subject_alt_name; - status = cached_cert.GetField(&CSSMOID_SubjectAltName, &subject_alt_name); - if (status || !subject_alt_name.field()) - return; - const CSSM_X509_EXTENSION* cssm_ext = - subject_alt_name.GetAs<CSSM_X509_EXTENSION>(); - if (!cssm_ext || !cssm_ext->value.parsedValue) - return; - const CE_GeneralNames* alt_name = - reinterpret_cast<const CE_GeneralNames*>(cssm_ext->value.parsedValue); - - for (size_t name = 0; name < alt_name->numNames; ++name) { - const CE_GeneralName& name_struct = alt_name->generalName[name]; - const CSSM_DATA& name_data = name_struct.name; - // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs - // respectively, both of which can be byte copied from - // CSSM_DATA::data into the appropriate output vector. - if (dns_names && name_struct.nameType == GNT_DNSName) { - dns_names->push_back(std::string( - reinterpret_cast<const char*>(name_data.Data), - name_data.Length)); - } else if (ip_addrs && name_struct.nameType == GNT_IPAddress) { - ip_addrs->push_back(std::string( - reinterpret_cast<const char*>(name_data.Data), - name_data.Length)); - } - } -} - -// static -bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, - std::string* encoded) { - CSSM_DATA der_data; - if (SecCertificateGetData(cert_handle, &der_data) != noErr) - return false; - encoded->assign(reinterpret_cast<char*>(der_data.Data), - der_data.Length); - return true; -} - -// static -bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, - X509Certificate::OSCertHandle b) { - DCHECK(a && b); - if (a == b) - return true; - if (CFEqual(a, b)) - return true; - CSSM_DATA a_data, b_data; - return SecCertificateGetData(a, &a_data) == noErr && - SecCertificateGetData(b, &b_data) == noErr && - a_data.Length == b_data.Length && - memcmp(a_data.Data, b_data.Data, a_data.Length) == 0; -} - -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - CSSM_DATA cert_data; - cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); - cert_data.Length = length; - - OSCertHandle cert_handle = NULL; - OSStatus status = SecCertificateCreateFromData(&cert_data, - CSSM_CERT_X_509v3, - CSSM_CERT_ENCODING_DER, - &cert_handle); - if (status != noErr) - return NULL; - if (!IsValidOSCertHandle(cert_handle)) { - CFRelease(cert_handle); - return NULL; - } - return cert_handle; -} - -// static -X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( - const char* data, int length, Format format) { - OSCertHandles results; - - switch (format) { - case FORMAT_SINGLE_CERTIFICATE: { - OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); - if (handle) - results.push_back(handle); - break; - } - case FORMAT_PKCS7: - AddCertificatesFromBytes(data, length, kSecFormatPKCS7, &results); - break; - default: - NOTREACHED() << "Certificate format " << format << " unimplemented"; - break; - } - - return results; -} - -// static -X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( - OSCertHandle handle) { - if (!handle) - return NULL; - return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - CFRelease(cert_handle); -} - -// static -SHA1HashValue X509Certificate::CalculateFingerprint( - OSCertHandle cert) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - CSSM_DATA cert_data; - OSStatus status = SecCertificateGetData(cert, &cert_data); - if (status) - return sha1; - - DCHECK(cert_data.Data); - DCHECK_NE(cert_data.Length, 0U); - - CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); - - return sha1; -} - -// static -SHA1HashValue X509Certificate::CalculateCAFingerprint( - const OSCertHandles& intermediates) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - // The CC_SHA(3cc) man page says all CC_SHA1_xxx routines return 1, so - // we don't check their return values. - CC_SHA1_CTX sha1_ctx; - CC_SHA1_Init(&sha1_ctx); - CSSM_DATA cert_data; - for (size_t i = 0; i < intermediates.size(); ++i) { - OSStatus status = SecCertificateGetData(intermediates[i], &cert_data); - if (status) - return sha1; - CC_SHA1_Update(&sha1_ctx, cert_data.Data, cert_data.Length); - } - CC_SHA1_Final(sha1.data, &sha1_ctx); - - return sha1; -} - -bool X509Certificate::SupportsSSLClientAuth() const { - x509_util::CSSMCachedCertificate cached_cert; - OSStatus status = cached_cert.Init(cert_handle_); - if (status) - return false; - - // RFC5280 says to take the intersection of the two extensions. - // - // Our underlying crypto libraries don't expose - // ClientCertificateType, so for now we will not support fixed - // Diffie-Hellman mechanisms. For rsa_sign, we need the - // digitalSignature bit. - // - // In particular, if a key has the nonRepudiation bit and not the - // digitalSignature one, we will not offer it to the user. - x509_util::CSSMFieldValue key_usage; - status = cached_cert.GetField(&CSSMOID_KeyUsage, &key_usage); - if (status == CSSM_OK && key_usage.field()) { - const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>(); - const CE_KeyUsage* key_usage_value = - reinterpret_cast<const CE_KeyUsage*>(ext->value.parsedValue); - if (!((*key_usage_value) & CE_KU_DigitalSignature)) - return false; - } - - status = cached_cert.GetField(&CSSMOID_ExtendedKeyUsage, &key_usage); - if (status == CSSM_OK && key_usage.field()) { - const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>(); - const CE_ExtendedKeyUsage* ext_key_usage = - reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue); - if (!ExtendedKeyUsageAllows(ext_key_usage, &CSSMOID_ClientAuth)) - return false; - } - return true; -} - -CFArrayRef X509Certificate::CreateClientCertificateChain() const { - // Initialize the result array with just the IdentityRef of the receiver: - SecIdentityRef identity; - OSStatus result; - { - base::AutoLock lock(crypto::GetMacSecurityServicesLock()); - result = SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity); - } - if (result) { - OSSTATUS_LOG(ERROR, result) << "SecIdentityCreateWithCertificate error"; - return NULL; - } - ScopedCFTypeRef<CFMutableArrayRef> chain( - CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); - CFArrayAppendValue(chain, identity); - - CFArrayRef cert_chain = NULL; - result = CopyCertChain(cert_handle_, &cert_chain); - ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain); - if (result) { - OSSTATUS_LOG(ERROR, result) << "CreateIdentityCertificateChain error"; - return chain.release(); - } - - // Append the intermediate certs from SecTrust to the result array: - if (cert_chain) { - int chain_count = CFArrayGetCount(cert_chain); - if (chain_count > 1) { - CFArrayAppendArray(chain, - cert_chain, - CFRangeMake(1, chain_count - 1)); - } - } - - return chain.release(); -} - -CFArrayRef X509Certificate::CreateOSCertChainForCert() const { - CFMutableArrayRef cert_list = - CFArrayCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeArrayCallBacks); - if (!cert_list) - return NULL; - - CFArrayAppendValue(cert_list, os_cert_handle()); - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) - CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); - - return cert_list; -} - -// static -X509Certificate::OSCertHandle -X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { - const char* data; - int length; - if (!pickle_iter->ReadData(&data, &length)) - return NULL; - - return CreateOSCertHandleFromBytes(data, length); -} - -// static -bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, - Pickle* pickle) { - CSSM_DATA cert_data; - OSStatus status = SecCertificateGetData(cert_handle, &cert_data); - if (status) - return false; - - return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), - cert_data.Length); -} - -// static -void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type) { - // Since we might fail, set the output parameters to default values first. - *type = kPublicKeyTypeUnknown; - *size_bits = 0; - - SecKeyRef key; - OSStatus status = SecCertificateCopyPublicKey(cert_handle, &key); - if (status) { - NOTREACHED() << "SecCertificateCopyPublicKey failed: " << status; - return; - } - ScopedCFTypeRef<SecKeyRef> scoped_key(key); - - const CSSM_KEY* cssm_key; - status = SecKeyGetCSSMKey(key, &cssm_key); - if (status) { - NOTREACHED() << "SecKeyGetCSSMKey failed: " << status; - return; - } - - *size_bits = cssm_key->KeyHeader.LogicalKeySizeInBits; - - switch (cssm_key->KeyHeader.AlgorithmId) { - case CSSM_ALGID_RSA: - *type = kPublicKeyTypeRSA; - break; - case CSSM_ALGID_DSA: - *type = kPublicKeyTypeDSA; - break; - case CSSM_ALGID_ECDSA: - *type = kPublicKeyTypeECDSA; - break; - case CSSM_ALGID_DH: - *type = kPublicKeyTypeDH; - break; - default: - *type = kPublicKeyTypeUnknown; - *size_bits = 0; - break; - } -} - -} // namespace net diff --git a/net/base/x509_certificate_net_log_param.cc b/net/base/x509_certificate_net_log_param.cc deleted file mode 100644 index e3a7db9..0000000 --- a/net/base/x509_certificate_net_log_param.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate_net_log_param.h" - -#include <string> -#include <vector> - -#include "base/values.h" -#include "net/base/x509_certificate.h" - -namespace net { - -base::Value* NetLogX509CertificateCallback(const X509Certificate* certificate, - NetLog::LogLevel log_level) { - base::DictionaryValue* dict = new base::DictionaryValue(); - base::ListValue* certs = new base::ListValue(); - std::vector<std::string> encoded_chain; - certificate->GetPEMEncodedChain(&encoded_chain); - for (size_t i = 0; i < encoded_chain.size(); ++i) - certs->Append(new base::StringValue(encoded_chain[i])); - dict->Set("certificates", certs); - return dict; -} - -} // namespace net diff --git a/net/base/x509_certificate_net_log_param.h b/net/base/x509_certificate_net_log_param.h deleted file mode 100644 index 36ae8f5..0000000 --- a/net/base/x509_certificate_net_log_param.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_CERT_NET_LOG_PARAM_H_ -#define NET_BASE_X509_CERT_NET_LOG_PARAM_H_ - -#include "net/base/net_log.h" - -namespace net { - -class X509Certificate; - -// Creates NetLog parameter to describe an X509Certificate. -base::Value* NetLogX509CertificateCallback( - const X509Certificate* certificate, - NetLog::LogLevel log_level); - -} // namespace net - -#endif // NET_BASE_X509_CERT_NET_LOG_PARAM_H_ diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc deleted file mode 100644 index 2fe571d..0000000 --- a/net/base/x509_certificate_nss.cc +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <cert.h> -#include <cryptohi.h> -#include <keyhi.h> -#include <nss.h> -#include <pk11pub.h> -#include <prtime.h> -#include <seccomon.h> -#include <secder.h> -#include <sechash.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/pickle.h" -#include "base/time.h" -#include "crypto/nss_util.h" -#include "crypto/rsa_private_key.h" -#include "crypto/scoped_nss_types.h" -#include "net/base/x509_util_nss.h" - -namespace net { - -void X509Certificate::Initialize() { - x509_util::ParsePrincipal(&cert_handle_->subject, &subject_); - x509_util::ParsePrincipal(&cert_handle_->issuer, &issuer_); - - x509_util::ParseDate(&cert_handle_->validity.notBefore, &valid_start_); - x509_util::ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); - - fingerprint_ = CalculateFingerprint(cert_handle_); - ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); - - serial_number_ = x509_util::ParseSerialNumber(cert_handle_); -} - -// static -X509Certificate* X509Certificate::CreateFromBytesWithNickname( - const char* data, - int length, - const char* nickname) { - OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data, - length, - nickname); - if (!cert_handle) - return NULL; - - X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); - FreeOSCertHandle(cert_handle); - - if (nickname) - cert->default_nickname_ = nickname; - - return cert; -} - -std::string X509Certificate::GetDefaultNickname(CertType type) const { - if (!default_nickname_.empty()) - return default_nickname_; - - std::string result; - if (type == USER_CERT && cert_handle_->slot) { - // Find the private key for this certificate and see if it has a - // nickname. If there is a private key, and it has a nickname, then - // we return that nickname. - SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert( - cert_handle_->slot, - cert_handle_, - NULL); // wincx - if (private_key) { - char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); - if (private_key_nickname) { - result = private_key_nickname; - PORT_Free(private_key_nickname); - SECKEY_DestroyPrivateKey(private_key); - return result; - } - SECKEY_DestroyPrivateKey(private_key); - } - } - - switch (type) { - case CA_CERT: { - char* nickname = CERT_MakeCANickname(cert_handle_); - result = nickname; - PORT_Free(nickname); - break; - } - case USER_CERT: { - // Create a nickname for a user certificate. - // We use the scheme used by Firefox: - // --> <subject's common name>'s <issuer's common name> ID. - // TODO(gspencer): internationalize this: it's wrong to - // hard code English. - - std::string username, ca_name; - char* temp_username = CERT_GetCommonName( - &cert_handle_->subject); - char* temp_ca_name = CERT_GetCommonName(&cert_handle_->issuer); - if (temp_username) { - username = temp_username; - PORT_Free(temp_username); - } - if (temp_ca_name) { - ca_name = temp_ca_name; - PORT_Free(temp_ca_name); - } - result = username + "'s " + ca_name + " ID"; - break; - } - case SERVER_CERT: - result = subject_.GetDisplayName(); - break; - case UNKNOWN_CERT: - default: - break; - } - return result; -} - -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - DCHECK(key); - base::Time not_valid_before = base::Time::Now(); - base::Time not_valid_after = not_valid_before + valid_duration; - CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(), - key->key(), - subject, - serial_number, - not_valid_before, - not_valid_after); - if (!cert) - return NULL; - - X509Certificate* x509_cert = X509Certificate::CreateFromHandle( - cert, X509Certificate::OSCertHandles()); - CERT_DestroyCertificate(cert); - return x509_cert; -} - -void X509Certificate::GetSubjectAltName( - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const { - x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs); -} - -bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { - return CERT_VerifyCertName(cert_handle_, hostname.c_str()) == SECSuccess; -} - -bool X509Certificate::IsIssuedByEncoded( - const std::vector<std::string>& valid_issuers) { - // Get certificate chain as scoped list of CERTCertificate objects. - std::vector<CERTCertificate*> cert_chain; - cert_chain.push_back(cert_handle_); - for (size_t n = 0; n < intermediate_ca_certs_.size(); ++n) { - cert_chain.push_back(intermediate_ca_certs_[n]); - } - // Convert encoded issuers to scoped CERTName* list. - std::vector<CERTName*> issuers; - crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - if (!x509_util::GetIssuersFromEncodedList(valid_issuers, - arena.get(), - &issuers)) { - return false; - } - return x509_util::IsCertificateIssuedBy(cert_chain, issuers); -} - -// static -bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, - std::string* encoded) { - if (!cert_handle->derCert.len) - return false; - encoded->assign(reinterpret_cast<char*>(cert_handle->derCert.data), - cert_handle->derCert.len); - return true; -} - -// static -bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, - X509Certificate::OSCertHandle b) { - DCHECK(a && b); - if (a == b) - return true; - return a->derCert.len == b->derCert.len && - memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0; -} - -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - return CreateOSCertHandleFromBytesWithNickname(data, length, NULL); -} - -// static -X509Certificate::OSCertHandle -X509Certificate::CreateOSCertHandleFromBytesWithNickname( - const char* data, - int length, - const char* nickname) { - if (length < 0) - return NULL; - - crypto::EnsureNSSInit(); - - if (!NSS_IsInitialized()) - return NULL; - - SECItem der_cert; - der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); - der_cert.len = length; - der_cert.type = siDERCertBuffer; - - // Parse into a certificate structure. - return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, - const_cast<char*>(nickname), - PR_FALSE, PR_TRUE); -} - -// static -X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( - const char* data, - int length, - Format format) { - return x509_util::CreateOSCertHandlesFromBytes(data, length, format); -} - -// static -X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( - OSCertHandle cert_handle) { - return CERT_DupCertificate(cert_handle); -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - CERT_DestroyCertificate(cert_handle); -} - -// static -SHA1HashValue X509Certificate::CalculateFingerprint( - OSCertHandle cert) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - DCHECK(NULL != cert->derCert.data); - DCHECK_NE(0U, cert->derCert.len); - - SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data, - cert->derCert.data, cert->derCert.len); - DCHECK_EQ(SECSuccess, rv); - - return sha1; -} - -// static -SHA1HashValue X509Certificate::CalculateCAFingerprint( - const OSCertHandles& intermediates) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - HASHContext* sha1_ctx = HASH_Create(HASH_AlgSHA1); - if (!sha1_ctx) - return sha1; - HASH_Begin(sha1_ctx); - for (size_t i = 0; i < intermediates.size(); ++i) { - CERTCertificate* ca_cert = intermediates[i]; - HASH_Update(sha1_ctx, ca_cert->derCert.data, ca_cert->derCert.len); - } - unsigned int result_len; - HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx)); - HASH_Destroy(sha1_ctx); - - return sha1; -} - -// static -X509Certificate::OSCertHandle -X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { - return x509_util::ReadOSCertHandleFromPickle(pickle_iter); -} - -// static -bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, - Pickle* pickle) { - return pickle->WriteData( - reinterpret_cast<const char*>(cert_handle->derCert.data), - cert_handle->derCert.len); -} - -// static -void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type) { - x509_util::GetPublicKeyInfo(cert_handle, size_bits, type); -} - -} // namespace net diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc deleted file mode 100644 index 13f645a..0000000 --- a/net/base/x509_certificate_openssl.cc +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <openssl/asn1.h> -#include <openssl/crypto.h> -#include <openssl/obj_mac.h> -#include <openssl/pem.h> -#include <openssl/pkcs7.h> -#include <openssl/sha.h> -#include <openssl/ssl.h> -#include <openssl/x509v3.h> - -#include "base/memory/singleton.h" -#include "base/pickle.h" -#include "base/sha1.h" -#include "base/string_number_conversions.h" -#include "base/string_util.h" -#include "crypto/openssl_util.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" -#include "net/base/x509_util_openssl.h" - -#if defined(OS_ANDROID) -#include "base/logging.h" -#include "net/android/network_library.h" -#endif - -namespace net { - -namespace { - -void CreateOSCertHandlesFromPKCS7Bytes( - const char* data, int length, - X509Certificate::OSCertHandles* handles) { - crypto::EnsureOpenSSLInit(); - const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data); - crypto::ScopedOpenSSL<PKCS7, PKCS7_free> pkcs7_cert( - d2i_PKCS7(NULL, &der_data, length)); - if (!pkcs7_cert.get()) - return; - - STACK_OF(X509)* certs = NULL; - int nid = OBJ_obj2nid(pkcs7_cert.get()->type); - if (nid == NID_pkcs7_signed) { - certs = pkcs7_cert.get()->d.sign->cert; - } else if (nid == NID_pkcs7_signedAndEnveloped) { - certs = pkcs7_cert.get()->d.signed_and_enveloped->cert; - } - - if (certs) { - for (int i = 0; i < sk_X509_num(certs); ++i) { - X509* x509_cert = - X509Certificate::DupOSCertHandle(sk_X509_value(certs, i)); - handles->push_back(x509_cert); - } - } -} - -void ParsePrincipalValues(X509_NAME* name, - int nid, - std::vector<std::string>* fields) { - for (int index = -1; - (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { - std::string field; - if (!x509_util::ParsePrincipalValueByIndex(name, index, &field)) - break; - fields->push_back(field); - } -} - -void ParsePrincipal(X509Certificate::OSCertHandle cert, - X509_NAME* x509_name, - CertPrincipal* principal) { - if (!x509_name) - return; - - ParsePrincipalValues(x509_name, NID_streetAddress, - &principal->street_addresses); - ParsePrincipalValues(x509_name, NID_organizationName, - &principal->organization_names); - ParsePrincipalValues(x509_name, NID_organizationalUnitName, - &principal->organization_unit_names); - ParsePrincipalValues(x509_name, NID_domainComponent, - &principal->domain_components); - - x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, - &principal->common_name); - x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, - &principal->locality_name); - x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, - &principal->state_or_province_name); - x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, - &principal->country_name); -} - -void ParseSubjectAltName(X509Certificate::OSCertHandle cert, - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addresses) { - DCHECK(dns_names || ip_addresses); - int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); - X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); - if (!alt_name_ext) - return; - - crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names( - reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); - if (!alt_names.get()) - return; - - for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { - const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); - if (name->type == GEN_DNS && dns_names) { - const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); - if (!dns_name) - continue; - int dns_name_len = ASN1_STRING_length(name->d.dNSName); - dns_names->push_back( - std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); - } else if (name->type == GEN_IPADD && ip_addresses) { - const unsigned char* ip_addr = name->d.iPAddress->data; - if (!ip_addr) - continue; - int ip_addr_len = name->d.iPAddress->length; - if (ip_addr_len != static_cast<int>(kIPv4AddressSize) && - ip_addr_len != static_cast<int>(kIPv6AddressSize)) { - // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress - // to have 4 or 16 bytes, whereas in a name constraint it includes a - // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. - LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; - continue; - } - ip_addresses->push_back( - std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); - } - } -} - -struct DERCache { - unsigned char* data; - int data_length; -}; - -void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, - long argl, void* argp) { - DERCache* der_cache = static_cast<DERCache*>(ptr); - if (!der_cache) - return; - if (der_cache->data) - OPENSSL_free(der_cache->data); - OPENSSL_free(der_cache); -} - -class X509InitSingleton { - public: - static X509InitSingleton* GetInstance() { - // We allow the X509 store to leak, because it is used from a non-joinable - // worker that is not stopped on shutdown, hence may still be using - // OpenSSL library after the AtExit runner has completed. - return Singleton<X509InitSingleton, - LeakySingletonTraits<X509InitSingleton> >::get(); - } - int der_cache_ex_index() const { return der_cache_ex_index_; } - X509_STORE* store() const { return store_.get(); } - - void ResetCertStore() { - store_.reset(X509_STORE_new()); - DCHECK(store_.get()); - X509_STORE_set_default_paths(store_.get()); - // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). - } - - private: - friend struct DefaultSingletonTraits<X509InitSingleton>; - X509InitSingleton() { - crypto::EnsureOpenSSLInit(); - der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free); - DCHECK_NE(der_cache_ex_index_, -1); - ResetCertStore(); - } - - int der_cache_ex_index_; - crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_; - - DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); -}; - -// Takes ownership of |data| (which must have been allocated by OpenSSL). -DERCache* SetDERCache(X509Certificate::OSCertHandle cert, - int x509_der_cache_index, - unsigned char* data, - int data_length) { - DERCache* internal_cache = static_cast<DERCache*>( - OPENSSL_malloc(sizeof(*internal_cache))); - if (!internal_cache) { - // We took ownership of |data|, so we must free if we can't add it to - // |cert|. - OPENSSL_free(data); - return NULL; - } - - internal_cache->data = data; - internal_cache->data_length = data_length; - X509_set_ex_data(cert, x509_der_cache_index, internal_cache); - return internal_cache; -} - -// Returns true if |der_cache| points to valid data, false otherwise. -// (note: the DER-encoded data in |der_cache| is owned by |cert|, callers should -// not free it). -bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert, - DERCache* der_cache) { - int x509_der_cache_index = - X509InitSingleton::GetInstance()->der_cache_ex_index(); - - // Re-encoding the DER data via i2d_X509 is an expensive operation, but it's - // necessary for comparing two certificates. We re-encode at most once per - // certificate and cache the data within the X509 cert using X509_set_ex_data. - DERCache* internal_cache = static_cast<DERCache*>( - X509_get_ex_data(cert, x509_der_cache_index)); - if (!internal_cache) { - unsigned char* data = NULL; - int data_length = i2d_X509(cert, &data); - if (data_length <= 0 || !data) - return false; - internal_cache = SetDERCache(cert, x509_der_cache_index, data, data_length); - if (!internal_cache) - return false; - } - *der_cache = *internal_cache; - return true; -} - -// 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 -X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( - OSCertHandle cert_handle) { - DCHECK(cert_handle); - // Using X509_dup causes the entire certificate to be reparsed. This - // conversion, besides being non-trivial, drops any associated - // application-specific data set by X509_set_ex_data. Using CRYPTO_add - // just bumps up the ref-count for the cert, without causing any allocations - // or deallocations. - CRYPTO_add(&cert_handle->references, 1, CRYPTO_LOCK_X509); - return cert_handle; -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - // Decrement the ref-count for the cert and, if all references are gone, - // free the memory and any application-specific data associated with the - // certificate. - X509_free(cert_handle); -} - -void X509Certificate::Initialize() { - crypto::EnsureOpenSSLInit(); - fingerprint_ = CalculateFingerprint(cert_handle_); - ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); - - ASN1_INTEGER* serial_num = X509_get_serialNumber(cert_handle_); - if (serial_num) { - // ASN1_INTEGERS represent the decoded number, in a format internal to - // OpenSSL. Most notably, this may have leading zeroes stripped off for - // numbers whose first byte is >= 0x80. Thus, it is necessary to - // re-encoded the integer back into DER, which is what the interface - // of X509Certificate exposes, to ensure callers get the proper (DER) - // value. - int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL); - unsigned char* buffer = reinterpret_cast<unsigned char*>( - WriteInto(&serial_number_, bytes_required + 1)); - int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer); - DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size()); - } - - ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); - ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); - x509_util::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); - x509_util::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); -} - -// static -void X509Certificate::ResetCertStore() { - X509InitSingleton::GetInstance()->ResetCertStore(); -} - -// static -SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { - SHA1HashValue sha1; - unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data)); - int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size); - CHECK(ret); - CHECK_EQ(sha1_size, sizeof(sha1.data)); - return sha1; -} - -// static -SHA1HashValue X509Certificate::CalculateCAFingerprint( - const OSCertHandles& intermediates) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - SHA_CTX sha1_ctx; - SHA1_Init(&sha1_ctx); - DERCache der_cache; - for (size_t i = 0; i < intermediates.size(); ++i) { - if (!GetDERAndCacheIfNeeded(intermediates[i], &der_cache)) - return sha1; - SHA1_Update(&sha1_ctx, der_cache.data, der_cache.data_length); - } - SHA1_Final(sha1.data, &sha1_ctx); - - return sha1; -} - -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - if (length < 0) - return NULL; - crypto::EnsureOpenSSLInit(); - const unsigned char* d2i_data = - reinterpret_cast<const unsigned char*>(data); - // Don't cache this data via SetDERCache as this wire format may be not be - // identical from the i2d_X509 roundtrip. - X509* cert = d2i_X509(NULL, &d2i_data, length); - return cert; -} - -// static -X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( - const char* data, int length, Format format) { - OSCertHandles results; - if (length < 0) - return results; - - switch (format) { - case FORMAT_SINGLE_CERTIFICATE: { - OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); - if (handle) - results.push_back(handle); - break; - } - case FORMAT_PKCS7: { - CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); - break; - } - default: { - NOTREACHED() << "Certificate format " << format << " unimplemented"; - break; - } - } - - return results; -} - -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - // TODO(port): Implement. See http://crbug.com/91512. - NOTIMPLEMENTED(); - return NULL; -} - -void X509Certificate::GetSubjectAltName( - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const { - if (dns_names) - dns_names->clear(); - if (ip_addrs) - ip_addrs->clear(); - - ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); -} - -// static -X509_STORE* X509Certificate::cert_store() { - return X509InitSingleton::GetInstance()->store(); -} - -// static -bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, - std::string* encoded) { - DERCache der_cache; - if (!GetDERAndCacheIfNeeded(cert_handle, &der_cache)) - return false; - encoded->assign(reinterpret_cast<const char*>(der_cache.data), - der_cache.data_length); - return true; -} - -// static -bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, - X509Certificate::OSCertHandle b) { - DCHECK(a && b); - if (a == b) - return true; - - // X509_cmp only checks the fingerprint, but we want to compare the whole - // DER data. Encoding it from OSCertHandle is an expensive operation, so we - // cache the DER (if not already cached via X509_set_ex_data). - DERCache der_cache_a, der_cache_b; - - return GetDERAndCacheIfNeeded(a, &der_cache_a) && - GetDERAndCacheIfNeeded(b, &der_cache_b) && - der_cache_a.data_length == der_cache_b.data_length && - memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; -} - -// static -X509Certificate::OSCertHandle -X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { - const char* data; - int length; - if (!pickle_iter->ReadData(&data, &length)) - return NULL; - - return CreateOSCertHandleFromBytes(data, length); -} - -// static -bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, - Pickle* pickle) { - DERCache der_cache; - if (!GetDERAndCacheIfNeeded(cert_handle, &der_cache)) - return false; - - return pickle->WriteData( - reinterpret_cast<const char*>(der_cache.data), - der_cache.data_length); -} - -// static -void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type) { - *type = kPublicKeyTypeUnknown; - *size_bits = 0; - - crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> 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) { - case EVP_PKEY_RSA: - *type = kPublicKeyTypeRSA; - *size_bits = EVP_PKEY_size(key) * 8; - break; - case EVP_PKEY_DSA: - *type = kPublicKeyTypeDSA; - *size_bits = EVP_PKEY_size(key) * 8; - break; - case EVP_PKEY_EC: - *type = kPublicKeyTypeECDSA; - *size_bits = EVP_PKEY_size(key); - break; - case EVP_PKEY_DH: - *type = kPublicKeyTypeDH; - *size_bits = EVP_PKEY_size(key) * 8; - break; - } -} - -bool X509Certificate::IsIssuedByEncoded( - const std::vector<std::string>& valid_issuers) { - if (valid_issuers.empty()) - return false; - - // 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()); - if (!issuer_names.get()) - return false; - - for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); - it != valid_issuers.end(); ++it) { - const unsigned char* p = - reinterpret_cast<const unsigned char*>(it->data()); - long len = static_cast<long>(it->length()); - X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); - if (ca_name == NULL) - return false; - sk_X509_NAME_push(issuer_names.get(), ca_name); - } - - // Create a temporary list of X509_NAME objects corresponding - // to the certificate chain. It doesn't own the object it points to. - std::vector<X509_NAME*> cert_names; - X509_NAME* issuer = X509_get_issuer_name(cert_handle_); - if (issuer == NULL) - return false; - - cert_names.push_back(issuer); - for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); - it != intermediate_ca_certs_.end(); ++it) { - issuer = X509_get_issuer_name(*it); - if (issuer == NULL) - return false; - cert_names.push_back(issuer); - } - - // and 'cert_names'. - for (size_t n = 0; n < cert_names.size(); ++n) { - for (int m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { - X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); - if (X509_NAME_cmp(issuer, cert_names[n]) == 0) { - return true; - } - } - } - - return false; -} - -} // namespace net diff --git a/net/base/x509_certificate_unittest.cc b/net/base/x509_certificate_unittest.cc deleted file mode 100644 index f66d6f0..0000000 --- a/net/base/x509_certificate_unittest.cc +++ /dev/null @@ -1,1170 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include "base/basictypes.h" -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/pickle.h" -#include "base/sha1.h" -#include "base/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "crypto/rsa_private_key.h" -#include "net/base/asn1_util.h" -#include "net/base/cert_test_util.h" -#include "net/base/net_errors.h" -#include "net/base/test_certificate_data.h" -#include "net/base/test_data_directory.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(USE_NSS) -#include <cert.h> -#endif - -using base::HexEncode; -using base::Time; - -namespace net { - -// Certificates for test data. They're obtained with: -// -// $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null -// $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der -// -// For fingerprint -// $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der - -// For valid_start, valid_expiry -// $ openssl x509 -inform DER -text -noout < /tmp/host.der | -// grep -A 2 Validity -// $ date +%s -d '<date str>' - -// Google's cert. -uint8 google_fingerprint[] = { - 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8, - 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c -}; - -// webkit.org's cert. -uint8 webkit_fingerprint[] = { - 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8, - 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2 -}; - -// thawte.com's cert (it's EV-licious!). -uint8 thawte_fingerprint[] = { - 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6, - 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37 -}; - -// A certificate for https://www.unosoft.hu/, whose AIA extension contains -// an LDAP URL without a host name. -uint8 unosoft_hu_fingerprint[] = { - 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, - 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 -}; - -// The fingerprint of the Google certificate used in the parsing tests, -// which is newer than the one included in the x509_certificate_data.h -uint8 google_parse_fingerprint[] = { - 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a, - 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2 -}; - -// The fingerprint for the Thawte SGC certificate -uint8 thawte_parse_fingerprint[] = { - 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f, - 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02 -}; - -// Dec 18 00:00:00 2009 GMT -const double kGoogleParseValidFrom = 1261094400; -// Dec 18 23:59:59 2011 GMT -const double kGoogleParseValidTo = 1324252799; - -struct CertificateFormatTestData { - const char* file_name; - X509Certificate::Format format; - uint8* chain_fingerprints[3]; -}; - -const CertificateFormatTestData FormatTestData[] = { - // DER Parsing - single certificate, DER encoded - { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE, - { google_parse_fingerprint, - NULL, } }, - // DER parsing - single certificate, PEM encoded - { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE, - { google_parse_fingerprint, - NULL, } }, - // PEM parsing - single certificate, PEM encoded with a PEB of - // "CERTIFICATE" - { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, - { google_parse_fingerprint, - NULL, } }, - // PEM parsing - sequence of certificates, PEM encoded with a PEB of - // "CERTIFICATE" - { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER - // encoding - { "google.binary.p7b", X509Certificate::FORMAT_PKCS7, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM - // encoded with a PEM PEB of "CERTIFICATE" - { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM - // encoded with a PEM PEB of "PKCS7" - { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - // All of the above, this time using auto-detection - { "google.single.der", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - NULL, } }, - { "google.single.pem", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - NULL, } }, - { "google.chain.pem", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - { "google.binary.p7b", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, - { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO, - { google_parse_fingerprint, - thawte_parse_fingerprint, - NULL, } }, -}; - -void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert, - uint8* expected_fingerprint, - double valid_from, double valid_to) { - ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); - - const CertPrincipal& subject = google_cert->subject(); - EXPECT_EQ("www.google.com", subject.common_name); - EXPECT_EQ("Mountain View", subject.locality_name); - EXPECT_EQ("California", subject.state_or_province_name); - EXPECT_EQ("US", subject.country_name); - EXPECT_EQ(0U, subject.street_addresses.size()); - ASSERT_EQ(1U, subject.organization_names.size()); - EXPECT_EQ("Google Inc", subject.organization_names[0]); - EXPECT_EQ(0U, subject.organization_unit_names.size()); - EXPECT_EQ(0U, subject.domain_components.size()); - - const CertPrincipal& issuer = google_cert->issuer(); - EXPECT_EQ("Thawte SGC CA", issuer.common_name); - EXPECT_EQ("", issuer.locality_name); - EXPECT_EQ("", issuer.state_or_province_name); - EXPECT_EQ("ZA", issuer.country_name); - EXPECT_EQ(0U, issuer.street_addresses.size()); - ASSERT_EQ(1U, issuer.organization_names.size()); - EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]); - EXPECT_EQ(0U, issuer.organization_unit_names.size()); - EXPECT_EQ(0U, issuer.domain_components.size()); - - // Use DoubleT because its epoch is the same on all platforms - const Time& valid_start = google_cert->valid_start(); - EXPECT_EQ(valid_from, valid_start.ToDoubleT()); - - const Time& valid_expiry = google_cert->valid_expiry(); - EXPECT_EQ(valid_to, valid_expiry.ToDoubleT()); - - const SHA1HashValue& fingerprint = google_cert->fingerprint(); - for (size_t i = 0; i < 20; ++i) - EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]); - - std::vector<std::string> dns_names; - google_cert->GetDNSNames(&dns_names); - ASSERT_EQ(1U, dns_names.size()); - EXPECT_EQ("www.google.com", dns_names[0]); -} - -TEST(X509CertificateTest, GoogleCertParsing) { - scoped_refptr<X509Certificate> google_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der))); - - CheckGoogleCert(google_cert, google_fingerprint, - 1238192407, // Mar 27 22:20:07 2009 GMT - 1269728407); // Mar 27 22:20:07 2010 GMT -} - -TEST(X509CertificateTest, WebkitCertParsing) { - scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); - - ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert); - - const CertPrincipal& subject = webkit_cert->subject(); - EXPECT_EQ("Cupertino", subject.locality_name); - EXPECT_EQ("California", subject.state_or_province_name); - EXPECT_EQ("US", subject.country_name); - EXPECT_EQ(0U, subject.street_addresses.size()); - ASSERT_EQ(1U, subject.organization_names.size()); - EXPECT_EQ("Apple Inc.", subject.organization_names[0]); - ASSERT_EQ(1U, subject.organization_unit_names.size()); - EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]); - EXPECT_EQ(0U, subject.domain_components.size()); - - const CertPrincipal& issuer = webkit_cert->issuer(); - EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name); - EXPECT_EQ("Scottsdale", issuer.locality_name); - EXPECT_EQ("Arizona", issuer.state_or_province_name); - EXPECT_EQ("US", issuer.country_name); - EXPECT_EQ(0U, issuer.street_addresses.size()); - ASSERT_EQ(1U, issuer.organization_names.size()); - EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]); - ASSERT_EQ(1U, issuer.organization_unit_names.size()); - EXPECT_EQ("http://certificates.godaddy.com/repository", - issuer.organization_unit_names[0]); - EXPECT_EQ(0U, issuer.domain_components.size()); - - // Use DoubleT because its epoch is the same on all platforms - const Time& valid_start = webkit_cert->valid_start(); - EXPECT_EQ(1205883319, valid_start.ToDoubleT()); // Mar 18 23:35:19 2008 GMT - - const Time& valid_expiry = webkit_cert->valid_expiry(); - EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT - - const SHA1HashValue& fingerprint = webkit_cert->fingerprint(); - for (size_t i = 0; i < 20; ++i) - EXPECT_EQ(webkit_fingerprint[i], fingerprint.data[i]); - - std::vector<std::string> dns_names; - webkit_cert->GetDNSNames(&dns_names); - ASSERT_EQ(2U, dns_names.size()); - EXPECT_EQ("*.webkit.org", dns_names[0]); - EXPECT_EQ("webkit.org", dns_names[1]); - - // Test that the wildcard cert matches properly. - EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org")); - EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org")); - EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org")); - EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com")); - EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com")); -} - -TEST(X509CertificateTest, ThawteCertParsing) { - scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der))); - - ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert); - - const CertPrincipal& subject = thawte_cert->subject(); - EXPECT_EQ("www.thawte.com", subject.common_name); - EXPECT_EQ("Mountain View", subject.locality_name); - EXPECT_EQ("California", subject.state_or_province_name); - EXPECT_EQ("US", subject.country_name); - EXPECT_EQ(0U, subject.street_addresses.size()); - ASSERT_EQ(1U, subject.organization_names.size()); - EXPECT_EQ("Thawte Inc", subject.organization_names[0]); - EXPECT_EQ(0U, subject.organization_unit_names.size()); - EXPECT_EQ(0U, subject.domain_components.size()); - - const CertPrincipal& issuer = thawte_cert->issuer(); - EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name); - EXPECT_EQ("", issuer.locality_name); - EXPECT_EQ("", issuer.state_or_province_name); - EXPECT_EQ("US", issuer.country_name); - EXPECT_EQ(0U, issuer.street_addresses.size()); - ASSERT_EQ(1U, issuer.organization_names.size()); - EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]); - ASSERT_EQ(1U, issuer.organization_unit_names.size()); - EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06", - issuer.organization_unit_names[0]); - EXPECT_EQ(0U, issuer.domain_components.size()); - - // Use DoubleT because its epoch is the same on all platforms - const Time& valid_start = thawte_cert->valid_start(); - EXPECT_EQ(1227052800, valid_start.ToDoubleT()); // Nov 19 00:00:00 2008 GMT - - const Time& valid_expiry = thawte_cert->valid_expiry(); - EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT - - const SHA1HashValue& fingerprint = thawte_cert->fingerprint(); - for (size_t i = 0; i < 20; ++i) - EXPECT_EQ(thawte_fingerprint[i], fingerprint.data[i]); - - std::vector<std::string> dns_names; - thawte_cert->GetDNSNames(&dns_names); - ASSERT_EQ(1U, dns_names.size()); - EXPECT_EQ("www.thawte.com", dns_names[0]); -} - -// Test that all desired AttributeAndValue pairs can be extracted when only -// a single RelativeDistinguishedName is present. "Normally" there is only -// one AVA per RDN, but some CAs place all AVAs within a single RDN. -// This is a regression test for http://crbug.com/101009 -TEST(X509CertificateTest, MultivalueRDN) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> multivalue_rdn_cert = - ImportCertFromFile(certs_dir, "multivalue_rdn.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), multivalue_rdn_cert); - - const CertPrincipal& subject = multivalue_rdn_cert->subject(); - EXPECT_EQ("Multivalue RDN Test", subject.common_name); - EXPECT_EQ("", subject.locality_name); - EXPECT_EQ("", subject.state_or_province_name); - EXPECT_EQ("US", subject.country_name); - EXPECT_EQ(0U, subject.street_addresses.size()); - ASSERT_EQ(1U, subject.organization_names.size()); - EXPECT_EQ("Chromium", subject.organization_names[0]); - ASSERT_EQ(1U, subject.organization_unit_names.size()); - EXPECT_EQ("Chromium net_unittests", subject.organization_unit_names[0]); - ASSERT_EQ(1U, subject.domain_components.size()); - EXPECT_EQ("Chromium", subject.domain_components[0]); -} - -// Test that characters which would normally be escaped in the string form, -// such as '=' or '"', are not escaped when parsed as individual components. -// This is a regression test for http://crbug.com/102839 -TEST(X509CertificateTest, UnescapedSpecialCharacters) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> unescaped_cert = - ImportCertFromFile(certs_dir, "unescaped.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), unescaped_cert); - - const CertPrincipal& subject = unescaped_cert->subject(); - EXPECT_EQ("127.0.0.1", subject.common_name); - EXPECT_EQ("Mountain View", subject.locality_name); - EXPECT_EQ("California", subject.state_or_province_name); - EXPECT_EQ("US", subject.country_name); - ASSERT_EQ(1U, subject.street_addresses.size()); - EXPECT_EQ("1600 Amphitheatre Parkway", subject.street_addresses[0]); - ASSERT_EQ(1U, subject.organization_names.size()); - EXPECT_EQ("Chromium = \"net_unittests\"", subject.organization_names[0]); - ASSERT_EQ(2U, subject.organization_unit_names.size()); - EXPECT_EQ("net_unittests", subject.organization_unit_names[0]); - EXPECT_EQ("Chromium", subject.organization_unit_names[1]); - EXPECT_EQ(0U, subject.domain_components.size()); -} - -TEST(X509CertificateTest, SerialNumbers) { - scoped_refptr<X509Certificate> google_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der))); - - static const uint8 google_serial[16] = { - 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9, - 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a, - }; - - ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size()); - EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial, - sizeof(google_serial)) == 0); - - // We also want to check a serial number where the first byte is >= 0x80 in - // case the underlying library tries to pad it. - scoped_refptr<X509Certificate> paypal_null_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(paypal_null_der), - sizeof(paypal_null_der))); - - static const uint8 paypal_null_serial[3] = {0x00, 0xf0, 0x9b}; - ASSERT_EQ(sizeof(paypal_null_serial), - paypal_null_cert->serial_number().size()); - EXPECT_TRUE(memcmp(paypal_null_cert->serial_number().data(), - paypal_null_serial, sizeof(paypal_null_serial)) == 0); -} - -TEST(X509CertificateTest, CAFingerprints) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "salesforce_com_test.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - scoped_refptr<X509Certificate> intermediate_cert1 = - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1); - - scoped_refptr<X509Certificate> intermediate_cert2 = - ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert1->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain1 = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - intermediates.clear(); - intermediates.push_back(intermediate_cert2->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain2 = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - // No intermediate CA certicates. - intermediates.clear(); - scoped_refptr<X509Certificate> cert_chain3 = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - static const uint8 cert_chain1_ca_fingerprint[20] = { - 0xc2, 0xf0, 0x08, 0x7d, 0x01, 0xe6, 0x86, 0x05, 0x3a, 0x4d, - 0x63, 0x3e, 0x7e, 0x70, 0xd4, 0xef, 0x65, 0xc2, 0xcc, 0x4f - }; - static const uint8 cert_chain2_ca_fingerprint[20] = { - 0xd5, 0x59, 0xa5, 0x86, 0x66, 0x9b, 0x08, 0xf4, 0x6a, 0x30, - 0xa1, 0x33, 0xf8, 0xa9, 0xed, 0x3d, 0x03, 0x8e, 0x2e, 0xa8 - }; - // The SHA-1 hash of nothing. - static const uint8 cert_chain3_ca_fingerprint[20] = { - 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, - 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 - }; - EXPECT_TRUE(memcmp(cert_chain1->ca_fingerprint().data, - cert_chain1_ca_fingerprint, 20) == 0); - EXPECT_TRUE(memcmp(cert_chain2->ca_fingerprint().data, - cert_chain2_ca_fingerprint, 20) == 0); - EXPECT_TRUE(memcmp(cert_chain3->ca_fingerprint().data, - cert_chain3_ca_fingerprint, 20) == 0); -} - -TEST(X509CertificateTest, ParseSubjectAltNames) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> san_cert = - ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert); - - std::vector<std::string> dns_names; - std::vector<std::string> ip_addresses; - san_cert->GetSubjectAltName(&dns_names, &ip_addresses); - - // Ensure that DNS names are correctly parsed. - ASSERT_EQ(1U, dns_names.size()); - EXPECT_EQ("test.example", dns_names[0]); - - // Ensure that both IPv4 and IPv6 addresses are correctly parsed. - ASSERT_EQ(2U, ip_addresses.size()); - - static const uint8 kIPv4Address[] = { - 0x7F, 0x00, 0x00, 0x02 - }; - ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size()); - EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address, - arraysize(kIPv4Address))); - - static const uint8 kIPv6Address[] = { - 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - }; - ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size()); - EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address, - arraysize(kIPv6Address))); - - // Ensure the subjectAltName dirName has not influenced the handling of - // the subject commonName. - EXPECT_EQ("127.0.0.1", san_cert->subject().common_name); -} - -TEST(X509CertificateTest, ExtractSPKIFromDERCert) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> cert = - ImportCertFromFile(certs_dir, "nist.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); - - std::string derBytes; - EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), - &derBytes)); - - base::StringPiece spkiBytes; - EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes)); - - uint8 hash[base::kSHA1Length]; - base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()), - spkiBytes.size(), hash); - - EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash))); -} - -TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) { - base::FilePath certs_dir = GetTestCertsDirectory(); - scoped_refptr<X509Certificate> cert = - ImportCertFromFile(certs_dir, "nist.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); - - std::string derBytes; - EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), - &derBytes)); - - std::vector<base::StringPiece> crl_urls; - EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes, &crl_urls)); - - EXPECT_EQ(1u, crl_urls.size()); - if (crl_urls.size() > 0) { - EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl", - crl_urls[0].as_string()); - } -} - -// Tests X509CertificateCache via X509Certificate::CreateFromHandle. We -// call X509Certificate::CreateFromHandle several times and observe whether -// it returns a cached or new OSCertHandle. -TEST(X509CertificateTest, Cache) { - X509Certificate::OSCertHandle google_cert_handle; - X509Certificate::OSCertHandle thawte_cert_handle; - - // Add a single certificate to the certificate cache. - google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle( - google_cert_handle, X509Certificate::OSCertHandles())); - X509Certificate::FreeOSCertHandle(google_cert_handle); - - // Add the same certificate, but as a new handle. - google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle( - google_cert_handle, X509Certificate::OSCertHandles())); - X509Certificate::FreeOSCertHandle(google_cert_handle); - - // A new X509Certificate should be returned. - EXPECT_NE(cert1.get(), cert2.get()); - // But both instances should share the underlying OS certificate handle. - EXPECT_EQ(cert1->os_cert_handle(), cert2->os_cert_handle()); - EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size()); - EXPECT_EQ(0u, cert2->GetIntermediateCertificates().size()); - - // Add the same certificate, but this time with an intermediate. This - // should result in the intermediate being cached. Note that this is not - // a legitimate chain, but is suitable for testing. - google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - thawte_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)); - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(thawte_cert_handle); - scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle( - google_cert_handle, intermediates)); - X509Certificate::FreeOSCertHandle(google_cert_handle); - X509Certificate::FreeOSCertHandle(thawte_cert_handle); - - // Test that the new certificate, even with intermediates, results in the - // same underlying handle being used. - EXPECT_EQ(cert1->os_cert_handle(), cert3->os_cert_handle()); - // Though they use the same OS handle, the intermediates should be different. - EXPECT_NE(cert1->GetIntermediateCertificates().size(), - cert3->GetIntermediateCertificates().size()); -} - -TEST(X509CertificateTest, Pickle) { - X509Certificate::OSCertHandle google_cert_handle = - X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - X509Certificate::OSCertHandle thawte_cert_handle = - X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(thawte_cert_handle); - scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( - google_cert_handle, intermediates); - ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get()); - - X509Certificate::FreeOSCertHandle(google_cert_handle); - X509Certificate::FreeOSCertHandle(thawte_cert_handle); - - Pickle pickle; - cert->Persist(&pickle); - - PickleIterator iter(pickle); - scoped_refptr<X509Certificate> cert_from_pickle = - X509Certificate::CreateFromPickle( - pickle, &iter, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3); - ASSERT_NE(static_cast<X509Certificate*>(NULL), cert_from_pickle); - EXPECT_TRUE(X509Certificate::IsSameOSCert( - cert->os_cert_handle(), cert_from_pickle->os_cert_handle())); - const X509Certificate::OSCertHandles& cert_intermediates = - cert->GetIntermediateCertificates(); - const X509Certificate::OSCertHandles& pickle_intermediates = - cert_from_pickle->GetIntermediateCertificates(); - ASSERT_EQ(cert_intermediates.size(), pickle_intermediates.size()); - for (size_t i = 0; i < cert_intermediates.size(); ++i) { - EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates[i], - pickle_intermediates[i])); - } -} - -TEST(X509CertificateTest, Policy) { - scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der))); - - scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); - - CertPolicy policy; - - EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::UNKNOWN); - EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); - EXPECT_FALSE(policy.HasAllowedCert()); - EXPECT_FALSE(policy.HasDeniedCert()); - - policy.Allow(google_cert.get()); - - EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::ALLOWED); - EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); - EXPECT_TRUE(policy.HasAllowedCert()); - EXPECT_FALSE(policy.HasDeniedCert()); - - policy.Deny(google_cert.get()); - - EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED); - EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); - EXPECT_FALSE(policy.HasAllowedCert()); - EXPECT_TRUE(policy.HasDeniedCert()); - - policy.Allow(webkit_cert.get()); - - EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED); - EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::ALLOWED); - EXPECT_TRUE(policy.HasAllowedCert()); - EXPECT_TRUE(policy.HasDeniedCert()); -} - -TEST(X509CertificateTest, IntermediateCertificates) { - scoped_refptr<X509Certificate> webkit_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); - - scoped_refptr<X509Certificate> thawte_cert( - X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der))); - - X509Certificate::OSCertHandle google_handle; - // Create object with no intermediates: - google_handle = X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(google_der), sizeof(google_der)); - X509Certificate::OSCertHandles intermediates1; - scoped_refptr<X509Certificate> cert1; - cert1 = X509Certificate::CreateFromHandle(google_handle, intermediates1); - EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size()); - - // Create object with 2 intermediates: - X509Certificate::OSCertHandles intermediates2; - intermediates2.push_back(webkit_cert->os_cert_handle()); - intermediates2.push_back(thawte_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert2; - cert2 = X509Certificate::CreateFromHandle(google_handle, intermediates2); - - // Verify it has all the intermediates: - const X509Certificate::OSCertHandles& cert2_intermediates = - cert2->GetIntermediateCertificates(); - ASSERT_EQ(2u, cert2_intermediates.size()); - EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[0], - webkit_cert->os_cert_handle())); - EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[1], - thawte_cert->os_cert_handle())); - - // Cleanup - X509Certificate::FreeOSCertHandle(google_handle); -} - -TEST(X509CertificateTest, IsIssuedByEncoded) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - // Test a client certificate from MIT. - scoped_refptr<X509Certificate> mit_davidben_cert( - ImportCertFromFile(certs_dir, "mit.davidben.der")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert); - - std::string mit_issuer(reinterpret_cast<const char*>(MITDN), - sizeof(MITDN)); - - // Test a certificate from Google, issued by Thawte - scoped_refptr<X509Certificate> google_cert( - ImportCertFromFile(certs_dir, "google.single.der")); - ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); - - std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN), - sizeof(ThawteDN)); - - // Check that the David Ben certificate is issued by MIT, but not - // by Thawte. - std::vector<std::string> issuers; - issuers.clear(); - issuers.push_back(mit_issuer); - EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers)); - EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers)); - - // Check that the Google certificate is issued by Thawte and not - // by MIT. - issuers.clear(); - issuers.push_back(thawte_issuer); - EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers)); - EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers)); - - // Check that they both pass when given a list of the two issuers. - issuers.clear(); - issuers.push_back(mit_issuer); - issuers.push_back(thawte_issuer); - EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers)); - EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers)); -} - -TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) { - base::FilePath certs_dir = GetTestCertsDirectory(); - - scoped_refptr<X509Certificate> server_cert = - ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); - - // The intermediate CA certificate's policyConstraints extension has a - // requireExplicitPolicy field with SkipCerts=0. - scoped_refptr<X509Certificate> intermediate_cert = - ImportCertFromFile(certs_dir, "dod_ca_17_cert.der"); - ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); - - std::string dod_ca_17_issuer(reinterpret_cast<const char*>(DodCA17DN), - sizeof(DodCA17DN)); - - scoped_refptr<X509Certificate> root_cert = - ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der"); - - std::string dod_root_ca_2_issuer( - reinterpret_cast<const char*>(DodRootCA2DN), sizeof(DodRootCA2DN)); - - X509Certificate::OSCertHandles intermediates; - intermediates.push_back(intermediate_cert->os_cert_handle()); - scoped_refptr<X509Certificate> cert_chain = - X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), - intermediates); - - std::vector<std::string> issuers; - - // Check that the chain is issued by DOD CA-17. - issuers.clear(); - issuers.push_back(dod_ca_17_issuer); - EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers)); - - // Check that the chain is also issued by DoD Root CA 2. - issuers.clear(); - issuers.push_back(dod_root_ca_2_issuer); - EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers)); - - // Check that the chain is issued by either one of the two DOD issuers. - issuers.clear(); - issuers.push_back(dod_ca_17_issuer); - issuers.push_back(dod_root_ca_2_issuer); - EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers)); - - // Check that an empty issuers list returns false. - issuers.clear(); - EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers)); - - // Check that the chain is not issued by MIT - std::string mit_issuer(reinterpret_cast<const char*>(MITDN), - sizeof(MITDN)); - issuers.clear(); - issuers.push_back(mit_issuer); - EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers)); -} - -#if !defined(OS_IOS) // TODO(ios): Unable to create certificates. -#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) -// This test creates a self-signed cert from a private key and then verify the -// content of the certificate. -TEST(X509CertificateTest, CreateSelfSigned) { - scoped_ptr<crypto::RSAPrivateKey> private_key( - crypto::RSAPrivateKey::Create(1024)); - scoped_refptr<X509Certificate> cert = - X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); - - EXPECT_EQ("subject", cert->subject().GetDisplayName()); - EXPECT_FALSE(cert->HasExpired()); - - const uint8 private_key_info[] = { - 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, - 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, - 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, - 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, - 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, - 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, - 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, - 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, - 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, - 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, - 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, - 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, - 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, - 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, - 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, - 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, - 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, - 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, - 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb, - 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, - 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, - 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95, - 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, - 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, - 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e, - 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, - 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, - 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa, - 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, - 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, - 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e, - 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, - 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, - 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00, - 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, - 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, - 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82, - 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, - 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, - 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8, - 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, - 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, - 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1, - 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, - 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, - 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62, - 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, - 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, - 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6, - 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, - 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, - 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9, - 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, - 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, - 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93, - 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, - 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, - 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17, - 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, - 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, - 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1, - 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, - 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, - 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd, - 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, - 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, - 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7, - 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, - 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, - 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99, - 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, - 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, - 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb, - 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, - 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, - 0xb1, 0xc5, 0x15, 0xf3 - }; - - std::vector<uint8> input; - input.resize(sizeof(private_key_info)); - memcpy(&input.front(), private_key_info, sizeof(private_key_info)); - - private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); - ASSERT_TRUE(private_key.get()); - - cert = X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); - - EXPECT_EQ("subject", cert->subject().GetDisplayName()); - EXPECT_FALSE(cert->HasExpired()); -} - -TEST(X509CertificateTest, GetDEREncoded) { - scoped_ptr<crypto::RSAPrivateKey> private_key( - crypto::RSAPrivateKey::Create(1024)); - scoped_refptr<X509Certificate> cert = - X509Certificate::CreateSelfSigned( - private_key.get(), "CN=subject", 0, base::TimeDelta::FromDays(1)); - - std::string der_cert; - EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), - &der_cert)); - EXPECT_FALSE(der_cert.empty()); -} -#endif -#endif // !defined(OS_IOS) - -class X509CertificateParseTest - : public testing::TestWithParam<CertificateFormatTestData> { - public: - virtual ~X509CertificateParseTest() {} - virtual void SetUp() { - test_data_ = GetParam(); - } - virtual void TearDown() {} - - protected: - CertificateFormatTestData test_data_; -}; - -TEST_P(X509CertificateParseTest, CanParseFormat) { - base::FilePath certs_dir = GetTestCertsDirectory(); - CertificateList certs = CreateCertificateListFromFile( - certs_dir, test_data_.file_name, test_data_.format); - ASSERT_FALSE(certs.empty()); - ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints)); - CheckGoogleCert(certs.front(), google_parse_fingerprint, - kGoogleParseValidFrom, kGoogleParseValidTo); - - size_t i; - for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) { - if (test_data_.chain_fingerprints[i] == NULL) { - // No more test certificates expected - make sure no more were - // returned before marking this test a success. - EXPECT_EQ(i, certs.size()); - break; - } - - // A cert is expected - make sure that one was parsed. - ASSERT_LT(i, certs.size()); - - // Compare the parsed certificate with the expected certificate, by - // comparing fingerprints. - const X509Certificate* cert = certs[i]; - const SHA1HashValue& actual_fingerprint = cert->fingerprint(); - uint8* expected_fingerprint = test_data_.chain_fingerprints[i]; - - for (size_t j = 0; j < 20; ++j) - EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]); - } -} - -INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest, - testing::ValuesIn(FormatTestData)); - -struct CertificateNameVerifyTestData { - // true iff we expect hostname to match an entry in cert_names. - bool expected; - // The hostname to match. - const char* hostname; - // Common name, may be used if |dns_names| or |ip_addrs| are empty. - const char* common_name; - // Comma separated list of certificate names to match against. Any occurrence - // of '#' will be replaced with a null character before processing. - const char* dns_names; - // Comma separated list of certificate IP Addresses to match against. Each - // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4. - const char* ip_addrs; -}; - -// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how -// to output the parameter that was passed. Without this, it will simply -// attempt to print out the first twenty bytes of the object, which depending -// on platform and alignment, may result in an invalid read. -void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { - ASSERT_TRUE(data.hostname && data.common_name); - // Using StringPiece to allow for optional fields being NULL. - *os << " expected: " << data.expected - << "; hostname: " << data.hostname - << "; common_name: " << data.common_name - << "; dns_names: " << base::StringPiece(data.dns_names) - << "; ip_addrs: " << base::StringPiece(data.ip_addrs); -} - -const CertificateNameVerifyTestData kNameVerifyTestData[] = { - { true, "foo.com", "foo.com" }, - { true, "f", "f" }, - { false, "h", "i" }, - { true, "bar.foo.com", "*.foo.com" }, - { true, "www.test.fr", "common.name", - "*.test.com,*.test.co.uk,*.test.de,*.test.fr" }, - { true, "wwW.tESt.fr", "common.name", - ",*.*,*.test.de,*.test.FR,www" }, - { false, "f.uk", ".uk" }, - { false, "w.bar.foo.com", "?.bar.foo.com" }, - { false, "www.foo.com", "(www|ftp).foo.com" }, - { false, "www.foo.com", "www.foo.com#" }, // # = null char. - { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" }, - { false, "www.house.example", "ww.house.example" }, - { false, "test.org", "", "www.test.org,*.test.org,*.org" }, - { false, "w.bar.foo.com", "w*.bar.foo.com" }, - { false, "www.bar.foo.com", "ww*ww.bar.foo.com" }, - { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" }, - { true, "wwww.bar.foo.com", "w*w.bar.foo.com" }, - { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" }, - { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" }, - { true, "wally.bar.foo.com", "*Ly.bar.foo.com" }, - { true, "ww%57.foo.com", "", "www.foo.com" }, - { true, "www&.foo.com", "www%26.foo.com" }, - // Common name must not be used if subject alternative name was provided. - { false, "www.test.co.jp", "www.test.co.jp", - "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" }, - { false, "www.bar.foo.com", "www.bar.foo.com", - "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," }, - { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" }, - { false, "66.77.88.99", "www.bath.org", "www.bath.org" }, - // IDN tests - { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" }, - { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" }, - { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br," - "xn--poema-*.com.br," - "xn--*-9qae5a.com.br," - "*--poema-9qae5a.com.br" }, - { true, "xn--poema-9qae5a.com.br", "*.com.br" }, - // The following are adapted from the examples quoted from - // http://tools.ietf.org/html/rfc6125#section-6.4.3 - // (e.g., *.example.com would match foo.example.com but - // not bar.foo.example.com or example.com). - { true, "foo.example.com", "*.example.com" }, - { false, "bar.foo.example.com", "*.example.com" }, - { false, "example.com", "*.example.com" }, - // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would - // be taken to match baz1.example.net and foobaz.example.net and - // buzz.example.net, respectively - { true, "baz1.example.net", "baz*.example.net" }, - { true, "foobaz.example.net", "*baz.example.net" }, - { true, "buzz.example.net", "b*z.example.net" }, - // Wildcards should not be valid unless there are at least three name - // components. - { true, "h.co.uk", "*.co.uk" }, - { false, "foo.com", "*.com" }, - { false, "foo.us", "*.us" }, - { false, "foo", "*" }, - // Multiple wildcards are not valid. - { false, "foo.example.com", "*.*.com" }, - { false, "foo.bar.example.com", "*.bar.*.com" }, - // Absolute vs relative DNS name tests. Although not explicitly specified - // in RFC 6125, absolute reference names (those ending in a .) should - // match either absolute or relative presented names. - { true, "foo.com", "foo.com." }, - { true, "foo.com.", "foo.com" }, - { true, "foo.com.", "foo.com." }, - { true, "f", "f." }, - { true, "f.", "f" }, - { true, "f.", "f." }, - { true, "www-3.bar.foo.com", "*.bar.foo.com." }, - { true, "www-3.bar.foo.com.", "*.bar.foo.com" }, - { true, "www-3.bar.foo.com.", "*.bar.foo.com." }, - { false, ".", "." }, - { false, "example.com", "*.com." }, - { false, "example.com.", "*.com" }, - { false, "example.com.", "*.com." }, - { false, "foo.", "*." }, - // IP addresses in common name; IPv4 only. - { true, "127.0.0.1", "127.0.0.1" }, - { true, "192.168.1.1", "192.168.1.1" }, - { true, "676768", "0.10.83.160" }, - { true, "1.2.3", "1.2.0.3" }, - { false, "192.169.1.1", "192.168.1.1" }, - { false, "12.19.1.1", "12.19.1.1/255.255.255.0" }, - { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210", - "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" }, - { false, "1111:2222:3333:4444:5555:6666:7777:8888", - "1111:2222:3333:4444:5555:6666:7777:8888" }, - { false, "::192.9.5.5", "[::192.9.5.5]" }, - // No wildcard matching in valid IP addresses - { false, "::192.9.5.5", "*.9.5.5" }, - { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" }, - { false, "192.168.1.11", "*.168.1.11" }, - { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" }, - // IP addresses in subject alternative name (common name ignored) - { true, "10.1.2.3", "", "", "10.1.2.3" }, - { true, "14.15", "", "", "14.0.0.15" }, - { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" }, - { false, "10.1.2.8", "10.20.2.8", "foo" }, - { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" }, - { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9", - "x00000000000000000000000006070808,x0000000000000000000000000607080a," - "xff000000000000000000000006070809,6.7.8.9" }, - { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "", - "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf," - "xff0000000000000000000000060708ff,10.0.0.1" }, - // Numeric only hostnames (none of these are considered valid IP addresses). - { false, "12345.6", "12345.6" }, - { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512", - "121.2.3.0"}, - { false, "1.2.3.4.5.6", "*.2.3.4.5.6" }, - { true, "1.2.3.4.5", "", "1.2.3.4.5" }, - // Invalid host names. - { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" }, - { false, "www.*.com", "www.*.com" }, - { false, "w$w.f.com", "w$w.f.com" }, - { false, "nocolonallowed:example", "", "nocolonallowed:example" }, - { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" }, - { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" }, -}; - -class X509CertificateNameVerifyTest - : public testing::TestWithParam<CertificateNameVerifyTestData> { -}; - -TEST_P(X509CertificateNameVerifyTest, VerifyHostname) { - CertificateNameVerifyTestData test_data = GetParam(); - - std::string common_name(test_data.common_name); - ASSERT_EQ(std::string::npos, common_name.find(',')); - std::replace(common_name.begin(), common_name.end(), '#', '\0'); - - std::vector<std::string> dns_names, ip_addressses; - if (test_data.dns_names) { - // Build up the certificate DNS names list. - std::string dns_name_line(test_data.dns_names); - std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0'); - base::SplitString(dns_name_line, ',', &dns_names); - } - - if (test_data.ip_addrs) { - // Build up the certificate IP address list. - std::string ip_addrs_line(test_data.ip_addrs); - std::vector<std::string> ip_addressses_ascii; - base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii); - for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) { - std::string& addr_ascii = ip_addressses_ascii[i]; - ASSERT_NE(0U, addr_ascii.length()); - if (addr_ascii[0] == 'x') { // Hex encoded address - addr_ascii.erase(0, 1); - std::vector<uint8> bytes; - EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes)) - << "Could not parse hex address " << addr_ascii << " i = " << i; - ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]), - bytes.size())); - ASSERT_EQ(16U, ip_addressses.back().size()) << i; - } else { // Decimal groups - std::vector<std::string> decimals_ascii; - base::SplitString(addr_ascii, '.', &decimals_ascii); - EXPECT_EQ(4U, decimals_ascii.size()) << i; - std::string addr_bytes; - for (size_t j = 0; j < decimals_ascii.size(); ++j) { - int decimal_value; - EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value)); - EXPECT_GE(decimal_value, 0); - EXPECT_LE(decimal_value, 255); - addr_bytes.push_back(static_cast<char>(decimal_value)); - } - ip_addressses.push_back(addr_bytes); - ASSERT_EQ(4U, ip_addressses.back().size()) << i; - } - } - } - - EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( - test_data.hostname, common_name, dns_names, ip_addressses)); -} - -INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, - testing::ValuesIn(kNameVerifyTestData)); - -} // namespace net diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc deleted file mode 100644 index 8a83e41..0000000 --- a/net/base/x509_certificate_win.cc +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_certificate.h" - -#include <blapi.h> // Implement CalculateChainFingerprint() with NSS. - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/pickle.h" -#include "base/sha1.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "crypto/capi_util.h" -#include "crypto/rsa_private_key.h" -#include "crypto/scoped_capi_types.h" -#include "net/base/net_errors.h" - -#pragma comment(lib, "crypt32.lib") - -using base::Time; - -namespace net { - -namespace { - -typedef crypto::ScopedCAPIHandle< - HCERTSTORE, - crypto::CAPIDestroyerWithFlags<HCERTSTORE, - CertCloseStore, 0> > ScopedHCERTSTORE; - -void ExplodedTimeToSystemTime(const base::Time::Exploded& exploded, - SYSTEMTIME* system_time) { - system_time->wYear = exploded.year; - system_time->wMonth = exploded.month; - system_time->wDayOfWeek = exploded.day_of_week; - system_time->wDay = exploded.day_of_month; - system_time->wHour = exploded.hour; - system_time->wMinute = exploded.minute; - system_time->wSecond = exploded.second; - system_time->wMilliseconds = exploded.millisecond; -} - -//----------------------------------------------------------------------------- - -// Decodes the cert's subjectAltName extension into a CERT_ALT_NAME_INFO -// structure and stores it in *output. -void GetCertSubjectAltName(PCCERT_CONTEXT cert, - scoped_ptr_malloc<CERT_ALT_NAME_INFO>* output) { - PCERT_EXTENSION extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2, - cert->pCertInfo->cExtension, - cert->pCertInfo->rgExtension); - if (!extension) - return; - - CRYPT_DECODE_PARA decode_para; - decode_para.cbSize = sizeof(decode_para); - decode_para.pfnAlloc = crypto::CryptAlloc; - decode_para.pfnFree = crypto::CryptFree; - CERT_ALT_NAME_INFO* alt_name_info = NULL; - DWORD alt_name_info_size = 0; - BOOL rv; - rv = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_SUBJECT_ALT_NAME2, - extension->Value.pbData, - extension->Value.cbData, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &alt_name_info, - &alt_name_info_size); - if (rv) - output->reset(alt_name_info); -} - -void AddCertsFromStore(HCERTSTORE store, - X509Certificate::OSCertHandles* results) { - PCCERT_CONTEXT cert = NULL; - - while ((cert = CertEnumCertificatesInStore(store, cert)) != NULL) { - PCCERT_CONTEXT to_add = NULL; - if (CertAddCertificateContextToStore( - NULL, // The cert won't be persisted in any cert store. This breaks - // any association the context currently has to |store|, which - // allows us, the caller, to safely close |store| without - // releasing the cert handles. - cert, - CERT_STORE_ADD_USE_EXISTING, - &to_add) && to_add != NULL) { - // When processing stores generated from PKCS#7/PKCS#12 files, it - // appears that the order returned is the inverse of the order that it - // appeared in the file. - // TODO(rsleevi): Ensure this order is consistent across all Win - // versions - results->insert(results->begin(), to_add); - } - } -} - -X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) { - X509Certificate::OSCertHandles results; - CERT_BLOB data_blob; - data_blob.cbData = length; - data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data)); - - HCERTSTORE out_store = NULL; - - DWORD expected_types = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | - CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | - CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED; - - if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &data_blob, expected_types, - CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, - &out_store, NULL, NULL) || out_store == NULL) { - return results; - } - - AddCertsFromStore(out_store, &results); - CertCloseStore(out_store, CERT_CLOSE_STORE_CHECK_FLAG); - - return results; -} - -// Given a CERT_NAME_BLOB, returns true if it appears in a given list, -// formatted as a vector of strings holding DER-encoded X.509 -// DistinguishedName entries. -bool IsCertNameBlobInIssuerList( - CERT_NAME_BLOB* name_blob, - const std::vector<std::string>& issuer_names) { - for (std::vector<std::string>::const_iterator it = issuer_names.begin(); - it != issuer_names.end(); ++it) { - CERT_NAME_BLOB issuer_blob; - issuer_blob.pbData = - reinterpret_cast<BYTE*>(const_cast<char*>(it->data())); - issuer_blob.cbData = static_cast<DWORD>(it->length()); - - BOOL rb = CertCompareCertificateName( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &issuer_blob, name_blob); - if (rb) - return true; - } - return false; -} - -} // namespace - -void X509Certificate::Initialize() { - DCHECK(cert_handle_); - subject_.ParseDistinguishedName(cert_handle_->pCertInfo->Subject.pbData, - cert_handle_->pCertInfo->Subject.cbData); - issuer_.ParseDistinguishedName(cert_handle_->pCertInfo->Issuer.pbData, - cert_handle_->pCertInfo->Issuer.cbData); - - valid_start_ = Time::FromFileTime(cert_handle_->pCertInfo->NotBefore); - valid_expiry_ = Time::FromFileTime(cert_handle_->pCertInfo->NotAfter); - - fingerprint_ = CalculateFingerprint(cert_handle_); - ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); - - const CRYPT_INTEGER_BLOB* serial = &cert_handle_->pCertInfo->SerialNumber; - scoped_array<uint8> serial_bytes(new uint8[serial->cbData]); - for (unsigned i = 0; i < serial->cbData; i++) - serial_bytes[i] = serial->pbData[serial->cbData - i - 1]; - serial_number_ = std::string( - reinterpret_cast<char*>(serial_bytes.get()), serial->cbData); -} - -// static -X509Certificate* X509Certificate::CreateSelfSigned( - crypto::RSAPrivateKey* key, - const std::string& subject, - uint32 serial_number, - base::TimeDelta valid_duration) { - // Get the ASN.1 encoding of the certificate subject. - std::wstring w_subject = ASCIIToWide(subject); - DWORD encoded_subject_length = 0; - if (!CertStrToName( - X509_ASN_ENCODING, - w_subject.c_str(), - CERT_X500_NAME_STR, NULL, NULL, &encoded_subject_length, NULL)) { - return NULL; - } - - scoped_array<BYTE> encoded_subject(new BYTE[encoded_subject_length]); - if (!CertStrToName( - X509_ASN_ENCODING, - w_subject.c_str(), - CERT_X500_NAME_STR, NULL, - encoded_subject.get(), - &encoded_subject_length, NULL)) { - return NULL; - } - - CERT_NAME_BLOB subject_name; - memset(&subject_name, 0, sizeof(subject_name)); - subject_name.cbData = encoded_subject_length; - subject_name.pbData = encoded_subject.get(); - - CRYPT_ALGORITHM_IDENTIFIER sign_algo; - memset(&sign_algo, 0, sizeof(sign_algo)); - sign_algo.pszObjId = szOID_RSA_SHA1RSA; - - base::Time not_before = base::Time::Now(); - base::Time not_after = not_before + valid_duration; - base::Time::Exploded exploded; - - // Create the system time structs representing our exploded times. - not_before.UTCExplode(&exploded); - SYSTEMTIME start_time; - ExplodedTimeToSystemTime(exploded, &start_time); - not_after.UTCExplode(&exploded); - SYSTEMTIME end_time; - ExplodedTimeToSystemTime(exploded, &end_time); - - PCCERT_CONTEXT cert_handle = - CertCreateSelfSignCertificate(key->provider(), &subject_name, - CERT_CREATE_SELFSIGN_NO_KEY_INFO, NULL, - &sign_algo, &start_time, &end_time, NULL); - DCHECK(cert_handle) << "Failed to create self-signed certificate: " - << GetLastError(); - if (!cert_handle) - return NULL; - - X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles()); - FreeOSCertHandle(cert_handle); - return cert; -} - -void X509Certificate::GetSubjectAltName( - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) const { - if (dns_names) - dns_names->clear(); - if (ip_addrs) - ip_addrs->clear(); - - if (!cert_handle_) - return; - - scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; - GetCertSubjectAltName(cert_handle_, &alt_name_info); - CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); - if (alt_name) { - int num_entries = alt_name->cAltEntry; - for (int i = 0; i < num_entries; i++) { - // dNSName is an ASN.1 IA5String representing a string of ASCII - // characters, so we can use WideToASCII here. - const CERT_ALT_NAME_ENTRY& entry = alt_name->rgAltEntry[i]; - - if (dns_names && entry.dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) { - dns_names->push_back(WideToASCII(entry.pwszDNSName)); - } else if (ip_addrs && - entry.dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS) { - ip_addrs->push_back(std::string( - reinterpret_cast<const char*>(entry.IPAddress.pbData), - entry.IPAddress.cbData)); - } - } - } -} - -PCCERT_CONTEXT X509Certificate::CreateOSCertChainForCert() const { - // Create an in-memory certificate store to hold this certificate and - // any intermediate certificates in |intermediate_ca_certs_|. The store - // will be referenced in the returned PCCERT_CONTEXT, and will not be freed - // until the PCCERT_CONTEXT is freed. - ScopedHCERTSTORE store(CertOpenStore( - CERT_STORE_PROV_MEMORY, 0, NULL, - CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL)); - if (!store.get()) - return NULL; - - // NOTE: This preserves all of the properties of |os_cert_handle()| except - // for CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two - // properties that hold access to already-opened private keys. If a handle - // has already been unlocked (eg: PIN prompt), then the first time that the - // identity is used for client auth, it may prompt the user again. - PCCERT_CONTEXT primary_cert; - BOOL ok = CertAddCertificateContextToStore(store.get(), os_cert_handle(), - CERT_STORE_ADD_ALWAYS, - &primary_cert); - if (!ok || !primary_cert) - return NULL; - - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { - CertAddCertificateContextToStore(store.get(), intermediate_ca_certs_[i], - CERT_STORE_ADD_ALWAYS, NULL); - } - - // Note: |store| is explicitly not released, as the call to CertCloseStore() - // when |store| goes out of scope will not actually free the store. Instead, - // the store will be freed when |primary_cert| is freed. - return primary_cert; -} - -// static -bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, - std::string* encoded) { - if (!cert_handle->pbCertEncoded || !cert_handle->cbCertEncoded) - return false; - encoded->assign(reinterpret_cast<char*>(cert_handle->pbCertEncoded), - cert_handle->cbCertEncoded); - return true; -} - -// static -bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, - X509Certificate::OSCertHandle b) { - DCHECK(a && b); - if (a == b) - return true; - return a->cbCertEncoded == b->cbCertEncoded && - memcmp(a->pbCertEncoded, b->pbCertEncoded, a->cbCertEncoded) == 0; -} - -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - OSCertHandle cert_handle = NULL; - if (!CertAddEncodedCertificateToStore( - NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data), - length, CERT_STORE_ADD_USE_EXISTING, &cert_handle)) - return NULL; - - return cert_handle; -} - -X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( - const char* data, int length, Format format) { - OSCertHandles results; - switch (format) { - case FORMAT_SINGLE_CERTIFICATE: { - OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); - if (handle != NULL) - results.push_back(handle); - break; - } - case FORMAT_PKCS7: - results = ParsePKCS7(data, length); - break; - default: - NOTREACHED() << "Certificate format " << format << " unimplemented"; - break; - } - - return results; -} - -// static -X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( - OSCertHandle cert_handle) { - return CertDuplicateCertificateContext(cert_handle); -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - CertFreeCertificateContext(cert_handle); -} - -// static -SHA1HashValue X509Certificate::CalculateFingerprint( - OSCertHandle cert) { - DCHECK(NULL != cert->pbCertEncoded); - DCHECK_NE(static_cast<DWORD>(0), cert->cbCertEncoded); - - BOOL rv; - SHA1HashValue sha1; - DWORD sha1_size = sizeof(sha1.data); - rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, - cert->cbCertEncoded, sha1.data, &sha1_size); - DCHECK(rv && sha1_size == sizeof(sha1.data)); - if (!rv) - memset(sha1.data, 0, sizeof(sha1.data)); - return sha1; -} - -// TODO(wtc): This function is implemented with NSS low-level hash -// functions to ensure it is fast. Reimplement this function with -// CryptoAPI. May need to cache the HCRYPTPROV to reduce the overhead. -// static -SHA1HashValue X509Certificate::CalculateCAFingerprint( - const OSCertHandles& intermediates) { - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - SHA1Context* sha1_ctx = SHA1_NewContext(); - if (!sha1_ctx) - return sha1; - SHA1_Begin(sha1_ctx); - for (size_t i = 0; i < intermediates.size(); ++i) { - PCCERT_CONTEXT ca_cert = intermediates[i]; - SHA1_Update(sha1_ctx, ca_cert->pbCertEncoded, ca_cert->cbCertEncoded); - } - unsigned int result_len; - SHA1_End(sha1_ctx, sha1.data, &result_len, SHA1_LENGTH); - SHA1_DestroyContext(sha1_ctx, PR_TRUE); - - return sha1; -} - -// static -X509Certificate::OSCertHandle -X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { - const char* data; - int length; - if (!pickle_iter->ReadData(&data, &length)) - return NULL; - - // Legacy serialized certificates were serialized with extended attributes, - // rather than as DER only. As a result, these serialized certificates are - // not portable across platforms and may have side-effects on Windows due - // to extended attributes being serialized/deserialized - - // http://crbug.com/118706. To avoid deserializing these attributes, write - // the deserialized cert into a temporary cert store and then create a new - // cert from the DER - that is, without attributes. - ScopedHCERTSTORE store( - CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL)); - if (!store.get()) - return NULL; - - OSCertHandle cert_handle = NULL; - if (!CertAddSerializedElementToStore( - store.get(), reinterpret_cast<const BYTE*>(data), length, - CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, - NULL, reinterpret_cast<const void **>(&cert_handle))) { - return NULL; - } - - std::string encoded; - bool ok = GetDEREncoded(cert_handle, &encoded); - FreeOSCertHandle(cert_handle); - cert_handle = NULL; - - if (ok) - cert_handle = CreateOSCertHandleFromBytes(encoded.data(), encoded.size()); - return cert_handle; -} - -// static -bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, - Pickle* pickle) { - return pickle->WriteData( - reinterpret_cast<char*>(cert_handle->pbCertEncoded), - cert_handle->cbCertEncoded); -} - -// static -void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, - size_t* size_bits, - PublicKeyType* type) { - *type = kPublicKeyTypeUnknown; - *size_bits = 0; - - PCCRYPT_OID_INFO oid_info = CryptFindOIDInfo( - CRYPT_OID_INFO_OID_KEY, - cert_handle->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, - CRYPT_PUBKEY_ALG_OID_GROUP_ID); - if (!oid_info) - return; - - CHECK_EQ(oid_info->dwGroupId, - static_cast<DWORD>(CRYPT_PUBKEY_ALG_OID_GROUP_ID)); - - *size_bits = CertGetPublicKeyLength( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - &cert_handle->pCertInfo->SubjectPublicKeyInfo); - - switch (oid_info->Algid) { - case CALG_RSA_SIGN: - case CALG_RSA_KEYX: - *type = kPublicKeyTypeRSA; - break; - case CALG_DSS_SIGN: - *type = kPublicKeyTypeDSA; - break; - case CALG_ECDSA: - *type = kPublicKeyTypeECDSA; - break; - case CALG_ECDH: - *type = kPublicKeyTypeECDH; - break; - } -} - -bool X509Certificate::IsIssuedByEncoded( - const std::vector<std::string>& valid_issuers) { - - // If the certificate's issuer in the list? - if (IsCertNameBlobInIssuerList(&cert_handle_->pCertInfo->Issuer, - valid_issuers)) { - return true; - } - // Otherwise, is any of the intermediate CA subjects in the list? - for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); - it != intermediate_ca_certs_.end(); ++it) { - if (IsCertNameBlobInIssuerList(&(*it)->pCertInfo->Issuer, - valid_issuers)) { - return true; - } - } - - return false; -} - -} // namespace net diff --git a/net/base/x509_util.cc b/net/base/x509_util.cc deleted file mode 100644 index 2e09a0f..0000000 --- a/net/base/x509_util.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util.h" - -#include "base/time.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace x509_util { - -ClientCertSorter::ClientCertSorter() : now_(base::Time::Now()) {} - -bool ClientCertSorter::operator()( - const scoped_refptr<X509Certificate>& a, - const scoped_refptr<X509Certificate>& b) const { - // Certificates that are null are sorted last. - if (!a.get() || !b.get()) - return a.get() && !b.get(); - - // Certificates that are expired/not-yet-valid are sorted last. - bool a_is_valid = now_ >= a->valid_start() && now_ <= a->valid_expiry(); - bool b_is_valid = now_ >= b->valid_start() && now_ <= b->valid_expiry(); - if (a_is_valid != b_is_valid) - return a_is_valid && !b_is_valid; - - // Certificates with longer expirations appear as higher priority (less - // than) certificates with shorter expirations. - if (a->valid_expiry() != b->valid_expiry()) - return a->valid_expiry() > b->valid_expiry(); - - // If the expiration dates are equivalent, certificates that were issued - // more recently should be prioritized over older certificates. - if (a->valid_start() != b->valid_start()) - return a->valid_start() > b->valid_start(); - - // Otherwise, prefer client certificates with shorter chains. - const X509Certificate::OSCertHandles& a_intermediates = - a->GetIntermediateCertificates(); - const X509Certificate::OSCertHandles& b_intermediates = - b->GetIntermediateCertificates(); - return a_intermediates.size() < b_intermediates.size(); -} - -} // namespace x509_util - -} // namespace net diff --git a/net/base/x509_util.h b/net/base/x509_util.h deleted file mode 100644 index 734eebd..0000000 --- a/net/base/x509_util.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_UTIL_H_ -#define NET_BASE_X509_UTIL_H_ - -#include <string> - -#include "base/memory/ref_counted.h" -#include "base/time.h" -#include "net/base/net_export.h" - -namespace crypto { -class ECPrivateKey; -} - -namespace net { - -class X509Certificate; - -namespace x509_util { - -// Returns true if the times can be used to create an X.509 certificate. -// Certificates can accept dates from Jan 1st, 1 to Dec 31, 9999. A bug in NSS -// limited the range to 1950-9999 -// (https://bugzilla.mozilla.org/show_bug.cgi?id=786531). This function will -// return whether it is supported by the currently used crypto library. -NET_EXPORT_PRIVATE bool IsSupportedValidityRange(base::Time not_valid_before, - base::Time not_valid_after); - -// Creates a server bound certificate containing the public key in |key|. -// Domain, serial number and validity period are given as -// parameters. The certificate is signed by the private key in |key|. -// The hashing algorithm for the signature is SHA-1. -// -// See Internet Draft draft-balfanz-tls-obc-00 for more details: -// http://tools.ietf.org/html/draft-balfanz-tls-obc-00 -NET_EXPORT_PRIVATE bool CreateDomainBoundCertEC( - crypto::ECPrivateKey* key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert); - -// Comparator for use in STL algorithms that will sort client certificates by -// order of preference. -// Returns true if |a| is more preferable than |b|, allowing it to be used -// with any algorithm that compares according to strict weak ordering. -// -// Criteria include: -// - Prefer certificates that have a longer validity period (later -// expiration dates) -// - If equal, prefer certificates that were issued more recently -// - If equal, prefer shorter chains (if available) -class NET_EXPORT_PRIVATE ClientCertSorter { - public: - ClientCertSorter(); - - bool operator()( - const scoped_refptr<X509Certificate>& a, - const scoped_refptr<X509Certificate>& b) const; - - private: - base::Time now_; -}; - -} // namespace x509_util - -} // namespace net - -#endif // NET_BASE_X509_UTIL_H_ diff --git a/net/base/x509_util_ios.cc b/net/base/x509_util_ios.cc deleted file mode 100644 index 66fc2aa..0000000 --- a/net/base/x509_util_ios.cc +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util_ios.h" - -#include <cert.h> -#include <CommonCrypto/CommonDigest.h> -#include <nss.h> -#include <prtypes.h> - -#include "base/mac/scoped_cftyperef.h" -#include "crypto/nss_util.h" -#include "net/base/x509_certificate.h" -#include "net/base/x509_util_nss.h" - -using base::mac::ScopedCFTypeRef; - -namespace net { -namespace x509_util_ios { - -namespace { - -// Creates an NSS certificate handle from |data|, which is |length| bytes in -// size. -CERTCertificate* CreateNSSCertHandleFromBytes(const char* data, - int length) { - if (length < 0) - return NULL; - - crypto::EnsureNSSInit(); - - if (!NSS_IsInitialized()) - return NULL; - - SECItem der_cert; - der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); - der_cert.len = length; - der_cert.type = siDERCertBuffer; - - // Parse into a certificate structure. - return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL, - PR_FALSE, PR_TRUE); -} - -} // namespace - -CERTCertificate* CreateNSSCertHandleFromOSHandle( - SecCertificateRef cert_handle) { - ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle)); - return CreateNSSCertHandleFromBytes( - reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), - CFDataGetLength(cert_data)); -} - -SecCertificateRef CreateOSCertHandleFromNSSHandle( - CERTCertificate* nss_cert_handle) { - return X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<const char*>(nss_cert_handle->derCert.data), - nss_cert_handle->derCert.len); -} - -X509Certificate* CreateCertFromNSSHandles( - CERTCertificate* cert_handle, - const std::vector<CERTCertificate*>& intermediates) { - ScopedCFTypeRef<SecCertificateRef> os_server_cert( - CreateOSCertHandleFromNSSHandle(cert_handle)); - if (!os_server_cert) - return NULL; - std::vector<SecCertificateRef> os_intermediates; - for (size_t i = 0; i < intermediates.size(); ++i) { - SecCertificateRef intermediate = - CreateOSCertHandleFromNSSHandle(intermediates[i]); - if (!intermediate) - break; - os_intermediates.push_back(intermediate); - } - - X509Certificate* cert = NULL; - if (intermediates.size() == os_intermediates.size()) { - cert = X509Certificate::CreateFromHandle(os_server_cert, - os_intermediates); - } - - for (size_t i = 0; i < os_intermediates.size(); ++i) - CFRelease(os_intermediates[i]); - return cert; -} - -SHA1HashValue CalculateFingerprintNSS(CERTCertificate* cert) { - DCHECK(cert->derCert.data); - DCHECK_NE(0U, cert->derCert.len); - SHA1HashValue sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - CC_SHA1(cert->derCert.data, cert->derCert.len, sha1.data); - return sha1; -} - -// NSSCertificate implementation. - -NSSCertificate::NSSCertificate(SecCertificateRef cert_handle) { - nss_cert_handle_ = CreateNSSCertHandleFromOSHandle(cert_handle); - DLOG_IF(INFO, cert_handle && !nss_cert_handle_) - << "Could not convert SecCertificateRef to CERTCertificate*"; -} - -NSSCertificate::~NSSCertificate() { - CERT_DestroyCertificate(nss_cert_handle_); -} - -CERTCertificate* NSSCertificate::cert_handle() const { - return nss_cert_handle_; -} - -// NSSCertChain implementation - -NSSCertChain::NSSCertChain(X509Certificate* certificate) { - DCHECK(certificate); - certs_.push_back(CreateNSSCertHandleFromOSHandle( - certificate->os_cert_handle())); - const X509Certificate::OSCertHandles& cert_intermediates = - certificate->GetIntermediateCertificates(); - for (size_t i = 0; i < cert_intermediates.size(); ++i) - certs_.push_back(CreateNSSCertHandleFromOSHandle(cert_intermediates[i])); -} - -NSSCertChain::~NSSCertChain() { - for (size_t i = 0; i < certs_.size(); ++i) - CERT_DestroyCertificate(certs_[i]); -} - -CERTCertificate* NSSCertChain::cert_handle() const { - return certs_.empty() ? NULL : certs_.front(); -} - -const std::vector<CERTCertificate*>& NSSCertChain::cert_chain() const { - return certs_; -} - -} // namespace x509_util_ios -} // namespace net diff --git a/net/base/x509_util_ios.h b/net/base/x509_util_ios.h deleted file mode 100644 index 1f242ed..0000000 --- a/net/base/x509_util_ios.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains functions for iOS to glue NSS and Security.framework -// together. - -#ifndef NET_BASE_X509_UTIL_IOS_H_ -#define NET_BASE_X509_UTIL_IOS_H_ - -#include <Security/Security.h> -#include <vector> - -#include "net/base/x509_cert_types.h" - -// Forward declaration; real one in <cert.h> -typedef struct CERTCertificateStr CERTCertificate; - -namespace net { - -class X509Certificate; - -namespace x509_util_ios { - -// Converts a Security.framework certificate handle (SecCertificateRef) into -// an NSS certificate handle (CERTCertificate*). -CERTCertificate* CreateNSSCertHandleFromOSHandle(SecCertificateRef cert_handle); - -// Converts an NSS certificate handle (CERTCertificate*) into a -// Security.framework handle (SecCertificateRef) -SecCertificateRef CreateOSCertHandleFromNSSHandle( - CERTCertificate* nss_cert_handle); - -// Create a new X509Certificate from the specified NSS server cert and -// intermediates. This is functionally equivalent to -// X509Certificate::CreateFromHandle(), except it supports receiving -// NSS CERTCertificate*s rather than iOS SecCertificateRefs. -X509Certificate* CreateCertFromNSSHandles( - CERTCertificate* cert_handle, - const std::vector<CERTCertificate*>& intermediates); - -SHA1HashValue CalculateFingerprintNSS(CERTCertificate* cert); - -// This is a wrapper class around the native NSS certificate handle. -// The constructor copies the certificate data from |cert_handle| and -// uses the NSS library to parse it. -class NSSCertificate { - public: - explicit NSSCertificate(SecCertificateRef cert_handle); - ~NSSCertificate(); - CERTCertificate* cert_handle() const; - private: - CERTCertificate* nss_cert_handle_; -}; - -// A wrapper class that loads a certificate and all of its intermediates into -// NSS. This is necessary for libpkix path building to be able to locate -// needed intermediates. -class NSSCertChain { - public: - explicit NSSCertChain(X509Certificate* certificate); - ~NSSCertChain(); - CERTCertificate* cert_handle() const; - const std::vector<CERTCertificate*>& cert_chain() const; - private: - std::vector<CERTCertificate*> certs_; -}; - -} // namespace x509_util_ios -} // namespace net - -#endif // NET_BASE_X509_UTIL_IOS_H_ diff --git a/net/base/x509_util_mac.cc b/net/base/x509_util_mac.cc deleted file mode 100644 index a53b5ac..0000000 --- a/net/base/x509_util_mac.cc +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util_mac.h" - -#include "base/logging.h" -#include "third_party/apple_apsl/cssmapplePriv.h" - -namespace net { - -namespace x509_util { - -namespace { - -// Creates a SecPolicyRef for the given OID, with optional value. -OSStatus CreatePolicy(const CSSM_OID* policy_oid, - void* option_data, - size_t option_length, - SecPolicyRef* policy) { - SecPolicySearchRef search; - OSStatus err = SecPolicySearchCreate(CSSM_CERT_X_509v3, policy_oid, NULL, - &search); - if (err) - return err; - err = SecPolicySearchCopyNext(search, policy); - CFRelease(search); - if (err) - return err; - - if (option_data) { - CSSM_DATA options_data = { - option_length, - reinterpret_cast<uint8_t*>(option_data) - }; - err = SecPolicySetValue(*policy, &options_data); - if (err) { - CFRelease(*policy); - return err; - } - } - return noErr; -} - -} // namespace - - -OSStatus CreateSSLClientPolicy(SecPolicyRef* policy) { - CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; - memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); - tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; - tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT; - - return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, - sizeof(tp_ssl_options), policy); -} - -OSStatus CreateSSLServerPolicy(const std::string& hostname, - SecPolicyRef* policy) { - CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; - memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); - tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; - if (!hostname.empty()) { - tp_ssl_options.ServerName = hostname.data(); - tp_ssl_options.ServerNameLen = hostname.size(); - } - - return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, - sizeof(tp_ssl_options), policy); -} - -OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { - return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); -} - -OSStatus CreateRevocationPolicies(bool enable_revocation_checking, - bool enable_ev_checking, - CFMutableArrayRef policies) { - OSStatus status = noErr; - - // In order to bypass the system revocation checking settings, the - // SecTrustRef must have at least one revocation policy associated with it. - // Since it is not known prior to verification whether the Apple TP will - // consider a certificate as an EV candidate, the default policy used is a - // CRL policy, since it does not communicate over the network. - // If the TP believes the leaf is an EV cert, it will explicitly add an - // OCSP policy to perform the online checking, and if it doesn't believe - // that the leaf is EV, then the default CRL policy will effectively no-op. - // This behaviour is used to implement EV-only revocation checking. - if (enable_ev_checking || enable_revocation_checking) { - CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; - memset(&tp_crl_options, 0, sizeof(tp_crl_options)); - tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; - // Only allow network CRL fetches if the caller explicitly requests - // online revocation checking. Note that, as of OS X 10.7.2, the system - // will set force this flag on according to system policies, so - // online revocation checks cannot be completely disabled. - if (enable_revocation_checking) - tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; - - SecPolicyRef crl_policy; - status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, - sizeof(tp_crl_options), &crl_policy); - if (status) - return status; - CFArrayAppendValue(policies, crl_policy); - CFRelease(crl_policy); - } - - // If revocation checking is explicitly enabled, then add an OCSP policy - // and allow network access. If both revocation checking and EV checking - // are disabled, then the added OCSP policy will be prevented from - // accessing the network. This is done because the TP will force an OCSP - // policy to be present when it believes the certificate is EV. If network - // fetching was not explicitly disabled, then it would be as if - // enable_ev_checking was always set to true. - if (enable_revocation_checking || !enable_ev_checking) { - CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; - memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); - tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; - - if (enable_revocation_checking) { - // The default for the OCSP policy is to fetch responses via the network, - // unlike the CRL policy default. The policy is further modified to - // prefer OCSP over CRLs, if both are specified on the certificate. This - // is because an OCSP response is both sufficient and typically - // significantly smaller than the CRL counterpart. - tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; - } else { - // Effectively disable OCSP checking by making it impossible to get an - // OCSP response. Even if the Apple TP forces OCSP, no checking will - // be able to succeed. If this happens, the Apple TP will report an error - // that OCSP was unavailable, but this will be handled and suppressed in - // X509Certificate::Verify(). - tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | - CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; - } - - SecPolicyRef ocsp_policy; - status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, - sizeof(tp_ocsp_options), &ocsp_policy); - if (status) - return status; - CFArrayAppendValue(policies, ocsp_policy); - CFRelease(ocsp_policy); - } - - return status; -} - -CSSMFieldValue::CSSMFieldValue() - : cl_handle_(CSSM_INVALID_HANDLE), - oid_(NULL), - field_(NULL) { -} -CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, - const CSSM_OID* oid, - CSSM_DATA_PTR field) - : cl_handle_(cl_handle), - oid_(const_cast<CSSM_OID_PTR>(oid)), - field_(field) { -} - -CSSMFieldValue::~CSSMFieldValue() { - Reset(CSSM_INVALID_HANDLE, NULL, NULL); -} - -void CSSMFieldValue::Reset(CSSM_CL_HANDLE cl_handle, - CSSM_OID_PTR oid, - CSSM_DATA_PTR field) { - if (cl_handle_ && oid_ && field_) - CSSM_CL_FreeFieldValue(cl_handle_, oid_, field_); - cl_handle_ = cl_handle; - oid_ = oid; - field_ = field; -} - -CSSMCachedCertificate::CSSMCachedCertificate() - : cl_handle_(CSSM_INVALID_HANDLE), - cached_cert_handle_(CSSM_INVALID_HANDLE) { -} -CSSMCachedCertificate::~CSSMCachedCertificate() { - if (cl_handle_ && cached_cert_handle_) - CSSM_CL_CertAbortCache(cl_handle_, cached_cert_handle_); -} - -OSStatus CSSMCachedCertificate::Init(SecCertificateRef os_cert_handle) { - DCHECK(!cl_handle_ && !cached_cert_handle_); - DCHECK(os_cert_handle); - CSSM_DATA cert_data; - OSStatus status = SecCertificateGetData(os_cert_handle, &cert_data); - if (status) - return status; - status = SecCertificateGetCLHandle(os_cert_handle, &cl_handle_); - if (status) { - DCHECK(!cl_handle_); - return status; - } - - status = CSSM_CL_CertCache(cl_handle_, &cert_data, &cached_cert_handle_); - if (status) - DCHECK(!cached_cert_handle_); - return status; -} - -OSStatus CSSMCachedCertificate::GetField(const CSSM_OID* field_oid, - CSSMFieldValue* field) const { - DCHECK(cl_handle_); - DCHECK(cached_cert_handle_); - - CSSM_OID_PTR oid = const_cast<CSSM_OID_PTR>(field_oid); - CSSM_DATA_PTR field_ptr = NULL; - CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE; - uint32 field_value_count = 0; - CSSM_RETURN status = CSSM_CL_CertGetFirstCachedFieldValue( - cl_handle_, cached_cert_handle_, oid, &results_handle, - &field_value_count, &field_ptr); - if (status) - return status; - - // Note: |field_value_count| may be > 1, indicating that more than one - // value is present. This may happen with extensions, but for current - // usages, only the first value is returned. - CSSM_CL_CertAbortQuery(cl_handle_, results_handle); - field->Reset(cl_handle_, oid, field_ptr); - return CSSM_OK; -} - -} // namespace x509_util - -} // namespace net diff --git a/net/base/x509_util_mac.h b/net/base/x509_util_mac.h deleted file mode 100644 index 9272bc7..0000000 --- a/net/base/x509_util_mac.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_UTIL_MAC_H_ -#define NET_BASE_X509_UTIL_MAC_H_ - -#include <CoreFoundation/CFArray.h> -#include <Security/Security.h> - -#include <string> - -#include "base/basictypes.h" -#include "net/base/net_export.h" - -namespace net { - -namespace x509_util { - -// Creates a security policy for certificates used as client certificates -// in SSL. -// If a policy is successfully created, it will be stored in -// |*policy| and ownership transferred to the caller. -OSStatus NET_EXPORT CreateSSLClientPolicy(SecPolicyRef* policy); - -// Create an SSL server policy. While certificate name validation will be -// performed by SecTrustEvaluate(), it has the following limitations: -// - Doesn't support IP addresses in dotted-quad literals (127.0.0.1) -// - Doesn't support IPv6 addresses -// - Doesn't support the iPAddress subjectAltName -// Providing the hostname is necessary in order to locate certain user or -// system trust preferences, such as those created by Safari. Preferences -// created by Keychain Access do not share this requirement. -// On success, stores the resultant policy in |*policy| and returns noErr. -OSStatus NET_EXPORT CreateSSLServerPolicy(const std::string& hostname, - SecPolicyRef* policy); - -// Creates a security policy for basic X.509 validation. If the policy is -// successfully created, it will be stored in |*policy| and ownership -// transferred to the caller. -OSStatus NET_EXPORT CreateBasicX509Policy(SecPolicyRef* policy); - -// Creates security policies to control revocation checking (OCSP and CRL). -// If |enable_revocation_checking| is true, revocation checking will be -// explicitly enabled. -// If |enable_revocation_checking| is false, but |enable_ev_checking| is -// true, then the system policies for EV checking (which include checking -// for an online OCSP response) will be permitted. However, if the OS -// does not believe the certificate is EV, no revocation checking will be -// performed. -// If both are false, then the policies returned will be explicitly -// prohibited from accessing the network or the local cache, regardless of -// system settings. -// If the policies are successfully created, they will be appended to -// |policies|. -OSStatus NET_EXPORT CreateRevocationPolicies(bool enable_revocation_checking, - bool enable_ev_checking, - CFMutableArrayRef policies); - -// Wrapper for a CSSM_DATA_PTR that was obtained via one of the CSSM field -// accessors (such as CSSM_CL_CertGet[First/Next]Value or -// CSSM_CL_CertGet[First/Next]CachedValue). -class CSSMFieldValue { - public: - CSSMFieldValue(); - CSSMFieldValue(CSSM_CL_HANDLE cl_handle, - const CSSM_OID* oid, - CSSM_DATA_PTR field); - ~CSSMFieldValue(); - - CSSM_OID_PTR oid() const { return oid_; } - CSSM_DATA_PTR field() const { return field_; } - - // Returns the field as if it was an arbitrary type - most commonly, by - // interpreting the field as a specific CSSM/CDSA parsed type, such as - // CSSM_X509_SUBJECT_PUBLIC_KEY_INFO or CSSM_X509_ALGORITHM_IDENTIFIER. - // An added check is applied to ensure that the current field is large - // enough to actually contain the requested type. - template <typename T> const T* GetAs() const { - if (!field_ || field_->Length < sizeof(T)) - return NULL; - return reinterpret_cast<const T*>(field_->Data); - } - - void Reset(CSSM_CL_HANDLE cl_handle, - CSSM_OID_PTR oid, - CSSM_DATA_PTR field); - - private: - CSSM_CL_HANDLE cl_handle_; - CSSM_OID_PTR oid_; - CSSM_DATA_PTR field_; - - DISALLOW_COPY_AND_ASSIGN(CSSMFieldValue); -}; - -// CSSMCachedCertificate is a container class that is used to wrap the -// CSSM_CL_CertCache APIs and provide safe and efficient access to -// certificate fields in their CSSM form. -// -// To provide efficient access to certificate/CRL fields, CSSM provides an -// API/SPI to "cache" a certificate/CRL. The exact meaning of a cached -// certificate is not defined by CSSM, but is documented to generally be some -// intermediate or parsed form of the certificate. In the case of Apple's -// CSSM CL implementation, the intermediate form is the parsed certificate -// stored in an internal format (which happens to be NSS). By caching the -// certificate, callers that wish to access multiple fields (such as subject, -// issuer, and validity dates) do not need to repeatedly parse the entire -// certificate, nor are they forced to convert all fields from their NSS types -// to their CSSM equivalents. This latter point is especially helpful when -// running on OS X 10.5, as it will fail to convert some fields that reference -// unsupported algorithms, such as ECC. -class CSSMCachedCertificate { - public: - CSSMCachedCertificate(); - ~CSSMCachedCertificate(); - - // Initializes the CSSMCachedCertificate by caching the specified - // |os_cert_handle|. On success, returns noErr. - // Note: Once initialized, the cached certificate should only be accessed - // from a single thread. - OSStatus Init(SecCertificateRef os_cert_handle); - - // Fetches the first value for the field associated with |field_oid|. - // If |field_oid| is a valid OID and is present in the current certificate, - // returns CSSM_OK and stores the first value in |field|. If additional - // values are associated with |field_oid|, they are ignored. - OSStatus GetField(const CSSM_OID* field_oid, CSSMFieldValue* field) const; - - private: - CSSM_CL_HANDLE cl_handle_; - CSSM_HANDLE cached_cert_handle_; -}; - -} // namespace x509_util - -} // namespace net - -#endif // NET_BASE_X509_UTIL_MAC_H_ diff --git a/net/base/x509_util_nss.cc b/net/base/x509_util_nss.cc deleted file mode 100644 index f4c253f..0000000 --- a/net/base/x509_util_nss.cc +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util.h" -#include "net/base/x509_util_nss.h" - -#include <cert.h> -#include <cryptohi.h> -#include <nss.h> -#include <pk11pub.h> -#include <prerror.h> -#include <secder.h> -#include <secmod.h> -#include <secport.h> - -#include "base/debug/leak_annotations.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/singleton.h" -#include "base/pickle.h" -#include "crypto/ec_private_key.h" -#include "crypto/nss_util.h" -#include "crypto/nss_util_internal.h" -#include "crypto/scoped_nss_types.h" -#include "crypto/third_party/nss/chromium-nss.h" -#include "net/base/x509_certificate.h" - -namespace net { - -namespace { - -class DomainBoundCertOIDWrapper { - public: - static DomainBoundCertOIDWrapper* GetInstance() { - // Instantiated as a leaky singleton to allow the singleton to be - // constructed on a worker thead that is not joined when a process - // shuts down. - return Singleton<DomainBoundCertOIDWrapper, - LeakySingletonTraits<DomainBoundCertOIDWrapper> >::get(); - } - - SECOidTag domain_bound_cert_oid_tag() const { - return domain_bound_cert_oid_tag_; - } - - private: - friend struct DefaultSingletonTraits<DomainBoundCertOIDWrapper>; - - DomainBoundCertOIDWrapper(); - - SECOidTag domain_bound_cert_oid_tag_; - - DISALLOW_COPY_AND_ASSIGN(DomainBoundCertOIDWrapper); -}; - -DomainBoundCertOIDWrapper::DomainBoundCertOIDWrapper() - : domain_bound_cert_oid_tag_(SEC_OID_UNKNOWN) { - // 1.3.6.1.4.1.11129.2.1.6 - // (iso.org.dod.internet.private.enterprises.google.googleSecurity. - // certificateExtensions.originBoundCertificate) - static const uint8 kObCertOID[] = { - 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x06 - }; - SECOidData oid_data; - memset(&oid_data, 0, sizeof(oid_data)); - oid_data.oid.data = const_cast<uint8*>(kObCertOID); - oid_data.oid.len = sizeof(kObCertOID); - oid_data.offset = SEC_OID_UNKNOWN; - oid_data.desc = "Origin Bound Certificate"; - oid_data.mechanism = CKM_INVALID_MECHANISM; - oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION; - domain_bound_cert_oid_tag_ = SECOID_AddEntry(&oid_data); - if (domain_bound_cert_oid_tag_ == SEC_OID_UNKNOWN) - LOG(ERROR) << "OB_CERT OID tag creation failed"; -} - -// Creates a Certificate object that may be passed to the SignCertificate -// method to generate an X509 certificate. -// Returns NULL if an error is encountered in the certificate creation -// process. -// Caller responsible for freeing returned certificate object. -CERTCertificate* CreateCertificate( - SECKEYPublicKey* public_key, - const std::string& subject, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after) { - // Create info about public key. - CERTSubjectPublicKeyInfo* spki = - SECKEY_CreateSubjectPublicKeyInfo(public_key); - if (!spki) - return NULL; - - // Create the certificate request. - CERTName* subject_name = - CERT_AsciiToName(const_cast<char*>(subject.c_str())); - CERTCertificateRequest* cert_request = - CERT_CreateCertificateRequest(subject_name, spki, NULL); - SECKEY_DestroySubjectPublicKeyInfo(spki); - - if (!cert_request) { - PRErrorCode prerr = PR_GetError(); - LOG(ERROR) << "Failed to create certificate request: " << prerr; - CERT_DestroyName(subject_name); - return NULL; - } - - CERTValidity* validity = CERT_CreateValidity( - crypto::BaseTimeToPRTime(not_valid_before), - crypto::BaseTimeToPRTime(not_valid_after)); - if (!validity) { - PRErrorCode prerr = PR_GetError(); - LOG(ERROR) << "Failed to create certificate validity object: " << prerr; - CERT_DestroyName(subject_name); - CERT_DestroyCertificateRequest(cert_request); - return NULL; - } - CERTCertificate* cert = CERT_CreateCertificate(serial_number, subject_name, - validity, cert_request); - if (!cert) { - PRErrorCode prerr = PR_GetError(); - LOG(ERROR) << "Failed to create certificate: " << prerr; - } - - // Cleanup for resources used to generate the cert. - CERT_DestroyName(subject_name); - CERT_DestroyValidity(validity); - CERT_DestroyCertificateRequest(cert_request); - - return cert; -} - -// Signs a certificate object, with |key| generating a new X509Certificate -// and destroying the passed certificate object (even when NULL is returned). -// The logic of this method references SignCert() in NSS utility certutil: -// http://mxr.mozilla.org/security/ident?i=SignCert. -// Returns true on success or false if an error is encountered in the -// certificate signing process. -bool SignCertificate( - CERTCertificate* cert, - SECKEYPrivateKey* key) { - // |arena| is used to encode the cert. - PLArenaPool* arena = cert->arena; - SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->keyType, - SEC_OID_SHA1); - if (algo_id == SEC_OID_UNKNOWN) - return false; - - SECStatus rv = SECOID_SetAlgorithmID(arena, &cert->signature, algo_id, 0); - if (rv != SECSuccess) - return false; - - // Generate a cert of version 3. - *(cert->version.data) = 2; - cert->version.len = 1; - - SECItem der = { siBuffer, NULL, 0 }; - - // Use ASN1 DER to encode the cert. - void* encode_result = SEC_ASN1EncodeItem( - NULL, &der, cert, SEC_ASN1_GET(CERT_CertificateTemplate)); - if (!encode_result) - return false; - - // Allocate space to contain the signed cert. - SECItem result = { siBuffer, NULL, 0 }; - - // Sign the ASN1 encoded cert and save it to |result|. - rv = DerSignData(arena, &result, &der, key, algo_id); - PORT_Free(der.data); - if (rv != SECSuccess) { - DLOG(ERROR) << "DerSignData: " << PORT_GetError(); - return false; - } - - // Save the signed result to the cert. - cert->derCert = result; - - return true; -} - -bool CreateDomainBoundCertInternal( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert) { - CERTCertificate* cert = CreateCertificate(public_key, - "CN=anonymous.invalid", - serial_number, - not_valid_before, - not_valid_after); - - if (!cert) - return false; - - // Create opaque handle used to add extensions later. - void* cert_handle; - if ((cert_handle = CERT_StartCertExtensions(cert)) == NULL) { - LOG(ERROR) << "Unable to get opaque handle for adding extensions"; - CERT_DestroyCertificate(cert); - return false; - } - - // Create SECItem for IA5String encoding. - SECItem domain_string_item = { - siAsciiString, - (unsigned char*)domain.data(), - static_cast<unsigned>(domain.size()) - }; - - // IA5Encode and arena allocate SECItem - SECItem* asn1_domain_string = SEC_ASN1EncodeItem( - cert->arena, NULL, &domain_string_item, - SEC_ASN1_GET(SEC_IA5StringTemplate)); - if (asn1_domain_string == NULL) { - LOG(ERROR) << "Unable to get ASN1 encoding for domain in domain_bound_cert" - " extension"; - CERT_DestroyCertificate(cert); - return false; - } - - // Add the extension to the opaque handle - if (CERT_AddExtension( - cert_handle, - DomainBoundCertOIDWrapper::GetInstance()->domain_bound_cert_oid_tag(), - asn1_domain_string, PR_TRUE, PR_TRUE) != SECSuccess){ - LOG(ERROR) << "Unable to add domain bound cert extension to opaque handle"; - CERT_DestroyCertificate(cert); - return false; - } - - // Copy extension into x509 cert - if (CERT_FinishExtensions(cert_handle) != SECSuccess){ - LOG(ERROR) << "Unable to copy extension to X509 cert"; - CERT_DestroyCertificate(cert); - return false; - } - - if (!SignCertificate(cert, private_key)) { - CERT_DestroyCertificate(cert); - return false; - } - - DCHECK(cert->derCert.len); - // XXX copied from X509Certificate::GetDEREncoded - der_cert->clear(); - der_cert->append(reinterpret_cast<char*>(cert->derCert.data), - cert->derCert.len); - CERT_DestroyCertificate(cert); - return true; -} - -#if defined(USE_NSS) || defined(OS_IOS) -// Callback for CERT_DecodeCertPackage(), used in -// CreateOSCertHandlesFromBytes(). -SECStatus PR_CALLBACK CollectCertsCallback(void* arg, - SECItem** certs, - int num_certs) { - X509Certificate::OSCertHandles* results = - reinterpret_cast<X509Certificate::OSCertHandles*>(arg); - - for (int i = 0; i < num_certs; ++i) { - X509Certificate::OSCertHandle handle = - X509Certificate::CreateOSCertHandleFromBytes( - reinterpret_cast<char*>(certs[i]->data), certs[i]->len); - if (handle) - results->push_back(handle); - } - - return SECSuccess; -} - -typedef scoped_ptr_malloc< - CERTName, - crypto::NSSDestroyer<CERTName, CERT_DestroyName> > ScopedCERTName; - -// Create a new CERTName object from its encoded representation. -// |arena| is the allocation pool to use. -// |data| points to a DER-encoded X.509 DistinguishedName. -// Return a new CERTName pointer on success, or NULL. -CERTName* CreateCertNameFromEncoded(PLArenaPool* arena, - const base::StringPiece& data) { - if (!arena) - return NULL; - - ScopedCERTName name(PORT_ArenaZNew(arena, CERTName)); - if (!name.get()) - return NULL; - - SECItem item; - item.len = static_cast<unsigned int>(data.length()); - item.data = reinterpret_cast<unsigned char*>( - const_cast<char*>(data.data())); - - SECStatus rv = SEC_ASN1DecodeItem( - arena, name.get(), SEC_ASN1_GET(CERT_NameTemplate), &item); - if (rv != SECSuccess) - return NULL; - - return name.release(); -} - -#endif // defined(USE_NSS) || defined(OS_IOS) - -} // namespace - -namespace x509_util { - -CERTCertificate* CreateSelfSignedCert( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& subject, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after) { - CERTCertificate* cert = CreateCertificate(public_key, - subject, - serial_number, - not_valid_before, - not_valid_after); - if (!cert) - return NULL; - - if (!SignCertificate(cert, private_key)) { - CERT_DestroyCertificate(cert); - return NULL; - } - - return cert; -} - -bool IsSupportedValidityRange(base::Time not_valid_before, - base::Time not_valid_after) { - CERTValidity* validity = CERT_CreateValidity( - crypto::BaseTimeToPRTime(not_valid_before), - crypto::BaseTimeToPRTime(not_valid_after)); - - if (!validity) - return false; - - CERT_DestroyValidity(validity); - return true; -} - -bool CreateDomainBoundCertEC( - crypto::ECPrivateKey* key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert) { - DCHECK(key); - return CreateDomainBoundCertInternal(key->public_key(), - key->key(), - domain, - serial_number, - not_valid_before, - not_valid_after, - der_cert); -} - -#if defined(USE_NSS) || defined(OS_IOS) -void ParsePrincipal(CERTName* name, CertPrincipal* principal) { - typedef char* (*CERTGetNameFunc)(CERTName* name); - - // TODO(jcampan): add business_category and serial_number. - // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and - // CERT_GetDomainComponentName functions, but they return only the most - // general (the first) RDN. NSS doesn't have a function for the street - // address. - static const SECOidTag kOIDs[] = { - SEC_OID_AVA_STREET_ADDRESS, - SEC_OID_AVA_ORGANIZATION_NAME, - SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, - SEC_OID_AVA_DC }; - - std::vector<std::string>* values[] = { - &principal->street_addresses, - &principal->organization_names, - &principal->organization_unit_names, - &principal->domain_components }; - DCHECK_EQ(arraysize(kOIDs), arraysize(values)); - - CERTRDN** rdns = name->rdns; - for (size_t rdn = 0; rdns[rdn]; ++rdn) { - CERTAVA** avas = rdns[rdn]->avas; - for (size_t pair = 0; avas[pair] != 0; ++pair) { - SECOidTag tag = CERT_GetAVATag(avas[pair]); - for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { - if (kOIDs[oid] == tag) { - SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value); - if (!decode_item) - break; - // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote. - std::string value(reinterpret_cast<char*>(decode_item->data), - decode_item->len); - values[oid]->push_back(value); - SECITEM_FreeItem(decode_item, PR_TRUE); - break; - } - } - } - } - - // Get CN, L, S, and C. - CERTGetNameFunc get_name_funcs[4] = { - CERT_GetCommonName, CERT_GetLocalityName, - CERT_GetStateName, CERT_GetCountryName }; - std::string* single_values[4] = { - &principal->common_name, &principal->locality_name, - &principal->state_or_province_name, &principal->country_name }; - for (size_t i = 0; i < arraysize(get_name_funcs); ++i) { - char* value = get_name_funcs[i](name); - if (value) { - single_values[i]->assign(value); - PORT_Free(value); - } - } -} - -void ParseDate(const SECItem* der_date, base::Time* result) { - PRTime prtime; - SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date); - DCHECK_EQ(SECSuccess, rv); - *result = crypto::PRTimeToBaseTime(prtime); -} - -std::string ParseSerialNumber(const CERTCertificate* certificate) { - return std::string(reinterpret_cast<char*>(certificate->serialNumber.data), - certificate->serialNumber.len); -} - -void GetSubjectAltName(CERTCertificate* cert_handle, - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs) { - if (dns_names) - dns_names->clear(); - if (ip_addrs) - ip_addrs->clear(); - - SECItem alt_name; - SECStatus rv = CERT_FindCertExtension(cert_handle, - SEC_OID_X509_SUBJECT_ALT_NAME, - &alt_name); - if (rv != SECSuccess) - return; - - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - DCHECK(arena != NULL); - - CERTGeneralName* alt_name_list; - alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name); - SECITEM_FreeItem(&alt_name, PR_FALSE); - - CERTGeneralName* name = alt_name_list; - while (name) { - // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs - // respectively, both of which can be byte copied from - // SECItemType::data into the appropriate output vector. - if (dns_names && name->type == certDNSName) { - dns_names->push_back(std::string( - reinterpret_cast<char*>(name->name.other.data), - name->name.other.len)); - } else if (ip_addrs && name->type == certIPAddress) { - ip_addrs->push_back(std::string( - reinterpret_cast<char*>(name->name.other.data), - name->name.other.len)); - } - name = CERT_GetNextGeneralName(name); - if (name == alt_name_list) - break; - } - PORT_FreeArena(arena, PR_FALSE); -} - -X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes( - const char* data, - int length, - X509Certificate::Format format) { - X509Certificate::OSCertHandles results; - if (length < 0) - return results; - - crypto::EnsureNSSInit(); - - if (!NSS_IsInitialized()) - return results; - - switch (format) { - case X509Certificate::FORMAT_SINGLE_CERTIFICATE: { - X509Certificate::OSCertHandle handle = - X509Certificate::CreateOSCertHandleFromBytes(data, length); - if (handle) - results.push_back(handle); - break; - } - case X509Certificate::FORMAT_PKCS7: { - // Make a copy since CERT_DecodeCertPackage may modify it - std::vector<char> data_copy(data, data + length); - - SECStatus result = CERT_DecodeCertPackage(&data_copy[0], - length, CollectCertsCallback, &results); - if (result != SECSuccess) - results.clear(); - break; - } - default: - NOTREACHED() << "Certificate format " << format << " unimplemented"; - break; - } - - return results; -} - -X509Certificate::OSCertHandle ReadOSCertHandleFromPickle( - PickleIterator* pickle_iter) { - const char* data; - int length; - if (!pickle_iter->ReadData(&data, &length)) - return NULL; - - return X509Certificate::CreateOSCertHandleFromBytes(data, length); -} - -void GetPublicKeyInfo(CERTCertificate* handle, - size_t* size_bits, - X509Certificate::PublicKeyType* type) { - // Since we might fail, set the output parameters to default values first. - *type = X509Certificate::kPublicKeyTypeUnknown; - *size_bits = 0; - - crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle)); - if (!key.get()) - return; - - *size_bits = SECKEY_PublicKeyStrengthInBits(key.get()); - - switch (key->keyType) { - case rsaKey: - *type = X509Certificate::kPublicKeyTypeRSA; - break; - case dsaKey: - *type = X509Certificate::kPublicKeyTypeDSA; - break; - case dhKey: - *type = X509Certificate::kPublicKeyTypeDH; - break; - case ecKey: - *type = X509Certificate::kPublicKeyTypeECDSA; - break; - default: - *type = X509Certificate::kPublicKeyTypeUnknown; - *size_bits = 0; - break; - } -} - -bool GetIssuersFromEncodedList( - const std::vector<std::string>& encoded_issuers, - PLArenaPool* arena, - std::vector<CERTName*>* out) { - std::vector<CERTName*> result; - for (size_t n = 0; n < encoded_issuers.size(); ++n) { - CERTName* name = CreateCertNameFromEncoded(arena, encoded_issuers[n]); - if (name != NULL) - result.push_back(name); - } - - if (result.size() == encoded_issuers.size()) { - out->swap(result); - return true; - } - - for (size_t n = 0; n < result.size(); ++n) - CERT_DestroyName(result[n]); - return false; -} - - -bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain, - const std::vector<CERTName*>& valid_issuers) { - for (size_t n = 0; n < cert_chain.size(); ++n) { - CERTName* cert_issuer = &cert_chain[n]->issuer; - for (size_t i = 0; i < valid_issuers.size(); ++i) { - if (CERT_CompareName(valid_issuers[i], cert_issuer) == SECEqual) - return true; - } - } - return false; -} - -#endif // defined(USE_NSS) || defined(OS_IOS) - -} // namespace x509_util - -} // namespace net diff --git a/net/base/x509_util_nss.h b/net/base/x509_util_nss.h deleted file mode 100644 index f40c503..0000000 --- a/net/base/x509_util_nss.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_UTIL_NSS_H_ -#define NET_BASE_X509_UTIL_NSS_H_ - -#include <string> -#include <vector> - -#include "base/time.h" -#include "net/base/x509_certificate.h" - -class PickleIterator; - -typedef struct CERTCertificateStr CERTCertificate; -typedef struct CERTNameStr CERTName; -typedef struct PLArenaPool PLArenaPool; -typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; -typedef struct SECItemStr SECItem; -typedef struct SECKEYPublicKeyStr SECKEYPublicKey; - -namespace net { - -namespace x509_util { - -// Creates a self-signed certificate containing |public_key|. Subject, serial -// number and validity period are given as parameters. The certificate is -// signed by |private_key|. The hashing algorithm for the signature is SHA-1. -// |subject| is a distinguished name defined in RFC4514. -CERTCertificate* CreateSelfSignedCert( - SECKEYPublicKey* public_key, - SECKEYPrivateKey* private_key, - const std::string& subject, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after); - -#if defined(USE_NSS) || defined(OS_IOS) -// Parses the Principal attribute from |name| and outputs the result in -// |principal|. -void ParsePrincipal(CERTName* name, - CertPrincipal* principal); - -// Parses the date from |der_date| and outputs the result in |result|. -void ParseDate(const SECItem* der_date, base::Time* result); - -// Parses the serial number from |certificate|. -std::string ParseSerialNumber(const CERTCertificate* certificate); - -// Gets the subjectAltName extension field from the certificate, if any. -void GetSubjectAltName(CERTCertificate* cert_handle, - std::vector<std::string>* dns_names, - std::vector<std::string>* ip_addrs); - -// Creates all possible OS certificate handles from |data| encoded in a specific -// |format|. Returns an empty collection on failure. -X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes( - const char* data, - int length, - X509Certificate::Format format); - -// Reads a single certificate from |pickle_iter| and returns a platform-specific -// certificate handle. Returns an invalid handle, NULL, on failure. -X509Certificate::OSCertHandle ReadOSCertHandleFromPickle( - PickleIterator* pickle_iter); - -// Sets |*size_bits| to be the length of the public key in bits, and sets -// |*type| to one of the |PublicKeyType| values. In case of -// |kPublicKeyTypeUnknown|, |*size_bits| will be set to 0. -void GetPublicKeyInfo(CERTCertificate* handle, - size_t* size_bits, - X509Certificate::PublicKeyType* type); - -// Create a list of CERTName objects from a list of DER-encoded X.509 -// DistinguishedName items. All objects are created in a given arena. -// |encoded_issuers| is the list of encoded DNs. -// |arena| is the arena used for all allocations. -// |out| will receive the result list on success. -// Return true on success. On failure, the caller must free the -// intermediate CERTName objects pushed to |out|. -bool GetIssuersFromEncodedList( - const std::vector<std::string>& issuers, - PLArenaPool* arena, - std::vector<CERTName*>* out); - -// Returns true iff a certificate is issued by any of the issuers listed -// by name in |valid_issuers|. -// |cert_chain| is the certificate's chain. -// |valid_issuers| is a list of strings, where each string contains -// a DER-encoded X.509 Distinguished Name. -bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain, - const std::vector<CERTName*>& valid_issuers); - -#endif // defined(USE_NSS) || defined(OS_IOS) - -} // namespace x509_util - -} // namespace net - -#endif // NET_BASE_X509_UTIL_NSS_H_ diff --git a/net/base/x509_util_nss_unittest.cc b/net/base/x509_util_nss_unittest.cc deleted file mode 100644 index c0dfd42..0000000 --- a/net/base/x509_util_nss_unittest.cc +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util.h" -#include "net/base/x509_util_nss.h" - -#include <cert.h> -#include <secoid.h> - -#include "base/memory/scoped_ptr.h" -#include "base/memory/ref_counted.h" -#include "crypto/ec_private_key.h" -#include "crypto/scoped_nss_types.h" -#include "crypto/signature_verifier.h" -#include "net/base/x509_certificate.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -CERTCertificate* CreateNSSCertHandleFromBytes(const char* data, size_t length) { - SECItem der_cert; - der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); - der_cert.len = length; - der_cert.type = siDERCertBuffer; - - // Parse into a certificate structure. - return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL, - PR_FALSE, PR_TRUE); -} - -#if !defined(OS_WIN) && !defined(OS_MACOSX) -void VerifyCertificateSignature(const std::string& der_cert, - const std::vector<uint8>& der_spki) { - crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - - CERTSignedData sd; - memset(&sd, 0, sizeof(sd)); - - SECItem der_cert_item = { - siDERCertBuffer, - reinterpret_cast<unsigned char*>(const_cast<char*>(der_cert.data())), - static_cast<unsigned int>(der_cert.size()) - }; - SECStatus rv = SEC_ASN1DecodeItem(arena.get(), &sd, - SEC_ASN1_GET(CERT_SignedDataTemplate), - &der_cert_item); - ASSERT_EQ(SECSuccess, rv); - - // The CERTSignedData.signatureAlgorithm is decoded, but SignatureVerifier - // wants the DER encoded form, so re-encode it again. - SECItem* signature_algorithm = SEC_ASN1EncodeItem( - arena.get(), - NULL, - &sd.signatureAlgorithm, - SEC_ASN1_GET(SECOID_AlgorithmIDTemplate)); - ASSERT_TRUE(signature_algorithm); - - crypto::SignatureVerifier verifier; - bool ok = verifier.VerifyInit( - signature_algorithm->data, - signature_algorithm->len, - sd.signature.data, - sd.signature.len / 8, // Signature is a BIT STRING, convert to bytes. - &der_spki[0], - der_spki.size()); - - ASSERT_TRUE(ok); - verifier.VerifyUpdate(sd.data.data, - sd.data.len); - - ok = verifier.VerifyFinal(); - EXPECT_TRUE(ok); -} -#endif // !defined(OS_WIN) && !defined(OS_MACOSX) - -void VerifyDomainBoundCert(const std::string& domain, - const std::string& der_cert) { - // Origin Bound Cert OID. - static const char oid_string[] = "1.3.6.1.4.1.11129.2.1.6"; - - // Create object neccessary for extension lookup call. - SECItem extension_object = { - siAsciiString, - (unsigned char*)domain.data(), - static_cast<unsigned int>(domain.size()) - }; - - // IA5Encode and arena allocate SECItem. - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - SECItem* expected = SEC_ASN1EncodeItem(arena, - NULL, - &extension_object, - SEC_ASN1_GET(SEC_IA5StringTemplate)); - - ASSERT_NE(static_cast<SECItem*>(NULL), expected); - - // Create OID SECItem. - SECItem ob_cert_oid = { siDEROID, NULL, 0 }; - SECStatus ok = SEC_StringToOID(arena, &ob_cert_oid, - oid_string, 0); - - ASSERT_EQ(SECSuccess, ok); - - SECOidTag ob_cert_oid_tag = SECOID_FindOIDTag(&ob_cert_oid); - - ASSERT_NE(SEC_OID_UNKNOWN, ob_cert_oid_tag); - - // This test is run on Mac and Win where X509Certificate::os_cert_handle isn't - // an NSS type, so we have to manually create a NSS certificate object so we - // can use CERT_FindCertExtension. We also check the subject and validity - // times using NSS since X509Certificate will fail with EC certs on OSX 10.5 - // (http://crbug.com/101231). - CERTCertificate* nss_cert = CreateNSSCertHandleFromBytes( - der_cert.data(), der_cert.size()); - - char* common_name = CERT_GetCommonName(&nss_cert->subject); - ASSERT_TRUE(common_name); - EXPECT_STREQ("anonymous.invalid", common_name); - PORT_Free(common_name); - EXPECT_EQ(SECSuccess, CERT_CertTimesValid(nss_cert)); - - // Lookup Origin Bound Cert extension in generated cert. - SECItem actual = { siBuffer, NULL, 0 }; - ok = CERT_FindCertExtension(nss_cert, - ob_cert_oid_tag, - &actual); - CERT_DestroyCertificate(nss_cert); - ASSERT_EQ(SECSuccess, ok); - - // Compare expected and actual extension values. - PRBool result = SECITEM_ItemsAreEqual(expected, &actual); - ASSERT_TRUE(result); - - // Do Cleanup. - SECITEM_FreeItem(&actual, PR_FALSE); - PORT_FreeArena(arena, PR_FALSE); -} - -} // namespace - -// This test creates a domain-bound cert from an EC private key and -// then verifies the content of the certificate. -TEST(X509UtilNSSTest, CreateDomainBoundCertEC) { - // Create a sample ASCII weborigin. - std::string domain = "weborigin.com"; - base::Time now = base::Time::Now(); - - scoped_ptr<crypto::ECPrivateKey> private_key( - crypto::ECPrivateKey::Create()); - std::string der_cert; - ASSERT_TRUE(x509_util::CreateDomainBoundCertEC( - private_key.get(), - domain, 1, - now, - now + base::TimeDelta::FromDays(1), - &der_cert)); - - VerifyDomainBoundCert(domain, der_cert); - -#if !defined(OS_WIN) && !defined(OS_MACOSX) - // signature_verifier_win and signature_verifier_mac can't handle EC certs. - std::vector<uint8> spki; - ASSERT_TRUE(private_key->ExportPublicKey(&spki)); - VerifyCertificateSignature(der_cert, spki); -#endif -} - -} // namespace net diff --git a/net/base/x509_util_openssl.cc b/net/base/x509_util_openssl.cc deleted file mode 100644 index 142bf77..0000000 --- a/net/base/x509_util_openssl.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util.h" -#include "net/base/x509_util_openssl.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/string_piece.h" -#include "net/base/x509_cert_types.h" - -namespace net { - -namespace x509_util { - -bool IsSupportedValidityRange(base::Time not_valid_before, - base::Time not_valid_after) { - if (not_valid_before > not_valid_after) - return false; - - // The validity field of a certificate can only encode years 1-9999. - - // Compute the base::Time values corresponding to Jan 1st,0001 and - // Jan 1st, 10000 respectively. Done by using the pre-computed numbers - // of days between these dates and the Unix epoch, i.e. Jan 1st, 1970, - // using the following Python script: - // - // from datetime import date as D - // print (D(1970,1,1)-D(1,1,1)) # -> 719162 days - // print (D(9999,12,31)-D(1970,1,1)) # -> 2932896 days - // - // Note: This ignores leap seconds, but should be enough in practice. - // - const int64 kDaysFromYear0001ToUnixEpoch = 719162; - const int64 kDaysFromUnixEpochToYear10000 = 2932896 + 1; - const base::Time kEpoch = base::Time::UnixEpoch(); - const base::Time kYear0001 = kEpoch - - base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch); - const base::Time kYear10000 = kEpoch + - base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000); - - if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 || - not_valid_after < kYear0001 || not_valid_after >= kYear10000) - return false; - - return true; -} - -bool CreateDomainBoundCertEC( - crypto::ECPrivateKey* key, - const std::string& domain, - uint32 serial_number, - base::Time not_valid_before, - base::Time not_valid_after, - std::string* der_cert) { - NOTIMPLEMENTED(); - return false; -} - -bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, - int index, - std::string* key, - std::string* value) { - X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index); - if (!entry) - return false; - - if (key) { - ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(entry); - key->assign(OBJ_nid2sn(OBJ_obj2nid(object))); - } - - ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); - if (!data) - return false; - - unsigned char* buf = NULL; - int len = ASN1_STRING_to_UTF8(&buf, data); - if (len <= 0) - return false; - - value->assign(reinterpret_cast<const char*>(buf), len); - OPENSSL_free(buf); - return true; -} - -bool ParsePrincipalValueByIndex(X509_NAME* name, - int index, - std::string* value) { - return ParsePrincipalKeyAndValueByIndex(name, index, NULL, value); -} - -bool ParsePrincipalValueByNID(X509_NAME* name, int nid, std::string* value) { - int index = X509_NAME_get_index_by_NID(name, nid, -1); - if (index < 0) - return false; - - return ParsePrincipalValueByIndex(name, index, value); -} - -bool ParseDate(ASN1_TIME* x509_time, base::Time* time) { - if (!x509_time || - (x509_time->type != V_ASN1_UTCTIME && - x509_time->type != V_ASN1_GENERALIZEDTIME)) - return false; - - base::StringPiece str_date(reinterpret_cast<const char*>(x509_time->data), - x509_time->length); - - CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? - CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; - return ParseCertificateDate(str_date, format, time); -} - -} // namespace x509_util - -} // namespace net diff --git a/net/base/x509_util_openssl.h b/net/base/x509_util_openssl.h deleted file mode 100644 index ad51425..0000000 --- a/net/base/x509_util_openssl.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_X509_UTIL_OPENSSL_H_ -#define NET_BASE_X509_UTIL_OPENSSL_H_ - -#include <openssl/asn1.h> -#include <openssl/x509v3.h> - -#include <string> -#include <vector> - -#include "net/base/net_export.h" - -namespace base { -class Time; -} // namespace base - -namespace net { - -// A collection of helper functions to fetch data from OpenSSL X509 certificates -// into more convenient std / base datatypes. -namespace x509_util { - -bool NET_EXPORT ParsePrincipalKeyAndValueByIndex(X509_NAME* name, - int index, - std::string* key, - std::string* value); - -bool NET_EXPORT ParsePrincipalValueByIndex(X509_NAME* name, - int index, - std::string* value); - -bool NET_EXPORT ParsePrincipalValueByNID(X509_NAME* name, - int nid, - std::string* value); - -bool NET_EXPORT ParseDate(ASN1_TIME* x509_time, base::Time* time); - -} // namespace x509_util - -} // namespace net - -#endif // NET_BASE_X509_UTIL_OPENSSL_H_ diff --git a/net/base/x509_util_openssl_unittest.cc b/net/base/x509_util_openssl_unittest.cc deleted file mode 100644 index eea3984..0000000 --- a/net/base/x509_util_openssl_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/scoped_ptr.h" -#include "crypto/ec_private_key.h" -#include "net/base/x509_util.h" -#include "net/base/x509_util_openssl.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -TEST(X509UtilOpenSSLTest, IsSupportedValidityRange) { - base::Time now = base::Time::Now(); - EXPECT_TRUE(x509_util::IsSupportedValidityRange(now, now)); - EXPECT_FALSE(x509_util::IsSupportedValidityRange( - now, now - base::TimeDelta::FromSeconds(1))); - - // See x509_util_openssl.cc to see how these were computed. - const int64 kDaysFromYear0001ToUnixEpoch = 719162; - const int64 kDaysFromUnixEpochToYear10000 = 2932896 + 1; - - // When computing too_old / too_late, add one day to account for - // possible leap seconds. - base::Time too_old = base::Time::UnixEpoch() - - base::TimeDelta::FromDays(kDaysFromYear0001ToUnixEpoch + 1); - - base::Time too_late = base::Time::UnixEpoch() + - base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000 + 1); - - EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, too_old)); - EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_old, now)); - - EXPECT_FALSE(x509_util::IsSupportedValidityRange(now, too_late)); - EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_late, too_late)); -} - -// For OpenSSL, x509_util::CreateDomainBoundCertEC() is not yet implemented -// and should return false. This unit test ensures that a stub implementation -// is present. -TEST(X509UtilOpenSSLTest, CreateDomainBoundCertNotImplemented) { - std::string domain = "weborigin.com"; - base::Time now = base::Time::Now(); - scoped_ptr<crypto::ECPrivateKey> private_key( - crypto::ECPrivateKey::Create()); - std::string der_cert; - EXPECT_FALSE(x509_util::CreateDomainBoundCertEC( - private_key.get(), - domain, 1, - now, - now + base::TimeDelta::FromDays(1), - &der_cert)); - EXPECT_TRUE(der_cert.empty()); - -} - -} // namespace net diff --git a/net/base/x509_util_unittest.cc b/net/base/x509_util_unittest.cc deleted file mode 100644 index 34c1781..0000000 --- a/net/base/x509_util_unittest.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/x509_util.h" - -#include <algorithm> - -#include "base/time.h" -#include "net/base/x509_certificate.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace x509_util { - -TEST(X509UtilTest, SortClientCertificates) { - CertificateList certs; - - const base::Time now = base::Time::Now(); - const base::TimeDelta five_days = base::TimeDelta::FromDays(5); - - certs.push_back(scoped_refptr<X509Certificate>(NULL)); - certs.push_back(new X509Certificate( - "expired", "expired", - base::Time::UnixEpoch(), base::Time::UnixEpoch())); - certs.push_back(new X509Certificate( - "not yet valid", "not yet valid", - base::Time::Max(), base::Time::Max())); - certs.push_back(new X509Certificate( - "older cert", "older cert", - now - five_days, now + five_days)); - certs.push_back(scoped_refptr<X509Certificate>(NULL)); - certs.push_back(new X509Certificate( - "newer cert", "newer cert", - now - base::TimeDelta::FromDays(3), now + five_days)); - - std::sort(certs.begin(), certs.end(), ClientCertSorter()); - - ASSERT_TRUE(certs[0].get()); - EXPECT_EQ("newer cert", certs[0]->subject().common_name); - ASSERT_TRUE(certs[1].get()); - EXPECT_EQ("older cert", certs[1]->subject().common_name); - ASSERT_TRUE(certs[2].get()); - EXPECT_EQ("not yet valid", certs[2]->subject().common_name); - ASSERT_TRUE(certs[3].get()); - EXPECT_EQ("expired", certs[3]->subject().common_name); - ASSERT_FALSE(certs[4].get()); - ASSERT_FALSE(certs[5].get()); -} - -} // namespace x509_util - -} // namespace net |