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

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

Issue 1094983002: Account for the OS returning an empty certificate chain. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 if (status) 171 if (status)
172 return status; 172 return status;
173 173
174 policies->reset(local_policies.release()); 174 policies->reset(local_policies.release());
175 return noErr; 175 return noErr;
176 } 176 }
177 177
178 // Stores the constructed certificate chain |cert_chain| and information about 178 // Stores the constructed certificate chain |cert_chain| and information about
179 // the signature algorithms used into |*verify_result|. If the leaf cert in 179 // the signature algorithms used into |*verify_result|. If the leaf cert in
180 // |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that 180 // |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that
181 // in |*leaf_is_weak|. 181 // in |*leaf_is_weak|. |cert_chain| must not be empty.
182 void GetCertChainInfo(CFArrayRef cert_chain, 182 void GetCertChainInfo(CFArrayRef cert_chain,
183 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info, 183 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info,
184 CertVerifyResult* verify_result, 184 CertVerifyResult* verify_result,
185 bool* leaf_is_weak) { 185 bool* leaf_is_weak) {
186 DCHECK_LT(0, CFArrayGetCount(cert_chain));
187
186 *leaf_is_weak = false; 188 *leaf_is_weak = false;
187 verify_result->verified_cert = nullptr;
188 verify_result->has_md2 = false; 189 verify_result->has_md2 = false;
189 verify_result->has_md4 = false; 190 verify_result->has_md4 = false;
190 verify_result->has_md5 = false; 191 verify_result->has_md5 = false;
191 verify_result->has_sha1 = false; 192 verify_result->has_sha1 = false;
192 193
193 SecCertificateRef verified_cert = NULL; 194 SecCertificateRef verified_cert = NULL;
194 std::vector<SecCertificateRef> verified_chain; 195 std::vector<SecCertificateRef> verified_chain;
195 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { 196 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
196 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( 197 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
197 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); 198 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) || 247 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
247 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) || 248 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
248 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) || 249 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
249 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) || 250 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
250 CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) { 251 CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) {
251 verify_result->has_sha1 = true; 252 verify_result->has_sha1 = true;
252 if (i == 0) 253 if (i == 0)
253 *leaf_is_weak = true; 254 *leaf_is_weak = true;
254 } 255 }
255 } 256 }
256 if (!verified_cert) 257 if (!verified_cert) {
258 NOTREACHED();
257 return; 259 return;
260 }
258 261
259 verify_result->verified_cert = 262 verify_result->verified_cert =
260 X509Certificate::CreateFromHandle(verified_cert, verified_chain); 263 X509Certificate::CreateFromHandle(verified_cert, verified_chain);
261 } 264 }
262 265
263 void AppendPublicKeyHashes(CFArrayRef chain, 266 void AppendPublicKeyHashes(CFArrayRef chain,
264 HashValueVector* hashes) { 267 HashValueVector* hashes) {
265 const CFIndex n = CFArrayGetCount(chain); 268 const CFIndex n = CFArrayGetCount(chain);
266 for (CFIndex i = 0; i < n; i++) { 269 for (CFIndex i = 0; i < n; i++) {
267 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( 270 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 SecTrustResultType temp_trust_result = kSecTrustResultDeny; 557 SecTrustResultType temp_trust_result = kSecTrustResultDeny;
555 ScopedCFTypeRef<CFArrayRef> temp_chain; 558 ScopedCFTypeRef<CFArrayRef> temp_chain;
556 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; 559 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL;
557 560
558 int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags, 561 int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags,
559 &temp_ref, &temp_trust_result, 562 &temp_ref, &temp_trust_result,
560 &temp_chain, &temp_chain_info); 563 &temp_chain, &temp_chain_info);
561 if (rv != OK) 564 if (rv != OK)
562 return rv; 565 return rv;
563 566
564 CertVerifyResult temp_verify_result;
565 bool leaf_is_weak = false;
566 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
567 &leaf_is_weak);
568
569 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified && 567 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
570 temp_trust_result != kSecTrustResultProceed); 568 temp_trust_result != kSecTrustResultProceed);
571 bool weak_chain = 569 bool weak_chain = false;
572 !leaf_is_weak && 570 if (CFArrayGetCount(temp_chain) > 0) {
573 (temp_verify_result.has_md2 || temp_verify_result.has_md4 || 571 CertVerifyResult temp_verify_result;
574 temp_verify_result.has_md5 || temp_verify_result.has_sha1); 572 bool leaf_is_weak = false;
573 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
574 &leaf_is_weak);
575 weak_chain = !leaf_is_weak &&
576 (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
577 temp_verify_result.has_md5 || temp_verify_result.has_sha1);
578 } else {
579 // If the chain is trusted or has recoverable errors, it cannot be empty.
Ryan Sleevi 2015/04/23 14:05:41 I find this comment actually makes the preceeding
davidben 2015/04/23 18:12:28 Done.
580 DCHECK(untrusted);
581 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
582 }
575 // Set the result to the current chain if: 583 // Set the result to the current chain if:
576 // - This is the first verification attempt. This ensures that if 584 // - This is the first verification attempt. This ensures that if
577 // everything is awful (e.g. it may just be an untrusted cert), that 585 // everything is awful (e.g. it may just be an untrusted cert), that
578 // what is reported is exactly what was sent by the server 586 // what is reported is exactly what was sent by the server
579 // - If the current chain is trusted, and the old chain was not trusted, 587 // - If the current chain is trusted, and the old chain was not trusted,
580 // then prefer this chain. This ensures that if there is at least a 588 // then prefer this chain. This ensures that if there is at least a
581 // valid path to a trust anchor, it's preferred over reporting an error. 589 // valid path to a trust anchor, it's preferred over reporting an error.
582 // - If the current chain is trusted, and the old chain is trusted, but 590 // - If the current chain is trusted, and the old chain is trusted, but
583 // the old chain contained weak algorithms while the current chain only 591 // the old chain contained weak algorithms while the current chain only
584 // contains strong algorithms, then prefer the current chain over the 592 // contains strong algorithms, then prefer the current chain over the
(...skipping 17 matching lines...) Expand all
602 break; 610 break;
603 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1); 611 CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
604 } 612 }
605 613
606 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) 614 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)
607 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 615 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
608 616
609 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set)) 617 if (crl_set && !CheckRevocationWithCRLSet(completed_chain, crl_set))
610 verify_result->cert_status |= CERT_STATUS_REVOKED; 618 verify_result->cert_status |= CERT_STATUS_REVOKED;
611 619
612 bool leaf_is_weak_unused = false; 620 if (CFArrayGetCount(completed_chain) > 0) {
613 GetCertChainInfo(completed_chain, chain_info, verify_result, 621 bool leaf_is_weak_unused = false;
614 &leaf_is_weak_unused); 622 GetCertChainInfo(completed_chain, chain_info, verify_result,
623 &leaf_is_weak_unused);
624 }
615 625
616 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits 626 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
617 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds 627 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
618 // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping 628 // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping
619 // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only 629 // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only
620 // error was due to an unsupported key size. 630 // error was due to an unsupported key size.
621 bool policy_failed = false; 631 bool policy_failed = false;
622 bool weak_key_or_signature_algorithm = false; 632 bool weak_key_or_signature_algorithm = false;
623 633
624 // Evaluate the results 634 // Evaluate the results
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } 775 }
766 } 776 }
767 } 777 }
768 } 778 }
769 } 779 }
770 780
771 return OK; 781 return OK;
772 } 782 }
773 783
774 } // namespace net 784 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698