OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |