Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: net/cert/cert_verify_proc_mac.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/cert_verify_proc_mac.h" 5 #include "net/cert/cert_verify_proc_mac.h"
6 6
7 #include <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <Security/Security.h> 9 #include <Security/Security.h>
10 10
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 verify_result->has_md5 = true; 229 verify_result->has_md5 = true;
230 } 230 }
231 } 231 }
232 if (!verified_cert) 232 if (!verified_cert)
233 return; 233 return;
234 234
235 verify_result->verified_cert = 235 verify_result->verified_cert =
236 X509Certificate::CreateFromHandle(verified_cert, verified_chain); 236 X509Certificate::CreateFromHandle(verified_cert, verified_chain);
237 } 237 }
238 238
239 void AppendPublicKeyHashes(CFArrayRef chain, 239 void AppendPublicKeyHashes(CFArrayRef chain, HashValueVector* hashes) {
240 HashValueVector* hashes) {
241 const CFIndex n = CFArrayGetCount(chain); 240 const CFIndex n = CFArrayGetCount(chain);
242 for (CFIndex i = 0; i < n; i++) { 241 for (CFIndex i = 0; i < n; i++) {
243 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( 242 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
244 const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); 243 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
245 244
246 CSSM_DATA cert_data; 245 CSSM_DATA cert_data;
247 OSStatus err = SecCertificateGetData(cert, &cert_data); 246 OSStatus err = SecCertificateGetData(cert, &cert_data);
248 DCHECK_EQ(err, noErr); 247 DCHECK_EQ(err, noErr);
249 base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data), 248 base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data),
250 cert_data.Length); 249 cert_data.Length);
251 base::StringPiece spki_bytes; 250 base::StringPiece spki_bytes;
252 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) 251 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
253 continue; 252 continue;
254 253
255 HashValue sha1(HASH_VALUE_SHA1); 254 HashValue sha1(HASH_VALUE_SHA1);
256 CC_SHA1(spki_bytes.data(), spki_bytes.size(), sha1.data()); 255 CC_SHA1(spki_bytes.data(), spki_bytes.size(), sha1.data());
257 hashes->push_back(sha1); 256 hashes->push_back(sha1);
258 257
259 HashValue sha256(HASH_VALUE_SHA256); 258 HashValue sha256(HASH_VALUE_SHA256);
260 CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data()); 259 CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data());
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // This function should only be called while the Mac Security Services lock is 351 // This function should only be called while the Mac Security Services lock is
353 // held. 352 // held.
354 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, 353 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
355 CFArrayRef trust_policies, 354 CFArrayRef trust_policies,
356 int flags, 355 int flags,
357 ScopedCFTypeRef<SecTrustRef>* trust_ref, 356 ScopedCFTypeRef<SecTrustRef>* trust_ref,
358 SecTrustResultType* trust_result, 357 SecTrustResultType* trust_result,
359 ScopedCFTypeRef<CFArrayRef>* verified_chain, 358 ScopedCFTypeRef<CFArrayRef>* verified_chain,
360 CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) { 359 CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) {
361 SecTrustRef tmp_trust = NULL; 360 SecTrustRef tmp_trust = NULL;
362 OSStatus status = SecTrustCreateWithCertificates(cert_array, trust_policies, 361 OSStatus status =
363 &tmp_trust); 362 SecTrustCreateWithCertificates(cert_array, trust_policies, &tmp_trust);
364 if (status) 363 if (status)
365 return NetErrorFromOSStatus(status); 364 return NetErrorFromOSStatus(status);
366 ScopedCFTypeRef<SecTrustRef> scoped_tmp_trust(tmp_trust); 365 ScopedCFTypeRef<SecTrustRef> scoped_tmp_trust(tmp_trust);
367 366
368 if (TestRootCerts::HasInstance()) { 367 if (TestRootCerts::HasInstance()) {
369 status = TestRootCerts::GetInstance()->FixupSecTrustRef(tmp_trust); 368 status = TestRootCerts::GetInstance()->FixupSecTrustRef(tmp_trust);
370 if (status) 369 if (status)
371 return NetErrorFromOSStatus(status); 370 return NetErrorFromOSStatus(status);
372 } 371 }
373 372
374 CSSM_APPLE_TP_ACTION_DATA tp_action_data; 373 CSSM_APPLE_TP_ACTION_DATA tp_action_data;
375 memset(&tp_action_data, 0, sizeof(tp_action_data)); 374 memset(&tp_action_data, 0, sizeof(tp_action_data));
376 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION; 375 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
377 // Allow CSSM to download any missing intermediate certificates if an 376 // Allow CSSM to download any missing intermediate certificates if an
378 // authorityInfoAccess extension or issuerAltName extension is present. 377 // authorityInfoAccess extension or issuerAltName extension is present.
379 tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET | 378 tp_action_data.ActionFlags =
380 CSSM_TP_ACTION_TRUST_SETTINGS; 379 CSSM_TP_ACTION_FETCH_CERT_FROM_NET | CSSM_TP_ACTION_TRUST_SETTINGS;
381 380
382 // Note: For EV certificates, the Apple TP will handle setting these flags 381 // Note: For EV certificates, the Apple TP will handle setting these flags
383 // as part of EV evaluation. 382 // as part of EV evaluation.
384 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) { 383 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) {
385 // Require a positive result from an OCSP responder or a CRL (or both) 384 // Require a positive result from an OCSP responder or a CRL (or both)
386 // for every certificate in the chain. The Apple TP automatically 385 // for every certificate in the chain. The Apple TP automatically
387 // excludes the self-signed root from this requirement. If a certificate 386 // excludes the self-signed root from this requirement. If a certificate
388 // is missing both a crlDistributionPoints extension and an 387 // is missing both a crlDistributionPoints extension and an
389 // authorityInfoAccess extension with an OCSP responder URL, then we 388 // authorityInfoAccess extension with an OCSP responder URL, then we
390 // will get a kSecTrustResultRecoverableTrustFailure back from 389 // will get a kSecTrustResultRecoverableTrustFailure back from
391 // SecTrustEvaluate(), with a 390 // SecTrustEvaluate(), with a
392 // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case, 391 // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case,
393 // we'll set our own result to include 392 // we'll set our own result to include
394 // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are 393 // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are
395 // present, and a check fails (server unavailable, OCSP retry later, 394 // present, and a check fails (server unavailable, OCSP retry later,
396 // signature mismatch), then we'll set our own result to include 395 // signature mismatch), then we'll set our own result to include
397 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION. 396 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION.
398 tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT; 397 tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;
399 398
400 // Note, even if revocation checking is disabled, SecTrustEvaluate() will 399 // Note, even if revocation checking is disabled, SecTrustEvaluate() will
401 // modify the OCSP options so as to attempt OCSP checking if it believes a 400 // modify the OCSP options so as to attempt OCSP checking if it believes a
402 // certificate may chain to an EV root. However, because network fetches 401 // certificate may chain to an EV root. However, because network fetches
403 // are disabled in CreateTrustPolicies() when revocation checking is 402 // are disabled in CreateTrustPolicies() when revocation checking is
404 // disabled, these will only go against the local cache. 403 // disabled, these will only go against the local cache.
405 } 404 }
406 405
407 CFDataRef action_data_ref = 406 CFDataRef action_data_ref =
408 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 407 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
409 reinterpret_cast<UInt8*>(&tp_action_data), 408 reinterpret_cast<UInt8*>(&tp_action_data),
410 sizeof(tp_action_data), kCFAllocatorNull); 409 sizeof(tp_action_data),
410 kCFAllocatorNull);
411 if (!action_data_ref) 411 if (!action_data_ref)
412 return ERR_OUT_OF_MEMORY; 412 return ERR_OUT_OF_MEMORY;
413 ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref); 413 ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref);
414 status = SecTrustSetParameters(tmp_trust, CSSM_TP_ACTION_DEFAULT, 414 status =
415 action_data_ref); 415 SecTrustSetParameters(tmp_trust, CSSM_TP_ACTION_DEFAULT, action_data_ref);
416 if (status) 416 if (status)
417 return NetErrorFromOSStatus(status); 417 return NetErrorFromOSStatus(status);
418 418
419 // Verify the certificate. A non-zero result from SecTrustGetResult() 419 // Verify the certificate. A non-zero result from SecTrustGetResult()
420 // indicates that some fatal error occurred and the chain couldn't be 420 // indicates that some fatal error occurred and the chain couldn't be
421 // processed, not that the chain contains no errors. We need to examine the 421 // processed, not that the chain contains no errors. We need to examine the
422 // output of SecTrustGetResult() to determine that. 422 // output of SecTrustGetResult() to determine that.
423 SecTrustResultType tmp_trust_result; 423 SecTrustResultType tmp_trust_result;
424 status = SecTrustEvaluate(tmp_trust, &tmp_trust_result); 424 status = SecTrustEvaluate(tmp_trust, &tmp_trust_result);
425 if (status) 425 if (status)
426 return NetErrorFromOSStatus(status); 426 return NetErrorFromOSStatus(status);
427 CFArrayRef tmp_verified_chain = NULL; 427 CFArrayRef tmp_verified_chain = NULL;
428 CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info; 428 CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info;
429 status = SecTrustGetResult(tmp_trust, &tmp_trust_result, &tmp_verified_chain, 429 status = SecTrustGetResult(
430 &tmp_chain_info); 430 tmp_trust, &tmp_trust_result, &tmp_verified_chain, &tmp_chain_info);
431 if (status) 431 if (status)
432 return NetErrorFromOSStatus(status); 432 return NetErrorFromOSStatus(status);
433 433
434 trust_ref->swap(scoped_tmp_trust); 434 trust_ref->swap(scoped_tmp_trust);
435 *trust_result = tmp_trust_result; 435 *trust_result = tmp_trust_result;
436 verified_chain->reset(tmp_verified_chain); 436 verified_chain->reset(tmp_verified_chain);
437 *chain_info = tmp_chain_info; 437 *chain_info = tmp_chain_info;
438 438
439 return OK; 439 return OK;
440 } 440 }
441 441
442 // OS X ships with both "GTE CyberTrust Global Root" and "Baltimore CyberTrust 442 // OS X ships with both "GTE CyberTrust Global Root" and "Baltimore CyberTrust
443 // Root" as part of its trusted root store. However, a cross-certified version 443 // Root" as part of its trusted root store. However, a cross-certified version
444 // of the "Baltimore CyberTrust Root" exists that chains to "GTE CyberTrust 444 // of the "Baltimore CyberTrust Root" exists that chains to "GTE CyberTrust
445 // Global Root". When OS X/Security.framework attempts to evaluate such a 445 // Global Root". When OS X/Security.framework attempts to evaluate such a
446 // certificate chain, it disregards the "Baltimore CyberTrust Root" that exists 446 // certificate chain, it disregards the "Baltimore CyberTrust Root" that exists
447 // within Keychain and instead attempts to terminate the chain in the "GTE 447 // within Keychain and instead attempts to terminate the chain in the "GTE
448 // CyberTrust Global Root". However, the GTE root is scheduled to be removed in 448 // CyberTrust Global Root". However, the GTE root is scheduled to be removed in
449 // a future OS X update (for sunsetting purposes), and once removed, such 449 // a future OS X update (for sunsetting purposes), and once removed, such
450 // chains will fail validation, even though a trust anchor still exists. 450 // chains will fail validation, even though a trust anchor still exists.
451 // 451 //
452 // Rather than over-generalizing a solution that may mask a number of TLS 452 // Rather than over-generalizing a solution that may mask a number of TLS
453 // misconfigurations, attempt to specifically match the affected 453 // misconfigurations, attempt to specifically match the affected
454 // cross-certified certificate and remove it from certificate chain processing. 454 // cross-certified certificate and remove it from certificate chain processing.
455 bool IsBadBaltimoreGTECertificate(SecCertificateRef cert) { 455 bool IsBadBaltimoreGTECertificate(SecCertificateRef cert) {
456 // Matches the GTE-signed Baltimore CyberTrust Root 456 // Matches the GTE-signed Baltimore CyberTrust Root
457 // https://cacert.omniroot.com/Baltimore-to-GTE-04-12.pem 457 // https://cacert.omniroot.com/Baltimore-to-GTE-04-12.pem
458 static const SHA1HashValue kBadBaltimoreHashNew = 458 static const SHA1HashValue kBadBaltimoreHashNew = {
459 { { 0x4D, 0x34, 0xEA, 0x92, 0x76, 0x4B, 0x3A, 0x31, 0x49, 0x11, 459 {0x4D, 0x34, 0xEA, 0x92, 0x76, 0x4B, 0x3A, 0x31, 0x49, 0x11, 0x99, 0x52,
460 0x99, 0x52, 0xF4, 0x19, 0x30, 0xCA, 0x11, 0x34, 0x83, 0x61 } }; 460 0xF4, 0x19, 0x30, 0xCA, 0x11, 0x34, 0x83, 0x61}};
461 // Matches the legacy GTE-signed Baltimore CyberTrust Root 461 // Matches the legacy GTE-signed Baltimore CyberTrust Root
462 // https://cacert.omniroot.com/gte-2-2025.pem 462 // https://cacert.omniroot.com/gte-2-2025.pem
463 static const SHA1HashValue kBadBaltimoreHashOld = 463 static const SHA1HashValue kBadBaltimoreHashOld = {
464 { { 0x54, 0xD8, 0xCB, 0x49, 0x1F, 0xA1, 0x6D, 0xF8, 0x87, 0xDC, 464 {0x54, 0xD8, 0xCB, 0x49, 0x1F, 0xA1, 0x6D, 0xF8, 0x87, 0xDC, 0x94, 0xA9,
465 0x94, 0xA9, 0x34, 0xCC, 0x83, 0x6B, 0xDA, 0xA8, 0xA3, 0x69 } }; 465 0x34, 0xCC, 0x83, 0x6B, 0xDA, 0xA8, 0xA3, 0x69}};
466 466
467 SHA1HashValue fingerprint = X509Certificate::CalculateFingerprint(cert); 467 SHA1HashValue fingerprint = X509Certificate::CalculateFingerprint(cert);
468 468
469 return fingerprint.Equals(kBadBaltimoreHashNew) || 469 return fingerprint.Equals(kBadBaltimoreHashNew) ||
470 fingerprint.Equals(kBadBaltimoreHashOld); 470 fingerprint.Equals(kBadBaltimoreHashOld);
471 } 471 }
472 472
473 // Attempts to re-verify |cert_array| after adjusting the inputs to work around 473 // Attempts to re-verify |cert_array| after adjusting the inputs to work around
474 // known issues in OS X. To be used if BuildAndEvaluateSecTrustRef fails to 474 // known issues in OS X. To be used if BuildAndEvaluateSecTrustRef fails to
475 // return a positive result for verification. 475 // return a positive result for verification.
(...skipping 21 matching lines...) Expand all
497 slice_point = i; 497 slice_point = i;
498 break; 498 break;
499 } 499 }
500 } 500 }
501 if (slice_point == 0) 501 if (slice_point == 0)
502 return; // Nothing to do. 502 return; // Nothing to do.
503 503
504 ScopedCFTypeRef<CFMutableArrayRef> adjusted_cert_array( 504 ScopedCFTypeRef<CFMutableArrayRef> adjusted_cert_array(
505 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); 505 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
506 // Note: This excludes the certificate at |slice_point|. 506 // Note: This excludes the certificate at |slice_point|.
507 CFArrayAppendArray(adjusted_cert_array, cert_array, 507 CFArrayAppendArray(
508 CFRangeMake(0, slice_point)); 508 adjusted_cert_array, cert_array, CFRangeMake(0, slice_point));
509 509
510 // Ignore the result; failure will preserve the old verification results. 510 // Ignore the result; failure will preserve the old verification results.
511 BuildAndEvaluateSecTrustRef( 511 BuildAndEvaluateSecTrustRef(adjusted_cert_array,
512 adjusted_cert_array, trust_policies, flags, trust_ref, trust_result, 512 trust_policies,
513 verified_chain, chain_info); 513 flags,
514 trust_ref,
515 trust_result,
516 verified_chain,
517 chain_info);
514 } 518 }
515 519
516 } // namespace 520 } // namespace
517 521
518 CertVerifyProcMac::CertVerifyProcMac() {} 522 CertVerifyProcMac::CertVerifyProcMac() {
523 }
519 524
520 CertVerifyProcMac::~CertVerifyProcMac() {} 525 CertVerifyProcMac::~CertVerifyProcMac() {
526 }
521 527
522 bool CertVerifyProcMac::SupportsAdditionalTrustAnchors() const { 528 bool CertVerifyProcMac::SupportsAdditionalTrustAnchors() const {
523 return false; 529 return false;
524 } 530 }
525 531
526 int CertVerifyProcMac::VerifyInternal( 532 int CertVerifyProcMac::VerifyInternal(
527 X509Certificate* cert, 533 X509Certificate* cert,
528 const std::string& hostname, 534 const std::string& hostname,
529 int flags, 535 int flags,
530 CRLSet* crl_set, 536 CRLSet* crl_set,
(...skipping 13 matching lines...) Expand all
544 550
545 // Serialize all calls that may use the Keychain, to work around various 551 // Serialize all calls that may use the Keychain, to work around various
546 // issues in OS X 10.6+ with multi-threaded access to Security.framework. 552 // issues in OS X 10.6+ with multi-threaded access to Security.framework.
547 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); 553 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
548 554
549 ScopedCFTypeRef<SecTrustRef> trust_ref; 555 ScopedCFTypeRef<SecTrustRef> trust_ref;
550 SecTrustResultType trust_result = kSecTrustResultDeny; 556 SecTrustResultType trust_result = kSecTrustResultDeny;
551 ScopedCFTypeRef<CFArrayRef> completed_chain; 557 ScopedCFTypeRef<CFArrayRef> completed_chain;
552 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL; 558 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL;
553 559
554 int rv = BuildAndEvaluateSecTrustRef( 560 int rv = BuildAndEvaluateSecTrustRef(cert_array,
555 cert_array, trust_policies, flags, &trust_ref, &trust_result, 561 trust_policies,
556 &completed_chain, &chain_info); 562 flags,
563 &trust_ref,
564 &trust_result,
565 &completed_chain,
566 &chain_info);
557 if (rv != OK) 567 if (rv != OK)
558 return rv; 568 return rv;
559 if (trust_result != kSecTrustResultUnspecified && 569 if (trust_result != kSecTrustResultUnspecified &&
560 trust_result != kSecTrustResultProceed) { 570 trust_result != kSecTrustResultProceed) {
561 RetrySecTrustEvaluateWithAdjustedChain( 571 RetrySecTrustEvaluateWithAdjustedChain(cert_array,
562 cert_array, trust_policies, flags, &trust_ref, &trust_result, 572 trust_policies,
563 &completed_chain, &chain_info); 573 flags,
574 &trust_ref,
575 &trust_result,
576 &completed_chain,
577 &chain_info);
564 } 578 }
565 579
566 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) 580 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)
567 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 581 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
568 582
569 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set)) 583 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set))
570 verify_result->cert_status |= CERT_STATUS_REVOKED; 584 verify_result->cert_status |= CERT_STATUS_REVOKED;
571 585
572 GetCertChainInfo(completed_chain, chain_info, verify_result); 586 GetCertChainInfo(completed_chain, chain_info, verify_result);
573 587
(...skipping 27 matching lines...) Expand all
601 if (status) 615 if (status)
602 return NetErrorFromOSStatus(status); 616 return NetErrorFromOSStatus(status);
603 if (cssm_result == CSSMERR_TP_VERIFY_ACTION_FAILED) { 617 if (cssm_result == CSSMERR_TP_VERIFY_ACTION_FAILED) {
604 policy_failed = true; 618 policy_failed = true;
605 } else { 619 } else {
606 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); 620 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
607 } 621 }
608 // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO 622 // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO
609 // structure which can catch multiple errors from each certificate. 623 // structure which can catch multiple errors from each certificate.
610 for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain); 624 for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain);
611 index < chain_count; ++index) { 625 index < chain_count;
626 ++index) {
612 if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED || 627 if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED ||
613 chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET) 628 chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET)
614 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 629 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
615 if (!IsCertStatusError(verify_result->cert_status) && 630 if (!IsCertStatusError(verify_result->cert_status) &&
616 chain_info[index].NumStatusCodes == 0) { 631 chain_info[index].NumStatusCodes == 0) {
617 LOG(WARNING) << "chain_info[" << index << "].NumStatusCodes is 0" 632 LOG(WARNING) << "chain_info[" << index << "].NumStatusCodes is 0"
618 ", chain_info[" << index << "].StatusBits is " 633 ", chain_info[" << index
619 << chain_info[index].StatusBits; 634 << "].StatusBits is " << chain_info[index].StatusBits;
620 } 635 }
621 for (uint32 status_code_index = 0; 636 for (uint32 status_code_index = 0;
622 status_code_index < chain_info[index].NumStatusCodes; 637 status_code_index < chain_info[index].NumStatusCodes;
623 ++status_code_index) { 638 ++status_code_index) {
624 // As of OS X 10.9, attempting to verify a certificate chain that 639 // As of OS X 10.9, attempting to verify a certificate chain that
625 // contains a weak signature algorithm (MD2, MD5) in an intermediate 640 // contains a weak signature algorithm (MD2, MD5) in an intermediate
626 // or leaf cert will be treated as a (recoverable) policy validation 641 // or leaf cert will be treated as a (recoverable) policy validation
627 // failure, with the status code CSSMERR_TP_INVALID_CERTIFICATE 642 // failure, with the status code CSSMERR_TP_INVALID_CERTIFICATE
628 // added to the Status Codes. Don't treat this code as an invalid 643 // added to the Status Codes. Don't treat this code as an invalid
629 // certificate; instead, map it to a weak key. Any truly invalid 644 // certificate; instead, map it to a weak key. Any truly invalid
630 // certificates will have the major error (cssm_result) set to 645 // certificates will have the major error (cssm_result) set to
631 // CSSMERR_TP_INVALID_CERTIFICATE, rather than 646 // CSSMERR_TP_INVALID_CERTIFICATE, rather than
632 // CSSMERR_TP_VERIFY_ACTION_FAILED. 647 // CSSMERR_TP_VERIFY_ACTION_FAILED.
633 CertStatus mapped_status = 0; 648 CertStatus mapped_status = 0;
634 if (policy_failed && 649 if (policy_failed &&
635 chain_info[index].StatusCodes[status_code_index] == 650 chain_info[index].StatusCodes[status_code_index] ==
636 CSSMERR_TP_INVALID_CERTIFICATE) { 651 CSSMERR_TP_INVALID_CERTIFICATE) {
637 mapped_status = CERT_STATUS_WEAK_SIGNATURE_ALGORITHM; 652 mapped_status = CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
653 weak_key_or_signature_algorithm = true;
654 } else {
655 mapped_status = CertStatusFromOSStatus(
656 chain_info[index].StatusCodes[status_code_index]);
657 if (mapped_status == CERT_STATUS_WEAK_KEY)
638 weak_key_or_signature_algorithm = true; 658 weak_key_or_signature_algorithm = true;
639 } else {
640 mapped_status = CertStatusFromOSStatus(
641 chain_info[index].StatusCodes[status_code_index]);
642 if (mapped_status == CERT_STATUS_WEAK_KEY)
643 weak_key_or_signature_algorithm = true;
644 } 659 }
645 verify_result->cert_status |= mapped_status; 660 verify_result->cert_status |= mapped_status;
646 } 661 }
647 } 662 }
648 if (policy_failed && !weak_key_or_signature_algorithm) { 663 if (policy_failed && !weak_key_or_signature_algorithm) {
649 // If CSSMERR_TP_VERIFY_ACTION_FAILED wasn't returned due to a weak 664 // If CSSMERR_TP_VERIFY_ACTION_FAILED wasn't returned due to a weak
650 // key, map it back to an appropriate error code. 665 // key, map it back to an appropriate error code.
651 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); 666 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
652 } 667 }
653 if (!IsCertStatusError(verify_result->cert_status)) { 668 if (!IsCertStatusError(verify_result->cert_status)) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 705
691 if (flags & CertVerifier::VERIFY_EV_CERT) { 706 if (flags & CertVerifier::VERIFY_EV_CERT) {
692 // Determine the certificate's EV status using SecTrustCopyExtendedResult(), 707 // Determine the certificate's EV status using SecTrustCopyExtendedResult(),
693 // which is an internal/private API function added in OS X 10.5.7. 708 // which is an internal/private API function added in OS X 10.5.7.
694 // Note: "ExtendedResult" means extended validation results. 709 // Note: "ExtendedResult" means extended validation results.
695 CFBundleRef bundle = 710 CFBundleRef bundle =
696 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); 711 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
697 if (bundle) { 712 if (bundle) {
698 SecTrustCopyExtendedResultFuncPtr copy_extended_result = 713 SecTrustCopyExtendedResultFuncPtr copy_extended_result =
699 reinterpret_cast<SecTrustCopyExtendedResultFuncPtr>( 714 reinterpret_cast<SecTrustCopyExtendedResultFuncPtr>(
700 CFBundleGetFunctionPointerForName(bundle, 715 CFBundleGetFunctionPointerForName(
701 CFSTR("SecTrustCopyExtendedResult"))); 716 bundle, CFSTR("SecTrustCopyExtendedResult")));
702 if (copy_extended_result) { 717 if (copy_extended_result) {
703 CFDictionaryRef ev_dict_temp = NULL; 718 CFDictionaryRef ev_dict_temp = NULL;
704 status = copy_extended_result(trust_ref, &ev_dict_temp); 719 status = copy_extended_result(trust_ref, &ev_dict_temp);
705 ScopedCFTypeRef<CFDictionaryRef> ev_dict(ev_dict_temp); 720 ScopedCFTypeRef<CFDictionaryRef> ev_dict(ev_dict_temp);
706 ev_dict_temp = NULL; 721 ev_dict_temp = NULL;
707 if (status == noErr && ev_dict) { 722 if (status == noErr && ev_dict) {
708 // In 10.7.3, SecTrustCopyExtendedResult returns noErr and populates 723 // In 10.7.3, SecTrustCopyExtendedResult returns noErr and populates
709 // ev_dict even for non-EV certificates, but only EV certificates 724 // ev_dict even for non-EV certificates, but only EV certificates
710 // will cause ev_dict to contain kSecEVOrganizationName. In previous 725 // will cause ev_dict to contain kSecEVOrganizationName. In previous
711 // releases, SecTrustCopyExtendedResult would only return noErr and 726 // releases, SecTrustCopyExtendedResult would only return noErr and
712 // populate ev_dict for EV certificates, but would always include 727 // populate ev_dict for EV certificates, but would always include
713 // kSecEVOrganizationName in that case, so checking for this key is 728 // kSecEVOrganizationName in that case, so checking for this key is
714 // appropriate for all known versions of SecTrustCopyExtendedResult. 729 // appropriate for all known versions of SecTrustCopyExtendedResult.
715 // The actual organization name is unneeded here and can be accessed 730 // The actual organization name is unneeded here and can be accessed
716 // through other means. All that matters here is the OS' conception 731 // through other means. All that matters here is the OS' conception
717 // of whether or not the certificate is EV. 732 // of whether or not the certificate is EV.
718 if (CFDictionaryContainsKey(ev_dict, 733 if (CFDictionaryContainsKey(ev_dict, kSecEVOrganizationName)) {
719 kSecEVOrganizationName)) {
720 verify_result->cert_status |= CERT_STATUS_IS_EV; 734 verify_result->cert_status |= CERT_STATUS_IS_EV;
721 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) 735 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY)
722 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 736 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
723 } 737 }
724 } 738 }
725 } 739 }
726 } 740 }
727 } 741 }
728 742
729 return OK; 743 return OK;
730 } 744 }
731 745
732 } // namespace net 746 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698