| Index: net/cert/cert_verify_proc_mac.cc
|
| diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc
|
| index 2290db04b69ecb48c8e983293daba26a76522552..46d1cc864b8c7c7b3e15cf38660202dca53ea019 100644
|
| --- a/net/cert/cert_verify_proc_mac.cc
|
| +++ b/net/cert/cert_verify_proc_mac.cc
|
| @@ -177,23 +177,12 @@ OSStatus CreateTrustPolicies(int flags, ScopedCFTypeRef<CFArrayRef>* policies) {
|
| return noErr;
|
| }
|
|
|
| -// Stores the constructed certificate chain |cert_chain| and information about
|
| -// the signature algorithms used into |*verify_result|. If the leaf cert in
|
| -// |cert_chain| contains a weak (MD2, MD4, MD5, SHA-1) signature, stores that
|
| -// in |*leaf_is_weak|. |cert_chain| must not be empty.
|
| -void GetCertChainInfo(CFArrayRef cert_chain,
|
| - CSSM_TP_APPLE_EVIDENCE_INFO* chain_info,
|
| - CertVerifyResult* verify_result,
|
| - bool* leaf_is_weak) {
|
| +// Stores the constructed certificate chain |cert_chain| into
|
| +// |*verify_result|. |cert_chain| must not be empty.
|
| +void CopyCertChainToVerifyResult(CFArrayRef cert_chain,
|
| + CertVerifyResult* verify_result) {
|
| DCHECK_LT(0, CFArrayGetCount(cert_chain));
|
|
|
| - *leaf_is_weak = false;
|
| - verify_result->has_md2 = false;
|
| - verify_result->has_md4 = false;
|
| - verify_result->has_md5 = false;
|
| - verify_result->has_sha1 = false;
|
| - verify_result->has_sha1_leaf = false;
|
| -
|
| SecCertificateRef verified_cert = NULL;
|
| std::vector<SecCertificateRef> verified_chain;
|
| for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
|
| @@ -204,6 +193,29 @@ void GetCertChainInfo(CFArrayRef cert_chain,
|
| } else {
|
| verified_chain.push_back(chain_cert);
|
| }
|
| + }
|
| + if (!verified_cert) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + verify_result->verified_cert =
|
| + X509Certificate::CreateFromHandle(verified_cert, verified_chain);
|
| +}
|
| +
|
| +// Returns true if the intermediates (excluding trusted certificates) use a
|
| +// weak hashing algorithm, but the target does not use a weak hash.
|
| +bool IsWeakChainBasedOnHashingAlgorithms(
|
| + CFArrayRef cert_chain,
|
| + CSSM_TP_APPLE_EVIDENCE_INFO* chain_info) {
|
| + DCHECK_LT(0, CFArrayGetCount(cert_chain));
|
| +
|
| + bool intermediates_contain_weak_hash = false;
|
| + bool leaf_uses_weak_hash = false;
|
| +
|
| + for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
|
| + SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
|
| + const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
|
|
|
| if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) ||
|
| (chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) {
|
| @@ -215,29 +227,26 @@ void GetCertChainInfo(CFArrayRef cert_chain,
|
| continue;
|
| }
|
|
|
| - bool is_leaf = i == 0;
|
| X509Certificate::SignatureHashAlgorithm hash_algorithm =
|
| - FillCertVerifyResultWeakSignature(chain_cert, is_leaf, verify_result);
|
| - if (is_leaf) {
|
| - switch (hash_algorithm) {
|
| - case X509Certificate::kSignatureHashAlgorithmMd2:
|
| - case X509Certificate::kSignatureHashAlgorithmMd4:
|
| - case X509Certificate::kSignatureHashAlgorithmMd5:
|
| - case X509Certificate::kSignatureHashAlgorithmSha1:
|
| - *leaf_is_weak = true;
|
| - break;
|
| - case X509Certificate::kSignatureHashAlgorithmOther:
|
| - break;
|
| - }
|
| + X509Certificate::GetSignatureHashAlgorithm(chain_cert);
|
| +
|
| + switch (hash_algorithm) {
|
| + case X509Certificate::kSignatureHashAlgorithmMd2:
|
| + case X509Certificate::kSignatureHashAlgorithmMd4:
|
| + case X509Certificate::kSignatureHashAlgorithmMd5:
|
| + case X509Certificate::kSignatureHashAlgorithmSha1:
|
| + if (i == 0) {
|
| + leaf_uses_weak_hash = true;
|
| + } else {
|
| + intermediates_contain_weak_hash = true;
|
| + }
|
| + break;
|
| + case X509Certificate::kSignatureHashAlgorithmOther:
|
| + break;
|
| }
|
| }
|
| - if (!verified_cert) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
|
|
| - verify_result->verified_cert =
|
| - X509Certificate::CreateFromHandle(verified_cert, verified_chain);
|
| + return !leaf_uses_weak_hash && intermediates_contain_weak_hash;
|
| }
|
|
|
| using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>;
|
| @@ -814,14 +823,8 @@ int VerifyWithGivenFlags(X509Certificate* cert,
|
| DCHECK(untrusted);
|
| DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
|
| } else {
|
| - CertVerifyResult temp_verify_result;
|
| - bool leaf_is_weak = false;
|
| - GetCertChainInfo(temp_chain, temp_chain_info, &temp_verify_result,
|
| - &leaf_is_weak);
|
| weak_chain =
|
| - !leaf_is_weak &&
|
| - (temp_verify_result.has_md2 || temp_verify_result.has_md4 ||
|
| - temp_verify_result.has_md5 || temp_verify_result.has_sha1);
|
| + IsWeakChainBasedOnHashingAlgorithms(temp_chain, temp_chain_info);
|
| }
|
| // Set the result to the current chain if:
|
| // - This is the first verification attempt. This ensures that if
|
| @@ -866,9 +869,7 @@ int VerifyWithGivenFlags(X509Certificate* cert,
|
| verify_result->cert_status |= CERT_STATUS_REVOKED;
|
|
|
| if (CFArrayGetCount(completed_chain) > 0) {
|
| - bool leaf_is_weak_unused = false;
|
| - GetCertChainInfo(completed_chain, chain_info, verify_result,
|
| - &leaf_is_weak_unused);
|
| + CopyCertChainToVerifyResult(completed_chain, verify_result);
|
| }
|
|
|
| // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
|
|
|