summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 21:49:42 +0000
committeramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 21:49:42 +0000
commit78d36a2f101aaa7dea9820b7001672c8f5f78f4f (patch)
treed6a12039ba0d4473fdb4a5232e5ed0c523d40822 /net
parent3213339b064c87a06785145cbe86de65cf42fd6e (diff)
downloadchromium_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.cc112
-rw-r--r--net/base/x509_cert_types.h133
-rw-r--r--net/base/x509_cert_types_mac.cc293
-rw-r--r--net/base/x509_cert_types_unittest.cc343
-rw-r--r--net/base/x509_certificate.cc49
-rw-r--r--net/base/x509_certificate.h96
-rw-r--r--net/base/x509_certificate_mac.cc198
-rw-r--r--net/net.gyp4
-rw-r--r--net/socket/ssl_client_socket_mac.cc29
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...";