Index: net/socket/ssl_client_socket_nss.cc |
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc |
index 4397ad65e82c5371d265e0014ffc89a1510f334d..8b05f1b64f7cdcf7bcf9782d3ff55f0f11f1f1ce 100644 |
--- a/net/socket/ssl_client_socket_nss.cc |
+++ b/net/socket/ssl_client_socket_nss.cc |
@@ -112,7 +112,10 @@ |
#include <Security/SecBase.h> |
#include <Security/SecCertificate.h> |
#include <Security/SecIdentity.h> |
+ |
#include "base/mac/mac_logging.h" |
+#include "base/synchronization/lock.h" |
+#include "crypto/mac_security_services_lock.h" |
#elif defined(USE_NSS) |
#include <dlfcn.h> |
#endif |
@@ -1397,29 +1400,31 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler( |
OSStatus os_error = noErr; |
SecIdentityRef identity = NULL; |
SecKeyRef private_key = NULL; |
- CFArrayRef chain = |
- core->ssl_config_.client_cert->CreateClientCertificateChain(); |
- if (chain) { |
- identity = reinterpret_cast<SecIdentityRef>( |
- const_cast<void*>(CFArrayGetValueAtIndex(chain, 0))); |
+ X509Certificate::OSCertHandles chain; |
+ { |
+ base::AutoLock lock(crypto::GetMacSecurityServicesLock()); |
+ os_error = SecIdentityCreateWithCertificate( |
+ NULL, core->ssl_config_.client_cert->os_cert_handle(), &identity); |
} |
- if (identity) |
+ if (os_error == noErr) { |
os_error = SecIdentityCopyPrivateKey(identity, &private_key); |
wtc
2013/04/16 18:50:32
Just wanted to make sure that we don't need to get
Ryan Sleevi
2013/04/16 19:00:26
Right. Neither of these call into the CSSM/CDSA bi
|
+ CFRelease(identity); |
+ } |
- if (chain && identity && os_error == noErr) { |
+ if (os_error == noErr) { |
// TODO(rsleevi): Error checking for NSS allocation errors. |
*result_certs = CERT_NewCertList(); |
*result_private_key = private_key; |
- for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) { |
+ chain.push_back(core->ssl_config_.client_cert->os_cert_handle()); |
+ const X509Certificate::OSCertHandles& intermediates = |
+ core->ssl_config_.client_cert->GetIntermediateCertificates(); |
+ if (!intermediates.empty()) |
+ chain.insert(chain.end(), intermediates.begin(), intermediates.end()); |
+ |
+ for (size_t i = 0, chain_count = chain.size(); i < chain_count; ++i) { |
CSSM_DATA cert_data; |
- SecCertificateRef cert_ref; |
- if (i == 0) { |
- cert_ref = core->ssl_config_.client_cert->os_cert_handle(); |
- } else { |
- cert_ref = reinterpret_cast<SecCertificateRef>( |
- const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); |
- } |
+ SecCertificateRef cert_ref = chain[i]; |
os_error = SecCertificateGetData(cert_ref, &cert_data); |
if (os_error != noErr) |
break; |
@@ -1431,23 +1436,20 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler( |
CERTCertificate* nss_cert = CERT_NewTempCertificate( |
CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); |
if (!nss_cert) { |
- // In the event of an NSS error we make up an OS error and reuse |
- // the error handling, below. |
+ // In the event of an NSS error, make up an OS error and reuse |
+ // the error handling below. |
os_error = errSecCreateChainFailed; |
break; |
} |
CERT_AddCertToListTail(*result_certs, nss_cert); |
} |
} |
+ |
if (os_error == noErr) { |
- int cert_count = 0; |
- if (chain) { |
- cert_count = CFArrayGetCount(chain); |
- CFRelease(chain); |
- } |
- core->AddCertProvidedEvent(cert_count); |
+ core->AddCertProvidedEvent(chain.size()); |
return SECSuccess; |
} |
+ |
OSSTATUS_LOG(WARNING, os_error) |
<< "Client cert found, but could not be used"; |
if (*result_certs) { |
@@ -1458,8 +1460,6 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler( |
*result_private_key = NULL; |
if (private_key) |
CFRelease(private_key); |
- if (chain) |
- CFRelease(chain); |
} |
// Send no client certificate. |