summaryrefslogtreecommitdiffstats
path: root/net/socket/ssl_client_socket_nss.cc
diff options
context:
space:
mode:
authorsnej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 23:44:45 +0000
committersnej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 23:44:45 +0000
commit4bee851c891ded2c3654729e0ea9a7ebd56e54bb (patch)
treebbb5fbcdcbfaa5c194af66dedb7e9fd135476f70 /net/socket/ssl_client_socket_nss.cc
parentd68a4fc6f448c6ebf407e2817320e7736c4735ee (diff)
downloadchromium_src-4bee851c891ded2c3654729e0ea9a7ebd56e54bb.zip
chromium_src-4bee851c891ded2c3654729e0ea9a7ebd56e54bb.tar.gz
chromium_src-4bee851c891ded2c3654729e0ea9a7ebd56e54bb.tar.bz2
Thread-safety for X509Certificate's intermediate-certs list.
BUG=32553,30001 TEST=none Review URL: http://codereview.chromium.org/661223 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40797 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/ssl_client_socket_nss.cc')
-rw-r--r--net/socket/ssl_client_socket_nss.cc47
1 files changed, 26 insertions, 21 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 994f1f3..4047c17 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -595,24 +595,11 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
if (!cert_store_)
cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
+ // Get each of the intermediate certificates in the server's chain.
+ // These will be added to the server's X509Certificate object, making
+ // them available to X509Certificate::Verify() for chain building.
+ X509Certificate::OSCertHandles intermediate_ca_certs;
PCCERT_CONTEXT cert_context = NULL;
- BOOL ok = CertAddEncodedCertificateToStore(
- cert_store_,
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- server_cert_nss_->derCert.data,
- server_cert_nss_->derCert.len,
- CERT_STORE_ADD_USE_EXISTING,
- &cert_context);
- DCHECK(ok);
- server_cert_ = X509Certificate::CreateFromHandle(
- cert_context, X509Certificate::SOURCE_FROM_NETWORK);
-
- // Add each of the intermediate certificates in the server's chain to
- // the server's X509Certificate object. This makes them available to
- // X509Certificate::Verify() for chain building.
- // TODO(wtc): Since X509Certificate::CreateFromHandle may return a
- // cached X509Certificate object, we may be adding intermediate CA
- // certificates to it repeatedly!
CERTCertList* cert_list = CERT_GetCertChainFromCert(
server_cert_nss_, PR_Now(), certUsageSSLCA);
if (cert_list) {
@@ -620,7 +607,7 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
!CERT_LIST_END(node, cert_list);
node = CERT_LIST_NEXT(node)) {
cert_context = NULL;
- ok = CertAddEncodedCertificateToStore(
+ BOOL ok = CertAddEncodedCertificateToStore(
cert_store_,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
node->cert->derCert.data,
@@ -629,14 +616,31 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
&cert_context);
DCHECK(ok);
if (node->cert != server_cert_nss_)
- server_cert_->AddIntermediateCertificate(cert_context);
+ intermediate_ca_certs.push_back(cert_context);
}
CERT_DestroyCertList(cert_list);
}
+
+ // Finally create the X509Certificate object.
+ BOOL ok = CertAddEncodedCertificateToStore(
+ cert_store_,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ server_cert_nss_->derCert.data,
+ server_cert_nss_->derCert.len,
+ CERT_STORE_ADD_USE_EXISTING,
+ &cert_context);
+ DCHECK(ok);
+ server_cert_ = X509Certificate::CreateFromHandle(
+ cert_context,
+ X509Certificate::SOURCE_FROM_NETWORK,
+ intermediate_ca_certs);
+ for (size_t i = 0; i < intermediate_ca_certs.size(); ++i)
+ CertFreeCertificateContext(intermediate_ca_certs[i]);
#else
server_cert_ = X509Certificate::CreateFromHandle(
CERT_DupCertificate(server_cert_nss_),
- X509Certificate::SOURCE_FROM_NETWORK);
+ X509Certificate::SOURCE_FROM_NETWORK,
+ X509Certificate::OSCertHandles());
#endif
}
}
@@ -1139,7 +1143,8 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler(
privkey = PK11_FindKeyByAnyCert(cert, wincx);
if (privkey) {
X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
- cert, X509Certificate::SOURCE_LONE_CERT_IMPORT);
+ cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
+ net::X509Certificate::OSCertHandles());
that->client_certs_.push_back(x509_cert);
SECKEY_DestroyPrivateKey(privkey);
continue;