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

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

Issue 2627523002: Refactor the assignment of CertVerifyResult::has_md2, etc. (Closed)
Patch Set: fix PrintTo() Created 3 years, 11 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
« no previous file with comments | « net/cert/cert_verify_proc_ios.cc ('k') | net/cert/cert_verify_proc_nss.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 // revocation preference. 170 // revocation preference.
171 status = x509_util::CreateRevocationPolicies( 171 status = x509_util::CreateRevocationPolicies(
172 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), local_policies); 172 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), local_policies);
173 if (status) 173 if (status)
174 return status; 174 return status;
175 175
176 policies->reset(local_policies.release()); 176 policies->reset(local_policies.release());
177 return noErr; 177 return noErr;
178 } 178 }
179 179
180 // Stores the constructed certificate chain |cert_chain| and information about 180 // Stores the constructed certificate chain |cert_chain| into
181 // the signature algorithms used into |*verify_result|. If the leaf cert in 181 // |*verify_result|. |cert_chain| must not be empty.
182 // |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that 182 void CopyCertChainToVerifyResult(CFArrayRef cert_chain,
183 // in |*leaf_is_weak|. |cert_chain| must not be empty. 183 CertVerifyResult* verify_result) {
184 void GetCertChainInfo(CFArrayRef cert_chain,
185 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info,
186 CertVerifyResult* verify_result,
187 bool* leaf_is_weak) {
188 DCHECK_LT(0, CFArrayGetCount(cert_chain)); 184 DCHECK_LT(0, CFArrayGetCount(cert_chain));
189 185
190 *leaf_is_weak = false;
191 verify_result->has_md2 = false;
192 verify_result->has_md4 = false;
193 verify_result->has_md5 = false;
194 verify_result->has_sha1 = false;
195 verify_result->has_sha1_leaf = false;
196
197 SecCertificateRef verified_cert = NULL; 186 SecCertificateRef verified_cert = NULL;
198 std::vector<SecCertificateRef> verified_chain; 187 std::vector<SecCertificateRef> verified_chain;
199 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { 188 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
200 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( 189 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
201 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); 190 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
202 if (i == 0) { 191 if (i == 0) {
203 verified_cert = chain_cert; 192 verified_cert = chain_cert;
204 } else { 193 } else {
205 verified_chain.push_back(chain_cert); 194 verified_chain.push_back(chain_cert);
206 } 195 }
196 }
197 if (!verified_cert) {
198 NOTREACHED();
199 return;
200 }
201
202 verify_result->verified_cert =
203 X509Certificate::CreateFromHandle(verified_cert, verified_chain);
204 }
205
206 // Returns true if the intermediates (excluding trusted certificates) use a
207 // weak hashing algorithm, but the target does not use a weak hash.
208 bool IsWeakChainBasedOnHashingAlgorithms(
209 CFArrayRef cert_chain,
210 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info) {
211 DCHECK_LT(0, CFArrayGetCount(cert_chain));
212
213 bool intermediates_contain_weak_hash = false;
214 bool leaf_uses_weak_hash = false;
215
216 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
217 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
218 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
207 219
208 if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) || 220 if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) ||
209 (chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) { 221 (chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) {
210 // The current certificate is either in the user's trusted store or is 222 // The current certificate is either in the user's trusted store or is
211 // a root (self-signed) certificate. Ignore the signature algorithm for 223 // a root (self-signed) certificate. Ignore the signature algorithm for
212 // these certificates, as it is meaningless for security. We allow 224 // these certificates, as it is meaningless for security. We allow
213 // self-signed certificates (i == 0 & IS_ROOT), since we accept that 225 // self-signed certificates (i == 0 & IS_ROOT), since we accept that
214 // any security assertions by such a cert are inherently meaningless. 226 // any security assertions by such a cert are inherently meaningless.
215 continue; 227 continue;
216 } 228 }
217 229
218 bool is_leaf = i == 0;
219 X509Certificate::SignatureHashAlgorithm hash_algorithm = 230 X509Certificate::SignatureHashAlgorithm hash_algorithm =
220 FillCertVerifyResultWeakSignature(chain_cert, is_leaf, verify_result); 231 X509Certificate::GetSignatureHashAlgorithm(chain_cert);
221 if (is_leaf) { 232
222 switch (hash_algorithm) { 233 switch (hash_algorithm) {
223 case X509Certificate::kSignatureHashAlgorithmMd2: 234 case X509Certificate::kSignatureHashAlgorithmMd2:
224 case X509Certificate::kSignatureHashAlgorithmMd4: 235 case X509Certificate::kSignatureHashAlgorithmMd4:
225 case X509Certificate::kSignatureHashAlgorithmMd5: 236 case X509Certificate::kSignatureHashAlgorithmMd5:
226 case X509Certificate::kSignatureHashAlgorithmSha1: 237 case X509Certificate::kSignatureHashAlgorithmSha1:
227 *leaf_is_weak = true; 238 if (i == 0) {
228 break; 239 leaf_uses_weak_hash = true;
229 case X509Certificate::kSignatureHashAlgorithmOther: 240 } else {
230 break; 241 intermediates_contain_weak_hash = true;
231 } 242 }
243 break;
244 case X509Certificate::kSignatureHashAlgorithmOther:
245 break;
232 } 246 }
233 } 247 }
234 if (!verified_cert) {
235 NOTREACHED();
236 return;
237 }
238 248
239 verify_result->verified_cert = 249 return !leaf_uses_weak_hash && intermediates_contain_weak_hash;
240 X509Certificate::CreateFromHandle(verified_cert, verified_chain);
241 } 250 }
242 251
243 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; 252 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>;
244 253
245 // Helper that looks up an extension by OID given a map of extensions. 254 // Helper that looks up an extension by OID given a map of extensions.
246 bool GetExtensionValue(const ExtensionsMap& extensions, 255 bool GetExtensionValue(const ExtensionsMap& extensions,
247 const net::der::Input& oid, 256 const net::der::Input& oid,
248 net::der::Input* value) { 257 net::der::Input* value) {
249 auto it = extensions.find(oid); 258 auto it = extensions.find(oid);
250 if (it == extensions.end()) 259 if (it == extensions.end())
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified && 816 bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
808 temp_trust_result != kSecTrustResultProceed) || 817 temp_trust_result != kSecTrustResultProceed) ||
809 crl_result == kCRLSetRevoked; 818 crl_result == kCRLSetRevoked;
810 bool weak_chain = false; 819 bool weak_chain = false;
811 if (CFArrayGetCount(temp_chain) == 0) { 820 if (CFArrayGetCount(temp_chain) == 0) {
812 // If the chain is empty, it cannot be trusted or have recoverable 821 // If the chain is empty, it cannot be trusted or have recoverable
813 // errors. 822 // errors.
814 DCHECK(untrusted); 823 DCHECK(untrusted);
815 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result); 824 DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
816 } else { 825 } else {
817 CertVerifyResult temp_verify_result;
818 bool leaf_is_weak = false;
819 GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
820 &leaf_is_weak);
821 weak_chain = 826 weak_chain =
822 !leaf_is_weak && 827 IsWeakChainBasedOnHashingAlgorithms(temp_chain, temp_chain_info);
823 (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
824 temp_verify_result.has_md5 || temp_verify_result.has_sha1);
825 } 828 }
826 // Set the result to the current chain if: 829 // Set the result to the current chain if:
827 // - This is the first verification attempt. This ensures that if 830 // - This is the first verification attempt. This ensures that if
828 // everything is awful (e.g. it may just be an untrusted cert), that 831 // everything is awful (e.g. it may just be an untrusted cert), that
829 // what is reported is exactly what was sent by the server 832 // what is reported is exactly what was sent by the server
830 // - If the current chain is trusted, and the old chain was not trusted, 833 // - If the current chain is trusted, and the old chain was not trusted,
831 // then prefer this chain. This ensures that if there is at least a 834 // then prefer this chain. This ensures that if there is at least a
832 // valid path to a trust anchor, it's preferred over reporting an error. 835 // valid path to a trust anchor, it's preferred over reporting an error.
833 // - If the current chain is trusted, and the old chain is trusted, but 836 // - If the current chain is trusted, and the old chain is trusted, but
834 // the old chain contained weak algorithms while the current chain only 837 // the old chain contained weak algorithms while the current chain only
(...skipping 24 matching lines...) Expand all
859 break; 862 break;
860 } 863 }
861 864
862 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) 865 if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)
863 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 866 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
864 867
865 if (*completed_chain_crl_result == kCRLSetRevoked) 868 if (*completed_chain_crl_result == kCRLSetRevoked)
866 verify_result->cert_status |= CERT_STATUS_REVOKED; 869 verify_result->cert_status |= CERT_STATUS_REVOKED;
867 870
868 if (CFArrayGetCount(completed_chain) > 0) { 871 if (CFArrayGetCount(completed_chain) > 0) {
869 bool leaf_is_weak_unused = false; 872 CopyCertChainToVerifyResult(completed_chain, verify_result);
870 GetCertChainInfo(completed_chain, chain_info, verify_result,
871 &leaf_is_weak_unused);
872 } 873 }
873 874
874 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits 875 // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
875 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds 876 // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
876 // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping 877 // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping
877 // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only 878 // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only
878 // error was due to an unsupported key size. 879 // error was due to an unsupported key size.
879 bool policy_failed = false; 880 bool policy_failed = false;
880 bool policy_fail_already_mapped = false; 881 bool policy_fail_already_mapped = false;
881 bool weak_key_or_signature_algorithm = false; 882 bool weak_key_or_signature_algorithm = false;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 // EV cert and it was covered by CRLSets or revocation checking passed. 1075 // EV cert and it was covered by CRLSets or revocation checking passed.
1075 verify_result->cert_status |= CERT_STATUS_IS_EV; 1076 verify_result->cert_status |= CERT_STATUS_IS_EV;
1076 } 1077 }
1077 1078
1078 return OK; 1079 return OK;
1079 } 1080 }
1080 1081
1081 } // namespace net 1082 } // namespace net
1082 1083
1083 #pragma clang diagnostic pop // "-Wdeprecated-declarations" 1084 #pragma clang diagnostic pop // "-Wdeprecated-declarations"
OLDNEW
« no previous file with comments | « net/cert/cert_verify_proc_ios.cc ('k') | net/cert/cert_verify_proc_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698