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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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|. |
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 *leaf_is_weak = false; | 186 *leaf_is_weak = false; |
187 verify_result->verified_cert = nullptr; | |
188 verify_result->has_md2 = false; | 187 verify_result->has_md2 = false; |
189 verify_result->has_md4 = false; | 188 verify_result->has_md4 = false; |
190 verify_result->has_md5 = false; | 189 verify_result->has_md5 = false; |
191 verify_result->has_sha1 = false; | 190 verify_result->has_sha1 = false; |
192 | 191 |
192 // If certificate verification fails unrecoverably, OS X will return an | |
193 // empty chain. CertVerifyResult is expected to contain the original | |
194 // certificate chain in this case, so leave |verify_result->verified_cert| | |
195 // unchanged. | |
196 if (CFArrayGetCount(cert_chain) == 0) | |
197 return; | |
198 | |
193 SecCertificateRef verified_cert = NULL; | 199 SecCertificateRef verified_cert = NULL; |
194 std::vector<SecCertificateRef> verified_chain; | 200 std::vector<SecCertificateRef> verified_chain; |
195 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { | 201 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { |
196 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( | 202 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( |
197 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); | 203 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); |
198 if (i == 0) { | 204 if (i == 0) { |
199 verified_cert = chain_cert; | 205 verified_cert = chain_cert; |
200 } else { | 206 } else { |
201 verified_chain.push_back(chain_cert); | 207 verified_chain.push_back(chain_cert); |
202 } | 208 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) || | 252 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) || |
247 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) || | 253 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) || |
248 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) || | 254 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) || |
249 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) || | 255 CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) || |
250 CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) { | 256 CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1)) { |
251 verify_result->has_sha1 = true; | 257 verify_result->has_sha1 = true; |
252 if (i == 0) | 258 if (i == 0) |
253 *leaf_is_weak = true; | 259 *leaf_is_weak = true; |
254 } | 260 } |
255 } | 261 } |
256 if (!verified_cert) | 262 if (!verified_cert) { |
263 NOTREACHED(); | |
257 return; | 264 return; |
265 } | |
258 | 266 |
259 verify_result->verified_cert = | 267 verify_result->verified_cert = |
260 X509Certificate::CreateFromHandle(verified_cert, verified_chain); | 268 X509Certificate::CreateFromHandle(verified_cert, verified_chain); |
261 } | 269 } |
262 | 270 |
263 void AppendPublicKeyHashes(CFArrayRef chain, | 271 void AppendPublicKeyHashes(CFArrayRef chain, |
264 HashValueVector* hashes) { | 272 HashValueVector* hashes) { |
265 const CFIndex n = CFArrayGetCount(chain); | 273 const CFIndex n = CFArrayGetCount(chain); |
266 for (CFIndex i = 0; i < n; i++) { | 274 for (CFIndex i = 0; i < n; i++) { |
267 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( | 275 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 status = SecTrustEvaluate(tmp_trust, &tmp_trust_result); | 456 status = SecTrustEvaluate(tmp_trust, &tmp_trust_result); |
449 if (status) | 457 if (status) |
450 return NetErrorFromOSStatus(status); | 458 return NetErrorFromOSStatus(status); |
451 CFArrayRef tmp_verified_chain = NULL; | 459 CFArrayRef tmp_verified_chain = NULL; |
452 CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info; | 460 CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info; |
453 status = SecTrustGetResult(tmp_trust, &tmp_trust_result, &tmp_verified_chain, | 461 status = SecTrustGetResult(tmp_trust, &tmp_trust_result, &tmp_verified_chain, |
454 &tmp_chain_info); | 462 &tmp_chain_info); |
455 if (status) | 463 if (status) |
456 return NetErrorFromOSStatus(status); | 464 return NetErrorFromOSStatus(status); |
457 | 465 |
466 // SecTrustGetResult may return an empty verified chain on some fatal | |
467 // errors. Guard against any library bugs which may return it in cases where | |
468 // a chain is expected. | |
469 if (CFArrayGetCount(tmp_verified_chain) == 0 || | |
470 (temp_trust_result == kSecTrustResultUnspecified || | |
471 temp_trust_result == kSecTrustResultProceed || | |
472 temp_trust_result == kSecTrustResultRecoverableTrustFailure)) { | |
473 NOTREACHED(); | |
474 return ERR_FAILED; | |
475 } | |
davidben
2015/04/18 00:23:40
This isn't necessary, but I was a little worried a
| |
476 | |
458 trust_ref->swap(scoped_tmp_trust); | 477 trust_ref->swap(scoped_tmp_trust); |
459 *trust_result = tmp_trust_result; | 478 *trust_result = tmp_trust_result; |
460 verified_chain->reset(tmp_verified_chain); | 479 verified_chain->reset(tmp_verified_chain); |
461 *chain_info = tmp_chain_info; | 480 *chain_info = tmp_chain_info; |
462 | 481 |
463 return OK; | 482 return OK; |
464 } | 483 } |
465 | 484 |
466 } // namespace | 485 } // namespace |
467 | 486 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
765 } | 784 } |
766 } | 785 } |
767 } | 786 } |
768 } | 787 } |
769 } | 788 } |
770 | 789 |
771 return OK; | 790 return OK; |
772 } | 791 } |
773 | 792 |
774 } // namespace net | 793 } // namespace net |
OLD | NEW |