Chromium Code Reviews| 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. |