diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-27 02:52:00 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-27 02:52:00 +0000 |
commit | 007c5d2383e8f9b7c8d8f79a26f9a016bea1916b (patch) | |
tree | 245cd55ca33a68f130e400aec97bb6e6108907dc /net/socket | |
parent | 09c7f0e70cbd6b5236d040db3e39118fcccc38ff (diff) | |
download | chromium_src-007c5d2383e8f9b7c8d8f79a26f9a016bea1916b.zip chromium_src-007c5d2383e8f9b7c8d8f79a26f9a016bea1916b.tar.gz chromium_src-007c5d2383e8f9b7c8d8f79a26f9a016bea1916b.tar.bz2 |
Fallback from platform client auth to NSS client auth.
Adds support for origin bound certs on Win and Mac.
BUG=88782
TEST=normal SSL client auth still works & origin-bound auth works following origin-bound testing doc.
Review URL: http://codereview.chromium.org/7839025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102877 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 104 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.h | 25 |
2 files changed, 74 insertions, 55 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index cca0591..41e3413 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -1543,13 +1543,6 @@ int SSLClientSocketNSS::DoHandshake() { return net_error; } -#if defined(NSS_PLATFORM_CLIENT_AUTH) -int SSLClientSocketNSS::ImportOBCertAndKey(CERTCertificate** cert, - SECKEYPrivateKey** key) { - NOTREACHED(); - return ERR_NOT_IMPLEMENTED; -} -#else int SSLClientSocketNSS::ImportOBCertAndKey(CERTCertificate** cert, SECKEYPrivateKey** key) { // Set the certificate. @@ -1583,14 +1576,7 @@ int SSLClientSocketNSS::ImportOBCertAndKey(CERTCertificate** cert, return OK; } -#endif -#if defined(NSS_PLATFORM_CLIENT_AUTH) -int SSLClientSocketNSS::DoGetOBCertComplete(int result) { - NOTREACHED(); - return ERR_NOT_IMPLEMENTED; -} -#else int SSLClientSocketNSS::DoGetOBCertComplete(int result) { ob_cert_request_handle_ = NULL; @@ -1614,7 +1600,6 @@ int SSLClientSocketNSS::DoGetOBCertComplete(int result) { GotoState(STATE_HANDSHAKE); return OK; } -#endif int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { if (ssl_config_.dns_cert_provenance_checking_enabled && @@ -2120,6 +2105,49 @@ SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, return SECSuccess; } +// static +bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) { + PRBool xtn_negotiated = PR_FALSE; + SECStatus rv = SSL_HandshakeNegotiatedExtension( + socket, ssl_ob_cert_xtn, &xtn_negotiated); + DCHECK_EQ(SECSuccess, rv); + + return xtn_negotiated ? true : false; +} + +SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler( + CERTCertificate** result_certificate, + SECKEYPrivateKey** result_private_key) { + ob_cert_xtn_negotiated_ = true; + + // We have negotiated the origin-bound certificate extension. + std::string origin = "https://" + host_and_port_.ToString(); + int error = origin_bound_cert_service_->GetOriginBoundCert( + origin, + &ob_private_key_, + &ob_cert_, + &handshake_io_callback_, + &ob_cert_request_handle_); + + if (error == OK) { + // Synchronous success. + int result = ImportOBCertAndKey(result_certificate, + result_private_key); + if (result != OK) + return SECFailure; + + return SECSuccess; + } + + if (error == ERR_IO_PENDING) { + // Asynchronous case. + client_auth_cert_needed_ = true; + return SECWouldBlock; + } + + return SECFailure; // Synchronous failure. +} + #if defined(NSS_PLATFORM_CLIENT_AUTH) // static // NSS calls this if a client certificate is needed. @@ -2128,9 +2156,17 @@ SECStatus SSLClientSocketNSS::PlatformClientAuthHandler( PRFileDesc* socket, CERTDistNames* ca_names, CERTCertList** result_certs, - void** result_private_key) { + void** result_private_key, + CERTCertificate** result_nss_certificate, + SECKEYPrivateKey** result_nss_private_key) { SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); + // Check if an origin-bound certificate is requested. + if (OriginBoundCertNegotiated(socket)) { + return that->OriginBoundClientAuthHandler( + result_nss_certificate, result_nss_private_key); + } + that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; #if defined(OS_WIN) if (that->ssl_config_.send_client_cert) { @@ -2385,39 +2421,9 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler( SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); // Check if an origin-bound certificate is requested. - PRBool xtn_negotiated = PR_FALSE; - SECStatus rv = SSL_HandshakeNegotiatedExtension( - socket, ssl_ob_cert_xtn, &xtn_negotiated); - DCHECK_EQ(SECSuccess, rv); - that->ob_cert_xtn_negotiated_ = xtn_negotiated ? true : false; - - if (that->ob_cert_xtn_negotiated_) { - // We have negotiated the origin-bound certificate extension. - std::string origin = "https://" + that->host_and_port_.ToString(); - int error = that->origin_bound_cert_service_->GetOriginBoundCert( - origin, - &that->ob_private_key_, - &that->ob_cert_, - &that->handshake_io_callback_, - &that->ob_cert_request_handle_); - - if (error == OK) { - // Synchronous success. - int result = that->ImportOBCertAndKey(result_certificate, - result_private_key); - if (result != OK) - return SECFailure; - - return SECSuccess; - } - - if (error == ERR_IO_PENDING) { - // Asynchronous case - that->client_auth_cert_needed_ = true; - return SECWouldBlock; - } - - return SECFailure; // Synchronous failure. + if (OriginBoundCertNegotiated(socket)) { + return that->OriginBoundClientAuthHandler( + result_certificate, result_private_key); } // Regular client certificate requested. diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 0d0b342..6d403f7 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -157,14 +157,27 @@ class SSLClientSocketNSS : public SSLClientSocket { // argument. static SECStatus OwnAuthCertHandler(void* arg, PRFileDesc* socket, PRBool checksig, PRBool is_server); - // NSS calls this when client authentication is requested. + // Returns true if connection negotiated the origin bound cert extension. + static bool OriginBoundCertNegotiated(PRFileDesc* socket); + // Origin bound cert client auth handler. + // Returns the value the ClientAuthHandler function should return. + SECStatus OriginBoundClientAuthHandler(CERTCertificate** result_certificate, + SECKEYPrivateKey** result_private_key); #if defined(NSS_PLATFORM_CLIENT_AUTH) - static SECStatus PlatformClientAuthHandler(void* arg, - PRFileDesc* socket, - CERTDistNames* ca_names, - CERTCertList** result_certs, - void** result_private_key); + // On platforms where we use the native certificate store, NSS calls this + // instead when client authentication is requested. At most one of + // (result_certs, result_private_key) or + // (result_nss_certificate, result_nss_private_key) should be set. + static SECStatus PlatformClientAuthHandler( + void* arg, + PRFileDesc* socket, + CERTDistNames* ca_names, + CERTCertList** result_certs, + void** result_private_key, + CERTCertificate** result_nss_certificate, + SECKEYPrivateKey** result_nss_private_key); #else + // NSS calls this when client authentication is requested. static SECStatus ClientAuthHandler(void* arg, PRFileDesc* socket, CERTDistNames* ca_names, |