diff options
author | snej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 16:59:54 +0000 |
---|---|---|
committer | snej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-05 16:59:54 +0000 |
commit | 76964955a0fc995d7a0c95feaeaa17891eab2205 (patch) | |
tree | 26aca3f0ef8c93d5330f24f6136bfb6136df0bbe /net/socket | |
parent | 357d16ba35c2f43322af5242d36bdf220b8f6455 (diff) | |
download | chromium_src-76964955a0fc995d7a0c95feaeaa17891eab2205.zip chromium_src-76964955a0fc995d7a0c95feaeaa17891eab2205.tar.gz chromium_src-76964955a0fc995d7a0c95feaeaa17891eab2205.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@40742 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/ssl_client_socket_mac.cc | 21 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 47 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_win.cc | 16 | ||||
-rw-r--r-- | net/socket/ssl_test_util.cc | 3 |
4 files changed, 41 insertions, 46 deletions
diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index 0720a40..1a0ca6d 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -411,29 +411,22 @@ X509Certificate* GetServerCert(SSLContextRef ssl_context) { DCHECK_GT(CFArrayGetCount(certs), 0); - SecCertificateRef server_cert = static_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(certs, 0))); - CFRetain(server_cert); - X509Certificate *x509_cert = X509Certificate::CreateFromHandle( - server_cert, X509Certificate::SOURCE_FROM_NETWORK); - if (!x509_cert) - return NULL; - // 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! + std::vector<SecCertificateRef> intermediate_ca_certs; CFIndex certs_length = CFArrayGetCount(certs); for (CFIndex i = 1; i < certs_length; ++i) { SecCertificateRef cert_ref = reinterpret_cast<SecCertificateRef>( const_cast<void*>(CFArrayGetValueAtIndex(certs, i))); - CFRetain(cert_ref); - x509_cert->AddIntermediateCertificate(cert_ref); + intermediate_ca_certs.push_back(cert_ref); } - return x509_cert; + SecCertificateRef server_cert = static_cast<SecCertificateRef>( + const_cast<void*>(CFArrayGetValueAtIndex(certs, 0))); + CFRetain(server_cert); + return X509Certificate::CreateFromHandle( + server_cert, X509Certificate::SOURCE_FROM_NETWORK, intermediate_ca_certs); } // Dynamically look up a pointer to a function exported by a bundle. diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 52dc09e..30566b3 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; diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc index 7e76f9e..bf4a547 100644 --- a/net/socket/ssl_client_socket_win.cc +++ b/net/socket/ssl_client_socket_win.cc @@ -68,13 +68,6 @@ static int MapSecurityError(SECURITY_STATUS err) { } } -// Returns true if the two CERT_CONTEXTs contain the same certificate. -bool SameCert(PCCERT_CONTEXT a, PCCERT_CONTEXT b) { - return a == b || - (a->cbCertEncoded == b->cbCertEncoded && - memcmp(a->pbCertEncoded, b->pbCertEncoded, b->cbCertEncoded) == 0); -} - //----------------------------------------------------------------------------- // A bitmask consisting of these bit flags encodes which versions of the SSL @@ -418,7 +411,8 @@ void SSLClientSocketWin::GetSSLCertRequestInfo( continue; } scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( - cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT); + cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, + net::X509Certificate::OSCertHandles()); cert_request_info->client_certs.push_back(cert); } @@ -1303,14 +1297,16 @@ int SSLClientSocketWin::DidCompleteHandshake() { return MapSecurityError(status); } if (renegotiating_ && - SameCert(server_cert_->os_cert_handle(), server_cert_handle)) { + X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(), + server_cert_handle)) { // We already verified the server certificate. Either it is good or the // user has accepted the certificate error. CertFreeCertificateContext(server_cert_handle); DidCompleteRenegotiation(); } else { server_cert_ = X509Certificate::CreateFromHandle( - server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); + server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, + net::X509Certificate::OSCertHandles()); next_state_ = STATE_VERIFY_CERT; } diff --git a/net/socket/ssl_test_util.cc b/net/socket/ssl_test_util.cc index 55d104c..56eba9c 100644 --- a/net/socket/ssl_test_util.cc +++ b/net/socket/ssl_test_util.cc @@ -112,7 +112,8 @@ static net::X509Certificate* LoadTemporaryCert(const FilePath& filename) { const_cast<void*>(CFArrayGetValueAtIndex(cert_array, 0))); CFRetain(cert_ref); return net::X509Certificate::CreateFromHandle(cert_ref, - net::X509Certificate::SOURCE_FROM_NETWORK); + net::X509Certificate::SOURCE_LONE_CERT_IMPORT, + net::X509Certificate::OSCertHandles()); } #endif |