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

Unified Diff: net/ssl/client_cert_store_mac.cc

Issue 2910893002: Improved support for loading client certificates on smart cards on macOS
Patch Set: Created 3 years, 7 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
« net/ssl/client_cert_store_mac.h ('K') | « net/ssl/client_cert_store_mac.h ('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 7fadb337f1e7735ae8ffd340c81c93c95588d7c4..d69ebbc0f1573001e6c79edf3a24e6199dbe1182 100644
--- a/net/ssl/client_cert_store_mac.cc
+++ b/net/ssl/client_cert_store_mac.cc
@@ -284,29 +284,7 @@ void ClientCertStoreMac::GetClientCerts(
if (err)
break;
ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity);
-
- SecCertificateRef cert_handle;
- err = SecIdentityCopyCertificate(identity, &cert_handle);
- if (err != noErr)
- continue;
- ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle);
-
- if (!SupportsSSLClientAuth(cert_handle))
- continue;
-
- scoped_refptr<X509Certificate> cert(
- x509_util::CreateX509CertificateFromSecCertificate(
- cert_handle, std::vector<SecCertificateRef>()));
- if (!cert)
- continue;
-
- if (preferred_identity && CFEqual(preferred_identity, identity)) {
- // Only one certificate should match.
- DCHECK(!preferred_cert.get());
- preferred_cert = cert;
- } else {
- regular_certs.push_back(cert);
- }
+ AddIdentity(regular_certs, preferred_cert, preferred_identity.get(), identity);
}
if (err != errSecItemNotFound) {
@@ -315,12 +293,74 @@ void ClientCertStoreMac::GetClientCerts(
return;
}
+ // For reasons I don't understand, macOS has two different ways of querying
+ // for client certificate identities. The way we just tried will miss some
+ // smart card based certificates, and this way misses some soft certificates.
Ryan Sleevi 2017/05/30 18:00:01 We try to avoid pronouns in comments (I/we) and tr
agaynor 2017/05/31 02:37:33 Done.
+ const void *keys[] = {
Ryan Sleevi 2017/05/30 18:00:01 You can use "git cl format" to ensure this is prop
Ryan Sleevi 2017/05/30 18:00:01 So, I _believe_ for correctness, that kSecAttrCanS
agaynor 2017/05/31 02:37:33 Done.
agaynor 2017/05/31 02:37:33 It's a boring old RSA key. I've added |kSecAttrCan
mattm 2017/06/05 23:34:27 Looking at that code a bit, it seems that SecItemC
+ kSecClass,
+ kSecMatchLimit,
+ kSecReturnRef,
+ };
+ const void *values[] = {
+ kSecClassIdentity,
+ kSecMatchLimitAll,
+ kCFBooleanTrue,
+ };
+ CFDictionaryRef query = CFDictionaryCreate(
Ryan Sleevi 2017/05/30 18:00:01 You can see we used the ScopedCFTypeRef C++ helper
agaynor 2017/05/31 02:37:33 Done.
+ kCFAllocatorDefault,
+ keys,
+ values,
+ sizeof(values) / sizeof(values[0]),
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks
+ );
+ CFArrayRef result = NULL;
+ err = SecItemCopyMatching(query, (CFTypeRef *)&result);
Ryan Sleevi 2017/05/30 18:00:00 Note: Chromium explicitly uses C++ casts rather th
agaynor 2017/05/31 02:37:33 Done.
+ if (!err) {
Ryan Sleevi 2017/05/30 18:00:01 In general, we try to handle the error case first,
+ for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
+ CFTypeRef item = CFArrayGetValueAtIndex(result, i);
+ AddIdentity(regular_certs, preferred_cert, preferred_identity, (SecIdentityRef)item);
+ }
+ }
+ CFRelease(query);
+ CFRelease(result);
+
CertificateList selected_certs;
GetClientCertsImpl(preferred_cert, regular_certs, request, true,
&selected_certs);
callback.Run(std::move(selected_certs));
}
+void ClientCertStoreMac::AddIdentity(
+ CertificateList& regular_certs,
+ scoped_refptr<X509Certificate>& preferred_cert,
+ SecIdentityRef preferred_identity,
+ SecIdentityRef identity) {
+ OSStatus err;
+ SecCertificateRef cert_handle;
Ryan Sleevi 2017/05/30 18:00:01 .InitializeInto :)
agaynor 2017/05/31 02:37:33 Done.
+ err = SecIdentityCopyCertificate(identity, &cert_handle);
+ if (err != noErr)
+ return;
+ ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle);
+
+ if (!SupportsSSLClientAuth(cert_handle))
+ return;
+
+ scoped_refptr<X509Certificate> cert(
+ x509_util::CreateX509CertificateFromSecCertificate(
+ cert_handle, std::vector<SecCertificateRef>()));
+ if (!cert)
+ return;
+
+ if (preferred_identity && CFEqual(preferred_identity, identity)) {
+ // Only one certificate should match.
+ DCHECK(!preferred_cert.get());
+ preferred_cert = cert;
+ } else {
+ regular_certs.push_back(cert);
+ }
+}
+
bool ClientCertStoreMac::SelectClientCertsForTesting(
const CertificateList& input_certs,
const SSLCertRequestInfo& request,
« net/ssl/client_cert_store_mac.h ('K') | « net/ssl/client_cert_store_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698