summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-27 02:52:00 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-27 02:52:00 +0000
commit007c5d2383e8f9b7c8d8f79a26f9a016bea1916b (patch)
tree245cd55ca33a68f130e400aec97bb6e6108907dc /net/socket
parent09c7f0e70cbd6b5236d040db3e39118fcccc38ff (diff)
downloadchromium_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.cc104
-rw-r--r--net/socket/ssl_client_socket_nss.h25
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,