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

Unified Diff: net/socket/ssl_client_socket_nss.cc

Issue 13866049: Fix client certificate authentication on Mac and Linux introduced in r178732 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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
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.

Powered by Google App Engine
This is Rietveld 408576698