x509_cert_types_mac.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-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 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const CSSM_OID* kOIDs[] = { 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_CommonName, 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_LocalityName, 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_StateProvinceName, 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_CountryName, 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_StreetAddress, 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_OrganizationName, 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_OrganizationalUnitName, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CSSMOID_DNQualifier // This should be "DC" but is undoubtedly wrong. 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // TODO(avi): Find the right OID. 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Converts raw CSSM_DATA to a std::string. (Char encoding is unaltered.) 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string DataToString(CSSM_DATA data); 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Converts raw CSSM_DATA in ISO-8859-1 to a std::string in UTF-8. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string Latin1DataToUTF8String(CSSM_DATA data); 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Converts big-endian UTF-16 to UTF-8 in a std::string. 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: The byte-order flipping is done in place on the input buffer! 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool UTF16BigEndianToUTF8(char16* chars, size_t length, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* out_string); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Converts big-endian UTF-32 to UTF-8 in a std::string. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note: The byte-order flipping is done in place on the input buffer! 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool UTF32BigEndianToUTF8(char32* chars, size_t length, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* out_string); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Adds a type+value pair to the appropriate vector from a C array. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The array is keyed by the matching OIDs from kOIDS[]. 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void AddTypeValuePair(const CSSM_OID type, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& value, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values[]); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Stores the first string of the vector, if any, to *single_value. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SetSingle(const std::vector<std::string> &values, 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* single_value); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CertPrincipal::Parse(const CSSM_X509_NAME* name) { 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> common_names, locality_names, state_names, 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch country_names; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values[] = { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &common_names, &locality_names, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &state_names, &country_names, 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(this->street_addresses), 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(this->organization_names), 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(this->organization_unit_names), 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(this->domain_components) 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(arraysize(kOIDs) == arraysize(values)); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t rdn = 0; rdn < name->numberOfRDNs; ++rdn) { 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_X509_RDN rdn_struct = name->RelativeDistinguishedName[rdn]; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t pair = 0; pair < rdn_struct.numberOfPairs; ++pair) { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_X509_TYPE_VALUE_PAIR pair_struct = 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rdn_struct.AttributeTypeAndValue[pair]; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair_struct.type, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DataToString(pair_struct.value), 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch values); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(common_names, &this->common_name); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(locality_names, &this->locality_name); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(state_names, &this->state_or_province_name); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(country_names, &this->country_name); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The following structs and templates work with Apple's very arcane and under- 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// documented SecAsn1Parser API, which is apparently the same as NSS's ASN.1 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// decoder: 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn1.html 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These are used to parse the contents of a raw 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BER DistinguishedName structure. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct KeyValuePair { 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_OID key; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int value_type; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CSSM_DATA value; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeOther = 0, 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypePrintableString, 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeIA5String, 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeT61String, 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeUTF8String, 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeBMPString, 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTypeUniversalString, 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SecAsn1Template kStringValueTemplate[] = { 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_CHOICE, offsetof(KeyValuePair, value_type), }, 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_PRINTABLE_STRING, 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypePrintableString }, 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_IA5_STRING, 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeIA5String }, 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_T61_STRING, 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeT61String }, 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_UTF8_STRING, 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUTF8String }, 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_BMP_STRING, 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeBMPString }, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_UNIVERSAL_STRING, 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offsetof(KeyValuePair, value), 0, KeyValuePair::kTypeUniversalString }, 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SecAsn1Template kKeyValuePairTemplate[] = { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(KeyValuePair) }, 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_OBJECT_ID, offsetof(KeyValuePair, key), }, 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_INLINE, 0, &kStringValueTemplate, }, 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 0, } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct KeyValuePairs { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePair* pairs; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SecAsn1Template kKeyValuePairSetTemplate[] = { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_SET_OF, offsetof(KeyValuePairs,pairs), 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kKeyValuePairTemplate, sizeof(KeyValuePairs) } 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct X509Name { 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePairs** pairs_list; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SecAsn1Template kNameTemplate[] = { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { SEC_ASN1_SEQUENCE_OF, offsetof(X509Name,pairs_list), 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kKeyValuePairSetTemplate, sizeof(X509Name) } 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CertPrincipal::ParseDistinguishedName(const void* ber_name_data, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ber_name_data); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First parse the BER |name_data| into the above structs. 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRef coder = NULL; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderCreate(&coder); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(coder); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch X509Name* name = NULL; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OSStatus err = SecAsn1Decode(coder, ber_name_data, length, kNameTemplate, 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &name); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (err) { 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "SecAsn1Decode returned " << err << "; name=" << name; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRelease(coder); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now scan the structs and add the values to my string vectors. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // I don't store multiple common/locality/state/country names, so use 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // temporary vectors for those. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> common_names, locality_names, state_names, 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch country_names; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values[] = { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &common_names, &locality_names, 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &state_names, &country_names, 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->street_addresses, 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->organization_names, 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->organization_unit_names, 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &this->domain_components 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(arraysize(kOIDs) == arraysize(values)); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int rdn=0; name[rdn].pairs_list; ++rdn) { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch KeyValuePair *pair; 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int pair_index = 0; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL != (pair = name[rdn].pairs_list[0][pair_index].pairs); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++pair_index) { 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (pair->value_type) { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeIA5String: // ASCII (that means 7-bit!) 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypePrintableString: // a subset of ASCII 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeUTF8String: // UTF-8 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, DataToString(pair->value), values); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeT61String: // T61, pretend it's Latin-1 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Latin1DataToUTF8String(pair->value), 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch values); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeBMPString: { // UTF-16, big-endian 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF16BigEndianToUTF8(reinterpret_cast<char16*>(pair->value.Data), 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pair->value.Length / sizeof(char16), 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, value, values); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case KeyValuePair::kTypeUniversalString: { // UTF-32, big-endian 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UTF32BigEndianToUTF8(reinterpret_cast<char32*>(pair->value.Data), 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pair->value.Length / sizeof(char32), 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, value, values); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(pair->value_type, KeyValuePair::kTypeOther); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't know what data type this is, but we'll store it as a blob. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Displaying the string may not work, but at least it can be compared 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // byte-for-byte by a Matches() call. 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddTypeValuePair(pair->key, DataToString(pair->value), values); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(common_names, &this->common_name); 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(locality_names, &this->locality_name); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(state_names, &this->state_or_province_name); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetSingle(country_names, &this->country_name); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Releasing |coder| frees all the memory pointed to via |name|. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SecAsn1CoderRelease(coder); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SUBROUTINES: 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string DataToString(CSSM_DATA data) { 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string( 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<std::string::value_type*>(data.Data), 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.Length); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::string Latin1DataToUTF8String(CSSM_DATA data) { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 utf16; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!CodepageToUTF16(DataToString(data), base::kCodepageLatin1, 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::OnStringConversionError::FAIL, &utf16)) 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ""; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF16ToUTF8(utf16); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool UTF16BigEndianToUTF8(char16* chars, size_t length, 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* out_string) { 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < length; i++) 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chars[i] = EndianU16_BtoN(chars[i]); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF16ToUTF8(chars, length, out_string); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool UTF32BigEndianToUTF8(char32* chars, size_t length, 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* out_string) { 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < length; i++) 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chars[i] = EndianS32_BtoN(chars[i]); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(WCHAR_T_IS_UTF32) 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WideToUTF8(reinterpret_cast<const wchar_t*>(chars), 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length, out_string); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#error This code doesn't handle 16-bit wchar_t. 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void AddTypeValuePair(const CSSM_OID type, 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& value, 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values[]) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (CSSMOIDEqual(&type, kOIDs[oid])) { 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch values[oid]->push_back(value); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SetSingle(const std::vector<std::string> &values, 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* single_value) { 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't expect to have more than one CN, L, S, and C. 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG_IF(WARNING, values.size() > 1) << "Didn't expect multiple values"; 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (values.size() > 0) 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *single_value = values[0]; 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 294