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 388d0fc41a93b81ba84d8565bec4996fbe0b31f7..dac6fe40fabd13b1ff31f9213324dd8e2314231e 100644 |
--- a/net/cert/cert_verify_proc_mac.cc |
+++ b/net/cert/cert_verify_proc_mac.cc |
@@ -184,12 +184,18 @@ void GetCertChainInfo(CFArrayRef cert_chain, |
CertVerifyResult* verify_result, |
bool* leaf_is_weak) { |
*leaf_is_weak = false; |
- verify_result->verified_cert = nullptr; |
verify_result->has_md2 = false; |
verify_result->has_md4 = false; |
verify_result->has_md5 = false; |
verify_result->has_sha1 = false; |
+ // If certificate verification fails unrecoverably, OS X will return an |
+ // empty chain. CertVerifyResult is expected to contain the original |
+ // certificate chain in this case, so leave |verify_result->verified_cert| |
+ // unchanged. |
+ if (CFArrayGetCount(cert_chain) == 0) |
+ return; |
+ |
SecCertificateRef verified_cert = NULL; |
std::vector<SecCertificateRef> verified_chain; |
for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) { |
@@ -253,8 +259,10 @@ void GetCertChainInfo(CFArrayRef cert_chain, |
*leaf_is_weak = true; |
} |
} |
- if (!verified_cert) |
+ if (!verified_cert) { |
+ NOTREACHED(); |
return; |
+ } |
verify_result->verified_cert = |
X509Certificate::CreateFromHandle(verified_cert, verified_chain); |
@@ -455,6 +463,17 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, |
if (status) |
return NetErrorFromOSStatus(status); |
+ // SecTrustGetResult may return an empty verified chain on some fatal |
+ // errors. Guard against any library bugs which may return it in cases where |
+ // a chain is expected. |
+ if (CFArrayGetCount(tmp_verified_chain) == 0 || |
+ (temp_trust_result == kSecTrustResultUnspecified || |
+ temp_trust_result == kSecTrustResultProceed || |
+ temp_trust_result == kSecTrustResultRecoverableTrustFailure)) { |
+ NOTREACHED(); |
+ return ERR_FAILED; |
+ } |
davidben
2015/04/18 00:23:40
This isn't necessary, but I was a little worried a
|
+ |
trust_ref->swap(scoped_tmp_trust); |
*trust_result = tmp_trust_result; |
verified_chain->reset(tmp_verified_chain); |