Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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_ios.h" | 5 #include "net/cert/cert_verify_proc_ios.h" |
| 6 | 6 |
| 7 #include <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/scoped_cftyperef.h" | 10 #include "base/mac/scoped_cftyperef.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 SecCertificateRef chain_cert = SecTrustGetCertificateAtIndex(tmp_trust, i); | 94 SecCertificateRef chain_cert = SecTrustGetCertificateAtIndex(tmp_trust, i); |
| 95 CFArrayAppendValue(tmp_verified_chain, chain_cert); | 95 CFArrayAppendValue(tmp_verified_chain, chain_cert); |
| 96 } | 96 } |
| 97 | 97 |
| 98 trust_ref->swap(scoped_tmp_trust); | 98 trust_ref->swap(scoped_tmp_trust); |
| 99 *trust_result = tmp_trust_result; | 99 *trust_result = tmp_trust_result; |
| 100 verified_chain->reset(tmp_verified_chain.release()); | 100 verified_chain->reset(tmp_verified_chain.release()); |
| 101 return OK; | 101 return OK; |
| 102 } | 102 } |
| 103 | 103 |
| 104 void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) { | 104 bool GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) { |
| 105 DCHECK_LT(0, CFArrayGetCount(cert_chain)); | 105 DCHECK_LT(0, CFArrayGetCount(cert_chain)); |
| 106 | 106 |
| 107 SecCertificateRef verified_cert = nullptr; | 107 SecCertificateRef verified_cert = nullptr; |
| 108 std::vector<SecCertificateRef> verified_chain; | 108 std::vector<SecCertificateRef> verified_chain; |
| 109 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { | 109 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { |
| 110 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( | 110 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( |
| 111 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); | 111 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); |
| 112 if (i == 0) { | 112 if (i == 0) { |
| 113 verified_cert = chain_cert; | 113 verified_cert = chain_cert; |
| 114 } else { | 114 } else { |
| 115 verified_chain.push_back(chain_cert); | 115 verified_chain.push_back(chain_cert); |
| 116 } | 116 } |
| 117 | 117 |
| 118 std::string der_bytes; | 118 std::string der_bytes; |
| 119 if (!X509Certificate::GetDEREncoded(chain_cert, &der_bytes)) | 119 if (!X509Certificate::GetDEREncoded(chain_cert, &der_bytes)) |
| 120 return; | 120 return false; |
| 121 | 121 |
| 122 base::StringPiece spki_bytes; | 122 base::StringPiece spki_bytes; |
| 123 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) | 123 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes)) |
| 124 continue; | 124 continue; |
|
eroman
2017/03/22 22:17:52
What makes this a non-fatal failure, whereas GetDE
mattm
2017/03/23 22:59:02
Good point, seems this should be fatal as well.
| |
| 125 | 125 |
| 126 HashValue sha1(HASH_VALUE_SHA1); | 126 HashValue sha1(HASH_VALUE_SHA1); |
| 127 CC_SHA1(spki_bytes.data(), spki_bytes.size(), sha1.data()); | 127 CC_SHA1(spki_bytes.data(), spki_bytes.size(), sha1.data()); |
| 128 verify_result->public_key_hashes.push_back(sha1); | 128 verify_result->public_key_hashes.push_back(sha1); |
| 129 | 129 |
| 130 HashValue sha256(HASH_VALUE_SHA256); | 130 HashValue sha256(HASH_VALUE_SHA256); |
| 131 CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data()); | 131 CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data()); |
| 132 verify_result->public_key_hashes.push_back(sha256); | 132 verify_result->public_key_hashes.push_back(sha256); |
| 133 | 133 |
| 134 // Ignore the signature algorithm for the trust anchor. | 134 // Ignore the signature algorithm for the trust anchor. |
| 135 if ((verify_result->cert_status & CERT_STATUS_AUTHORITY_INVALID) == 0 && | 135 if ((verify_result->cert_status & CERT_STATUS_AUTHORITY_INVALID) == 0 && |
| 136 i == count - 1) { | 136 i == count - 1) { |
| 137 continue; | 137 continue; |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 if (!verified_cert) { | 140 if (!verified_cert) { |
| 141 NOTREACHED(); | 141 NOTREACHED(); |
| 142 return; | 142 return false; |
| 143 } | 143 } |
| 144 | 144 |
| 145 verify_result->verified_cert = | 145 verify_result->verified_cert = |
| 146 X509Certificate::CreateFromHandle(verified_cert, verified_chain); | 146 X509Certificate::CreateFromHandle(verified_cert, verified_chain); |
| 147 return !!verify_result->verified_cert; | |
| 147 } | 148 } |
| 148 | 149 |
| 149 } // namespace | 150 } // namespace |
| 150 | 151 |
| 151 CertVerifyProcIOS::CertVerifyProcIOS() {} | 152 CertVerifyProcIOS::CertVerifyProcIOS() {} |
| 152 | 153 |
| 153 // The iOS APIs don't expose an API-stable set of reasons for certificate | 154 // The iOS APIs don't expose an API-stable set of reasons for certificate |
| 154 // validation failures. However, internally, the reason is tracked, and it's | 155 // validation failures. However, internally, the reason is tracked, and it's |
| 155 // converted to user-facing localized strings. | 156 // converted to user-facing localized strings. |
| 156 // | 157 // |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 case kSecTrustResultUnspecified: | 258 case kSecTrustResultUnspecified: |
| 258 case kSecTrustResultProceed: | 259 case kSecTrustResultProceed: |
| 259 break; | 260 break; |
| 260 case kSecTrustResultDeny: | 261 case kSecTrustResultDeny: |
| 261 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; | 262 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; |
| 262 break; | 263 break; |
| 263 default: | 264 default: |
| 264 verify_result->cert_status |= GetCertFailureStatusFromTrust(trust_ref); | 265 verify_result->cert_status |= GetCertFailureStatusFromTrust(trust_ref); |
| 265 } | 266 } |
| 266 | 267 |
| 267 GetCertChainInfo(final_chain, verify_result); | 268 if (!GetCertChainInfo(final_chain, verify_result)) |
| 269 return ERR_CERT_INVALID; | |
|
eroman
2017/03/22 22:17:52
Is it necessary to set cert_status too?
mattm
2017/03/23 22:59:02
Hm, I guess setting cert_status and letting that p
| |
| 268 | 270 |
| 269 // iOS lacks the ability to distinguish built-in versus non-built-in roots, | 271 // iOS lacks the ability to distinguish built-in versus non-built-in roots, |
| 270 // so opt to 'fail open' of any restrictive policies that apply to built-in | 272 // so opt to 'fail open' of any restrictive policies that apply to built-in |
| 271 // roots. | 273 // roots. |
| 272 verify_result->is_issued_by_known_root = false; | 274 verify_result->is_issued_by_known_root = false; |
| 273 | 275 |
| 274 if (IsCertStatusError(verify_result->cert_status)) | 276 if (IsCertStatusError(verify_result->cert_status)) |
| 275 return MapCertStatusToNetError(verify_result->cert_status); | 277 return MapCertStatusToNetError(verify_result->cert_status); |
| 276 | 278 |
| 277 return OK; | 279 return OK; |
| 278 } | 280 } |
| 279 | 281 |
| 280 } // namespace net | 282 } // namespace net |
| OLD | NEW |