Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/base/x509_certificate.h"
      6 
      7 #include <CommonCrypto/CommonDigest.h>
      8 #include <CoreServices/CoreServices.h>
      9 #include <Security/Security.h>
     10 #include <time.h>
     11 
     12 #include <vector>
     13 
     14 #include "base/lazy_instance.h"
     15 #include "base/logging.h"
     16 #include "base/mac/scoped_cftyperef.h"
     17 #include "base/memory/singleton.h"
     18 #include "base/pickle.h"
     19 #include "base/sha1.h"
     20 #include "base/sys_string_conversions.h"
     21 #include "crypto/cssm_init.h"
     22 #include "crypto/nss_util.h"
     23 #include "crypto/rsa_private_key.h"
     24 #include "net/base/asn1_util.h"
     25 #include "net/base/cert_status_flags.h"
     26 #include "net/base/cert_verify_result.h"
     27 #include "net/base/net_errors.h"
     28 #include "net/base/test_root_certs.h"
     29 #include "net/base/x509_certificate_known_roots_mac.h"
     30 #include "third_party/apple_apsl/cssmapplePriv.h"
     31 #include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h"
     32 
     33 using base::mac::ScopedCFTypeRef;
     34 using base::Time;
     35 
     36 namespace net {
     37 
     38 namespace {
     39 
     40 typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef,
     41                                                       CFDictionaryRef*);
     42 
     43 int NetErrorFromOSStatus(OSStatus status) {
     44   switch (status) {
     45     case noErr:
     46       return OK;
     47     case errSecNotAvailable:
     48     case errSecNoCertificateModule:
     49     case errSecNoPolicyModule:
     50       return ERR_NOT_IMPLEMENTED;
     51     case errSecAuthFailed:
     52       return ERR_ACCESS_DENIED;
     53     default:
     54       LOG(ERROR) << "Unknown error " << status << " mapped to ERR_FAILED";
     55       return ERR_FAILED;
     56   }
     57 }
     58 
     59 int CertStatusFromOSStatus(OSStatus status) {
     60   switch (status) {
     61     case noErr:
     62       return 0;
     63 
     64     case CSSMERR_TP_INVALID_ANCHOR_CERT:
     65     case CSSMERR_TP_NOT_TRUSTED:
     66     case CSSMERR_TP_INVALID_CERT_AUTHORITY:
     67       return CERT_STATUS_AUTHORITY_INVALID;
     68 
     69     case CSSMERR_TP_CERT_EXPIRED:
     70     case CSSMERR_TP_CERT_NOT_VALID_YET:
     71       // "Expired" and "not yet valid" collapse into a single status.
     72       return CERT_STATUS_DATE_INVALID;
     73 
     74     case CSSMERR_TP_CERT_REVOKED:
     75     case CSSMERR_TP_CERT_SUSPENDED:
     76       return CERT_STATUS_REVOKED;
     77 
     78     case CSSMERR_APPLETP_HOSTNAME_MISMATCH:
     79       return CERT_STATUS_COMMON_NAME_INVALID;
     80 
     81     case CSSMERR_APPLETP_CRL_NOT_FOUND:
     82     case CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK:
     83     case CSSMERR_APPLETP_OCSP_UNAVAILABLE:
     84       return CERT_STATUS_NO_REVOCATION_MECHANISM;
     85 
     86     case CSSMERR_APPLETP_CRL_NOT_TRUSTED:
     87     case CSSMERR_APPLETP_CRL_SERVER_DOWN:
     88     case CSSMERR_APPLETP_CRL_NOT_VALID_YET:
     89     case CSSMERR_APPLETP_NETWORK_FAILURE:
     90     case CSSMERR_APPLETP_OCSP_BAD_RESPONSE:
     91     case CSSMERR_APPLETP_OCSP_NO_SIGNER:
     92     case CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED:
     93     case CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED:
     94     case CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ:
     95     case CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR:
     96     case CSSMERR_APPLETP_OCSP_RESP_TRY_LATER:
     97       // We asked for a revocation check, but didn't get it.
     98       return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
     99 
    100     default:
    101       // Failure was due to something Chromium doesn't define a
    102       // specific status for (such as basic constraints violation, or
    103       // unknown critical extension)
    104       return CERT_STATUS_INVALID;
    105   }
    106 }
    107 
    108 bool OverrideHostnameMismatch(const std::string& hostname,
    109                               std::vector<std::string>* dns_names) {
    110   // SecTrustEvaluate() does not check dotted IP addresses. If
    111   // hostname is provided as, say, 127.0.0.1, then the error
    112   // CSSMERR_APPLETP_HOSTNAME_MISMATCH will always be returned,
    113   // even if the certificate contains 127.0.0.1 as one of its names.
    114   // We, however, want to allow that behavior. SecTrustEvaluate()
    115   // only checks for digits and dots when considering whether a
    116   // hostname is an IP address, so IPv6 and hex addresses go through
    117   // its normal comparison.
    118   bool is_dotted_ip = true;
    119   bool override_hostname_mismatch = false;
    120   for (std::string::const_iterator c = hostname.begin();
    121        c != hostname.end() && is_dotted_ip; ++c)
    122     is_dotted_ip = (*c >= '0' && *c <= '9') || *c == '.';
    123   if (is_dotted_ip) {
    124     for (std::vector<std::string>::const_iterator name = dns_names->begin();
    125          name != dns_names->end() && !override_hostname_mismatch; ++name)
    126       override_hostname_mismatch = (*name == hostname);
    127   }
    128   return override_hostname_mismatch;
    129 }
    130 
    131 struct CSSMFields {
    132   CSSMFields() : cl_handle(NULL), num_of_fields(0), fields(NULL) {}
    133   ~CSSMFields() {
    134     if (cl_handle)
    135       CSSM_CL_FreeFields(cl_handle, num_of_fields, &fields);
    136   }
    137 
    138   CSSM_CL_HANDLE cl_handle;
    139   uint32 num_of_fields;
    140   CSSM_FIELD_PTR fields;
    141 };
    142 
    143 OSStatus GetCertFields(X509Certificate::OSCertHandle cert_handle,
    144                        CSSMFields* fields) {
    145   DCHECK(cert_handle);
    146   DCHECK(fields);
    147 
    148   CSSM_DATA cert_data;
    149   OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
    150   if (status)
    151     return status;
    152 
    153   status = SecCertificateGetCLHandle(cert_handle, &fields->cl_handle);
    154   if (status) {
    155     DCHECK(!fields->cl_handle);
    156     return status;
    157   }
    158 
    159   status = CSSM_CL_CertGetAllFields(fields->cl_handle, &cert_data,
    160                                     &fields->num_of_fields, &fields->fields);
    161   return status;
    162 }
    163 
    164 void GetCertGeneralNamesForOID(X509Certificate::OSCertHandle cert_handle,
    165                                CSSM_OID oid, CE_GeneralNameType name_type,
    166                                std::vector<std::string>* result) {
    167   // For future extension: We only support general names of types
    168   // GNT_RFC822Name, GNT_DNSName or GNT_URI.
    169   DCHECK(name_type == GNT_RFC822Name ||
    170          name_type == GNT_DNSName ||
    171          name_type == GNT_URI);
    172 
    173   CSSMFields fields;
    174   OSStatus status = GetCertFields(cert_handle, &fields);
    175   if (status)
    176     return;
    177 
    178   for (size_t field = 0; field < fields.num_of_fields; ++field) {
    179     if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
    180       CSSM_X509_EXTENSION_PTR cssm_ext =
    181           reinterpret_cast<CSSM_X509_EXTENSION_PTR>(
    182               fields.fields[field].FieldValue.Data);
    183       CE_GeneralNames* alt_name =
    184           reinterpret_cast<CE_GeneralNames*>(cssm_ext->value.parsedValue);
    185 
    186       for (size_t name = 0; name < alt_name->numNames; ++name) {
    187         const CE_GeneralName& name_struct = alt_name->generalName[name];
    188         // All of the general name types we support are encoded as
    189         // IA5String. In general, we should be switching off
    190         // |name_struct.nameType| and doing type-appropriate conversions. See
    191         // certextensions.h and the comment immediately preceding
    192         // CE_GeneralNameType for more information.
    193         if (name_struct.nameType == name_type) {
    194           const CSSM_DATA& name_data = name_struct.name;
    195           std::string value = std::string(
    196               reinterpret_cast<const char*>(name_data.Data),
    197               name_data.Length);
    198           result->push_back(value);
    199         }
    200       }
    201     }
    202   }
    203 }
    204 
    205 void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle,
    206                        CSSM_OID oid, Time* result) {
    207   *result = Time::Time();
    208 
    209   CSSMFields fields;
    210   OSStatus status = GetCertFields(cert_handle, &fields);
    211   if (status)
    212     return;
    213 
    214   for (size_t field = 0; field < fields.num_of_fields; ++field) {
    215     if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
    216       CSSM_X509_TIME* x509_time = reinterpret_cast<CSSM_X509_TIME*>(
    217           fields.fields[field].FieldValue.Data);
    218       if (x509_time->timeType != BER_TAG_UTC_TIME &&
    219           x509_time->timeType != BER_TAG_GENERALIZED_TIME) {
    220         LOG(ERROR) << "Unsupported date/time format "
    221                    << x509_time->timeType;
    222         return;
    223       }
    224 
    225       base::StringPiece time_string(
    226           reinterpret_cast<const char*>(x509_time->time.Data),
    227           x509_time->time.Length);
    228       CertDateFormat format = x509_time->timeType == BER_TAG_UTC_TIME ?
    229           CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
    230       if (!ParseCertificateDate(time_string, format, result))
    231         LOG(ERROR) << "Invalid certificate date/time " << time_string;
    232       return;
    233     }
    234   }
    235 }
    236 
    237 std::string GetCertSerialNumber(X509Certificate::OSCertHandle cert_handle) {
    238   CSSMFields fields;
    239   OSStatus status = GetCertFields(cert_handle, &fields);
    240   if (status)
    241     return "";
    242 
    243   std::string ret;
    244   for (size_t field = 0; field < fields.num_of_fields; ++field) {
    245     if (!CSSMOIDEqual(&fields.fields[field].FieldOid,
    246                       &CSSMOID_X509V1SerialNumber)) {
    247       continue;
    248     }
    249     ret.assign(
    250         reinterpret_cast<char*>(fields.fields[field].FieldValue.Data),
    251         fields.fields[field].FieldValue.Length);
    252     break;
    253   }
    254 
    255   // Remove leading zeros.
    256   while (ret.size() > 1 && ret[0] == 0)
    257     ret = ret.substr(1, ret.size() - 1);
    258 
    259   return ret;
    260 }
    261 
    262 // Creates a SecPolicyRef for the given OID, with optional value.
    263 OSStatus CreatePolicy(const CSSM_OID* policy_OID,
    264                       void* option_data,
    265                       size_t option_length,
    266                       SecPolicyRef* policy) {
    267   SecPolicySearchRef search;
    268   OSStatus err = SecPolicySearchCreate(CSSM_CERT_X_509v3, policy_OID, NULL,
    269                                        &search);
    270   if (err)
    271     return err;
    272   err = SecPolicySearchCopyNext(search, policy);
    273   CFRelease(search);
    274   if (err)
    275     return err;
    276 
    277   if (option_data) {
    278     CSSM_DATA options_data = {
    279       option_length,
    280       reinterpret_cast<uint8_t*>(option_data)
    281     };
    282     err = SecPolicySetValue(*policy, &options_data);
    283     if (err) {
    284       CFRelease(*policy);
    285       return err;
    286     }
    287   }
    288   return noErr;
    289 }
    290 
    291 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to
    292 // validate a certificate for an SSL peer. |hostname| contains the name of
    293 // the SSL peer that the certificate should be verified against. |flags| is
    294 // a bitwise-OR of VerifyFlags that can further alter how trust is
    295 // validated, such as how revocation is checked. If successful, returns
    296 // noErr, and stores the resultant array of SecPolicyRefs in |policies|.
    297 OSStatus CreateTrustPolicies(const std::string& hostname, int flags,
    298                              ScopedCFTypeRef<CFArrayRef>* policies) {
    299   // Create an SSL SecPolicyRef, and configure it to perform hostname
    300   // validation. The hostname check does 99% of what we want, with the
    301   // exception of dotted IPv4 addreses, which we handle ourselves below.
    302   CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = {
    303     CSSM_APPLE_TP_SSL_OPTS_VERSION,
    304     hostname.size(),
    305     hostname.data(),
    306     0
    307   };
    308   SecPolicyRef ssl_policy;
    309   OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options,
    310                                  sizeof(tp_ssl_options), &ssl_policy);
    311   if (status)
    312     return status;
    313   ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
    314 
    315   // Manually add OCSP and CRL policies. If neither an OCSP or CRL policy is
    316   // specified, the Apple TP module will add whatever the system settings
    317   // are, which is not desirable here.
    318   //
    319   // Note that this causes any locally configured OCSP responder URL to be
    320   // ignored.
    321   CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options;
    322   memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options));
    323   tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
    324 
    325   CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options;
    326   memset(&tp_crl_options, 0, sizeof(tp_crl_options));
    327   tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
    328 
    329   if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) {
    330     // If an OCSP responder is available, use it, and avoid fetching any
    331     // CRLs for that certificate if possible, as they may be much larger.
    332     tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
    333     // Ensure that CRLs can be fetched if a crlDistributionPoint extension
    334     // is found. Otherwise, only the local CRL cache will be consulted.
    335     tp_crl_options.CrlFlags |= CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
    336   } else {
    337     // Disable OCSP network fetching, but still permit cached OCSP responses
    338     // to be used. This is equivalent to the Windows code's usage of
    339     // CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY.
    340     tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET;
    341     // The default CrlFlags will ensure only cached CRLs are used.
    342   }
    343 
    344   SecPolicyRef ocsp_policy;
    345   status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options,
    346                         sizeof(tp_ocsp_options), &ocsp_policy);
    347   if (status)
    348     return status;
    349   ScopedCFTypeRef<SecPolicyRef> scoped_ocsp_policy(ocsp_policy);
    350 
    351   SecPolicyRef crl_policy;
    352   status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options,
    353                         sizeof(tp_crl_options), &crl_policy);
    354   if (status)
    355     return status;
    356   ScopedCFTypeRef<SecPolicyRef> scoped_crl_policy(crl_policy);
    357 
    358   CFTypeRef local_policies[] = { ssl_policy, ocsp_policy, crl_policy };
    359   CFArrayRef policy_array = CFArrayCreate(kCFAllocatorDefault, local_policies,
    360                                           arraysize(local_policies),
    361                                           &kCFTypeArrayCallBacks);
    362   if (!policy_array)
    363     return memFullErr;
    364 
    365   policies->reset(policy_array);
    366   return noErr;
    367 }
    368 
    369 // Gets the issuer for a given cert, starting with the cert itself and
    370 // including the intermediate and finally root certificates (if any).
    371 // This function calls SecTrust but doesn't actually pay attention to the trust
    372 // result: it shouldn't be used to determine trust, just to traverse the chain.
    373 // Caller is responsible for releasing the value stored into *out_cert_chain.
    374 OSStatus CopyCertChain(SecCertificateRef cert_handle,
    375                        CFArrayRef* out_cert_chain) {
    376   DCHECK(cert_handle);
    377   DCHECK(out_cert_chain);
    378   // Create an SSL policy ref configured for client cert evaluation.
    379   SecPolicyRef ssl_policy;
    380   OSStatus result = X509Certificate::CreateSSLClientPolicy(&ssl_policy);
    381   if (result)
    382     return result;
    383   ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
    384 
    385   // Create a SecTrustRef.
    386   ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
    387       NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
    388       1, &kCFTypeArrayCallBacks));
    389   SecTrustRef trust_ref = NULL;
    390   result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref);
    391   if (result)
    392     return result;
    393   ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
    394 
    395   // Evaluate trust, which creates the cert chain.
    396   SecTrustResultType status;
    397   CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
    398   result = SecTrustEvaluate(trust, &status);
    399   if (result)
    400     return result;
    401   return SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
    402 }
    403 
    404 // Returns true if |purpose| is listed as allowed in |usage|. This
    405 // function also considers the "Any" purpose. If the attribute is
    406 // present and empty, we return false.
    407 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage,
    408                             const CSSM_OID* purpose) {
    409   for (unsigned p = 0; p < usage->numPurposes; ++p) {
    410     if (CSSMOIDEqual(&usage->purposes[p], purpose))
    411       return true;
    412     if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny))
    413       return true;
    414   }
    415   return false;
    416 }
    417 
    418 // Test that a given |cert_handle| is actually a valid X.509 certificate, and
    419 // return true if it is.
    420 //
    421 // On OS X, SecCertificateCreateFromData() does not return any errors if
    422 // called with invalid data, as long as data is present. The actual decoding
    423 // of the certificate does not happen until an API that requires a CSSM
    424 // handle is called. While SecCertificateGetCLHandle is the most likely
    425 // candidate, as it performs the parsing, it does not check whether the
    426 // parsing was actually successful. Instead, SecCertificateGetSubject is
    427 // used (supported since 10.3), as a means to check that the certificate
    428 // parsed as a valid X.509 certificate.
    429 bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
    430   const CSSM_X509_NAME* sanity_check = NULL;
    431   OSStatus status = SecCertificateGetSubject(cert_handle, &sanity_check);
    432   return status == noErr && sanity_check;
    433 }
    434 
    435 // Parses |data| of length |length|, attempting to decode it as the specified
    436 // |format|. If |data| is in the specified format, any certificates contained
    437 // within are stored into |output|.
    438 void AddCertificatesFromBytes(const char* data, size_t length,
    439                               SecExternalFormat format,
    440                               X509Certificate::OSCertHandles* output) {
    441   SecExternalFormat input_format = format;
    442   ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
    443       kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length,
    444       kCFAllocatorNull));
    445 
    446   CFArrayRef items = NULL;
    447   OSStatus status = SecKeychainItemImport(local_data, NULL, &input_format,
    448                                           NULL, 0, NULL, NULL, &items);
    449   if (status) {
    450     DLOG(WARNING) << status << " Unable to import items from data of length "
    451                   << length;
    452     return;
    453   }
    454 
    455   ScopedCFTypeRef<CFArrayRef> scoped_items(items);
    456   CFTypeID cert_type_id = SecCertificateGetTypeID();
    457 
    458   for (CFIndex i = 0; i < CFArrayGetCount(items); ++i) {
    459     SecKeychainItemRef item = reinterpret_cast<SecKeychainItemRef>(
    460         const_cast<void*>(CFArrayGetValueAtIndex(items, i)));
    461 
    462     // While inputFormat implies only certificates will be imported, if/when
    463     // other formats (eg: PKCS#12) are supported, this may also include
    464     // private keys or other items types, so filter appropriately.
    465     if (CFGetTypeID(item) == cert_type_id) {
    466       SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(item);
    467       // OS X ignores |input_format| if it detects that |local_data| is PEM
    468       // encoded, attempting to decode data based on internal rules for PEM
    469       // block headers. If a PKCS#7 blob is encoded with a PEM block of
    470       // CERTIFICATE, OS X 10.5 will return a single, invalid certificate
    471       // based on the decoded data. If this happens, the certificate should
    472       // not be included in |output|. Because |output| is empty,
    473       // CreateCertificateListfromBytes will use PEMTokenizer to decode the
    474       // data. When called again with the decoded data, OS X will honor
    475       // |input_format|, causing decode to succeed. On OS X 10.6, the data
    476       // is properly decoded as a PKCS#7, whether PEM or not, which avoids
    477       // the need to fallback to internal decoding.
    478       if (IsValidOSCertHandle(cert)) {
    479         CFRetain(cert);
    480         output->push_back(cert);
    481       }
    482     }
    483   }
    484 }
    485 
    486 struct CSSMOIDString {
    487   const CSSM_OID* oid_;
    488   std::string string_;
    489 };
    490 
    491 typedef std::vector<CSSMOIDString> CSSMOIDStringVector;
    492 
    493 bool CERTNameToCSSMOIDVector(CERTName* name, CSSMOIDStringVector* out_values) {
    494   struct OIDCSSMMap {
    495     SECOidTag sec_OID_;
    496     const CSSM_OID* cssm_OID_;
    497   };
    498 
    499   const OIDCSSMMap kOIDs[] = {
    500       { SEC_OID_AVA_COMMON_NAME, &CSSMOID_CommonName },
    501       { SEC_OID_AVA_COUNTRY_NAME, &CSSMOID_CountryName },
    502       { SEC_OID_AVA_LOCALITY, &CSSMOID_LocalityName },
    503       { SEC_OID_AVA_STATE_OR_PROVINCE, &CSSMOID_StateProvinceName },
    504       { SEC_OID_AVA_STREET_ADDRESS, &CSSMOID_StreetAddress },
    505       { SEC_OID_AVA_ORGANIZATION_NAME, &CSSMOID_OrganizationName },
    506       { SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, &CSSMOID_OrganizationalUnitName },
    507       { SEC_OID_AVA_DN_QUALIFIER, &CSSMOID_DNQualifier },
    508       { SEC_OID_RFC1274_UID, &CSSMOID_UniqueIdentifier },
    509       { SEC_OID_PKCS9_EMAIL_ADDRESS, &CSSMOID_EmailAddress },
    510   };
    511 
    512   CERTRDN** rdns = name->rdns;
    513   for (size_t rdn = 0; rdns[rdn]; ++rdn) {
    514     CERTAVA** avas = rdns[rdn]->avas;
    515     for (size_t pair = 0; avas[pair] != 0; ++pair) {
    516       SECOidTag tag = CERT_GetAVATag(avas[pair]);
    517       if (tag == SEC_OID_UNKNOWN) {
    518         return false;
    519       }
    520       CSSMOIDString oidString;
    521       bool found_oid = false;
    522       for (size_t oid = 0; oid < ARRAYSIZE_UNSAFE(kOIDs); ++oid) {
    523         if (kOIDs[oid].sec_OID_ == tag) {
    524           SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
    525           if (!decode_item)
    526             return false;
    527 
    528           // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
    529           std::string value(reinterpret_cast<char*>(decode_item->data),
    530                             decode_item->len);
    531           oidString.oid_ = kOIDs[oid].cssm_OID_;
    532           oidString.string_ = value;
    533           out_values->push_back(oidString);
    534           SECITEM_FreeItem(decode_item, PR_TRUE);
    535           found_oid = true;
    536           break;
    537         }
    538       }
    539       if (!found_oid) {
    540         DLOG(ERROR) << "Unrecognized OID: " << tag;
    541       }
    542     }
    543   }
    544   return true;
    545 }
    546 
    547 class ScopedCertName {
    548  public:
    549   explicit ScopedCertName(CERTName* name) : name_(name) { }
    550   ~ScopedCertName() {
    551     if (name_) CERT_DestroyName(name_);
    552   }
    553   operator CERTName*() { return name_; }
    554 
    555  private:
    556   CERTName* name_;
    557 };
    558 
    559 class ScopedEncodedCertResults {
    560  public:
    561   explicit ScopedEncodedCertResults(CSSM_TP_RESULT_SET* results)
    562       : results_(results) { }
    563   ~ScopedEncodedCertResults() {
    564     if (results_) {
    565       CSSM_ENCODED_CERT* encCert =
    566           reinterpret_cast<CSSM_ENCODED_CERT*>(results_->Results);
    567       for (uint32 i = 0; i < results_->NumberOfResults; i++) {
    568         crypto::CSSMFree(encCert[i].CertBlob.Data);
    569       }
    570     }
    571     crypto::CSSMFree(results_->Results);
    572     crypto::CSSMFree(results_);
    573   }
    574 
    575 private:
    576   CSSM_TP_RESULT_SET* results_;
    577 };
    578 
    579 void AppendPublicKeyHashes(CFArrayRef chain,
    580                            std::vector<SHA1Fingerprint>* hashes) {
    581   const CFIndex n = CFArrayGetCount(chain);
    582   for (CFIndex i = 0; i < n; i++) {
    583     SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
    584         const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
    585 
    586     CSSM_DATA cert_data;
    587     OSStatus err = SecCertificateGetData(cert, &cert_data);
    588     DCHECK_EQ(err, noErr);
    589     base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data),
    590                                cert_data.Length);
    591     base::StringPiece spki_bytes;
    592     if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
    593       continue;
    594 
    595     SHA1Fingerprint hash;
    596     CC_SHA1(spki_bytes.data(), spki_bytes.size(), hash.data);
    597     hashes->push_back(hash);
    598   }
    599 }
    600 
    601 }  // namespace
    602 
    603 void X509Certificate::Initialize() {
    604   const CSSM_X509_NAME* name;
    605   OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
    606   if (!status)
    607     subject_.Parse(name);
    608 
    609   status = SecCertificateGetIssuer(cert_handle_, &name);
    610   if (!status)
    611     issuer_.Parse(name);
    612 
    613   GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore,
    614                     &valid_start_);
    615   GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
    616                     &valid_expiry_);
    617 
    618   fingerprint_ = CalculateFingerprint(cert_handle_);
    619   serial_number_ = GetCertSerialNumber(cert_handle_);
    620 }
    621 
    622 // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
    623 // that we recognise as a standard root.
    624 // static
    625 bool X509Certificate::IsIssuedByKnownRoot(CFArrayRef chain) {
    626   int n = CFArrayGetCount(chain);
    627   if (n < 1)
    628     return false;
    629   SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
    630       const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
    631   SHA1Fingerprint hash = X509Certificate::CalculateFingerprint(root_ref);
    632   return IsSHA1HashInSortedArray(
    633       hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes));
    634 }
    635 
    636 // static
    637 X509Certificate* X509Certificate::CreateSelfSigned(
    638     crypto::RSAPrivateKey* key,
    639     const std::string& subject,
    640     uint32 serial_number,
    641     base::TimeDelta valid_duration) {
    642   DCHECK(key);
    643   DCHECK(!subject.empty());
    644 
    645   if (valid_duration.InSeconds() > UINT32_MAX) {
    646      LOG(ERROR) << "valid_duration too big" << valid_duration.InSeconds();
    647      valid_duration = base::TimeDelta::FromSeconds(UINT32_MAX);
    648   }
    649 
    650   // There is a comment in
    651   // http://www.opensource.apple.com/source/security_certtool/security_certtool-31828/src/CertTool.cpp
    652   // that serial_numbers being passed into CSSM_TP_SubmitCredRequest can't have
    653   // their high bit set. We will continue though and mask it out below.
    654   if (serial_number & 0x80000000)
    655     LOG(ERROR) << "serial_number has high bit set " << serial_number;
    656 
    657   // NSS is used to parse the subject string into a set of
    658   // CSSM_OID/string pairs. There doesn't appear to be a system routine for
    659   // parsing Distinguished Name strings.
    660   crypto::EnsureNSSInit();
    661 
    662   CSSMOIDStringVector subject_name_oids;
    663   ScopedCertName subject_name(
    664       CERT_AsciiToName(const_cast<char*>(subject.c_str())));
    665   if (!CERTNameToCSSMOIDVector(subject_name, &subject_name_oids)) {
    666     DLOG(ERROR) << "Unable to generate CSSMOIDMap from " << subject;
    667     return NULL;
    668   }
    669 
    670   // Convert the map of oid/string pairs into an array of
    671   // CSSM_APPLE_TP_NAME_OIDs.
    672   std::vector<CSSM_APPLE_TP_NAME_OID> cssm_subject_names;
    673   for(CSSMOIDStringVector::iterator iter = subject_name_oids.begin();
    674       iter != subject_name_oids.end(); ++iter) {
    675     CSSM_APPLE_TP_NAME_OID cssm_subject_name;
    676     cssm_subject_name.oid = iter->oid_;
    677     cssm_subject_name.string = iter->string_.c_str();
    678     cssm_subject_names.push_back(cssm_subject_name);
    679   }
    680 
    681   if (cssm_subject_names.empty()) {
    682     DLOG(ERROR) << "cssm_subject_names.size() == 0. Input: " << subject;
    683     return NULL;
    684   }
    685 
    686   // Set up a certificate request.
    687   CSSM_APPLE_TP_CERT_REQUEST certReq;
    688   memset(&certReq, 0, sizeof(certReq));
    689   certReq.cspHand = crypto::GetSharedCSPHandle();
    690   certReq.clHand = crypto::GetSharedCLHandle();
    691     // See comment about serial numbers above.
    692   certReq.serialNumber = serial_number & 0x7fffffff;
    693   certReq.numSubjectNames = cssm_subject_names.size();
    694   certReq.subjectNames = &cssm_subject_names[0];
    695   certReq.numIssuerNames = 0; // Root.
    696   certReq.issuerNames = NULL;
    697   certReq.issuerNameX509 = NULL;
    698   certReq.certPublicKey = key->public_key();
    699   certReq.issuerPrivateKey = key->key();
    700   // These are the Apple defaults.
    701   certReq.signatureAlg = CSSM_ALGID_SHA1WithRSA;
    702   certReq.signatureOid = CSSMOID_SHA1WithRSA;
    703   certReq.notBefore = 0;
    704   certReq.notAfter = static_cast<uint32>(valid_duration.InSeconds());
    705   certReq.numExtensions = 0;
    706   certReq.extensions = NULL;
    707   certReq.challengeString = NULL;
    708 
    709   CSSM_TP_REQUEST_SET reqSet;
    710   reqSet.NumberOfRequests = 1;
    711   reqSet.Requests = &certReq;
    712 
    713   CSSM_FIELD policyId;
    714   memset(&policyId, 0, sizeof(policyId));
    715   policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN;
    716 
    717   CSSM_TP_CALLERAUTH_CONTEXT callerAuthContext;
    718   memset(&callerAuthContext, 0, sizeof(callerAuthContext));
    719   callerAuthContext.Policy.NumberOfPolicyIds = 1;
    720   callerAuthContext.Policy.PolicyIds = &policyId;
    721 
    722   CSSM_TP_HANDLE tp_handle = crypto::GetSharedTPHandle();
    723   CSSM_DATA refId;
    724   memset(&refId, 0, sizeof(refId));
    725   sint32 estTime;
    726   CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest(tp_handle, NULL,
    727       CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, &reqSet, &callerAuthContext,
    728        &estTime, &refId);
    729   if(crtn) {
    730     DLOG(ERROR) << "CSSM_TP_SubmitCredRequest failed " << crtn;
    731     return NULL;
    732   }
    733 
    734   CSSM_BOOL confirmRequired;
    735   CSSM_TP_RESULT_SET *resultSet = NULL;
    736   crtn = CSSM_TP_RetrieveCredResult(tp_handle, &refId, NULL, &estTime,
    737                                     &confirmRequired, &resultSet);
    738   ScopedEncodedCertResults scopedResults(resultSet);
    739   crypto::CSSMFree(refId.Data);
    740   if (crtn) {
    741     DLOG(ERROR) << "CSSM_TP_RetrieveCredResult failed " << crtn;
    742     return NULL;
    743   }
    744 
    745   if (confirmRequired) {
    746     // Potential leak here of resultSet. |confirmRequired| should never be
    747     // true.
    748     DLOG(ERROR) << "CSSM_TP_RetrieveCredResult required confirmation";
    749     return NULL;
    750   }
    751 
    752   if (resultSet->NumberOfResults != 1) {
    753      DLOG(ERROR) << "Unexpected number of results: "
    754                  << resultSet->NumberOfResults;
    755     return NULL;
    756   }
    757 
    758   CSSM_ENCODED_CERT* encCert =
    759       reinterpret_cast<CSSM_ENCODED_CERT*>(resultSet->Results);
    760   base::mac::ScopedCFTypeRef<SecCertificateRef> scoped_cert;
    761   SecCertificateRef certificate_ref = NULL;
    762   OSStatus os_status =
    763       SecCertificateCreateFromData(&encCert->CertBlob, encCert->CertType,
    764                                    encCert->CertEncoding, &certificate_ref);
    765   if (os_status != 0) {
    766     DLOG(ERROR) << "SecCertificateCreateFromData failed: " << os_status;
    767     return NULL;
    768   }
    769   scoped_cert.reset(certificate_ref);
    770 
    771   return CreateFromHandle(
    772      scoped_cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
    773      X509Certificate::OSCertHandles());
    774 }
    775 
    776 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
    777   dns_names->clear();
    778 
    779   GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName,
    780                             dns_names);
    781 
    782   if (dns_names->empty())
    783     dns_names->push_back(subject_.common_name);
    784 }
    785 
    786 int X509Certificate::Verify(const std::string& hostname, int flags,
    787                             CertVerifyResult* verify_result) const {
    788   verify_result->Reset();
    789 
    790   if (IsBlacklisted()) {
    791     verify_result->cert_status |= CERT_STATUS_REVOKED;
    792     return ERR_CERT_REVOKED;
    793   }
    794 
    795   ScopedCFTypeRef<CFArrayRef> trust_policies;
    796   OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies);
    797   if (status)
    798     return NetErrorFromOSStatus(status);
    799 
    800   // Create and configure a SecTrustRef, which takes our certificate(s)
    801   // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an
    802   // array of certificates, the first of which is the certificate we're
    803   // verifying, and the subsequent (optional) certificates are used for
    804   // chain building.
    805   CFMutableArrayRef cert_array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
    806                                                       &kCFTypeArrayCallBacks);
    807   if (!cert_array)
    808     return ERR_OUT_OF_MEMORY;
    809   ScopedCFTypeRef<CFArrayRef> scoped_cert_array(cert_array);
    810   CFArrayAppendValue(cert_array, cert_handle_);
    811   for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
    812     CFArrayAppendValue(cert_array, intermediate_ca_certs_[i]);
    813 
    814   // From here on, only one thread can be active at a time. We have had a number
    815   // of sporadic crashes in the SecTrustEvaluate call below, way down inside
    816   // Apple's cert code, which we suspect are caused by a thread-safety issue.
    817   // So as a speculative fix allow only one thread to use SecTrust on this cert.
    818   base::AutoLock lock(verification_lock_);
    819 
    820   SecTrustRef trust_ref = NULL;
    821   status = SecTrustCreateWithCertificates(cert_array, trust_policies,
    822                                           &trust_ref);
    823   if (status)
    824     return NetErrorFromOSStatus(status);
    825   ScopedCFTypeRef<SecTrustRef> scoped_trust_ref(trust_ref);
    826 
    827   if (TestRootCerts::HasInstance()) {
    828     status = TestRootCerts::GetInstance()->FixupSecTrustRef(trust_ref);
    829     if (status)
    830       return NetErrorFromOSStatus(status);
    831   }
    832 
    833   CSSM_APPLE_TP_ACTION_DATA tp_action_data;
    834   memset(&tp_action_data, 0, sizeof(tp_action_data));
    835   tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
    836   // Allow CSSM to download any missing intermediate certificates if an
    837   // authorityInfoAccess extension or issuerAltName extension is present.
    838   tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET;
    839 
    840   if (flags & VERIFY_REV_CHECKING_ENABLED) {
    841     // Require a positive result from an OCSP responder or a CRL (or both)
    842     // for every certificate in the chain. The Apple TP automatically
    843     // excludes the self-signed root from this requirement. If a certificate
    844     // is missing both a crlDistributionPoints extension and an
    845     // authorityInfoAccess extension with an OCSP responder URL, then we
    846     // will get a kSecTrustResultRecoverableTrustFailure back from
    847     // SecTrustEvaluate(), with a
    848     // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case,
    849     // we'll set our own result to include
    850     // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are
    851     // present, and a check fails (server unavailable, OCSP retry later,
    852     // signature mismatch), then we'll set our own result to include
    853     // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION.
    854     tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;
    855     verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
    856   } else {
    857     // EV requires revocation checking.
    858     // Note, under the hood, SecTrustEvaluate() will modify the OCSP options
    859     // so as to attempt OCSP fetching if it believes a certificate may chain
    860     // to an EV root. However, because network fetches are disabled in
    861     // CreateTrustPolicies() when revocation checking is disabled, these
    862     // will only go against the local cache.
    863     flags &= ~VERIFY_EV_CERT;
    864   }
    865 
    866   CFDataRef action_data_ref =
    867       CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
    868                                   reinterpret_cast<UInt8*>(&tp_action_data),
    869                                   sizeof(tp_action_data), kCFAllocatorNull);
    870   if (!action_data_ref)
    871     return ERR_OUT_OF_MEMORY;
    872   ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref);
    873   status = SecTrustSetParameters(trust_ref, CSSM_TP_ACTION_DEFAULT,
    874                                  action_data_ref);
    875   if (status)
    876     return NetErrorFromOSStatus(status);
    877 
    878   // Verify the certificate. A non-zero result from SecTrustGetResult()
    879   // indicates that some fatal error occurred and the chain couldn't be
    880   // processed, not that the chain contains no errors. We need to examine the
    881   // output of SecTrustGetResult() to determine that.
    882   SecTrustResultType trust_result;
    883   status = SecTrustEvaluate(trust_ref, &trust_result);
    884   if (status)
    885     return NetErrorFromOSStatus(status);
    886   CFArrayRef completed_chain = NULL;
    887   CSSM_TP_APPLE_EVIDENCE_INFO* chain_info;
    888   status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain,
    889                              &chain_info);
    890   if (status)
    891     return NetErrorFromOSStatus(status);
    892   ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain);
    893 
    894   // Evaluate the results
    895   OSStatus cssm_result;
    896   bool got_certificate_error = false;
    897   switch (trust_result) {
    898     case kSecTrustResultUnspecified:
    899     case kSecTrustResultProceed:
    900       // Certificate chain is valid and trusted ("unspecified" indicates that
    901       // the user has not explicitly set a trust setting)
    902       break;
    903 
    904     case kSecTrustResultDeny:
    905     case kSecTrustResultConfirm:
    906       // Certificate chain is explicitly untrusted. For kSecTrustResultConfirm,
    907       // we're following what Secure Transport does and treating it as
    908       // "deny".
    909       verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
    910       break;
    911 
    912     case kSecTrustResultRecoverableTrustFailure:
    913       // Certificate chain has a failure that can be overridden by the user.
    914       status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
    915       if (status)
    916         return NetErrorFromOSStatus(status);
    917       switch (cssm_result) {
    918         case CSSMERR_TP_NOT_TRUSTED:
    919         case CSSMERR_TP_INVALID_ANCHOR_CERT:
    920           verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
    921           break;
    922         case CSSMERR_TP_CERT_EXPIRED:
    923         case CSSMERR_TP_CERT_NOT_VALID_YET:
    924           verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
    925           break;
    926         case CSSMERR_TP_CERT_REVOKED:
    927         case CSSMERR_TP_CERT_SUSPENDED:
    928           verify_result->cert_status |= CERT_STATUS_REVOKED;
    929           break;
    930         default:
    931           // Look for specific per-certificate errors below.
    932           break;
    933       }
    934       // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO
    935       // structure which can catch multiple errors from each certificate.
    936       for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain);
    937            index < chain_count; ++index) {
    938         if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED ||
    939             chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET)
    940           verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
    941         for (uint32 status_code_index = 0;
    942              status_code_index < chain_info[index].NumStatusCodes;
    943              ++status_code_index) {
    944           got_certificate_error = true;
    945           int cert_status = CertStatusFromOSStatus(
    946               chain_info[index].StatusCodes[status_code_index]);
    947           if (cert_status == CERT_STATUS_COMMON_NAME_INVALID) {
    948             std::vector<std::string> names;
    949             GetDNSNames(&names);
    950             if (OverrideHostnameMismatch(hostname, &names))
    951               cert_status = 0;
    952           }
    953           verify_result->cert_status |= cert_status;
    954         }
    955       }
    956       // Be paranoid and ensure that we recorded at least one certificate
    957       // status on receiving kSecTrustResultRecoverableTrustFailure. The
    958       // call to SecTrustGetCssmResultCode() should pick up when the chain
    959       // is not trusted and the loop through CSSM_TP_APPLE_EVIDENCE_INFO
    960       // should pick up everything else, but let's be safe.
    961       if (!verify_result->cert_status && !got_certificate_error) {
    962         verify_result->cert_status |= CERT_STATUS_INVALID;
    963         NOTREACHED();
    964       }
    965       break;
    966 
    967     default:
    968       status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
    969       if (status)
    970         return NetErrorFromOSStatus(status);
    971       verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
    972       if (!verify_result->cert_status)
    973         verify_result->cert_status |= CERT_STATUS_INVALID;
    974       break;
    975   }
    976 
    977   // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
    978   // compatible with Windows, which in turn implements this behavior to be
    979   // compatible with WinHTTP, which doesn't report this error (bug 3004).
    980   verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
    981 
    982   if (IsCertStatusError(verify_result->cert_status))
    983     return MapCertStatusToNetError(verify_result->cert_status);
    984 
    985   if (flags & VERIFY_EV_CERT) {
    986     // Determine the certificate's EV status using SecTrustCopyExtendedResult(),
    987     // which we need to look up because the function wasn't added until
    988     // Mac OS X 10.5.7.
    989     // Note: "ExtendedResult" means extended validation results.
    990     CFBundleRef bundle =
    991         CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
    992     if (bundle) {
    993       SecTrustCopyExtendedResultFuncPtr copy_extended_result =
    994           reinterpret_cast<SecTrustCopyExtendedResultFuncPtr>(
    995               CFBundleGetFunctionPointerForName(bundle,
    996                   CFSTR("SecTrustCopyExtendedResult")));
    997       if (copy_extended_result) {
    998         CFDictionaryRef ev_dict = NULL;
    999         status = copy_extended_result(trust_ref, &ev_dict);
   1000         if (!status && ev_dict) {
   1001           // The returned dictionary contains the EV organization name from the
   1002           // server certificate, which we don't need at this point (and we
   1003           // have other ways to access, anyway). All we care is that
   1004           // SecTrustCopyExtendedResult() returned noErr and a non-NULL
   1005           // dictionary.
   1006           CFRelease(ev_dict);
   1007           verify_result->cert_status |= CERT_STATUS_IS_EV;
   1008         }
   1009       }
   1010     }
   1011   }
   1012 
   1013   AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes);
   1014   verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain);
   1015 
   1016   if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) {
   1017     verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
   1018     return MapCertStatusToNetError(verify_result->cert_status);
   1019   }
   1020 
   1021   return OK;
   1022 }
   1023 
   1024 bool X509Certificate::GetDEREncoded(std::string* encoded) {
   1025   encoded->clear();
   1026   CSSM_DATA der_data;
   1027   if(SecCertificateGetData(cert_handle_, &der_data) == noErr) {
   1028     encoded->append(reinterpret_cast<char*>(der_data.Data),
   1029                     der_data.Length);
   1030     return true;
   1031   }
   1032   return false;
   1033 }
   1034 
   1035 bool X509Certificate::VerifyEV() const {
   1036   // We don't call this private method, but we do need to implement it because
   1037   // it's defined in x509_certificate.h. We perform EV checking in the
   1038   // Verify() above.
   1039   NOTREACHED();
   1040   return false;
   1041 }
   1042 
   1043 // static
   1044 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
   1045                                    X509Certificate::OSCertHandle b) {
   1046   DCHECK(a && b);
   1047   if (a == b)
   1048     return true;
   1049   if (CFEqual(a, b))
   1050     return true;
   1051   CSSM_DATA a_data, b_data;
   1052   return SecCertificateGetData(a, &a_data) == noErr &&
   1053       SecCertificateGetData(b, &b_data) == noErr &&
   1054       a_data.Length == b_data.Length &&
   1055       memcmp(a_data.Data, b_data.Data, a_data.Length) == 0;
   1056 }
   1057 
   1058 // static
   1059 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
   1060     const char* data, int length) {
   1061   CSSM_DATA cert_data;
   1062   cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
   1063   cert_data.Length = length;
   1064 
   1065   OSCertHandle cert_handle = NULL;
   1066   OSStatus status = SecCertificateCreateFromData(&cert_data,
   1067                                                  CSSM_CERT_X_509v3,
   1068                                                  CSSM_CERT_ENCODING_DER,
   1069                                                  &cert_handle);
   1070   if (status != noErr)
   1071     return NULL;
   1072   if (!IsValidOSCertHandle(cert_handle)) {
   1073     CFRelease(cert_handle);
   1074     return NULL;
   1075   }
   1076   return cert_handle;
   1077 }
   1078 
   1079 // static
   1080 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
   1081     const char* data, int length, Format format) {
   1082   OSCertHandles results;
   1083 
   1084   switch (format) {
   1085     case FORMAT_SINGLE_CERTIFICATE: {
   1086       OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
   1087       if (handle)
   1088         results.push_back(handle);
   1089       break;
   1090     }
   1091     case FORMAT_PKCS7:
   1092       AddCertificatesFromBytes(data, length, kSecFormatPKCS7, &results);
   1093       break;
   1094     default:
   1095       NOTREACHED() << "Certificate format " << format << " unimplemented";
   1096       break;
   1097   }
   1098 
   1099   return results;
   1100 }
   1101 
   1102 // static
   1103 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
   1104     OSCertHandle handle) {
   1105   if (!handle)
   1106     return NULL;
   1107   return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
   1108 }
   1109 
   1110 // static
   1111 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
   1112   CFRelease(cert_handle);
   1113 }
   1114 
   1115 // static
   1116 SHA1Fingerprint X509Certificate::CalculateFingerprint(
   1117     OSCertHandle cert) {
   1118   SHA1Fingerprint sha1;
   1119   memset(sha1.data, 0, sizeof(sha1.data));
   1120 
   1121   CSSM_DATA cert_data;
   1122   OSStatus status = SecCertificateGetData(cert, &cert_data);
   1123   if (status)
   1124     return sha1;
   1125 
   1126   DCHECK(cert_data.Data);
   1127   DCHECK_NE(cert_data.Length, 0U);
   1128 
   1129   CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
   1130 
   1131   return sha1;
   1132 }
   1133 
   1134 bool X509Certificate::SupportsSSLClientAuth() const {
   1135   CSSMFields fields;
   1136   if (GetCertFields(cert_handle_, &fields) != noErr)
   1137     return false;
   1138 
   1139   // Gather the extensions we care about. We do not support
   1140   // CSSMOID_NetscapeCertType on OS X.
   1141   const CE_ExtendedKeyUsage* ext_key_usage = NULL;
   1142   const CE_KeyUsage* key_usage = NULL;
   1143   for (unsigned f = 0; f < fields.num_of_fields; ++f) {
   1144     const CSSM_FIELD& field = fields.fields[f];
   1145     const CSSM_X509_EXTENSION* ext =
   1146         reinterpret_cast<const CSSM_X509_EXTENSION*>(field.FieldValue.Data);
   1147     if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_KeyUsage)) {
   1148       key_usage = reinterpret_cast<const CE_KeyUsage*>(ext->value.parsedValue);
   1149     } else if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_ExtendedKeyUsage)) {
   1150       ext_key_usage =
   1151           reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue);
   1152     }
   1153   }
   1154 
   1155   // RFC5280 says to take the intersection of the two extensions.
   1156   //
   1157   // Our underlying crypto libraries don't expose
   1158   // ClientCertificateType, so for now we will not support fixed
   1159   // Diffie-Hellman mechanisms. For rsa_sign, we need the
   1160   // digitalSignature bit.
   1161   //
   1162   // In particular, if a key has the nonRepudiation bit and not the
   1163   // digitalSignature one, we will not offer it to the user.
   1164   if (key_usage && !((*key_usage) & CE_KU_DigitalSignature))
   1165     return false;
   1166   if (ext_key_usage && !ExtendedKeyUsageAllows(ext_key_usage,
   1167                                                &CSSMOID_ClientAuth))
   1168     return false;
   1169   return true;
   1170 }
   1171 
   1172 bool X509Certificate::IsIssuedBy(
   1173     const std::vector<CertPrincipal>& valid_issuers) {
   1174   // Get the cert's issuer chain.
   1175   CFArrayRef cert_chain = NULL;
   1176   OSStatus result;
   1177   result = CopyCertChain(os_cert_handle(), &cert_chain);
   1178   if (result)
   1179     return false;
   1180   ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain);
   1181 
   1182   // Check all the certs in the chain for a match.
   1183   int n = CFArrayGetCount(cert_chain);
   1184   for (int i = 0; i < n; ++i) {
   1185     SecCertificateRef cert_handle = reinterpret_cast<SecCertificateRef>(
   1186         const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
   1187     scoped_refptr<X509Certificate> cert(X509Certificate::CreateFromHandle(
   1188         cert_handle,
   1189         X509Certificate::SOURCE_LONE_CERT_IMPORT,
   1190         X509Certificate::OSCertHandles()));
   1191     for (unsigned j = 0; j < valid_issuers.size(); j++) {
   1192       if (cert->issuer().Matches(valid_issuers[j]))
   1193         return true;
   1194     }
   1195   }
   1196   return false;
   1197 }
   1198 
   1199 // static
   1200 OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* out_policy) {
   1201   CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = {
   1202     CSSM_APPLE_TP_SSL_OPTS_VERSION,
   1203     0,
   1204     NULL,
   1205     CSSM_APPLE_TP_SSL_CLIENT
   1206   };
   1207   return CreatePolicy(&CSSMOID_APPLE_TP_SSL,
   1208                       &tp_ssl_options,
   1209                       sizeof(tp_ssl_options),
   1210                       out_policy);
   1211 }
   1212 
   1213 // static
   1214 bool X509Certificate::GetSSLClientCertificates(
   1215     const std::string& server_domain,
   1216     const std::vector<CertPrincipal>& valid_issuers,
   1217     CertificateList* certs) {
   1218   ScopedCFTypeRef<SecIdentityRef> preferred_identity;
   1219   if (!server_domain.empty()) {
   1220     // See if there's an identity preference for this domain:
   1221     ScopedCFTypeRef<CFStringRef> domain_str(
   1222         base::SysUTF8ToCFStringRef("https://" + server_domain));
   1223     SecIdentityRef identity = NULL;
   1224     // While SecIdentityCopyPreferences appears to take a list of CA issuers
   1225     // to restrict the identity search to, within Security.framework the
   1226     // argument is ignored and filtering unimplemented. See
   1227     // SecIdentity.cpp in libsecurity_keychain, specifically
   1228     // _SecIdentityCopyPreferenceMatchingName().
   1229     if (SecIdentityCopyPreference(domain_str, 0, NULL, &identity) == noErr)
   1230       preferred_identity.reset(identity);
   1231   }
   1232 
   1233   // Now enumerate the identities in the available keychains.
   1234   SecIdentitySearchRef search = nil;
   1235   OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search);
   1236   ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search);
   1237   while (!err) {
   1238     SecIdentityRef identity = NULL;
   1239     err = SecIdentitySearchCopyNext(search, &identity);
   1240     if (err)
   1241       break;
   1242     ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity);
   1243 
   1244     SecCertificateRef cert_handle;
   1245     err = SecIdentityCopyCertificate(identity, &cert_handle);
   1246     if (err != noErr)
   1247       continue;
   1248     ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle);
   1249 
   1250     scoped_refptr<X509Certificate> cert(
   1251         CreateFromHandle(cert_handle, SOURCE_LONE_CERT_IMPORT,
   1252                          OSCertHandles()));
   1253     if (cert->HasExpired() || !cert->SupportsSSLClientAuth())
   1254       continue;
   1255 
   1256     // Skip duplicates (a cert may be in multiple keychains).
   1257     const SHA1Fingerprint& fingerprint = cert->fingerprint();
   1258     unsigned i;
   1259     for (i = 0; i < certs->size(); ++i) {
   1260       if ((*certs)[i]->fingerprint().Equals(fingerprint))
   1261         break;
   1262     }
   1263     if (i < certs->size())
   1264       continue;
   1265 
   1266     bool is_preferred = preferred_identity &&
   1267         CFEqual(preferred_identity, identity);
   1268 
   1269     // Make sure the issuer matches valid_issuers, if given.
   1270     // But an explicit cert preference overrides this.
   1271     if (!is_preferred &&
   1272         !valid_issuers.empty() &&
   1273         !cert->IsIssuedBy(valid_issuers))
   1274       continue;
   1275 
   1276     // The cert passes, so add it to the vector.
   1277     // If it's the preferred identity, add it at the start (so it'll be
   1278     // selected by default in the UI.)
   1279     if (is_preferred)
   1280       certs->insert(certs->begin(), cert);
   1281     else
   1282       certs->push_back(cert);
   1283   }
   1284 
   1285   if (err != errSecItemNotFound) {
   1286     LOG(ERROR) << "SecIdentitySearch error " << err;
   1287     return false;
   1288   }
   1289   return true;
   1290 }
   1291 
   1292 CFArrayRef X509Certificate::CreateClientCertificateChain() const {
   1293   // Initialize the result array with just the IdentityRef of the receiver:
   1294   OSStatus result;
   1295   SecIdentityRef identity;
   1296   result = SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity);
   1297   if (result) {
   1298     LOG(ERROR) << "SecIdentityCreateWithCertificate error " << result;
   1299     return NULL;
   1300   }
   1301   ScopedCFTypeRef<CFMutableArrayRef> chain(
   1302       CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
   1303   CFArrayAppendValue(chain, identity);
   1304 
   1305   CFArrayRef cert_chain = NULL;
   1306   result = CopyCertChain(cert_handle_, &cert_chain);
   1307   ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain);
   1308   if (result) {
   1309     LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
   1310     return chain.release();
   1311   }
   1312 
   1313   // Append the intermediate certs from SecTrust to the result array:
   1314   if (cert_chain) {
   1315     int chain_count = CFArrayGetCount(cert_chain);
   1316     if (chain_count > 1) {
   1317       CFArrayAppendArray(chain,
   1318                          cert_chain,
   1319                          CFRangeMake(1, chain_count - 1));
   1320     }
   1321   }
   1322 
   1323   return chain.release();
   1324 }
   1325 
   1326 // static
   1327 X509Certificate::OSCertHandle
   1328 X509Certificate::ReadCertHandleFromPickle(const Pickle& pickle,
   1329                                           void** pickle_iter) {
   1330   const char* data;
   1331   int length;
   1332   if (!pickle.ReadData(pickle_iter, &data, &length))
   1333     return NULL;
   1334 
   1335   return CreateOSCertHandleFromBytes(data, length);
   1336 }
   1337 
   1338 // static
   1339 bool X509Certificate::WriteCertHandleToPickle(OSCertHandle cert_handle,
   1340                                               Pickle* pickle) {
   1341   CSSM_DATA cert_data;
   1342   OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
   1343   if (status)
   1344     return false;
   1345 
   1346   return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data),
   1347                            cert_data.Length);
   1348 }
   1349 
   1350 }  // namespace net
   1351