diff options
author | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 21:49:42 +0000 |
---|---|---|
committer | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 21:49:42 +0000 |
commit | 78d36a2f101aaa7dea9820b7001672c8f5f78f4f (patch) | |
tree | d6a12039ba0d4473fdb4a5232e5ed0c523d40822 /net | |
parent | 3213339b064c87a06785145cbe86de65cf42fd6e (diff) | |
download | chromium_src-78d36a2f101aaa7dea9820b7001672c8f5f78f4f.zip chromium_src-78d36a2f101aaa7dea9820b7001672c8f5f78f4f.tar.gz chromium_src-78d36a2f101aaa7dea9820b7001672c8f5f78f4f.tar.bz2 |
Revert due to compile failures
Revert 42822 - Mac: Make clientcert picker only show certs the server will accept.
BUG=38691
TEST=manual testing with various sites
Review URL: http://codereview.chromium.org/1128008
TBR=snej@chromium.org
Review URL: http://codereview.chromium.org/1417003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42830 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/x509_cert_types.cc | 112 | ||||
-rw-r--r-- | net/base/x509_cert_types.h | 133 | ||||
-rw-r--r-- | net/base/x509_cert_types_mac.cc | 293 | ||||
-rw-r--r-- | net/base/x509_cert_types_unittest.cc | 343 | ||||
-rw-r--r-- | net/base/x509_certificate.cc | 49 | ||||
-rw-r--r-- | net/base/x509_certificate.h | 96 | ||||
-rw-r--r-- | net/base/x509_certificate_mac.cc | 198 | ||||
-rw-r--r-- | net/net.gyp | 4 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_mac.cc | 29 |
9 files changed, 235 insertions, 1022 deletions
diff --git a/net/base/x509_cert_types.cc b/net/base/x509_cert_types.cc deleted file mode 100644 index 8329216..0000000 --- a/net/base/x509_cert_types.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2006-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/x509_cert_types.h" - -#include "net/base/x509_certificate.h" -#include "base/logging.h" - -namespace net { - -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; -} - - -bool CertPrincipal::Matches(const CertPrincipal& against) const { - return match(common_name, against.common_name) && - 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); -} - -std::ostream& operator<<(std::ostream& s, const CertPrincipal& p) { - s << "CertPrincipal["; - if (!p.common_name.empty()) - s << "cn=\"" << p.common_name << "\" "; - for (unsigned i = 0; i < p.street_addresses.size(); ++i) - s << "street=\"" << p.street_addresses[i] << "\" "; - if (!p.locality_name.empty()) - s << "l=\"" << p.locality_name << "\" "; - for (unsigned i = 0; i < p.organization_names.size(); ++i) - s << "o=\"" << p.organization_names[i] << "\" "; - for (unsigned i = 0; i < p.organization_unit_names.size(); ++i) - s << "ou=\"" << p.organization_unit_names[i] << "\" "; - if (!p.state_or_province_name.empty()) - s << "st=\"" << p.state_or_province_name << "\" "; - if (!p.country_name.empty()) - s << "c=\"" << p.country_name << "\" "; - for (unsigned i = 0; i < p.domain_components.size(); ++i) - s << "dc=\"" << p.domain_components[i] << "\" "; - return s << "]"; -} - -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(); -} - -} // namespace net diff --git a/net/base/x509_cert_types.h b/net/base/x509_cert_types.h deleted file mode 100644 index cf23f58..0000000 --- a/net/base/x509_cert_types.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2007-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_X509_TYPES_H_ -#define NET_BASE_X509_TYPES_H_ - -#include <string.h> - -#include <iostream> -#include <map> -#include <set> -#include <string> -#include <vector> - -#include "base/ref_counted.h" -#include "base/singleton.h" -#include "base/time.h" -#include "testing/gtest/include/gtest/gtest_prod.h" - -#if defined(OS_WIN) -#include <windows.h> -#include <wincrypt.h> -#elif defined(OS_MACOSX) -#include <Security/x509defs.h> -#elif defined(USE_NSS) -// Forward declaration; real one in <cert.h> -struct CERTCertificateStr; -#endif - -namespace net { - -class X509Certificate; - -// SHA-1 fingerprint (160 bits) of a certificate. -struct SHA1Fingerprint { - bool Equals(const SHA1Fingerprint& other) const { - return memcmp(data, other.data, sizeof(data)) == 0; - } - - unsigned char data[20]; -}; - -class SHA1FingerprintLessThan - : public std::binary_function<SHA1Fingerprint, SHA1Fingerprint, bool> { - public: - bool operator() (const SHA1Fingerprint& lhs, const SHA1Fingerprint& rhs) const; -}; - -// CertPrincipal represents the issuer or subject field of an X.509 certificate. -struct CertPrincipal { - CertPrincipal() { } - explicit CertPrincipal(const std::string& name) : common_name(name) { } - - // Parses a BER-format DistinguishedName. - bool ParseDistinguishedName(const void* ber_name_data, size_t length); - -#if defined(OS_MACOSX) - // Parses a CSSM_X509_NAME struct. - void Parse(const CSSM_X509_NAME* name); -#endif - - // Returns true if all attributes of the two objects match, - // where "match" is defined in RFC 5280 sec. 7.1. - bool Matches(const CertPrincipal& against) const; - - // The different attributes for a principal. 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; -}; - -// Writes a human-readable description of a CertPrincipal, for debugging. -std::ostream& operator<<(std::ostream& s, const CertPrincipal& p); - -// This class is useful for maintaining policies about which certificates are -// permitted or forbidden for a particular purpose. -class 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, - }; - - // 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<SHA1Fingerprint, SHA1FingerprintLessThan> allowed_; - - // The set of fingerprints of denied certificates. - std::set<SHA1Fingerprint, SHA1FingerprintLessThan> denied_; -}; - -#if defined(OS_MACOSX) -// 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 - -} // namespace net - -#endif // NET_BASE_X509_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 504dde5..0000000 --- a/net/base/x509_cert_types_mac.cc +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright (c) 2006-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/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/utf_string_conversions.h" - -namespace net { - -static const CSSM_OID* kOIDs[] = { - &CSSMOID_CommonName, - &CSSMOID_LocalityName, - &CSSMOID_StateProvinceName, - &CSSMOID_CountryName, - &CSSMOID_StreetAddress, - &CSSMOID_OrganizationName, - &CSSMOID_OrganizationalUnitName, - &CSSMOID_DNQualifier // This should be "DC" but is undoubtedly wrong. -}; // TODO(avi): Find the right OID. - -// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.) -static std::string DataToString(CSSM_DATA data); - -// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8. -static std::string Latin1DataToUTF8String(CSSM_DATA data); - -// 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! -static bool UTF16BigEndianToUTF8(char16* chars, size_t length, - std::string* 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! -static bool UTF32BigEndianToUTF8(char32* chars, size_t length, - std::string* out_string); - -// Adds a type+value pair to the appropriate vector from a C array. -// The array is keyed by the matching OIDs from kOIDS[]. - static void AddTypeValuePair(const CSSM_OID type, - const std::string& value, - std::vector<std::string>* values[]); - -// Stores the first string of the vector, if any, to *single_value. -static void SetSingle(const std::vector<std::string> &values, - std::string* single_value); - - -void CertPrincipal::Parse(const CSSM_X509_NAME* name) { - 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 (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) { - CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn]; - for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) { - CSSM_X509_TYPE_VALUE_PAIR pair_struct = - rdn_struct.AttributeTypeAndValue[pair]; - AddTypeValuePair(pair_struct.type, - DataToString(pair_struct.value), - values); - } - } - - 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); -} - - -// 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. - -struct KeyValuePair { - CSSM_OID key; - int value_type; - CSSM_DATA value; - - enum { - kTypeOther = 0, - kTypePrintableString, - kTypeIA5String, - kTypeT61String, - kTypeUTF8String, - kTypeBMPString, - kTypeUniversalString, - }; -}; - -static const SecAsn1Template kStringValueTemplate[] = { - { SEC_ASN1_CHOICE, offsetof(KeyValuePair, value_type), }, - { SEC_ASN1_PRINTABLE_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypePrintableString }, - { SEC_ASN1_IA5_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeIA5String }, - { SEC_ASN1_T61_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeT61String }, - { SEC_ASN1_UTF8_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUTF8String }, - { SEC_ASN1_BMP_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeBMPString }, - { SEC_ASN1_UNIVERSAL_STRING, - offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUniversalString }, - { 0, } -}; - -static const SecAsn1Template kKeyValuePairTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(KeyValuePair) }, - { SEC_ASN1_OBJECT_ID, offsetof(KeyValuePair, key), }, - { SEC_ASN1_INLINE, 0, &kStringValueTemplate, }, - { 0, } -}; - -struct KeyValuePairs { - KeyValuePair* pairs; -}; - -static const SecAsn1Template kKeyValuePairSetTemplate[] = { - { SEC_ASN1_SET_OF, offsetof(KeyValuePairs,pairs), - kKeyValuePairTemplate, sizeof(KeyValuePairs) } -}; - -struct X509Name { - KeyValuePairs** pairs_list; -}; - -static const SecAsn1Template kNameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name,pairs_list), - kKeyValuePairSetTemplate, sizeof(X509Name) } -}; - -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) { - LOG(ERROR) << "SecAsn1Decode returned " << err << "; name=" << name; - 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) { - KeyValuePair *pair; - for (int pair_index = 0; - NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs); - ++pair_index) { - switch (pair->value_type) { - case KeyValuePair::kTypeIA5String: // ASCII (that means 7-bit!) - case KeyValuePair::kTypePrintableString: // a subset of ASCII - case KeyValuePair::kTypeUTF8String: // UTF-8 - AddTypeValuePair(pair->key, DataToString(pair->value), values); - break; - case KeyValuePair::kTypeT61String: // T61, pretend it's Latin-1 - AddTypeValuePair(pair->key, - Latin1DataToUTF8String(pair->value), - values); - break; - case KeyValuePair::kTypeBMPString: { // UTF-16, big-endian - std::string value; - UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data), - pair->value.Length / sizeof(char16), - &value); - AddTypeValuePair(pair->key, value, values); - break; - } - case KeyValuePair::kTypeUniversalString: { // UTF-32, big-endian - std::string value; - UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data), - pair->value.Length / sizeof(char32), - &value); - AddTypeValuePair(pair->key, value, values); - break; - } - default: - DCHECK_EQ(pair->value_type, KeyValuePair::kTypeOther); - // 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->key, 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; -} - - -// SUBROUTINES: - -static std::string DataToString(CSSM_DATA data) { - return std::string( - reinterpret_cast<std::string::value_type*>(data.Data), - data.Length); -} - -static std::string Latin1DataToUTF8String(CSSM_DATA data) { - string16 utf16; - if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1, - base::OnStringConversionError::FAIL, &utf16)) - return ""; - return UTF16ToUTF8(utf16); -} - -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); -} - -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 -} - - static 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; - } - } -} - -static 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.size() > 0) - *single_value = values[0]; -} - -} // 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 27104cc..0000000 --- a/net/base/x509_cert_types_unittest.cc +++ /dev/null @@ -1,343 +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/x509_cert_types.h" -#include "testing/gtest/include/gtest/gtest.h" - -// 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 -static const uint8_t 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 -static const uint8_t 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 -static const uint8_t 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 -static const uint8_t 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 -static const uint8_t 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) -static const uint8_t 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 -}; - -namespace net { - -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)); -} - -#if defined(OS_MACOSX) // ParseDistinguishedName not implemented for Win/Linux - -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]); -} -#endif - -} diff --git a/net/base/x509_certificate.cc b/net/base/x509_certificate.cc index 367afda..adf73b9 100644 --- a/net/base/x509_certificate.cc +++ b/net/base/x509_certificate.cc @@ -4,9 +4,7 @@ #include "net/base/x509_certificate.h" -#if defined(OS_MACOSX) -#include <Security/Security.h> -#elif defined(USE_NSS) +#if defined(USE_NSS) #include <cert.h> #endif @@ -58,8 +56,8 @@ bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, } bool X509Certificate::FingerprintLessThan::operator()( - const SHA1Fingerprint& lhs, - const SHA1Fingerprint& rhs) const { + const Fingerprint& lhs, + const Fingerprint& rhs) const { for (size_t i = 0; i < sizeof(lhs.data); ++i) { if (lhs.data[i] < rhs.data[i]) return true; @@ -123,6 +121,47 @@ X509Certificate* X509Certificate::Cache::Find(const Fingerprint& fingerprint) { return pos->second; }; +X509Certificate::Policy::Judgment X509Certificate::Policy::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 X509Certificate::Policy::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 X509Certificate::Policy::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 X509Certificate::Policy::HasAllowedCert() const { + return !allowed_.empty(); +} + +bool X509Certificate::Policy::HasDeniedCert() const { + return !denied_.empty(); +} + // static X509Certificate* X509Certificate::CreateFromHandle( OSCertHandle cert_handle, diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h index 32c16f1..ec287ce 100644 --- a/net/base/x509_certificate.h +++ b/net/base/x509_certificate.h @@ -15,15 +15,13 @@ #include "base/ref_counted.h" #include "base/singleton.h" #include "base/time.h" -#include "net/base/x509_cert_types.h" #include "testing/gtest/include/gtest/gtest_prod.h" #if defined(OS_WIN) #include <windows.h> #include <wincrypt.h> #elif defined(OS_MACOSX) -#include <CoreFoundation/CFArray.h> -#include <Security/SecBase.h> +#include <Security/Security.h> #elif defined(USE_NSS) // Forward declaration; real one in <cert.h> struct CERTCertificateStr; @@ -38,6 +36,28 @@ class CertVerifyResult; // X509Certificate represents an X.509 certificate used by SSL. class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { public: + // SHA-1 fingerprint (160 bits) of a certificate. + struct Fingerprint { + bool Equals(const Fingerprint& other) const { + return memcmp(data, other.data, sizeof(data)) == 0; + } + + unsigned char data[20]; + }; + + class FingerprintLessThan + : public std::binary_function<Fingerprint, Fingerprint, bool> { + public: + bool operator() (const Fingerprint& lhs, const Fingerprint& rhs) const; + }; + + // Predicate functor used in maps when X509Certificate is used as the key. + class LessThan + : public std::binary_function<X509Certificate*, X509Certificate*, bool> { + public: + bool operator() (X509Certificate* lhs, X509Certificate* rhs) const; + }; + // A handle to the certificate object in the underlying crypto library. // We assume that OSCertHandle is a pointer type on all platforms and // NULL is an invalid OSCertHandle. @@ -54,18 +74,62 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { typedef std::vector<OSCertHandle> OSCertHandles; - // Legacy names for types now defined in x509_cert_types.h. - // TODO(snej): Clean up existing code using these names to use the new names. - typedef CertPrincipal Principal; - typedef CertPolicy Policy; - typedef SHA1Fingerprint Fingerprint; - typedef SHA1FingerprintLessThan FingerprintLessThan; + // Principal represent an X.509 principal. + struct Principal { + Principal() { } + explicit Principal(const std::string& name) : common_name(name) { } - // Predicate functor used in maps when X509Certificate is used as the key. - class LessThan - : public std::binary_function<X509Certificate*, X509Certificate*, bool> { + // The different attributes for a principal. 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 Policy { public: - bool operator() (X509Certificate* lhs, X509Certificate* rhs) const; + // 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, + }; + + // 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<Fingerprint, FingerprintLessThan> allowed_; + + // The set of fingerprints of denied certificates. + std::set<Fingerprint, FingerprintLessThan> denied_; }; // Where the certificate comes from. The enumeration constants are @@ -167,9 +231,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { // Does this certificate's usage allow SSL client authentication? bool SupportsSSLClientAuth() const; - // Do any of the given issuer names appear in this cert's chain of trust? - bool IsIssuedBy(const std::vector<CertPrincipal>& valid_issuers); - // Creates a security policy for SSL client certificates. static OSStatus CreateSSLClientPolicy(SecPolicyRef* outPolicy); @@ -177,11 +238,8 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { // |server_domain| is a hint for which domain the cert is to be sent to // (a cert previously specified as the default for that domain will be given // precedence and returned first in the output vector.) - // If valid_issuers is non-empty, only certs that were transitively issued by - // one of the given names will be included in the list. static bool GetSSLClientCertificates( const std::string& server_domain, - const std::vector<CertPrincipal>& valid_issuers, std::vector<scoped_refptr<X509Certificate> >* certs); // Creates the chain of certs to use for this client identity cert. diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc index a4c37ba..16e7604 100644 --- a/net/base/x509_certificate_mac.cc +++ b/net/base/x509_certificate_mac.cc @@ -5,7 +5,6 @@ #include "net/base/x509_certificate.h" #include <CommonCrypto/CommonDigest.h> -#include <Security/Security.h> #include <time.h> #include "base/scoped_cftyperef.h" @@ -81,6 +80,11 @@ namespace { typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef, CFDictionaryRef*); +inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { + return oid1->Length == oid2->Length && + (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); +} + int NetErrorFromOSStatus(OSStatus status) { switch (status) { case noErr: @@ -169,6 +173,64 @@ bool OverrideHostnameMismatch(const std::string& hostname, return override_hostname_mismatch; } +void ParsePrincipal(const CSSM_X509_NAME* name, + X509Certificate::Principal* principal) { + std::vector<std::string> common_names, locality_names, state_names, + country_names; + + // TODO(jcampan): add business_category and serial_number. + const CSSM_OID* kOIDs[] = { &CSSMOID_CommonName, + &CSSMOID_LocalityName, + &CSSMOID_StateProvinceName, + &CSSMOID_CountryName, + &CSSMOID_StreetAddress, + &CSSMOID_OrganizationName, + &CSSMOID_OrganizationalUnitName, + &CSSMOID_DNQualifier }; // This should be "DC" + // but is undoubtedly + // wrong. TODO(avi): + // Find the right OID. + + std::vector<std::string>* values[] = { + &common_names, &locality_names, + &state_names, &country_names, + &(principal->street_addresses), + &(principal->organization_names), + &(principal->organization_unit_names), + &(principal->domain_components) }; + DCHECK(arraysize(kOIDs) == arraysize(values)); + + for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) { + CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn]; + for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) { + CSSM_X509_TYPE_VALUE_PAIR pair_struct = + rdn_struct.AttributeTypeAndValue[pair]; + for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { + if (CSSMOIDEqual(&pair_struct.type, kOIDs[oid])) { + std::string value = + std::string(reinterpret_cast<std::string::value_type*> + (pair_struct.value.Data), + pair_struct.value.Length); + values[oid]->push_back(value); + break; + } + } + } + } + + // We don't expect to have more than one CN, L, S, and C. + std::vector<std::string>* single_value_lists[4] = { + &common_names, &locality_names, &state_names, &country_names }; + 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(single_value_lists); ++i) { + DCHECK(single_value_lists[i]->size() <= 1); + if (single_value_lists[i]->size() > 0) + *(single_values[i]) = (*(single_value_lists[i]))[0]; + } +} + struct CSSMFields { CSSMFields() : cl_handle(NULL), num_of_fields(0), fields(NULL) {} ~CSSMFields() { @@ -324,51 +386,17 @@ OSStatus CreatePolicy(const CSSM_OID* policy_OID, return noErr; } -// 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 && out_cert_chain); - // Create an SSL policy ref configured for client cert evaluation. - SecPolicyRef ssl_policy; - OSStatus result = X509Certificate::CreateSSLClientPolicy(&ssl_policy); - if (result) - return result; - scoped_cftyperef<SecPolicyRef> scoped_ssl_policy(ssl_policy); - - // Create a SecTrustRef. - scoped_cftyperef<CFArrayRef> input_certs( - CFArrayCreate(NULL, (const void**)&cert_handle, 1, - &kCFTypeArrayCallBacks)); - SecTrustRef trust_ref = NULL; - result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref); - if (result) - return result; - scoped_cftyperef<SecTrustRef> trust(trust_ref); - - // Evaluate trust, which creates the cert chain. - SecTrustResultType status; - CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; - result = SecTrustEvaluate(trust, &status); - if (result) - return result; - return SecTrustGetResult(trust, &status, out_cert_chain, &status_chain); -} - } // namespace void X509Certificate::Initialize() { const CSSM_X509_NAME* name; OSStatus status = SecCertificateGetSubject(cert_handle_, &name); if (!status) { - subject_.Parse(name); + ParsePrincipal(name, &subject_); } status = SecCertificateGetIssuer(cert_handle_, &name); if (!status) { - issuer_.Parse(name); + ParsePrincipal(name, &issuer_); } GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore, @@ -714,34 +742,6 @@ bool X509Certificate::SupportsSSLClientAuth() const { return false; } -bool X509Certificate::IsIssuedBy( - const std::vector<CertPrincipal>& valid_issuers) { - // Get the cert's issuer chain. - CFArrayRef cert_chain = NULL; - OSStatus result; - result = CopyCertChain(os_cert_handle(), &cert_chain); - if (result != noErr) - return false; - scoped_cftyperef<CFArrayRef> scoped_cert_chain(cert_chain); - - // Check all the certs in the chain for a match. - int n = CFArrayGetCount(cert_chain); - for (int i = 0; i < n; ++i) { - SecCertificateRef cert_handle = reinterpret_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); - CFRetain(cert_handle); - scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( - cert_handle, - X509Certificate::SOURCE_LONE_CERT_IMPORT, - X509Certificate::OSCertHandles()); - for (unsigned j = 0; j < valid_issuers.size(); j++) { - if (cert->subject().Matches(valid_issuers[j])) - return true; - } - } - return false; -} - // static OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* out_policy) { CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { @@ -759,7 +759,6 @@ OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* out_policy) { // static bool X509Certificate::GetSSLClientCertificates ( const std::string& server_domain, - const std::vector<Principal>& valid_issuers, std::vector<scoped_refptr<X509Certificate> >* certs) { scoped_cftyperef<SecIdentityRef> preferred_identity; if (!server_domain.empty()) { @@ -769,12 +768,11 @@ bool X509Certificate::GetSSLClientCertificates ( SecIdentityRef identity = NULL; if (SecIdentityCopyPreference(domain_str, 0, - NULL, // validIssuers argument is ignored :( + NULL, &identity) == noErr) preferred_identity.reset(identity); } - // Now enumerate the identities in the available keychains. SecIdentitySearchRef search = nil; OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search); scoped_cftyperef<SecIdentitySearchRef> scoped_search(search); @@ -807,20 +805,10 @@ bool X509Certificate::GetSSLClientCertificates ( if (i < certs->size()) continue; - bool is_preferred = preferred_identity && - CFEqual(preferred_identity, identity); - - // Make sure the issuer matches valid_issuers, if given. - // But an explicit cert preference overrides this. - if (!is_preferred && - valid_issuers.size() > 0 && - !cert->IsIssuedBy(valid_issuers)) - continue; - // The cert passes, so add it to the vector. // If it's the preferred identity, add it at the start (so it'll be // selected by default in the UI.) - if (is_preferred) + if (preferred_identity && CFEqual(preferred_identity, identity)) certs->insert(certs->begin(), cert); else certs->push_back(cert); @@ -846,20 +834,46 @@ CFArrayRef X509Certificate::CreateClientCertificateChain() const { CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); CFArrayAppendValue(chain, identity); - CFArrayRef cert_chain = NULL; - result = CopyCertChain(cert_handle_, &cert_chain); - if (result) - goto exit; - - // 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)); + { + // Create an SSL policy ref configured for client cert evaluation. + SecPolicyRef ssl_policy; + result = CreateSSLClientPolicy(&ssl_policy); + if (result) + goto exit; + scoped_cftyperef<SecPolicyRef> scoped_ssl_policy(ssl_policy); + + // Use a SecTrust object to find the intermediate certs in the trust chain. + scoped_cftyperef<CFArrayRef> input_certs( + CFArrayCreate(NULL, (const void**)&cert_handle_, 1, + &kCFTypeArrayCallBacks)); + SecTrustRef trust_ref = NULL; + result = SecTrustCreateWithCertificates(input_certs, + ssl_policy, + &trust_ref); + if (result) + goto exit; + scoped_cftyperef<SecTrustRef> trust(trust_ref); + + SecTrustResultType status; + CFArrayRef trust_chain = NULL; + CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; + result = SecTrustEvaluate(trust, &status); + if (result) + goto exit; + result = SecTrustGetResult(trust, &status, &trust_chain, &status_chain); + if (result) + goto exit; + + // Append the intermediate certs from SecTrust to the result array: + if (trust_chain) { + int chain_count = CFArrayGetCount(trust_chain); + if (chain_count > 1) { + CFArrayAppendArray(chain, + trust_chain, + CFRangeMake(1, chain_count - 1)); + } + CFRelease(trust_chain); } - CFRelease(cert_chain); } exit: if (result) diff --git a/net/net.gyp b/net/net.gyp index 34e77fc..a6ed78d 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -161,9 +161,6 @@ 'base/x509_certificate_mac.cc', 'base/x509_certificate_nss.cc', 'base/x509_certificate_win.cc', - 'base/x509_cert_types.cc', - 'base/x509_cert_types.h', - 'base/x509_cert_types_mac.cc', ], 'export_dependent_settings': [ '../base/base.gyp:base', @@ -636,7 +633,6 @@ 'base/test_completion_callback_unittest.cc', 'base/upload_data_stream_unittest.cc', 'base/x509_certificate_unittest.cc', - 'base/x509_cert_types_unittest.cc', 'disk_cache/addr_unittest.cc', 'disk_cache/backend_unittest.cc', 'disk_cache/bitmap_unittest.cc', diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index ad3c747..4cf7722 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -655,32 +655,19 @@ void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { void SSLClientSocketMac::GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) { // I'm being asked for available client certs (identities). - // First, get the cert issuer names allowed by the server. - std::vector<CertPrincipal> valid_issuers; - CFArrayRef valid_issuer_names = NULL; - if (SSLCopyDistinguishedNames(ssl_context_, &valid_issuer_names) == noErr && - valid_issuer_names != NULL) { - SSL_LOG << "Server has " << CFArrayGetCount(valid_issuer_names) - << " valid issuer names"; - int n = CFArrayGetCount(valid_issuer_names); - for (int i = 0; i < n; i++) { - // Parse each name into a CertPrincipal object. - CFDataRef issuer = reinterpret_cast<CFDataRef>( - CFArrayGetValueAtIndex(valid_issuer_names, i)); - CertPrincipal p; - if (p.ParseDistinguishedName(CFDataGetBytePtr(issuer), - CFDataGetLength(issuer))) { - valid_issuers.push_back(p); - } - } - CFRelease(valid_issuer_names); + + CFArrayRef allowed_issuer_names = NULL; + if (SSLCopyDistinguishedNames(ssl_context_, &allowed_issuer_names) == noErr && + allowed_issuer_names != NULL) { + SSL_LOG << "Server has " << CFArrayGetCount(allowed_issuer_names) + << " allowed issuer names"; + CFRelease(allowed_issuer_names); + // TODO(snej): Filter GetSSLClientCertificates using this array. } - // Now get the available client certs whose issuers are allowed by the server. cert_request_info->host_and_port = hostname_; cert_request_info->client_certs.clear(); X509Certificate::GetSSLClientCertificates(hostname_, - valid_issuers, &cert_request_info->client_certs); SSL_LOG << "Asking user to choose between " << cert_request_info->client_certs.size() << " client certs..."; |