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

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

Issue 2347893002: Revert of CertVerifyProcMac: Add Keychain re-ordering hack, check CRLsets in path pruning loop. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl patch is broken so try a manual revert instead Created 4 years, 3 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
« no previous file with comments | « net/BUILD.gn ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10 matching lines...) Expand all
21 #include "base/synchronization/lock.h" 21 #include "base/synchronization/lock.h"
22 #include "crypto/mac_security_services_lock.h" 22 #include "crypto/mac_security_services_lock.h"
23 #include "crypto/sha2.h" 23 #include "crypto/sha2.h"
24 #include "net/base/hash_value.h" 24 #include "net/base/hash_value.h"
25 #include "net/base/net_errors.h" 25 #include "net/base/net_errors.h"
26 #include "net/cert/asn1_util.h" 26 #include "net/cert/asn1_util.h"
27 #include "net/cert/cert_status_flags.h" 27 #include "net/cert/cert_status_flags.h"
28 #include "net/cert/cert_verifier.h" 28 #include "net/cert/cert_verifier.h"
29 #include "net/cert/cert_verify_result.h" 29 #include "net/cert/cert_verify_result.h"
30 #include "net/cert/crl_set.h" 30 #include "net/cert/crl_set.h"
31 #include "net/cert/test_keychain_search_list_mac.h"
32 #include "net/cert/test_root_certs.h" 31 #include "net/cert/test_root_certs.h"
33 #include "net/cert/x509_certificate.h" 32 #include "net/cert/x509_certificate.h"
34 #include "net/cert/x509_util_mac.h" 33 #include "net/cert/x509_util_mac.h"
35 34
36 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. 35 // CSSM functions are deprecated as of OSX 10.7, but have no replacement.
37 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 36 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
38 #pragma clang diagnostic push 37 #pragma clang diagnostic push
39 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 38 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
40 39
41 // From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with 40 // From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 // specific status for (such as basic constraints violation, or 141 // specific status for (such as basic constraints violation, or
143 // unknown critical extension) 142 // unknown critical extension)
144 OSSTATUS_LOG(WARNING, status) 143 OSSTATUS_LOG(WARNING, status)
145 << "Unknown error mapped to CERT_STATUS_INVALID"; 144 << "Unknown error mapped to CERT_STATUS_INVALID";
146 return CERT_STATUS_INVALID; 145 return CERT_STATUS_INVALID;
147 } 146 }
148 } 147 }
149 } 148 }
150 149
151 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to 150 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to
152 // validate a certificate for an SSL server. |flags| is a bitwise-OR of 151 // validate a certificate for an SSL server. |hostname| contains the name of
153 // VerifyFlags that can further alter how trust is validated, such as how 152 // the SSL server that the certificate should be verified against. |flags| is
154 // revocation is checked. If successful, returns noErr, and stores the 153 // a bitwise-OR of VerifyFlags that can further alter how trust is validated,
155 // resultant array of SecPolicyRefs in |policies|. 154 // such as how revocation is checked. If successful, returns noErr, and
156 OSStatus CreateTrustPolicies(int flags, ScopedCFTypeRef<CFArrayRef>* policies) { 155 // stores the resultant array of SecPolicyRefs in |policies|.
156 OSStatus CreateTrustPolicies(const std::string& hostname,
157 int flags,
158 ScopedCFTypeRef<CFArrayRef>* policies) {
157 ScopedCFTypeRef<CFMutableArrayRef> local_policies( 159 ScopedCFTypeRef<CFMutableArrayRef> local_policies(
158 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); 160 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
159 if (!local_policies) 161 if (!local_policies)
160 return memFullErr; 162 return memFullErr;
161 163
162 SecPolicyRef ssl_policy; 164 SecPolicyRef ssl_policy;
163 OSStatus status = 165 OSStatus status = x509_util::CreateSSLServerPolicy(hostname, &ssl_policy);
164 x509_util::CreateSSLServerPolicy(std::string(), &ssl_policy);
165 if (status) 166 if (status)
166 return status; 167 return status;
167 CFArrayAppendValue(local_policies, ssl_policy); 168 CFArrayAppendValue(local_policies, ssl_policy);
168 CFRelease(ssl_policy); 169 CFRelease(ssl_policy);
169 170
170 // Explicitly add revocation policies, in order to override system 171 // Explicitly add revocation policies, in order to override system
171 // revocation checking policies and instead respect the application-level 172 // revocation checking policies and instead respect the application-level
172 // revocation preference. 173 // revocation preference.
173 status = x509_util::CreateRevocationPolicies( 174 status = x509_util::CreateRevocationPolicies(
174 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), 175 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED),
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // failure, no output parameters are modified. 370 // failure, no output parameters are modified.
370 // 371 //
371 // Note: An OK return does not mean that |cert_array| is trusted, merely that 372 // Note: An OK return does not mean that |cert_array| is trusted, merely that
372 // verification was performed successfully. 373 // verification was performed successfully.
373 // 374 //
374 // This function should only be called while the Mac Security Services lock is 375 // This function should only be called while the Mac Security Services lock is
375 // held. 376 // held.
376 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, 377 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
377 CFArrayRef trust_policies, 378 CFArrayRef trust_policies,
378 int flags, 379 int flags,
379 CFArrayRef keychain_search_list,
380 ScopedCFTypeRef<SecTrustRef>* trust_ref, 380 ScopedCFTypeRef<SecTrustRef>* trust_ref,
381 SecTrustResultType* trust_result, 381 SecTrustResultType* trust_result,
382 ScopedCFTypeRef<CFArrayRef>* verified_chain, 382 ScopedCFTypeRef<CFArrayRef>* verified_chain,
383 CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) { 383 CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) {
384 SecTrustRef tmp_trust = NULL; 384 SecTrustRef tmp_trust = NULL;
385 OSStatus status = SecTrustCreateWithCertificates(cert_array, trust_policies, 385 OSStatus status = SecTrustCreateWithCertificates(cert_array, trust_policies,
386 &tmp_trust); 386 &tmp_trust);
387 if (status) 387 if (status)
388 return NetErrorFromOSStatus(status); 388 return NetErrorFromOSStatus(status);
389 ScopedCFTypeRef<SecTrustRef> scoped_tmp_trust(tmp_trust); 389 ScopedCFTypeRef<SecTrustRef> scoped_tmp_trust(tmp_trust);
390 390
391 if (TestRootCerts::HasInstance()) { 391 if (TestRootCerts::HasInstance()) {
392 status = TestRootCerts::GetInstance()->FixupSecTrustRef(tmp_trust); 392 status = TestRootCerts::GetInstance()->FixupSecTrustRef(tmp_trust);
393 if (status) 393 if (status)
394 return NetErrorFromOSStatus(status); 394 return NetErrorFromOSStatus(status);
395 } 395 }
396 396
397 if (keychain_search_list) {
398 status = SecTrustSetKeychains(tmp_trust, keychain_search_list);
399 if (status)
400 return NetErrorFromOSStatus(status);
401 }
402
403 CSSM_APPLE_TP_ACTION_DATA tp_action_data; 397 CSSM_APPLE_TP_ACTION_DATA tp_action_data;
404 memset(&tp_action_data, 0, sizeof(tp_action_data)); 398 memset(&tp_action_data, 0, sizeof(tp_action_data));
405 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION; 399 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
406 // Allow CSSM to download any missing intermediate certificates if an 400 // Allow CSSM to download any missing intermediate certificates if an
407 // authorityInfoAccess extension or issuerAltName extension is present. 401 // authorityInfoAccess extension or issuerAltName extension is present.
408 tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET | 402 tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET |
409 CSSM_TP_ACTION_TRUST_SETTINGS; 403 CSSM_TP_ACTION_TRUST_SETTINGS;
410 404
411 // Note: For EV certificates, the Apple TP will handle setting these flags 405 // Note: For EV certificates, the Apple TP will handle setting these flags
412 // as part of EV evaluation. 406 // as part of EV evaluation.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 533
540 int CertVerifyProcMac::VerifyInternal( 534 int CertVerifyProcMac::VerifyInternal(
541 X509Certificate* cert, 535 X509Certificate* cert,
542 const std::string& hostname, 536 const std::string& hostname,
543 const std::string& ocsp_response, 537 const std::string& ocsp_response,
544 int flags, 538 int flags,
545 CRLSet* crl_set, 539 CRLSet* crl_set,
546 const CertificateList& additional_trust_anchors, 540 const CertificateList& additional_trust_anchors,
547 CertVerifyResult* verify_result) { 541 CertVerifyResult* verify_result) {
548 ScopedCFTypeRef<CFArrayRef> trust_policies; 542 ScopedCFTypeRef<CFArrayRef> trust_policies;
549 OSStatus status = CreateTrustPolicies(flags, &trust_policies); 543 OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies);
550 if (status) 544 if (status)
551 return NetErrorFromOSStatus(status); 545 return NetErrorFromOSStatus(status);
552 546
547 // Create and configure a SecTrustRef, which takes our certificate(s)
548 // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an
549 // array of certificates, the first of which is the certificate we're
550 // verifying, and the subsequent (optional) certificates are used for
551 // chain building.
552 ScopedCFTypeRef<CFMutableArrayRef> cert_array(
553 cert->CreateOSCertChainForCert());
554
553 // Serialize all calls that may use the Keychain, to work around various 555 // Serialize all calls that may use the Keychain, to work around various
554 // issues in OS X 10.6+ with multi-threaded access to Security.framework. 556 // issues in OS X 10.6+ with multi-threaded access to Security.framework.
555 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); 557 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
556 558
557 ScopedCFTypeRef<SecTrustRef> trust_ref; 559 ScopedCFTypeRef<SecTrustRef> trust_ref;
558 SecTrustResultType trust_result = kSecTrustResultDeny; 560 SecTrustResultType trust_result = kSecTrustResultDeny;
559 ScopedCFTypeRef<CFArrayRef> completed_chain; 561 ScopedCFTypeRef<CFArrayRef> completed_chain;
560 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL; 562 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL;
561 bool candidate_untrusted = true; 563 bool candidate_untrusted = true;
562 bool candidate_weak = false; 564 bool candidate_weak = false;
563 bool completed_chain_revoked = false;
564 565
565 // OS X lacks proper path discovery; it will take the input certs and never 566 // OS X lacks proper path discovery; it will take the input certs and never
566 // backtrack the graph attempting to discover valid paths. 567 // backtrack the graph attempting to discover valid paths.
567 // This can create issues in some situations: 568 // This can create issues in some situations:
568 // - When OS X changes the trust store, there may be a chain 569 // - When OS X changes the trust store, there may be a chain
569 // A -> B -> C -> D 570 // A -> B -> C -> D
570 // where OS X trusts D (on some versions) and trusts C (on some versions). 571 // where OS X trusts D (on some versions) and trusts C (on some versions).
571 // If a server supplies a chain A, B, C (cross-signed by D), then this chain 572 // If a server supplies a chain A, B, C (cross-signed by D), then this chain
572 // will successfully validate on systems that trust D, but fail for systems 573 // will successfully validate on systems that trust D, but fail for systems
573 // that trust C. If the server supplies a chain of A -> B, then it forces 574 // that trust C. If the server supplies a chain of A -> B, then it forces
(...skipping 15 matching lines...) Expand all
589 // version of C signed by D is signed using a weak algorithm (e.g. SHA-1), 590 // version of C signed by D is signed using a weak algorithm (e.g. SHA-1),
590 // while the version of C in the trust store's signature doesn't matter. 591 // while the version of C in the trust store's signature doesn't matter.
591 // Since a 'strong' chain exists, it would be desirable to prefer this 592 // Since a 'strong' chain exists, it would be desirable to prefer this
592 // chain. 593 // chain.
593 // 594 //
594 // - A variant of the above example, it may be that the version of B sent by 595 // - A variant of the above example, it may be that the version of B sent by
595 // the server is signed using a weak algorithm, but the version of B 596 // the server is signed using a weak algorithm, but the version of B
596 // present in the AIA of A is signed using a strong algorithm. Since a 597 // present in the AIA of A is signed using a strong algorithm. Since a
597 // 'strong' chain exists, it would be desirable to prefer this chain. 598 // 'strong' chain exists, it would be desirable to prefer this chain.
598 // 599 //
599 // - A user keychain may contain a less desirable intermediate or root.
600 // OS X gives the user keychains higher priority than the system keychain,
601 // so it may build a weak chain.
602 //
603 // Because of this, the code below first attempts to validate the peer's 600 // Because of this, the code below first attempts to validate the peer's
604 // identity using the supplied chain. If it is not trusted (e.g. the OS only 601 // identity using the supplied chain. If it is not trusted (e.g. the OS only
605 // trusts C, but the version of C signed by D was sent, and D is not trusted), 602 // trusts C, but the version of C signed by D was sent, and D is not trusted),
606 // or if it contains a weak chain, it will begin lopping off certificates 603 // or if it contains a weak chain, it will begin lopping off certificates
607 // from the end of the chain and attempting to verify. If a stronger, trusted 604 // from the end of the chain and attempting to verify. If a stronger, trusted
608 // chain is found, it is used, otherwise, the algorithm continues until only 605 // chain is found, it is used, otherwise, the algorithm continues until only
609 // the peer's certificate remains. 606 // the peer's certificate remains.
610 // 607 //
611 // If the loop does not find a trusted chain, the loop will be repeated with
612 // the keychain search order altered to give priority to the System Roots
613 // keychain.
614 //
615 // This does cause a performance hit for these users, but only in cases where 608 // This does cause a performance hit for these users, but only in cases where
616 // OS X is building weaker chains than desired, or when it would otherwise 609 // OS X is building weaker chains than desired, or when it would otherwise
617 // fail the connection. 610 // fail the connection.
618 for (bool try_reordered_keychain : {false, true}) { 611 while (CFArrayGetCount(cert_array) > 0) {
619 ScopedCFTypeRef<CFArrayRef> scoped_alternate_keychain_search_list; 612 ScopedCFTypeRef<SecTrustRef> temp_ref;
620 if (TestKeychainSearchList::HasInstance()) { 613 SecTrustResultType temp_trust_result = kSecTrustResultDeny;
621 // Unit tests need to be able to hermetically simulate situations where a 614 ScopedCFTypeRef<CFArrayRef> temp_chain;
622 // user has an undesirable certificate in a per-user keychain. 615 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL;
623 // Adding/Removing a Keychain using SecKeychainCreate/SecKeychainDelete 616
624 // has global side effects, which would break other tests and processes 617 int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags,
625 // running on the same machine, so instead tests may load pre-created 618 &temp_ref, &temp_trust_result,
626 // keychains using SecKeychainOpen and then inject them through 619 &temp_chain, &temp_chain_info);
627 // TestKeychainSearchList. 620 if (rv != OK)
628 CFArrayRef keychain_search_list; 621 return rv;
629 status = TestKeychainSearchList::GetInstance()->CopySearchList( 622
630 &keychain_search_list); 623 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
631 if (status) 624 temp_trust_result != kSecTrustResultProceed);
632 return NetErrorFromOSStatus(status); 625 bool weak_chain = false;
633 scoped_alternate_keychain_search_list.reset(keychain_search_list); 626 if (CFArrayGetCount(temp_chain) == 0) {
627 // If the chain is empty, it cannot be trusted or have recoverable
628 // errors.
629 DCHECK(untrusted);
630 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
631 } else {
632 CertVerifyResult temp_verify_result;
633 bool leaf_is_weak = false;
634 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
635 &leaf_is_weak);
636 weak_chain = !leaf_is_weak &&
637 (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
638 temp_verify_result.has_md5 || temp_verify_result.has_sha1);
634 } 639 }
635 if (try_reordered_keychain) { 640 // Set the result to the current chain if:
636 // If a TestKeychainSearchList is present, it will have already set 641 // - This is the first verification attempt. This ensures that if
637 // |scoped_alternate_keychain_search_list|, which will be used as the 642 // everything is awful (e.g. it may just be an untrusted cert), that
638 // basis for reordering the keychain. Otherwise, get the current keychain 643 // what is reported is exactly what was sent by the server
639 // search list and use that. 644 // - If the current chain is trusted, and the old chain was not trusted,
640 if (!scoped_alternate_keychain_search_list) { 645 // then prefer this chain. This ensures that if there is at least a
641 CFArrayRef keychain_search_list; 646 // valid path to a trust anchor, it's preferred over reporting an error.
642 status = SecKeychainCopySearchList(&keychain_search_list); 647 // - If the current chain is trusted, and the old chain is trusted, but
643 if (status) 648 // the old chain contained weak algorithms while the current chain only
644 return NetErrorFromOSStatus(status); 649 // contains strong algorithms, then prefer the current chain over the
645 scoped_alternate_keychain_search_list.reset(keychain_search_list); 650 // old chain.
646 } 651 //
647 CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( 652 // Note: If the leaf certificate itself is weak, then the only
648 kCFAllocatorDefault, 653 // consideration is whether or not there is a trusted chain. That's
649 CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, 654 // because no amount of path discovery will fix a weak leaf.
650 scoped_alternate_keychain_search_list.get()); 655 if (!trust_ref || (!untrusted && (candidate_untrusted ||
651 if (!mutable_keychain_search_list) 656 (candidate_weak && !weak_chain)))) {
652 return ERR_OUT_OF_MEMORY; 657 trust_ref = temp_ref;
653 scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); 658 trust_result = temp_trust_result;
659 completed_chain = temp_chain;
660 chain_info = temp_chain_info;
654 661
655 SecKeychainRef keychain; 662 candidate_untrusted = untrusted;
656 // Get a reference to the System Roots keychain. The System Roots 663 candidate_weak = weak_chain;
657 // keychain is not normally present in the keychain search list, but is
658 // implicitly checked after the keychains in the search list. By
659 // including it directly, force it to be checked first. This is a gross
660 // hack, but the path is known to be valid on OS X 10.9-10.11.
661 status = SecKeychainOpen(
662 "/System/Library/Keychains/SystemRootCertificates.keychain",
663 &keychain);
664 if (status)
665 return NetErrorFromOSStatus(status);
666 ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
667
668 CFArrayInsertValueAtIndex(mutable_keychain_search_list, 0, keychain);
669 }
670
671 ScopedCFTypeRef<CFMutableArrayRef> cert_array(
672 cert->CreateOSCertChainForCert());
673
674 // Beginning with the certificate chain as supplied by the server, attempt
675 // to verify the chain. If a failure is encountered, trim a certificate
676 // from the end (so long as one remains) and retry, in the hope of forcing
677 // OS X to find a better path.
678 while (CFArrayGetCount(cert_array) > 0) {
679 ScopedCFTypeRef<SecTrustRef> temp_ref;
680 SecTrustResultType temp_trust_result = kSecTrustResultDeny;
681 ScopedCFTypeRef<CFArrayRef> temp_chain;
682 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL;
683
684 int rv = BuildAndEvaluateSecTrustRef(
685 cert_array, trust_policies, flags,
686 scoped_alternate_keychain_search_list.get(), &temp_ref,
687 &temp_trust_result, &temp_chain, &temp_chain_info);
688 if (rv != OK)
689 return rv;
690
691 // Check to see if the path |temp_chain| has been revoked. This is less
692 // than ideal to perform after path building, rather than during, because
693 // there may be multiple paths to trust anchors, and only some of them
694 // are revoked. Ideally, CRLSets would be part of path building, which
695 // they are when using NSS (Linux) or CryptoAPI (Windows).
696 //
697 // The CRLSet checking is performed inside the loop in the hope that if a
698 // path is revoked, it's an older path, and the only reason it was built
699 // is because the server forced it (by supplying an older or less
700 // desirable intermediate) or because the user had installed a
701 // certificate in their Keychain forcing this path. However, this means
702 // its still possible for a CRLSet block of an intermediate to prevent
703 // access, even when there is a 'good' chain. To fully remedy this, a
704 // solution might be to have CRLSets contain enough knowledge about what
705 // the 'desired' path might be, but for the time being, the
706 // implementation is kept as 'simple' as it can be.
707 bool revoked =
708 (crl_set && !CheckRevocationWithCRLSet(temp_chain, crl_set));
709 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
710 temp_trust_result != kSecTrustResultProceed) ||
711 revoked;
712 bool weak_chain = false;
713 if (CFArrayGetCount(temp_chain) == 0) {
714 // If the chain is empty, it cannot be trusted or have recoverable
715 // errors.
716 DCHECK(untrusted);
717 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
718 } else {
719 CertVerifyResult temp_verify_result;
720 bool leaf_is_weak = false;
721 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
722 &leaf_is_weak);
723 weak_chain =
724 !leaf_is_weak &&
725 (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
726 temp_verify_result.has_md5 || temp_verify_result.has_sha1);
727 }
728 // Set the result to the current chain if:
729 // - This is the first verification attempt. This ensures that if
730 // everything is awful (e.g. it may just be an untrusted cert), that
731 // what is reported is exactly what was sent by the server
732 // - If the current chain is trusted, and the old chain was not trusted,
733 // then prefer this chain. This ensures that if there is at least a
734 // valid path to a trust anchor, it's preferred over reporting an error.
735 // - If the current chain is trusted, and the old chain is trusted, but
736 // the old chain contained weak algorithms while the current chain only
737 // contains strong algorithms, then prefer the current chain over the
738 // old chain.
739 //
740 // Note: If the leaf certificate itself is weak, then the only
741 // consideration is whether or not there is a trusted chain. That's
742 // because no amount of path discovery will fix a weak leaf.
743 if (!trust_ref || (!untrusted && (candidate_untrusted ||
744 (candidate_weak && !weak_chain)))) {
745 trust_ref = temp_ref;
746 trust_result = temp_trust_result;
747 completed_chain = temp_chain;
748 completed_chain_revoked = revoked;
749 chain_info = temp_chain_info;
750
751 candidate_untrusted = untrusted;
752 candidate_weak = weak_chain;
753 }
754 // Short-circuit when a current, trusted chain is found.
755 if (!untrusted && !weak_chain)
756 break;
757 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
758 } 664 }
759 // Short-circuit when a current, trusted chain is found. 665 // Short-circuit when a current, trusted chain is found.
760 if (!candidate_untrusted && !candidate_weak) 666 if (!untrusted && !weak_chain)
761 break; 667 break;
668 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
762 } 669 }
763 670
764 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) 671 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)
765 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 672 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
766 673
767 if (completed_chain_revoked) 674 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set))
768 verify_result->cert_status |= CERT_STATUS_REVOKED; 675 verify_result->cert_status |= CERT_STATUS_REVOKED;
769 676
770 if (CFArrayGetCount(completed_chain) > 0) { 677 if (CFArrayGetCount(completed_chain) > 0) {
771 bool leaf_is_weak_unused = false; 678 bool leaf_is_weak_unused = false;
772 GetCertChainInfo(completed_chain, chain_info, verify_result, 679 GetCertChainInfo(completed_chain, chain_info, verify_result,
773 &leaf_is_weak_unused); 680 &leaf_is_weak_unused);
774 } 681 }
775 682
776 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits 683 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
777 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds 684 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 } 835 }
929 } 836 }
930 } 837 }
931 838
932 return OK; 839 return OK;
933 } 840 }
934 841
935 } // namespace net 842 } // namespace net
936 843
937 #pragma clang diagnostic pop // "-Wdeprecated-declarations" 844 #pragma clang diagnostic pop // "-Wdeprecated-declarations"
OLDNEW
« no previous file with comments | « net/BUILD.gn ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698