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

Unified Diff: net/ssl/client_cert_store_mac.cc

Issue 2753143002: move X509Certificate::SupportsSSLClientAuth to client_cert_store_mac.cc (Closed)
Patch Set: . Created 3 years, 9 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/cert/x509_certificate_mac.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/ssl/client_cert_store_mac.cc
diff --git a/net/ssl/client_cert_store_mac.cc b/net/ssl/client_cert_store_mac.cc
index 4b44ab37d1219ba18c5caed09d084797940e06ed..93debe9621e5a61e1764dba626341d0f95f88539 100644
--- a/net/ssl/client_cert_store_mac.cc
+++ b/net/ssl/client_cert_store_mac.cc
@@ -121,6 +121,57 @@ bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
return true;
}
+// Returns true if |purpose| is listed as allowed in |usage|. This
+// function also considers the "Any" purpose. If the attribute is
+// present and empty, we return false.
+bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage,
+ const CSSM_OID* purpose) {
+ for (unsigned p = 0; p < usage->numPurposes; ++p) {
+ if (CSSMOIDEqual(&usage->purposes[p], purpose))
+ return true;
+ if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny))
+ return true;
+ }
+ return false;
+}
+
+// Does |cert|'s usage allow SSL client authentication?
+bool SupportsSSLClientAuth(SecCertificateRef cert) {
+ x509_util::CSSMCachedCertificate cached_cert;
+ OSStatus status = cached_cert.Init(cert);
+ if (status)
+ return false;
+
+ // RFC5280 says to take the intersection of the two extensions.
+ //
+ // Our underlying crypto libraries don't expose
+ // ClientCertificateType, so for now we will not support fixed
+ // Diffie-Hellman mechanisms. For rsa_sign, we need the
+ // digitalSignature bit.
+ //
+ // In particular, if a key has the nonRepudiation bit and not the
+ // digitalSignature one, we will not offer it to the user.
+ x509_util::CSSMFieldValue key_usage;
+ status = cached_cert.GetField(&CSSMOID_KeyUsage, &key_usage);
+ if (status == CSSM_OK && key_usage.field()) {
+ const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>();
+ const CE_KeyUsage* key_usage_value =
+ reinterpret_cast<const CE_KeyUsage*>(ext->value.parsedValue);
+ if (!((*key_usage_value) & CE_KU_DigitalSignature))
+ return false;
+ }
+
+ status = cached_cert.GetField(&CSSMOID_ExtendedKeyUsage, &key_usage);
+ if (status == CSSM_OK && key_usage.field()) {
+ const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>();
+ const CE_ExtendedKeyUsage* ext_key_usage =
+ reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue);
+ if (!ExtendedKeyUsageAllows(ext_key_usage, &CSSMOID_ClientAuth))
+ return false;
+ }
+ return true;
+}
+
// Examines the certificates in |preferred_cert| and |regular_certs| to find
// all certificates that match the client certificate request in |request|,
// storing the matching certificates in |selected_certs|.
@@ -142,7 +193,7 @@ void GetClientCertsImpl(const scoped_refptr<X509Certificate>& preferred_cert,
selected_certs->clear();
for (size_t i = 0; i < preliminary_list.size(); ++i) {
scoped_refptr<X509Certificate>& cert = preliminary_list[i];
- if (cert->HasExpired() || !cert->SupportsSSLClientAuth())
+ if (cert->HasExpired() || !SupportsSSLClientAuth(cert->os_cert_handle()))
continue;
// Skip duplicates (a cert may be in multiple keychains).
« no previous file with comments | « net/cert/x509_certificate_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698