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 <cert.h> 8 #include <cryptohi.h> 9 #include <keyhi.h> 10 #include <nss.h> 11 #include <pk11pub.h> 12 #include <prerror.h> 13 #include <prtime.h> 14 #include <secder.h> 15 #include <secerr.h> 16 #include <sechash.h> 17 #include <sslerr.h> 18 19 #include "base/logging.h" 20 #include "base/memory/scoped_ptr.h" 21 #include "base/pickle.h" 22 #include "base/time.h" 23 #include "crypto/nss_util.h" 24 #include "crypto/rsa_private_key.h" 25 #include "net/base/cert_status_flags.h" 26 #include "net/base/cert_verify_result.h" 27 #include "net/base/ev_root_ca_metadata.h" 28 #include "net/base/net_errors.h" 29 30 namespace net { 31 32 namespace { 33 34 class ScopedCERTCertificatePolicies { 35 public: 36 explicit ScopedCERTCertificatePolicies(CERTCertificatePolicies* policies) 37 : policies_(policies) {} 38 39 ~ScopedCERTCertificatePolicies() { 40 if (policies_) 41 CERT_DestroyCertificatePoliciesExtension(policies_); 42 } 43 44 private: 45 CERTCertificatePolicies* policies_; 46 47 DISALLOW_COPY_AND_ASSIGN(ScopedCERTCertificatePolicies); 48 }; 49 50 // ScopedCERTValOutParam manages destruction of values in the CERTValOutParam 51 // array that cvout points to. cvout must be initialized as passed to 52 // CERT_PKIXVerifyCert, so that the array must be terminated with 53 // cert_po_end type. 54 // When it goes out of scope, it destroys values of cert_po_trustAnchor 55 // and cert_po_certList types, but doesn't release the array itself. 56 class ScopedCERTValOutParam { 57 public: 58 explicit ScopedCERTValOutParam(CERTValOutParam* cvout) 59 : cvout_(cvout) {} 60 61 ~ScopedCERTValOutParam() { 62 if (cvout_ == NULL) 63 return; 64 for (CERTValOutParam *p = cvout_; p->type != cert_po_end; p++) { 65 switch (p->type) { 66 case cert_po_trustAnchor: 67 if (p->value.pointer.cert) { 68 CERT_DestroyCertificate(p->value.pointer.cert); 69 p->value.pointer.cert = NULL; 70 } 71 break; 72 case cert_po_certList: 73 if (p->value.pointer.chain) { 74 CERT_DestroyCertList(p->value.pointer.chain); 75 p->value.pointer.chain = NULL; 76 } 77 break; 78 default: 79 break; 80 } 81 } 82 } 83 84 private: 85 CERTValOutParam* cvout_; 86 87 DISALLOW_COPY_AND_ASSIGN(ScopedCERTValOutParam); 88 }; 89 90 // Map PORT_GetError() return values to our network error codes. 91 int MapSecurityError(int err) { 92 switch (err) { 93 case PR_DIRECTORY_LOOKUP_ERROR: // DNS lookup error. 94 return ERR_NAME_NOT_RESOLVED; 95 case SEC_ERROR_INVALID_ARGS: 96 return ERR_INVALID_ARGUMENT; 97 case SSL_ERROR_BAD_CERT_DOMAIN: 98 return ERR_CERT_COMMON_NAME_INVALID; 99 case SEC_ERROR_INVALID_TIME: 100 case SEC_ERROR_EXPIRED_CERTIFICATE: 101 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 102 return ERR_CERT_DATE_INVALID; 103 case SEC_ERROR_UNKNOWN_ISSUER: 104 case SEC_ERROR_UNTRUSTED_ISSUER: 105 case SEC_ERROR_CA_CERT_INVALID: 106 return ERR_CERT_AUTHORITY_INVALID; 107 case SEC_ERROR_REVOKED_CERTIFICATE: 108 case SEC_ERROR_UNTRUSTED_CERT: // Treat as revoked. 109 return ERR_CERT_REVOKED; 110 case SEC_ERROR_BAD_DER: 111 case SEC_ERROR_BAD_SIGNATURE: 112 case SEC_ERROR_CERT_NOT_VALID: 113 // TODO(port): add an ERR_CERT_WRONG_USAGE error code. 114 case SEC_ERROR_CERT_USAGES_INVALID: 115 case SEC_ERROR_INADEQUATE_KEY_USAGE: 116 case SEC_ERROR_INADEQUATE_CERT_TYPE: 117 case SEC_ERROR_POLICY_VALIDATION_FAILED: 118 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: 119 case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: 120 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: 121 case SEC_ERROR_EXTENSION_VALUE_INVALID: 122 return ERR_CERT_INVALID; 123 default: 124 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; 125 return ERR_FAILED; 126 } 127 } 128 129 // Map PORT_GetError() return values to our cert status flags. 130 int MapCertErrorToCertStatus(int err) { 131 switch (err) { 132 case SSL_ERROR_BAD_CERT_DOMAIN: 133 return CERT_STATUS_COMMON_NAME_INVALID; 134 case SEC_ERROR_INVALID_TIME: 135 case SEC_ERROR_EXPIRED_CERTIFICATE: 136 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 137 return CERT_STATUS_DATE_INVALID; 138 case SEC_ERROR_UNKNOWN_ISSUER: 139 case SEC_ERROR_UNTRUSTED_ISSUER: 140 case SEC_ERROR_CA_CERT_INVALID: 141 return CERT_STATUS_AUTHORITY_INVALID; 142 // TODO(port): map CERT_STATUS_NO_REVOCATION_MECHANISM. 143 case SEC_ERROR_OCSP_BAD_HTTP_RESPONSE: 144 case SEC_ERROR_OCSP_SERVER_ERROR: 145 return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; 146 case SEC_ERROR_REVOKED_CERTIFICATE: 147 case SEC_ERROR_UNTRUSTED_CERT: // Treat as revoked. 148 return CERT_STATUS_REVOKED; 149 case SEC_ERROR_BAD_DER: 150 case SEC_ERROR_BAD_SIGNATURE: 151 case SEC_ERROR_CERT_NOT_VALID: 152 // TODO(port): add a CERT_STATUS_WRONG_USAGE error code. 153 case SEC_ERROR_CERT_USAGES_INVALID: 154 case SEC_ERROR_INADEQUATE_KEY_USAGE: // Key usage. 155 case SEC_ERROR_INADEQUATE_CERT_TYPE: // Extended key usage and whether 156 // the certificate is a CA. 157 case SEC_ERROR_POLICY_VALIDATION_FAILED: 158 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: 159 case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: 160 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: 161 case SEC_ERROR_EXTENSION_VALUE_INVALID: 162 return CERT_STATUS_INVALID; 163 default: 164 return 0; 165 } 166 } 167 168 // Saves some information about the certificate chain cert_list in 169 // *verify_result. The caller MUST initialize *verify_result before calling 170 // this function. 171 // Note that cert_list[0] is the end entity certificate and cert_list doesn't 172 // contain the root CA certificate. 173 void GetCertChainInfo(CERTCertList* cert_list, 174 CertVerifyResult* verify_result) { 175 // NOTE: Using a NSS library before 3.12.3.1 will crash below. To see the 176 // NSS version currently in use: 177 // 1. use ldd on the chrome executable for NSS's location (ie. libnss3.so*) 178 // 2. use ident libnss3.so* for the library's version 179 DCHECK(cert_list); 180 int i = 0; 181 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); 182 !CERT_LIST_END(node, cert_list); 183 node = CERT_LIST_NEXT(node), i++) { 184 SECAlgorithmID& signature = node->cert->signature; 185 SECOidTag oid_tag = SECOID_FindOIDTag(&signature.algorithm); 186 switch (oid_tag) { 187 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 188 verify_result->has_md5 = true; 189 if (i != 0) 190 verify_result->has_md5_ca = true; 191 break; 192 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: 193 verify_result->has_md2 = true; 194 if (i != 0) 195 verify_result->has_md2_ca = true; 196 break; 197 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: 198 verify_result->has_md4 = true; 199 break; 200 default: 201 break; 202 } 203 } 204 } 205 206 // IsKnownRoot returns true if the given certificate is one that we believe 207 // is a standard (as opposed to user-installed) root. 208 bool IsKnownRoot(CERTCertificate* root) { 209 if (!root->slot) 210 return false; 211 212 // This magic name is taken from 213 // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/builtins/constants.c&rev=1.13&mark=86,89#79 214 return 0 == strcmp(PK11_GetSlotName(root->slot), 215 "NSS Builtin Objects"); 216 } 217 218 typedef char* (*CERTGetNameFunc)(CERTName* name); 219 220 void ParsePrincipal(CERTName* name, 221 CertPrincipal* principal) { 222 // TODO(jcampan): add business_category and serial_number. 223 // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and 224 // CERT_GetDomainComponentName functions, but they return only the most 225 // general (the first) RDN. NSS doesn't have a function for the street 226 // address. 227 static const SECOidTag kOIDs[] = { 228 SEC_OID_AVA_STREET_ADDRESS, 229 SEC_OID_AVA_ORGANIZATION_NAME, 230 SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, 231 SEC_OID_AVA_DC }; 232 233 std::vector<std::string>* values[] = { 234 &principal->street_addresses, 235 &principal->organization_names, 236 &principal->organization_unit_names, 237 &principal->domain_components }; 238 DCHECK(arraysize(kOIDs) == arraysize(values)); 239 240 CERTRDN** rdns = name->rdns; 241 for (size_t rdn = 0; rdns[rdn]; ++rdn) { 242 CERTAVA** avas = rdns[rdn]->avas; 243 for (size_t pair = 0; avas[pair] != 0; ++pair) { 244 SECOidTag tag = CERT_GetAVATag(avas[pair]); 245 for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { 246 if (kOIDs[oid] == tag) { 247 SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value); 248 if (!decode_item) 249 break; 250 // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote. 251 std::string value(reinterpret_cast<char*>(decode_item->data), 252 decode_item->len); 253 values[oid]->push_back(value); 254 SECITEM_FreeItem(decode_item, PR_TRUE); 255 break; 256 } 257 } 258 } 259 } 260 261 // Get CN, L, S, and C. 262 CERTGetNameFunc get_name_funcs[4] = { 263 CERT_GetCommonName, CERT_GetLocalityName, 264 CERT_GetStateName, CERT_GetCountryName }; 265 std::string* single_values[4] = { 266 &principal->common_name, &principal->locality_name, 267 &principal->state_or_province_name, &principal->country_name }; 268 for (size_t i = 0; i < arraysize(get_name_funcs); ++i) { 269 char* value = get_name_funcs[i](name); 270 if (value) { 271 single_values[i]->assign(value); 272 PORT_Free(value); 273 } 274 } 275 } 276 277 void ParseDate(SECItem* der_date, base::Time* result) { 278 PRTime prtime; 279 SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date); 280 DCHECK(rv == SECSuccess); 281 *result = crypto::PRTimeToBaseTime(prtime); 282 } 283 284 void GetCertSubjectAltNamesOfType(X509Certificate::OSCertHandle cert_handle, 285 CERTGeneralNameType name_type, 286 std::vector<std::string>* result) { 287 // For future extension: We only support general names of types 288 // RFC822Name, DNSName or URI. 289 DCHECK(name_type == certRFC822Name || 290 name_type == certDNSName || 291 name_type == certURI); 292 293 SECItem alt_name; 294 SECStatus rv = CERT_FindCertExtension(cert_handle, 295 SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name); 296 if (rv != SECSuccess) 297 return; 298 299 PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 300 DCHECK(arena != NULL); 301 302 CERTGeneralName* alt_name_list; 303 alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name); 304 SECITEM_FreeItem(&alt_name, PR_FALSE); 305 306 CERTGeneralName* name = alt_name_list; 307 while (name) { 308 // All of the general name types we support are encoded as 309 // IA5String. In general, we should be switching off 310 // |name->type| and doing type-appropriate conversions. 311 if (name->type == name_type) { 312 unsigned char* p = name->name.other.data; 313 int len = name->name.other.len; 314 std::string value = std::string(reinterpret_cast<char*>(p), len); 315 result->push_back(value); 316 } 317 name = CERT_GetNextGeneralName(name); 318 if (name == alt_name_list) 319 break; 320 } 321 PORT_FreeArena(arena, PR_FALSE); 322 } 323 324 // Forward declarations. 325 SECStatus RetryPKIXVerifyCertWithWorkarounds( 326 X509Certificate::OSCertHandle cert_handle, int num_policy_oids, 327 std::vector<CERTValInParam>* cvin, CERTValOutParam* cvout); 328 SECOidTag GetFirstCertPolicy(X509Certificate::OSCertHandle cert_handle); 329 330 // Call CERT_PKIXVerifyCert for the cert_handle. 331 // Verification results are stored in an array of CERTValOutParam. 332 // If policy_oids is not NULL and num_policy_oids is positive, policies 333 // are also checked. 334 // Caller must initialize cvout before calling this function. 335 SECStatus PKIXVerifyCert(X509Certificate::OSCertHandle cert_handle, 336 bool check_revocation, 337 const SECOidTag* policy_oids, 338 int num_policy_oids, 339 CERTValOutParam* cvout) { 340 bool use_crl = check_revocation; 341 bool use_ocsp = check_revocation; 342 343 // These CAs have multiple keys, which trigger two bugs in NSS's CRL code. 344 // 1. NSS may use one key to verify a CRL signed with another key, 345 // incorrectly concluding that the CRL's signature is invalid. 346 // Hopefully this bug will be fixed in NSS 3.12.9. 347 // 2. NSS considers all certificates issued by the CA as revoked when it 348 // receives a CRL with an invalid signature. This overly strict policy 349 // has been relaxed in NSS 3.12.7. See 350 // https://bugzilla.mozilla.org/show_bug.cgi?id=562542. 351 // So we have to turn off CRL checking for these CAs. See 352 // http://crbug.com/55695. 353 static const char* const kMultipleKeyCA[] = { 354 "CN=Microsoft Secure Server Authority," 355 "DC=redmond,DC=corp,DC=microsoft,DC=com", 356 "CN=Microsoft Secure Server Authority", 357 }; 358 359 if (!NSS_VersionCheck("3.12.7")) { 360 for (size_t i = 0; i < arraysize(kMultipleKeyCA); ++i) { 361 if (strcmp(cert_handle->issuerName, kMultipleKeyCA[i]) == 0) { 362 use_crl = false; 363 break; 364 } 365 } 366 } 367 368 PRUint64 revocation_method_flags = 369 CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD | 370 CERT_REV_M_ALLOW_NETWORK_FETCHING | 371 CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE | 372 CERT_REV_M_IGNORE_MISSING_FRESH_INFO | 373 CERT_REV_M_STOP_TESTING_ON_FRESH_INFO; 374 PRUint64 revocation_method_independent_flags = 375 CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; 376 if (policy_oids && num_policy_oids > 0) { 377 // EV verification requires revocation checking. Consider the certificate 378 // revoked if we don't have revocation info. 379 // TODO(wtc): Add a bool parameter to expressly specify we're doing EV 380 // verification or we want strict revocation flags. 381 revocation_method_flags |= CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE; 382 revocation_method_independent_flags |= 383 CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE; 384 } else { 385 revocation_method_flags |= CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE; 386 revocation_method_independent_flags |= 387 CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT; 388 } 389 PRUint64 method_flags[2]; 390 method_flags[cert_revocation_method_crl] = revocation_method_flags; 391 method_flags[cert_revocation_method_ocsp] = revocation_method_flags; 392 393 if (use_crl) { 394 method_flags[cert_revocation_method_crl] |= 395 CERT_REV_M_TEST_USING_THIS_METHOD; 396 } 397 if (use_ocsp) { 398 method_flags[cert_revocation_method_ocsp] |= 399 CERT_REV_M_TEST_USING_THIS_METHOD; 400 } 401 402 CERTRevocationMethodIndex preferred_revocation_methods[1]; 403 if (use_ocsp) { 404 preferred_revocation_methods[0] = cert_revocation_method_ocsp; 405 } else { 406 preferred_revocation_methods[0] = cert_revocation_method_crl; 407 } 408 409 CERTRevocationFlags revocation_flags; 410 revocation_flags.leafTests.number_of_defined_methods = 411 arraysize(method_flags); 412 revocation_flags.leafTests.cert_rev_flags_per_method = method_flags; 413 revocation_flags.leafTests.number_of_preferred_methods = 414 arraysize(preferred_revocation_methods); 415 revocation_flags.leafTests.preferred_methods = preferred_revocation_methods; 416 revocation_flags.leafTests.cert_rev_method_independent_flags = 417 revocation_method_independent_flags; 418 419 revocation_flags.chainTests.number_of_defined_methods = 420 arraysize(method_flags); 421 revocation_flags.chainTests.cert_rev_flags_per_method = method_flags; 422 revocation_flags.chainTests.number_of_preferred_methods = 423 arraysize(preferred_revocation_methods); 424 revocation_flags.chainTests.preferred_methods = preferred_revocation_methods; 425 revocation_flags.chainTests.cert_rev_method_independent_flags = 426 revocation_method_independent_flags; 427 428 std::vector<CERTValInParam> cvin; 429 cvin.reserve(5); 430 CERTValInParam in_param; 431 // No need to set cert_pi_trustAnchors here. 432 in_param.type = cert_pi_revocationFlags; 433 in_param.value.pointer.revocation = &revocation_flags; 434 cvin.push_back(in_param); 435 if (policy_oids && num_policy_oids > 0) { 436 in_param.type = cert_pi_policyOID; 437 in_param.value.arraySize = num_policy_oids; 438 in_param.value.array.oids = policy_oids; 439 cvin.push_back(in_param); 440 } 441 in_param.type = cert_pi_end; 442 cvin.push_back(in_param); 443 444 SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, 445 &cvin[0], cvout, NULL); 446 if (rv != SECSuccess) { 447 rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, 448 &cvin, cvout); 449 } 450 return rv; 451 } 452 453 // PKIXVerifyCert calls this function to work around some bugs in 454 // CERT_PKIXVerifyCert. All the arguments of this function are either the 455 // arguments or local variables of PKIXVerifyCert. 456 SECStatus RetryPKIXVerifyCertWithWorkarounds( 457 X509Certificate::OSCertHandle cert_handle, int num_policy_oids, 458 std::vector<CERTValInParam>* cvin, CERTValOutParam* cvout) { 459 // We call this function when the first CERT_PKIXVerifyCert call in 460 // PKIXVerifyCert failed, so we initialize |rv| to SECFailure. 461 SECStatus rv = SECFailure; 462 int nss_error = PORT_GetError(); 463 CERTValInParam in_param; 464 465 // If we get SEC_ERROR_UNKNOWN_ISSUER, we may be missing an intermediate 466 // CA certificate, so we retry with cert_pi_useAIACertFetch. 467 // cert_pi_useAIACertFetch has several bugs in its error handling and 468 // error reporting (NSS bug 528743), so we don't use it by default. 469 // Note: When building a certificate chain, CERT_PKIXVerifyCert may 470 // incorrectly pick a CA certificate with the same subject name as the 471 // missing intermediate CA certificate, and fail with the 472 // SEC_ERROR_BAD_SIGNATURE error (NSS bug 524013), so we also retry with 473 // cert_pi_useAIACertFetch on SEC_ERROR_BAD_SIGNATURE. 474 if (nss_error == SEC_ERROR_UNKNOWN_ISSUER || 475 nss_error == SEC_ERROR_BAD_SIGNATURE) { 476 DCHECK_EQ(cvin->back().type, cert_pi_end); 477 cvin->pop_back(); 478 in_param.type = cert_pi_useAIACertFetch; 479 in_param.value.scalar.b = PR_TRUE; 480 cvin->push_back(in_param); 481 in_param.type = cert_pi_end; 482 cvin->push_back(in_param); 483 rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, 484 &(*cvin)[0], cvout, NULL); 485 if (rv == SECSuccess) 486 return rv; 487 int new_nss_error = PORT_GetError(); 488 if (new_nss_error == SEC_ERROR_INVALID_ARGS || 489 new_nss_error == SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE || 490 new_nss_error == SEC_ERROR_BAD_HTTP_RESPONSE || 491 new_nss_error == SEC_ERROR_BAD_LDAP_RESPONSE || 492 !IS_SEC_ERROR(new_nss_error)) { 493 // Use the original error code because of cert_pi_useAIACertFetch's 494 // bad error reporting. 495 PORT_SetError(nss_error); 496 return rv; 497 } 498 nss_error = new_nss_error; 499 } 500 501 // If an intermediate CA certificate has requireExplicitPolicy in its 502 // policyConstraints extension, CERT_PKIXVerifyCert fails with 503 // SEC_ERROR_POLICY_VALIDATION_FAILED because we didn't specify any 504 // certificate policy (NSS bug 552775). So we retry with the certificate 505 // policy found in the server certificate. 506 if (nss_error == SEC_ERROR_POLICY_VALIDATION_FAILED && 507 num_policy_oids == 0) { 508 SECOidTag policy = GetFirstCertPolicy(cert_handle); 509 if (policy != SEC_OID_UNKNOWN) { 510 DCHECK_EQ(cvin->back().type, cert_pi_end); 511 cvin->pop_back(); 512 in_param.type = cert_pi_policyOID; 513 in_param.value.arraySize = 1; 514 in_param.value.array.oids = &policy; 515 cvin->push_back(in_param); 516 in_param.type = cert_pi_end; 517 cvin->push_back(in_param); 518 rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, 519 &(*cvin)[0], cvout, NULL); 520 if (rv != SECSuccess) { 521 // Use the original error code. 522 PORT_SetError(nss_error); 523 } 524 } 525 } 526 527 return rv; 528 } 529 530 // Decodes the certificatePolicies extension of the certificate. Returns 531 // NULL if the certificate doesn't have the extension or the extension can't 532 // be decoded. The returned value must be freed with a 533 // CERT_DestroyCertificatePoliciesExtension call. 534 CERTCertificatePolicies* DecodeCertPolicies( 535 X509Certificate::OSCertHandle cert_handle) { 536 SECItem policy_ext; 537 SECStatus rv = CERT_FindCertExtension( 538 cert_handle, SEC_OID_X509_CERTIFICATE_POLICIES, &policy_ext); 539 if (rv != SECSuccess) 540 return NULL; 541 CERTCertificatePolicies* policies = 542 CERT_DecodeCertificatePoliciesExtension(&policy_ext); 543 SECITEM_FreeItem(&policy_ext, PR_FALSE); 544 return policies; 545 } 546 547 // Returns the OID tag for the first certificate policy in the certificate's 548 // certificatePolicies extension. Returns SEC_OID_UNKNOWN if the certificate 549 // has no certificate policy. 550 SECOidTag GetFirstCertPolicy(X509Certificate::OSCertHandle cert_handle) { 551 CERTCertificatePolicies* policies = DecodeCertPolicies(cert_handle); 552 if (!policies) 553 return SEC_OID_UNKNOWN; 554 ScopedCERTCertificatePolicies scoped_policies(policies); 555 CERTPolicyInfo* policy_info = policies->policyInfos[0]; 556 if (!policy_info) 557 return SEC_OID_UNKNOWN; 558 if (policy_info->oid != SEC_OID_UNKNOWN) 559 return policy_info->oid; 560 561 // The certificate policy is unknown to NSS. We need to create a dynamic 562 // OID tag for the policy. 563 SECOidData od; 564 od.oid.len = policy_info->policyID.len; 565 od.oid.data = policy_info->policyID.data; 566 od.offset = SEC_OID_UNKNOWN; 567 // NSS doesn't allow us to pass an empty description, so I use a hardcoded, 568 // default description here. The description doesn't need to be unique for 569 // each OID. 570 od.desc = "a certificate policy"; 571 od.mechanism = CKM_INVALID_MECHANISM; 572 od.supportedExtension = INVALID_CERT_EXTENSION; 573 return SECOID_AddEntry(&od); 574 } 575 576 bool CheckCertPolicies(X509Certificate::OSCertHandle cert_handle, 577 SECOidTag ev_policy_tag) { 578 CERTCertificatePolicies* policies = DecodeCertPolicies(cert_handle); 579 if (!policies) { 580 LOG(ERROR) << "Cert has no policies extension or extension couldn't be " 581 "decoded."; 582 return false; 583 } 584 ScopedCERTCertificatePolicies scoped_policies(policies); 585 CERTPolicyInfo** policy_infos = policies->policyInfos; 586 while (*policy_infos != NULL) { 587 CERTPolicyInfo* policy_info = *policy_infos++; 588 SECOidTag oid_tag = policy_info->oid; 589 if (oid_tag == SEC_OID_UNKNOWN) 590 continue; 591 if (oid_tag == ev_policy_tag) 592 return true; 593 } 594 LOG(ERROR) << "No EV Policy Tag"; 595 return false; 596 } 597 598 SECStatus PR_CALLBACK 599 CollectCertsCallback(void* arg, SECItem** certs, int num_certs) { 600 X509Certificate::OSCertHandles* results = 601 reinterpret_cast<X509Certificate::OSCertHandles*>(arg); 602 603 for (int i = 0; i < num_certs; ++i) { 604 X509Certificate::OSCertHandle handle = 605 X509Certificate::CreateOSCertHandleFromBytes( 606 reinterpret_cast<char*>(certs[i]->data), certs[i]->len); 607 if (handle) 608 results->push_back(handle); 609 } 610 611 return SECSuccess; 612 } 613 614 SHA1Fingerprint CertPublicKeyHash(CERTCertificate* cert) { 615 SHA1Fingerprint hash; 616 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, hash.data, 617 cert->derPublicKey.data, cert->derPublicKey.len); 618 DCHECK_EQ(rv, SECSuccess); 619 return hash; 620 } 621 622 void AppendPublicKeyHashes(CERTCertList* cert_list, 623 CERTCertificate* root_cert, 624 std::vector<SHA1Fingerprint>* hashes) { 625 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); 626 !CERT_LIST_END(node, cert_list); 627 node = CERT_LIST_NEXT(node)) { 628 hashes->push_back(CertPublicKeyHash(node->cert)); 629 } 630 hashes->push_back(CertPublicKeyHash(root_cert)); 631 } 632 633 } // namespace 634 635 void X509Certificate::Initialize() { 636 ParsePrincipal(&cert_handle_->subject, &subject_); 637 ParsePrincipal(&cert_handle_->issuer, &issuer_); 638 639 ParseDate(&cert_handle_->validity.notBefore, &valid_start_); 640 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); 641 642 fingerprint_ = CalculateFingerprint(cert_handle_); 643 644 serial_number_ = std::string( 645 reinterpret_cast<char*>(cert_handle_->serialNumber.data), 646 cert_handle_->serialNumber.len); 647 // Remove leading zeros. 648 while (serial_number_.size() > 1 && serial_number_[0] == 0) 649 serial_number_ = serial_number_.substr(1, serial_number_.size() - 1); 650 } 651 652 // static 653 X509Certificate* X509Certificate::CreateSelfSigned( 654 crypto::RSAPrivateKey* key, 655 const std::string& subject, 656 uint32 serial_number, 657 base::TimeDelta valid_duration) { 658 DCHECK(key); 659 660 // Create info about public key. 661 CERTSubjectPublicKeyInfo* spki = 662 SECKEY_CreateSubjectPublicKeyInfo(key->public_key()); 663 if (!spki) 664 return NULL; 665 666 // Create the certificate request. 667 CERTName* subject_name = 668 CERT_AsciiToName(const_cast<char*>(subject.c_str())); 669 CERTCertificateRequest* cert_request = 670 CERT_CreateCertificateRequest(subject_name, spki, NULL); 671 SECKEY_DestroySubjectPublicKeyInfo(spki); 672 673 if (!cert_request) { 674 PRErrorCode prerr = PR_GetError(); 675 LOG(ERROR) << "Failed to create certificate request: " << prerr; 676 CERT_DestroyName(subject_name); 677 return NULL; 678 } 679 680 PRTime now = PR_Now(); 681 PRTime not_after = now + valid_duration.InMicroseconds(); 682 683 // Note that the time is now in micro-second unit. 684 CERTValidity* validity = CERT_CreateValidity(now, not_after); 685 CERTCertificate* cert = CERT_CreateCertificate(serial_number, subject_name, 686 validity, cert_request); 687 if (!cert) { 688 PRErrorCode prerr = PR_GetError(); 689 LOG(ERROR) << "Failed to create certificate: " << prerr; 690 } 691 692 // Cleanup for resources used to generate the cert. 693 CERT_DestroyName(subject_name); 694 CERT_DestroyValidity(validity); 695 CERT_DestroyCertificateRequest(cert_request); 696 697 // Sign the cert here. The logic of this method references SignCert() in NSS 698 // utility certutil: http://mxr.mozilla.org/security/ident?i=SignCert. 699 700 // |arena| is used to encode the cert. 701 PRArenaPool* arena = cert->arena; 702 SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->key()->keyType, 703 SEC_OID_SHA1); 704 if (algo_id == SEC_OID_UNKNOWN) { 705 CERT_DestroyCertificate(cert); 706 return NULL; 707 } 708 709 SECStatus rv = SECOID_SetAlgorithmID(arena, &cert->signature, algo_id, 0); 710 if (rv != SECSuccess) { 711 CERT_DestroyCertificate(cert); 712 return NULL; 713 } 714 715 // Generate a cert of version 3. 716 *(cert->version.data) = 2; 717 cert->version.len = 1; 718 719 SECItem der; 720 der.len = 0; 721 der.data = NULL; 722 723 // Use ASN1 DER to encode the cert. 724 void* encode_result = SEC_ASN1EncodeItem( 725 arena, &der, cert, SEC_ASN1_GET(CERT_CertificateTemplate)); 726 if (!encode_result) { 727 CERT_DestroyCertificate(cert); 728 return NULL; 729 } 730 731 // Allocate space to contain the signed cert. 732 SECItem* result = SECITEM_AllocItem(arena, NULL, 0); 733 if (!result) { 734 CERT_DestroyCertificate(cert); 735 return NULL; 736 } 737 738 // Sign the ASN1 encoded cert and save it to |result|. 739 rv = SEC_DerSignData(arena, result, der.data, der.len, key->key(), algo_id); 740 if (rv != SECSuccess) { 741 CERT_DestroyCertificate(cert); 742 return NULL; 743 } 744 745 // Save the signed result to the cert. 746 cert->derCert = *result; 747 748 X509Certificate* x509_cert = 749 CreateFromHandle(cert, SOURCE_LONE_CERT_IMPORT, OSCertHandles()); 750 CERT_DestroyCertificate(cert); 751 return x509_cert; 752 } 753 754 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 755 dns_names->clear(); 756 757 // Compare with CERT_VerifyCertName(). 758 GetCertSubjectAltNamesOfType(cert_handle_, certDNSName, dns_names); 759 760 if (dns_names->empty()) 761 dns_names->push_back(subject_.common_name); 762 } 763 764 int X509Certificate::Verify(const std::string& hostname, 765 int flags, 766 CertVerifyResult* verify_result) const { 767 verify_result->Reset(); 768 769 if (IsBlacklisted()) { 770 verify_result->cert_status |= CERT_STATUS_REVOKED; 771 return ERR_CERT_REVOKED; 772 } 773 774 // Make sure that the hostname matches with the common name of the cert. 775 SECStatus status = CERT_VerifyCertName(cert_handle_, hostname.c_str()); 776 if (status != SECSuccess) 777 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; 778 779 // Make sure that the cert is valid now. 780 SECCertTimeValidity validity = CERT_CheckCertValidTimes( 781 cert_handle_, PR_Now(), PR_TRUE); 782 if (validity != secCertTimeValid) 783 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 784 785 CERTValOutParam cvout[3]; 786 int cvout_index = 0; 787 cvout[cvout_index].type = cert_po_certList; 788 cvout[cvout_index].value.pointer.chain = NULL; 789 int cvout_cert_list_index = cvout_index; 790 cvout_index++; 791 cvout[cvout_index].type = cert_po_trustAnchor; 792 cvout[cvout_index].value.pointer.cert = NULL; 793 int cvout_trust_anchor_index = cvout_index; 794 cvout_index++; 795 cvout[cvout_index].type = cert_po_end; 796 ScopedCERTValOutParam scoped_cvout(cvout); 797 798 bool check_revocation = (flags & VERIFY_REV_CHECKING_ENABLED); 799 if (check_revocation) { 800 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 801 } else { 802 // EV requires revocation checking. 803 flags &= ~VERIFY_EV_CERT; 804 } 805 status = PKIXVerifyCert(cert_handle_, check_revocation, NULL, 0, cvout); 806 if (status != SECSuccess) { 807 int err = PORT_GetError(); 808 LOG(ERROR) << "CERT_PKIXVerifyCert for " << hostname 809 << " failed err=" << err; 810 // CERT_PKIXVerifyCert rerports the wrong error code for 811 // expired certificates (NSS bug 491174) 812 if (err == SEC_ERROR_CERT_NOT_VALID && 813 (verify_result->cert_status & CERT_STATUS_DATE_INVALID) != 0) 814 err = SEC_ERROR_EXPIRED_CERTIFICATE; 815 int cert_status = MapCertErrorToCertStatus(err); 816 if (cert_status) { 817 verify_result->cert_status |= cert_status; 818 return MapCertStatusToNetError(verify_result->cert_status); 819 } 820 // |err| is not a certificate error. 821 return MapSecurityError(err); 822 } 823 824 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, 825 verify_result); 826 if (IsCertStatusError(verify_result->cert_status)) 827 return MapCertStatusToNetError(verify_result->cert_status); 828 829 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, 830 cvout[cvout_trust_anchor_index].value.pointer.cert, 831 &verify_result->public_key_hashes); 832 833 verify_result->is_issued_by_known_root = 834 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); 835 836 if ((flags & VERIFY_EV_CERT) && VerifyEV()) 837 verify_result->cert_status |= CERT_STATUS_IS_EV; 838 839 if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) { 840 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; 841 return MapCertStatusToNetError(verify_result->cert_status); 842 } 843 844 return OK; 845 } 846 847 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { 848 return CERT_VerifyCertName(cert_handle_, hostname.c_str()) == SECSuccess; 849 } 850 851 // Studied Mozilla's code (esp. security/manager/ssl/src/nsIdentityChecking.cpp 852 // and nsNSSCertHelper.cpp) to learn how to verify EV certificate. 853 // TODO(wtc): A possible optimization is that we get the trust anchor from 854 // the first PKIXVerifyCert call. We look up the EV policy for the trust 855 // anchor. If the trust anchor has no EV policy, we know the cert isn't EV. 856 // Otherwise, we pass just that EV policy (as opposed to all the EV policies) 857 // to the second PKIXVerifyCert call. 858 bool X509Certificate::VerifyEV() const { 859 EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance(); 860 861 CERTValOutParam cvout[3]; 862 int cvout_index = 0; 863 cvout[cvout_index].type = cert_po_trustAnchor; 864 cvout[cvout_index].value.pointer.cert = NULL; 865 int cvout_trust_anchor_index = cvout_index; 866 cvout_index++; 867 cvout[cvout_index].type = cert_po_end; 868 ScopedCERTValOutParam scoped_cvout(cvout); 869 870 SECStatus status = PKIXVerifyCert(cert_handle_, 871 true, 872 metadata->GetPolicyOIDs(), 873 metadata->NumPolicyOIDs(), 874 cvout); 875 if (status != SECSuccess) 876 return false; 877 878 CERTCertificate* root_ca = 879 cvout[cvout_trust_anchor_index].value.pointer.cert; 880 if (root_ca == NULL) 881 return false; 882 SHA1Fingerprint fingerprint = 883 X509Certificate::CalculateFingerprint(root_ca); 884 SECOidTag ev_policy_tag = SEC_OID_UNKNOWN; 885 if (!metadata->GetPolicyOID(fingerprint, &ev_policy_tag)) 886 return false; 887 888 if (!CheckCertPolicies(cert_handle_, ev_policy_tag)) 889 return false; 890 891 return true; 892 } 893 894 bool X509Certificate::GetDEREncoded(std::string* encoded) { 895 if (!cert_handle_->derCert.len) 896 return false; 897 encoded->clear(); 898 encoded->append(reinterpret_cast<char*>(cert_handle_->derCert.data), 899 cert_handle_->derCert.len); 900 return true; 901 } 902 903 // static 904 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, 905 X509Certificate::OSCertHandle b) { 906 DCHECK(a && b); 907 if (a == b) 908 return true; 909 return a->derCert.len == b->derCert.len && 910 memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0; 911 } 912 913 // static 914 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 915 const char* data, int length) { 916 if (length < 0) 917 return NULL; 918 919 crypto::EnsureNSSInit(); 920 921 if (!NSS_IsInitialized()) 922 return NULL; 923 924 SECItem der_cert; 925 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data)); 926 der_cert.len = length; 927 der_cert.type = siDERCertBuffer; 928 929 // Parse into a certificate structure. 930 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL, 931 PR_FALSE, PR_TRUE); 932 } 933 934 // static 935 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( 936 const char* data, int length, Format format) { 937 OSCertHandles results; 938 if (length < 0) 939 return results; 940 941 crypto::EnsureNSSInit(); 942 943 if (!NSS_IsInitialized()) 944 return results; 945 946 switch (format) { 947 case FORMAT_SINGLE_CERTIFICATE: { 948 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); 949 if (handle) 950 results.push_back(handle); 951 break; 952 } 953 case FORMAT_PKCS7: { 954 // Make a copy since CERT_DecodeCertPackage may modify it 955 std::vector<char> data_copy(data, data + length); 956 957 SECStatus result = CERT_DecodeCertPackage(&data_copy[0], 958 length, CollectCertsCallback, &results); 959 if (result != SECSuccess) 960 results.clear(); 961 break; 962 } 963 default: 964 NOTREACHED() << "Certificate format " << format << " unimplemented"; 965 break; 966 } 967 968 return results; 969 } 970 971 // static 972 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 973 OSCertHandle cert_handle) { 974 return CERT_DupCertificate(cert_handle); 975 } 976 977 // static 978 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 979 CERT_DestroyCertificate(cert_handle); 980 } 981 982 // static 983 SHA1Fingerprint X509Certificate::CalculateFingerprint( 984 OSCertHandle cert) { 985 SHA1Fingerprint sha1; 986 memset(sha1.data, 0, sizeof(sha1.data)); 987 988 DCHECK(NULL != cert->derCert.data); 989 DCHECK(0 != cert->derCert.len); 990 991 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data, 992 cert->derCert.data, cert->derCert.len); 993 DCHECK(rv == SECSuccess); 994 995 return sha1; 996 } 997 998 // static 999 X509Certificate::OSCertHandle 1000 X509Certificate::ReadCertHandleFromPickle(const Pickle& pickle, 1001 void** pickle_iter) { 1002 const char* data; 1003 int length; 1004 if (!pickle.ReadData(pickle_iter, &data, &length)) 1005 return NULL; 1006 1007 return CreateOSCertHandleFromBytes(data, length); 1008 } 1009 1010 // static 1011 bool X509Certificate::WriteCertHandleToPickle(OSCertHandle cert_handle, 1012 Pickle* pickle) { 1013 return pickle->WriteData( 1014 reinterpret_cast<const char*>(cert_handle->derCert.data), 1015 cert_handle->derCert.len); 1016 } 1017 1018 } // namespace net 1019