15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_cert_types.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdint.h> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreServices/CoreServices.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <Security/SecAsn1Coder.h> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <Security/Security.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_logging.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/base/net_string_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The BER encoding of 0.9.2342.19200300.100.1.25. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On 10.6 and later this is available as CSSMOID_DomainComponent, which is an 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// external symbol from Security.framework. However, it appears that Apple's 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation improperly encoded this on 10.6+, and even still is 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unavailable on 10.5, so simply including the raw BER here. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: CSSM is allowed to store CSSM_OIDs in any arbitrary format desired, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as long as the symbols are properly exposed. The fact that Apple's 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation stores it in BER is an internal implementation detail 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// observed by studying libsecurity_cssm. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8 kDomainComponentData[] = { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CSSM_OID kDomainComponentOID = { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(kDomainComponentData), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<uint8*>(kDomainComponentData) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CSSM_OID* kOIDs[] = { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_CommonName, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_LocalityName, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_StateProvinceName, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_CountryName, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_StreetAddress, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_OrganizationName, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CSSMOID_OrganizationalUnitName, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kDomainComponentOID, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following structs and templates work with Apple's very arcane and under- 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// decoder: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are used to parse the contents of a raw 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BER DistinguishedName structure. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SecAsn1Template kStringValueTemplate[] = { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_CHOICE, offsetof(CSSM_X509_TYPE_VALUE_PAIR, valueType), }, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_PRINTABLE_STRING, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_PRINTABLE_STRING }, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_IA5_STRING, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_IA5_STRING }, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_T61_STRING, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_T61_STRING }, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_UTF8_STRING, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_PKIX_UTF8_STRING }, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_BMP_STRING, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_PKIX_BMP_STRING }, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_UNIVERSAL_STRING, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsetof(CSSM_X509_TYPE_VALUE_PAIR, value), 0, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BER_TAG_PKIX_UNIVERSAL_STRING }, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0, } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SecAsn1Template kKeyValuePairTemplate[] = { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CSSM_X509_TYPE_VALUE_PAIR) }, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_OBJECT_ID, offsetof(CSSM_X509_TYPE_VALUE_PAIR, type), }, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_INLINE, 0, &kStringValueTemplate, }, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0, } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct KeyValuePairs { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSSM_X509_TYPE_VALUE_PAIR* pairs; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SecAsn1Template kKeyValuePairSetTemplate[] = { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_SET_OF, offsetof(KeyValuePairs, pairs), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kKeyValuePairTemplate, sizeof(KeyValuePairs) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct X509Name { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyValuePairs** pairs_list; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SecAsn1Template kNameTemplate[] = { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name, pairs_list), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kKeyValuePairSetTemplate, sizeof(X509Name) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DataToString(CSSM_DATA data) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<std::string::value_type*>(data.Data), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.Length); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Latin1DataToUTF8String(CSSM_DATA data) { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 utf16; 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!ConvertToUTF16(DataToString(data), kCharsetLatin1, &utf16)) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::UTF16ToUTF8(utf16); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts big-endian UTF-16 to UTF-8 in a std::string. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: The byte-order flipping is done in place on the input buffer! 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool UTF16BigEndianToUTF8(base::char16* chars, size_t length, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out_string) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < length; i++) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[i] = EndianU16_BtoN(chars[i]); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::UTF16ToUTF8(chars, length, out_string); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts big-endian UTF-32 to UTF-8 in a std::string. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: The byte-order flipping is done in place on the input buffer! 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool UTF32BigEndianToUTF8(int32_t* chars, size_t length, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out_string) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < length; ++i) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[i] = EndianS32_BtoN(chars[i]); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(WCHAR_T_IS_UTF32) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::WideToUTF8(reinterpret_cast<const wchar_t*>(chars), 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu length, out_string); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error This code doesn't handle 16-bit wchar_t. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a type+value pair to the appropriate vector from a C array. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The array is keyed by the matching OIDs from kOIDS[]. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddTypeValuePair(const CSSM_OID type, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* values[]) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CSSMOIDEqual(&type, kOIDs[oid])) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values[oid]->push_back(value); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stores the first string of the vector, if any, to *single_value. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetSingle(const std::vector<std::string>& values, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* single_value) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't expect to have more than one CN, L, S, and C. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values"; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!values.empty()) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *single_value = values[0]; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool match(const std::string& str, const std::string& against) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(snej): Use the full matching rules specified in RFC 5280 sec. 7.1 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // including trimming and case-folding: <http://www.ietf.org/rfc/rfc5280.txt>. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return against == str; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool match(const std::vector<std::string>& rdn1, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& rdn2) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Two relative distinguished names RDN1 and RDN2 match if they have the 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same number of naming attributes and for each naming attribute in RDN1 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is a matching naming attribute in RDN2." --RFC 5280 sec. 7.1. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rdn1.size() != rdn2.size()) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i1 = 0; i1 < rdn1.size(); ++i1) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned i2; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i2 = 0; i2 < rdn2.size(); ++i2) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match(rdn1[i1], rdn2[i2])) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i2 == rdn2.size()) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t length) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ber_name_data); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First parse the BER |name_data| into the above structs. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecAsn1CoderRef coder = NULL; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecAsn1CoderCreate(&coder); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(coder); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Name* name = NULL; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &name); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSSTATUS_LOG(ERROR, err) << "SecAsn1Decode"; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecAsn1CoderRelease(coder); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now scan the structs and add the values to my string vectors. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I don't store multiple common/locality/state/country names, so use 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // temporary vectors for those. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> common_names, locality_names, state_names, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) country_names; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* values[] = { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &common_names, &locality_names, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &state_names, &country_names, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &this->street_addresses, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &this->organization_names, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &this->organization_unit_names, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &this->domain_components 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(arraysize(kOIDs) == arraysize(values)); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int rdn = 0; name[rdn].pairs_list; ++rdn) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSSM_X509_TYPE_VALUE_PAIR* pair; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int pair_index = 0; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++pair_index) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (pair->valueType) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_IA5_STRING: // ASCII (that means 7-bit!) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_PRINTABLE_STRING: // a subset of ASCII 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_PKIX_UTF8_STRING: // UTF-8 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddTypeValuePair(pair->type, DataToString(pair->value), values); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_T61_STRING: // T61, pretend it's Latin-1 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddTypeValuePair(pair->type, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Latin1DataToUTF8String(pair->value), 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_PKIX_BMP_STRING: { // UTF-16, big-endian 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UTF16BigEndianToUTF8( 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) reinterpret_cast<base::char16*>(pair->value.Data), 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) pair->value.Length / sizeof(base::char16), 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &value); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddTypeValuePair(pair->type, value, values); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BER_TAG_PKIX_UNIVERSAL_STRING: { // UTF-32, big-endian 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UTF32BigEndianToUTF8(reinterpret_cast<int32_t*>(pair->value.Data), 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pair->value.Length / sizeof(int32_t), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &value); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddTypeValuePair(pair->type, value, values); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(pair->valueType, BER_TAG_UNKNOWN); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't know what data type this is, but we'll store it as a blob. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Displaying the string may not work, but at least it can be compared 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // byte-for-byte by a Matches() call. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddTypeValuePair(pair->type, DataToString(pair->value), values); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSingle(common_names, &this->common_name); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSingle(locality_names, &this->locality_name); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSingle(state_names, &this->state_or_province_name); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetSingle(country_names, &this->country_name); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releasing |coder| frees all the memory pointed to via |name|. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecAsn1CoderRelease(coder); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CertPrincipal::Matches(const CertPrincipal& against) const { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match(common_name, against.common_name) && 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(locality_name, against.locality_name) && 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(state_or_province_name, against.state_or_province_name) && 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(country_name, against.country_name) && 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(street_addresses, against.street_addresses) && 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(organization_names, against.organization_names) && 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(organization_unit_names, against.organization_unit_names) && 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match(domain_components, against.domain_components); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 293