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

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

Issue 2101303005: 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: review changes and url_request_unittest fixes Created 4 years, 5 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
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"
31 #include "net/cert/test_root_certs.h" 32 #include "net/cert/test_root_certs.h"
32 #include "net/cert/x509_certificate.h" 33 #include "net/cert/x509_certificate.h"
33 #include "net/cert/x509_util_mac.h" 34 #include "net/cert/x509_util_mac.h"
34 35
35 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. 36 // CSSM functions are deprecated as of OSX 10.7, but have no replacement.
36 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 37 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
37 #pragma clang diagnostic push 38 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 39 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
39 40
40 // From 10.7.2 libsecurity_keychain-55035/lib/SecTrustPriv.h, for use with 41 // 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
141 // specific status for (such as basic constraints violation, or 142 // specific status for (such as basic constraints violation, or
142 // unknown critical extension) 143 // unknown critical extension)
143 OSSTATUS_LOG(WARNING, status) 144 OSSTATUS_LOG(WARNING, status)
144 << "Unknown error mapped to CERT_STATUS_INVALID"; 145 << "Unknown error mapped to CERT_STATUS_INVALID";
145 return CERT_STATUS_INVALID; 146 return CERT_STATUS_INVALID;
146 } 147 }
147 } 148 }
148 } 149 }
149 150
150 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to 151 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to
151 // validate a certificate for an SSL server. |hostname| contains the name of 152 // validate a certificate for an SSL server. |flags| is a bitwise-OR of
152 // the SSL server that the certificate should be verified against. |flags| is 153 // VerifyFlags that can further alter how trust is validated, such as how
153 // a bitwise-OR of VerifyFlags that can further alter how trust is validated, 154 // revocation is checked. If successful, returns noErr, and stores the
154 // such as how revocation is checked. If successful, returns noErr, and 155 // resultant array of SecPolicyRefs in |policies|.
155 // stores the resultant array of SecPolicyRefs in |policies|. 156 OSStatus CreateTrustPolicies(int flags, ScopedCFTypeRef<CFArrayRef>* policies) {
156 OSStatus CreateTrustPolicies(const std::string& hostname,
157 int flags,
158 ScopedCFTypeRef<CFArrayRef>* policies) {
159 ScopedCFTypeRef<CFMutableArrayRef> local_policies( 157 ScopedCFTypeRef<CFMutableArrayRef> local_policies(
160 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); 158 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
161 if (!local_policies) 159 if (!local_policies)
162 return memFullErr; 160 return memFullErr;
163 161
164 SecPolicyRef ssl_policy; 162 SecPolicyRef ssl_policy;
165 OSStatus status = x509_util::CreateSSLServerPolicy(hostname, &ssl_policy); 163 OSStatus status =
164 x509_util::CreateSSLServerPolicy(std::string(), &ssl_policy);
166 if (status) 165 if (status)
167 return status; 166 return status;
168 CFArrayAppendValue(local_policies, ssl_policy); 167 CFArrayAppendValue(local_policies, ssl_policy);
169 CFRelease(ssl_policy); 168 CFRelease(ssl_policy);
170 169
171 // Explicitly add revocation policies, in order to override system 170 // Explicitly add revocation policies, in order to override system
172 // revocation checking policies and instead respect the application-level 171 // revocation checking policies and instead respect the application-level
173 // revocation preference. 172 // revocation preference.
174 status = x509_util::CreateRevocationPolicies( 173 status = x509_util::CreateRevocationPolicies(
175 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), 174 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED),
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // failure, no output parameters are modified. 369 // failure, no output parameters are modified.
371 // 370 //
372 // Note: An OK return does not mean that |cert_array| is trusted, merely that 371 // Note: An OK return does not mean that |cert_array| is trusted, merely that
373 // verification was performed successfully. 372 // verification was performed successfully.
374 // 373 //
375 // This function should only be called while the Mac Security Services lock is 374 // This function should only be called while the Mac Security Services lock is
376 // held. 375 // held.
377 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, 376 int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
378 CFArrayRef trust_policies, 377 CFArrayRef trust_policies,
379 int flags, 378 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
397 CSSM_APPLE_TP_ACTION_DATA tp_action_data; 403 CSSM_APPLE_TP_ACTION_DATA tp_action_data;
398 memset(&tp_action_data, 0, sizeof(tp_action_data)); 404 memset(&tp_action_data, 0, sizeof(tp_action_data));
399 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION; 405 tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
400 // Allow CSSM to download any missing intermediate certificates if an 406 // Allow CSSM to download any missing intermediate certificates if an
401 // authorityInfoAccess extension or issuerAltName extension is present. 407 // authorityInfoAccess extension or issuerAltName extension is present.
402 tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET | 408 tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET |
403 CSSM_TP_ACTION_TRUST_SETTINGS; 409 CSSM_TP_ACTION_TRUST_SETTINGS;
404 410
405 // Note: For EV certificates, the Apple TP will handle setting these flags 411 // Note: For EV certificates, the Apple TP will handle setting these flags
406 // as part of EV evaluation. 412 // as part of EV evaluation.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 539
534 int CertVerifyProcMac::VerifyInternal( 540 int CertVerifyProcMac::VerifyInternal(
535 X509Certificate* cert, 541 X509Certificate* cert,
536 const std::string& hostname, 542 const std::string& hostname,
537 const std::string& ocsp_response, 543 const std::string& ocsp_response,
538 int flags, 544 int flags,
539 CRLSet* crl_set, 545 CRLSet* crl_set,
540 const CertificateList& additional_trust_anchors, 546 const CertificateList& additional_trust_anchors,
541 CertVerifyResult* verify_result) { 547 CertVerifyResult* verify_result) {
542 ScopedCFTypeRef<CFArrayRef> trust_policies; 548 ScopedCFTypeRef<CFArrayRef> trust_policies;
543 OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies); 549 OSStatus status = CreateTrustPolicies(flags, &trust_policies);
544 if (status) 550 if (status)
545 return NetErrorFromOSStatus(status); 551 return NetErrorFromOSStatus(status);
546 552
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
555 // Serialize all calls that may use the Keychain, to work around various 553 // Serialize all calls that may use the Keychain, to work around various
556 // issues in OS X 10.6+ with multi-threaded access to Security.framework. 554 // issues in OS X 10.6+ with multi-threaded access to Security.framework.
557 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); 555 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
558 556
559 ScopedCFTypeRef<SecTrustRef> trust_ref; 557 ScopedCFTypeRef<SecTrustRef> trust_ref;
560 SecTrustResultType trust_result = kSecTrustResultDeny; 558 SecTrustResultType trust_result = kSecTrustResultDeny;
561 ScopedCFTypeRef<CFArrayRef> completed_chain; 559 ScopedCFTypeRef<CFArrayRef> completed_chain;
562 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL; 560 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL;
563 bool candidate_untrusted = true; 561 bool candidate_untrusted = true;
564 bool candidate_weak = false; 562 bool candidate_weak = false;
563 bool completed_chain_revoked = false;
565 564
566 // OS X lacks proper path discovery; it will take the input certs and never 565 // OS X lacks proper path discovery; it will take the input certs and never
567 // backtrack the graph attempting to discover valid paths. 566 // backtrack the graph attempting to discover valid paths.
568 // This can create issues in some situations: 567 // This can create issues in some situations:
569 // - When OS X changes the trust store, there may be a chain 568 // - When OS X changes the trust store, there may be a chain
570 // A -> B -> C -> D 569 // A -> B -> C -> D
571 // where OS X trusts D (on some versions) and trusts C (on some versions). 570 // where OS X trusts D (on some versions) and trusts C (on some versions).
572 // If a server supplies a chain A, B, C (cross-signed by D), then this chain 571 // If a server supplies a chain A, B, C (cross-signed by D), then this chain
573 // will successfully validate on systems that trust D, but fail for systems 572 // will successfully validate on systems that trust D, but fail for systems
574 // that trust C. If the server supplies a chain of A -> B, then it forces 573 // that trust C. If the server supplies a chain of A -> B, then it forces
(...skipping 15 matching lines...) Expand all
590 // version of C signed by D is signed using a weak algorithm (e.g. SHA-1), 589 // version of C signed by D is signed using a weak algorithm (e.g. SHA-1),
591 // while the version of C in the trust store's signature doesn't matter. 590 // while the version of C in the trust store's signature doesn't matter.
592 // Since a 'strong' chain exists, it would be desirable to prefer this 591 // Since a 'strong' chain exists, it would be desirable to prefer this
593 // chain. 592 // chain.
594 // 593 //
595 // - A variant of the above example, it may be that the version of B sent by 594 // - A variant of the above example, it may be that the version of B sent by
596 // the server is signed using a weak algorithm, but the version of B 595 // the server is signed using a weak algorithm, but the version of B
597 // present in the AIA of A is signed using a strong algorithm. Since a 596 // present in the AIA of A is signed using a strong algorithm. Since a
598 // 'strong' chain exists, it would be desirable to prefer this chain. 597 // 'strong' chain exists, it would be desirable to prefer this chain.
599 // 598 //
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 //
600 // Because of this, the code below first attempts to validate the peer's 603 // Because of this, the code below first attempts to validate the peer's
601 // identity using the supplied chain. If it is not trusted (e.g. the OS only 604 // identity using the supplied chain. If it is not trusted (e.g. the OS only
602 // trusts C, but the version of C signed by D was sent, and D is not trusted), 605 // trusts C, but the version of C signed by D was sent, and D is not trusted),
603 // or if it contains a weak chain, it will begin lopping off certificates 606 // or if it contains a weak chain, it will begin lopping off certificates
604 // from the end of the chain and attempting to verify. If a stronger, trusted 607 // from the end of the chain and attempting to verify. If a stronger, trusted
605 // chain is found, it is used, otherwise, the algorithm continues until only 608 // chain is found, it is used, otherwise, the algorithm continues until only
606 // the peer's certificate remains. 609 // the peer's certificate remains.
607 // 610 //
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 //
608 // This does cause a performance hit for these users, but only in cases where 615 // This does cause a performance hit for these users, but only in cases where
609 // OS X is building weaker chains than desired, or when it would otherwise 616 // OS X is building weaker chains than desired, or when it would otherwise
610 // fail the connection. 617 // fail the connection.
611 while (CFArrayGetCount(cert_array) > 0) { 618 for (bool try_reordered_keychain : {false, true}) {
Ryan Sleevi 2016/08/12 19:50:17 NICE! :)
612 ScopedCFTypeRef<SecTrustRef> temp_ref; 619 ScopedCFTypeRef<CFArrayRef> scoped_alternate_keychain_search_list;
613 SecTrustResultType temp_trust_result = kSecTrustResultDeny; 620 if (TestKeychainSearchList::HasInstance()) {
614 ScopedCFTypeRef<CFArrayRef> temp_chain; 621 CFArrayRef keychain_search_list;
615 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; 622 status = TestKeychainSearchList::GetInstance()->CopySearchList(
623 &keychain_search_list);
624 if (status)
625 return NetErrorFromOSStatus(status);
626 scoped_alternate_keychain_search_list.reset(keychain_search_list);
627 }
Ryan Sleevi 2016/08/12 19:50:17 Could you add some additional documentation here e
mattm 2016/08/16 01:41:34 Done.
628 if (try_reordered_keychain) {
629 if (!scoped_alternate_keychain_search_list) {
630 CFArrayRef keychain_search_list;
631 status = SecKeychainCopySearchList(&keychain_search_list);
632 if (status)
633 return NetErrorFromOSStatus(status);
634 scoped_alternate_keychain_search_list.reset(keychain_search_list);
635 }
636 CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy(
637 kCFAllocatorDefault,
638 CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1,
639 scoped_alternate_keychain_search_list.get());
640 if (!mutable_keychain_search_list)
641 return ERR_OUT_OF_MEMORY;
642 scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list);
616 643
617 int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags, 644 SecKeychainRef keychain;
618 &temp_ref, &temp_trust_result, 645 // Get a reference to the System Roots keychain. This is a gross hack,
619 &temp_chain, &temp_chain_info); 646 // but the path is known to be valid on OS X 10.9-10.11.
620 if (rv != OK) 647 status = SecKeychainOpen(
621 return rv; 648 "/System/Library/Keychains/SystemRootCertificates.keychain",
649 &keychain);
Ryan Sleevi 2016/08/12 19:50:17 DESIGN: Is it worth adding a unit test for this ca
mattm 2016/08/16 01:41:34 Done.
650 if (status)
651 return NetErrorFromOSStatus(status);
652 ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
622 653
623 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified && 654 CFArrayInsertValueAtIndex(mutable_keychain_search_list, 0, keychain);
624 temp_trust_result != kSecTrustResultProceed);
625 bool weak_chain = false;
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);
639 } 655 }
640 // Set the result to the current chain if:
641 // - This is the first verification attempt. This ensures that if
642 // everything is awful (e.g. it may just be an untrusted cert), that
643 // what is reported is exactly what was sent by the server
644 // - If the current chain is trusted, and the old chain was not trusted,
645 // then prefer this chain. This ensures that if there is at least a
646 // valid path to a trust anchor, it's preferred over reporting an error.
647 // - If the current chain is trusted, and the old chain is trusted, but
648 // the old chain contained weak algorithms while the current chain only
649 // contains strong algorithms, then prefer the current chain over the
650 // old chain.
651 //
652 // Note: If the leaf certificate itself is weak, then the only
653 // consideration is whether or not there is a trusted chain. That's
654 // because no amount of path discovery will fix a weak leaf.
655 if (!trust_ref || (!untrusted && (candidate_untrusted ||
656 (candidate_weak && !weak_chain)))) {
657 trust_ref = temp_ref;
658 trust_result = temp_trust_result;
659 completed_chain = temp_chain;
660 chain_info = temp_chain_info;
661 656
662 candidate_untrusted = untrusted; 657 ScopedCFTypeRef<CFMutableArrayRef> cert_array(
663 candidate_weak = weak_chain; 658 cert->CreateOSCertChainForCert());
659
660 while (CFArrayGetCount(cert_array) > 0) {
Ryan Sleevi 2016/08/12 19:50:17 I'm a little nervous that this is moved far away f
mattm 2016/08/16 01:41:34 Done.
661 ScopedCFTypeRef<SecTrustRef> temp_ref;
662 SecTrustResultType temp_trust_result = kSecTrustResultDeny;
663 ScopedCFTypeRef<CFArrayRef> temp_chain;
664 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL;
665
666 int rv = BuildAndEvaluateSecTrustRef(
667 cert_array, trust_policies, flags,
668 scoped_alternate_keychain_search_list.get(), &temp_ref,
669 &temp_trust_result, &temp_chain, &temp_chain_info);
670 if (rv != OK)
671 return rv;
672
673 bool revoked =
674 (crl_set && !CheckRevocationWithCRLSet(temp_chain, crl_set));
Ryan Sleevi 2016/08/12 19:50:17 I suspect we should do with some documentation her
mattm 2016/08/16 01:41:34 That would be great since I'm not sure what the nu
Ryan Sleevi 2016/08/17 02:28:12 // Check to see if the path |temp_chain| has been
mattm 2016/08/17 03:50:57 Ah, that. Done.
675 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
676 temp_trust_result != kSecTrustResultProceed) ||
677 revoked;
678 bool weak_chain = false;
679 if (CFArrayGetCount(temp_chain) == 0) {
680 // If the chain is empty, it cannot be trusted or have recoverable
681 // errors.
682 DCHECK(untrusted);
683 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
684 } else {
685 CertVerifyResult temp_verify_result;
686 bool leaf_is_weak = false;
687 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
688 &leaf_is_weak);
689 weak_chain =
690 !leaf_is_weak &&
691 (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
692 temp_verify_result.has_md5 || temp_verify_result.has_sha1);
693 }
694 // Set the result to the current chain if:
695 // - This is the first verification attempt. This ensures that if
696 // everything is awful (e.g. it may just be an untrusted cert), that
697 // what is reported is exactly what was sent by the server
698 // - If the current chain is trusted, and the old chain was not trusted,
699 // then prefer this chain. This ensures that if there is at least a
700 // valid path to a trust anchor, it's preferred over reporting an error.
701 // - If the current chain is trusted, and the old chain is trusted, but
702 // the old chain contained weak algorithms while the current chain only
703 // contains strong algorithms, then prefer the current chain over the
704 // old chain.
705 //
706 // Note: If the leaf certificate itself is weak, then the only
707 // consideration is whether or not there is a trusted chain. That's
708 // because no amount of path discovery will fix a weak leaf.
709 if (!trust_ref || (!untrusted && (candidate_untrusted ||
710 (candidate_weak && !weak_chain)))) {
711 trust_ref = temp_ref;
712 trust_result = temp_trust_result;
713 completed_chain = temp_chain;
714 completed_chain_revoked = revoked;
715 chain_info = temp_chain_info;
716
717 candidate_untrusted = untrusted;
718 candidate_weak = weak_chain;
719 }
720 // Short-circuit when a current, trusted chain is found.
721 if (!untrusted && !weak_chain)
722 break;
723 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
664 } 724 }
665 // Short-circuit when a current, trusted chain is found. 725 // Short-circuit when a current, trusted chain is found.
666 if (!untrusted && !weak_chain) 726 if (!candidate_untrusted && !candidate_weak)
667 break; 727 break;
668 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
669 } 728 }
670 729
671 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) 730 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)
672 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 731 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
673 732
674 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set)) 733 if (completed_chain_revoked)
675 verify_result->cert_status |= CERT_STATUS_REVOKED; 734 verify_result->cert_status |= CERT_STATUS_REVOKED;
676 735
677 if (CFArrayGetCount(completed_chain) > 0) { 736 if (CFArrayGetCount(completed_chain) > 0) {
678 bool leaf_is_weak_unused = false; 737 bool leaf_is_weak_unused = false;
679 GetCertChainInfo(completed_chain, chain_info, verify_result, 738 GetCertChainInfo(completed_chain, chain_info, verify_result,
680 &leaf_is_weak_unused); 739 &leaf_is_weak_unused);
681 } 740 }
682 741
683 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits 742 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
684 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds 743 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 } 894 }
836 } 895 }
837 } 896 }
838 897
839 return OK; 898 return OK;
840 } 899 }
841 900
842 } // namespace net 901 } // namespace net
843 902
844 #pragma clang diagnostic pop // "-Wdeprecated-declarations" 903 #pragma clang diagnostic pop // "-Wdeprecated-declarations"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698