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

Unified Diff: net/cert/cert_verify_proc_ios.cc

Issue 1871043003: Fixing BoringSSL on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix TARGET_IPHONE_SIMULATOR case. Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/BUILD.gn ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/cert_verify_proc_ios.cc
diff --git a/net/cert/cert_verify_proc_ios.cc b/net/cert/cert_verify_proc_ios.cc
index 5f2884f8a8411a15cba982047888ed378026bf3b..f7f72fc1ebda5a3abb6a59b5c86953c934dfb9a5 100644
--- a/net/cert/cert_verify_proc_ios.cc
+++ b/net/cert/cert_verify_proc_ios.cc
@@ -140,6 +140,12 @@ void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data());
verify_result->public_key_hashes.push_back(sha256);
+ // Ignore the signature algorithm for the trust anchor.
+ if ((verify_result->cert_status & CERT_STATUS_AUTHORITY_INVALID) == 0 &&
+ i == count - 1) {
+ continue;
+ }
+
int sig_alg = OBJ_obj2nid(x509_cert->sig_alg->algorithm);
if (sig_alg == NID_md2WithRSAEncryption) {
verify_result->has_md2 = true;
@@ -166,6 +172,62 @@ void GetCertChainInfo(CFArrayRef cert_chain, CertVerifyResult* verify_result) {
X509Certificate::CreateFromHandle(verified_cert, verified_chain);
}
+// The iOS APIs don't expose an API-stable set of reasons for certificate
+// validation failures. However, internally, the reason is tracked, and it's
+// converted to user-facing localized strings.
+//
+// In the absence of a consistent API, convert the English strings to their
+// localized counterpart, and then compare that with the error properties. If
Nico 2016/04/12 19:58:02 Hahahahaha :-(
+// they're equal, it's a strong sign that this was the cause for the error.
+// While this will break if/when iOS changes the contents of these strings,
+// it's sufficient enough for now.
+//
+// TODO(rsleevi): https://crbug.com/601915 - Use a less brittle solution when
+// possible.
+CertStatus GetFailureFromTrustProperties(CFArrayRef properties) {
+ CertStatus reason = 0;
+
+ if (!properties)
+ return CERT_STATUS_INVALID;
+
+ const CFIndex properties_length = CFArrayGetCount(properties);
+ if (properties_length == 0)
+ return CERT_STATUS_INVALID;
+
+ CFBundleRef bundle =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Security"));
+ CFStringRef date_string =
+ CFSTR("One or more certificates have expired or are not valid yet.");
+ CFStringRef date_error = CFBundleCopyLocalizedString(
Eugene But (OOO till 7-30) 2016/04/14 17:49:12 This is a memory leak (and everything else returne
+ bundle, date_string, date_string, CFSTR("SecCertificate"));
+ CFStringRef trust_string = CFSTR("Root certificate is not trusted.");
+ CFStringRef trust_error = CFBundleCopyLocalizedString(
+ bundle, trust_string, trust_string, CFSTR("SecCertificate"));
+ CFStringRef weak_string =
+ CFSTR("One or more certificates is using a weak key size.");
+ CFStringRef weak_error = CFBundleCopyLocalizedString(
+ bundle, weak_string, weak_string, CFSTR("SecCertificate"));
+
+ for (CFIndex i = 0; i < properties_length; ++i) {
+ CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(properties, i)));
+ CFStringRef error = reinterpret_cast<CFStringRef>(
+ const_cast<void*>(CFDictionaryGetValue(dict, CFSTR("value"))));
+
+ if (CFEqual(error, date_error)) {
+ reason |= CERT_STATUS_DATE_INVALID;
+ } else if (CFEqual(error, trust_error)) {
+ reason |= CERT_STATUS_AUTHORITY_INVALID;
+ } else if (CFEqual(error, weak_error)) {
+ reason |= CERT_STATUS_WEAK_KEY;
+ } else {
+ reason |= CERT_STATUS_INVALID;
+ }
+ }
+
+ return reason;
+}
+
} // namespace
CertVerifyProcIOS::CertVerifyProcIOS() {}
@@ -207,21 +269,21 @@ int CertVerifyProcIOS::VerifyInternal(
if (CFArrayGetCount(final_chain) == 0)
return ERR_FAILED;
- GetCertChainInfo(final_chain, verify_result);
-
// TODO(sleevi): Support CRLSet revocation.
- // TODO(svaldez): Add specific error codes for trust errors resulting from
- // expired/not-yet-valid certs.
switch (trust_result) {
case kSecTrustResultUnspecified:
case kSecTrustResultProceed:
break;
case kSecTrustResultDeny:
verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
+ break;
default:
- verify_result->cert_status |= CERT_STATUS_INVALID;
+ CFArrayRef properties = SecTrustCopyProperties(trust_ref);
+ verify_result->cert_status |= GetFailureFromTrustProperties(properties);
}
+ GetCertChainInfo(final_chain, verify_result);
+
// Perform hostname verification independent of SecTrustEvaluate.
if (!verify_result->verified_cert->VerifyNameMatch(
hostname, &verify_result->common_name_fallback_used)) {
« no previous file with comments | « net/BUILD.gn ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698