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..c17d99fe577dfd3c9f1d4215483db72f98ca765f 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 && |
+ (tmp_trust_result == kSecTrustResultUnspecified || |
+ tmp_trust_result == kSecTrustResultProceed || |
+ tmp_trust_result == kSecTrustResultRecoverableTrustFailure)) { |
Ryan Sleevi
2015/04/18 00:54:58
Why only these status codes?
And, from your descr
davidben
2015/04/22 21:57:58
You've got it backwards. These are the status code
|
+ NOTREACHED(); |
+ return ERR_FAILED; |
+ } |
+ |
trust_ref->swap(scoped_tmp_trust); |
*trust_result = tmp_trust_result; |
verified_chain->reset(tmp_verified_chain); |