| 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..9637ac766afa4f750419c0e551ef4435f0357b80 100644
|
| --- a/net/ssl/client_cert_store_mac.cc
|
| +++ b/net/ssl/client_cert_store_mac.cc
|
| @@ -21,6 +21,7 @@
|
| #include "base/synchronization/lock.h"
|
| #include "crypto/mac_security_services_lock.h"
|
| #include "net/base/host_port_pair.h"
|
| +#include "net/cert/test_keychain_search_list_mac.h"
|
| #include "net/cert/x509_util.h"
|
| #include "net/cert/x509_util_mac.h"
|
|
|
| @@ -66,6 +67,22 @@ OSStatus CopyCertChain(SecCertificateRef cert_handle,
|
| return result;
|
| ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
|
|
|
| + ScopedCFTypeRef<CFArrayRef> scoped_alternate_keychain_search_list;
|
| + // XXX use TestKeychainSearchList
|
| + if (TestKeychainSearchList::HasInstance()) {
|
| + OSStatus status = TestKeychainSearchList::GetInstance()->CopySearchList(
|
| + &scoped_alternate_keychain_search_list);
|
| + if (status)
|
| + return status;
|
| +
|
| + {
|
| + base::AutoLock lock(crypto::GetMacSecurityServicesLock());
|
| + status = SecTrustSetKeychains(trust, scoped_alternate_keychain_search_list.get());
|
| + }
|
| + if (status)
|
| + return status;
|
| + }
|
| +
|
| // Evaluate trust, which creates the cert chain.
|
| SecTrustResultType status;
|
| CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
|
| @@ -73,12 +90,19 @@ OSStatus CopyCertChain(SecCertificateRef cert_handle,
|
| base::AutoLock lock(crypto::GetMacSecurityServicesLock());
|
| result = SecTrustEvaluate(trust, &status);
|
| }
|
| - if (result)
|
| + if (result) {
|
| + OSSTATUS_LOG(ERROR, result) << "SecTrustEvaluate error";
|
| return result;
|
| + }
|
| +LOG(WARNING) << "SecTrustEvaluate status=" << status;
|
| {
|
| base::AutoLock lock(crypto::GetMacSecurityServicesLock());
|
| result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
|
| }
|
| + if (result) {
|
| + OSSTATUS_LOG(ERROR, result) << "SecTrustGetResult error";
|
| + }
|
| +LOG(WARNING) << "SecTrustGetResult status=" << status;
|
| return result;
|
| }
|
|
|
| @@ -91,6 +115,7 @@ bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
|
| DCHECK(cert);
|
| DCHECK(cert->get());
|
|
|
| +LOG(WARNING) << "IsIssuedByInKeychain " << (*cert)->subject().GetDisplayName();
|
| X509Certificate::OSCertHandle cert_handle = (*cert)->os_cert_handle();
|
| CFArrayRef cert_chain = NULL;
|
| OSStatus result = CopyCertChain(cert_handle, &cert_chain);
|
| @@ -101,6 +126,8 @@ bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
|
|
|
| if (!cert_chain)
|
| return false;
|
| +
|
| + LOG(WARNING) << "chain size: " << CFArrayGetCount(cert_chain);
|
|
|
| X509Certificate::OSCertHandles intermediates;
|
| for (CFIndex i = 1, chain_count = CFArrayGetCount(cert_chain);
|
| @@ -114,9 +141,12 @@ bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
|
| cert_handle, intermediates));
|
| CFRelease(cert_chain); // Also frees |intermediates|.
|
|
|
| - if (!new_cert->IsIssuedByEncoded(valid_issuers))
|
| + if (!new_cert->IsIssuedByEncoded(valid_issuers)) {
|
| +LOG(WARNING) << "no.";
|
| return false;
|
| + }
|
|
|
| +LOG(WARNING) << "yes.";
|
| cert->swap(new_cert);
|
| return true;
|
| }
|
| @@ -208,11 +238,72 @@ void ClientCertStoreMac::GetClientCerts(const SSLCertRequestInfo& request,
|
| scoped_refptr<X509Certificate> preferred_cert = NULL;
|
| CertificateList regular_certs;
|
|
|
| + ScopedCFTypeRef<CFMutableDictionaryRef> query(
|
| + CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
|
| + &kCFTypeDictionaryValueCallBacks));
|
| +
|
| + CFDictionarySetValue(query, kSecClass, kSecClassIdentity);
|
| + CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
|
| + CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
|
| +
|
| + ScopedCFTypeRef<CFArrayRef> scoped_alternate_keychain_search_list;
|
| + if (TestKeychainSearchList::HasInstance()) {
|
| + OSStatus status = TestKeychainSearchList::GetInstance()->CopySearchList(
|
| + &scoped_alternate_keychain_search_list);
|
| + if (status) {
|
| + OSSTATUS_LOG(ERROR, status) << "TestKeychainSearchList::CopySearchList error";
|
| + selected_certs->clear();
|
| + callback.Run();
|
| + return;
|
| + }
|
| + CFDictionarySetValue(query, kSecMatchSearchList, scoped_alternate_keychain_search_list.get());
|
| + }
|
| +
|
| + CFArrayRef matching_items;
|
| + OSStatus err;
|
| + {
|
| + base::AutoLock lock(crypto::GetMacSecurityServicesLock());
|
| + err = SecItemCopyMatching(query, (CFTypeRef*)&matching_items);
|
| + }
|
| + if (err) {
|
| + OSSTATUS_LOG(ERROR, err) << "SecItemCopyMatching error";
|
| + selected_certs->clear();
|
| + callback.Run();
|
| + return;
|
| + }
|
| + ScopedCFTypeRef<CFArrayRef> scoped_matching_items(matching_items);
|
| +
|
| + for (CFIndex i = 0, item_count = CFArrayGetCount(matching_items);
|
| + i < item_count; ++i) {
|
| + SecIdentityRef identity = reinterpret_cast<SecIdentityRef>(
|
| + const_cast<void*>(CFArrayGetValueAtIndex(matching_items, i)));
|
| + SecCertificateRef cert_handle;
|
| + err = SecIdentityCopyCertificate(identity, &cert_handle);
|
| + if (err != noErr)
|
| + continue;
|
| + ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle);
|
| +
|
| + scoped_refptr<X509Certificate> cert(
|
| + X509Certificate::CreateFromHandle(cert_handle,
|
| + X509Certificate::OSCertHandles()));
|
| +
|
| + 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);
|
| + }
|
| + }
|
| +LOG(WARNING) << "have preferred=" << !!preferred_cert << " regular_certs.size=" << regular_certs.size();
|
| +
|
| +#if 0
|
| SecIdentitySearchRef search = NULL;
|
| OSStatus err;
|
| {
|
| base::AutoLock lock(crypto::GetMacSecurityServicesLock());
|
| - err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search);
|
| + err = SecIdentitySearchCreate(scoped_alternate_keychain_search_list,
|
| + CSSM_KEYUSE_SIGN, &search);
|
| }
|
| if (err) {
|
| selected_certs->clear();
|
| @@ -255,6 +346,7 @@ void ClientCertStoreMac::GetClientCerts(const SSLCertRequestInfo& request,
|
| callback.Run();
|
| return;
|
| }
|
| +#endif
|
|
|
| GetClientCertsImpl(preferred_cert, regular_certs, request, true,
|
| selected_certs);
|
|
|