13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/x509_cert_types.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <CoreServices/CoreServices.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <Security/Security.h> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <Security/SecAsn1Coder.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/icu_string_conversions.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochnamespace { 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst CSSM_OID* kOIDs[] = { 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_CommonName, 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_LocalityName, 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_StateProvinceName, 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_CountryName, 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_StreetAddress, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_OrganizationName, 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_OrganizationalUnitName, 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_DNQualifier // This should be "DC" but is undoubtedly wrong. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // TODO(avi): Find the right OID. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The following structs and templates work with Apple's very arcane and under- 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// decoder: 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These are used to parse the contents of a raw 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BER DistinguishedName structure. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct KeyValuePair { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_OID key; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int value_type; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_DATA value; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeOther = 0, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypePrintableString, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeIA5String, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeT61String, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeUTF8String, 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeBMPString, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeUniversalString, 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst SecAsn1Template kStringValueTemplate[] = { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_CHOICE, offsetof(KeyValuePair, value_type), }, 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_PRINTABLE_STRING, 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypePrintableString }, 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_IA5_STRING, 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeIA5String }, 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_T61_STRING, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeT61String }, 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_UTF8_STRING, 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUTF8String }, 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_BMP_STRING, 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeBMPString }, 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_UNIVERSAL_STRING, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUniversalString }, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, } 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst SecAsn1Template kKeyValuePairTemplate[] = { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(KeyValuePair) }, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_OBJECT_ID, offsetof(KeyValuePair, key), }, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_INLINE, 0, &kStringValueTemplate, }, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, } 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct KeyValuePairs { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePair* pairs; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst SecAsn1Template kKeyValuePairSetTemplate[] = { 83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { SEC_ASN1_SET_OF, offsetof(KeyValuePairs, pairs), 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kKeyValuePairTemplate, sizeof(KeyValuePairs) } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct X509Name { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePairs** pairs_list; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst SecAsn1Template kNameTemplate[] = { 92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name, pairs_list), 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kKeyValuePairSetTemplate, sizeof(X509Name) } 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.) 97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::string DataToString(CSSM_DATA data) { 98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return std::string( 99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reinterpret_cast<std::string::value_type*>(data.Data), 100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch data.Length); 101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8. 104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::string Latin1DataToUTF8String(CSSM_DATA data) { 105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 utf16; 106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1, 107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::OnStringConversionError::FAIL, &utf16)) 108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return ""; 109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return UTF16ToUTF8(utf16); 110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Converts big-endian UTF-16 to UTF-8 in a std::string. 113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Note: The byte-order flipping is done in place on the input buffer! 114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool UTF16BigEndianToUTF8(char16* chars, size_t length, 115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string* out_string) { 116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t i = 0; i < length; i++) 117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch chars[i] = EndianU16_BtoN(chars[i]); 118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return UTF16ToUTF8(chars, length, out_string); 119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Converts big-endian UTF-32 to UTF-8 in a std::string. 122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Note: The byte-order flipping is done in place on the input buffer! 123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool UTF32BigEndianToUTF8(char32* chars, size_t length, 124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string* out_string) { 125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t i = 0; i < length; ++i) 126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch chars[i] = EndianS32_BtoN(chars[i]); 127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#if defined(WCHAR_T_IS_UTF32) 128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return WideToUTF8(reinterpret_cast<const wchar_t*>(chars), 129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch length, out_string); 130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#else 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#error This code doesn't handle 16-bit wchar_t. 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#endif 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Adds a type+value pair to the appropriate vector from a C array. 136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// The array is keyed by the matching OIDs from kOIDS[]. 137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid AddTypeValuePair(const CSSM_OID type, 138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::string& value, 139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::vector<std::string>* values[]) { 140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { 141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (CSSMOIDEqual(&type, kOIDs[oid])) { 142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch values[oid]->push_back(value); 143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch break; 144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Stores the first string of the vector, if any, to *single_value. 149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid SetSingle(const std::vector<std::string>& values, 150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::string* single_value) { 151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We don't expect to have more than one CN, L, S, and C. 152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values"; 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!values.empty()) 154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch *single_value = values[0]; 155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool match(const std::string& str, const std::string& against) { 158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO(snej): Use the full matching rules specified in RFC 5280 sec. 7.1 159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // including trimming and case-folding: <http://www.ietf.org/rfc/rfc5280.txt>. 160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return against == str; 161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool match(const std::vector<std::string>& rdn1, 164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::vector<std::string>& rdn2) { 165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // "Two relative distinguished names RDN1 and RDN2 match if they have the 166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // same number of naming attributes and for each naming attribute in RDN1 167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // there is a matching naming attribute in RDN2." --RFC 5280 sec. 7.1. 168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (rdn1.size() != rdn2.size()) 169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (unsigned i1 = 0; i1 < rdn1.size(); ++i1) { 171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch unsigned i2; 172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (i2 = 0; i2 < rdn2.size(); ++i2) { 173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (match(rdn1[i1], rdn2[i2])) 174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch break; 175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (i2 == rdn2.size()) 177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} // namespace 183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length) { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ber_name_data); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First parse the BER |name_data| into the above structs. 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRef coder = NULL; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderCreate(&coder); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(coder); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch X509Name* name = NULL; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate, 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &name); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (err) { 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "SecAsn1Decode returned " << err << "; name=" << name; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRelease(coder); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now scan the structs and add the values to my string vectors. 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // I don't store multiple common/locality/state/country names, so use 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // temporary vectors for those. 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> common_names, locality_names, state_names, 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch country_names; 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values[] = { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &common_names, &locality_names, 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &state_names, &country_names, 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->street_addresses, 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->organization_names, 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->organization_unit_names, 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->domain_components 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(arraysize(kOIDs) == arraysize(values)); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (int rdn = 0; name[rdn].pairs_list; ++rdn) { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePair *pair; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int pair_index = 0; 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++pair_index) { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (pair->value_type) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeIA5String: // ASCII (that means 7-bit!) 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypePrintableString: // a subset of ASCII 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeUTF8String: // UTF-8 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, DataToString(pair->value), values); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeT61String: // T61, pretend it's Latin-1 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Latin1DataToUTF8String(pair->value), 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch values); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeBMPString: { // UTF-16, big-endian 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data), 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pair->value.Length / sizeof(char16), 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, value, values); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeUniversalString: { // UTF-32, big-endian 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data), 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pair->value.Length / sizeof(char32), 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, value, values); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(pair->value_type, KeyValuePair::kTypeOther); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't know what data type this is, but we'll store it as a blob. 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Displaying the string may not work, but at least it can be compared 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // byte-for-byte by a Matches() call. 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, DataToString(pair->value), values); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(common_names, &this->common_name); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(locality_names, &this->locality_name); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(state_names, &this->state_or_province_name); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(country_names, &this->country_name); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Releasing |coder| frees all the memory pointed to via |name|. 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRelease(coder); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 269201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CertPrincipal::Parse(const CSSM_X509_NAME* name) { 270201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::vector<std::string> common_names, locality_names, state_names, 271201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch country_names; 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::vector<std::string>* values[] = { 274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &common_names, &locality_names, 275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &state_names, &country_names, 276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &(this->street_addresses), 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &(this->organization_names), 278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &(this->organization_unit_names), 279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &(this->domain_components) 280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(arraysize(kOIDs) == arraysize(values)); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) { 284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn]; 285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) { 286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CSSM_X509_TYPE_VALUE_PAIR pair_struct = 287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch rdn_struct.AttributeTypeAndValue[pair]; 288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch AddTypeValuePair(pair_struct.type, 289201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DataToString(pair_struct.value), 290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch values); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SetSingle(common_names, &this->common_name); 295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SetSingle(locality_names, &this->locality_name); 296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SetSingle(state_names, &this->state_or_province_name); 297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SetSingle(country_names, &this->country_name); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool CertPrincipal::Matches(const CertPrincipal& against) const { 301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return match(common_name, against.common_name) && 302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(locality_name, against.locality_name) && 303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(state_or_province_name, against.state_or_province_name) && 304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(country_name, against.country_name) && 305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(street_addresses, against.street_addresses) && 306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(organization_names, against.organization_names) && 307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(organization_unit_names, against.organization_unit_names) && 308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch match(domain_components, against.domain_components); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 312