summaryrefslogtreecommitdiffstats
path: root/net/socket/ssl_client_socket_nss.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket/ssl_client_socket_nss.cc')
-rw-r--r--net/socket/ssl_client_socket_nss.cc34
1 files changed, 30 insertions, 4 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 085e52c..44aa579 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -1268,10 +1268,36 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler(
// handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
return SECWouldBlock;
#elif defined(OS_MACOSX)
- // TODO(wtc): see http://crbug.com/45369.
- // Not implemented. Send no client certificate.
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
+ if (that->ssl_config_.send_client_cert) {
+ // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using
+ // CDSA/CSSM yet (http://crbug.com/45369), so client_cert must be NULL.
+ DCHECK(!that->ssl_config_.client_cert);
+ // Send no client certificate.
+ return SECFailure;
+ }
+
+ that->client_certs_.clear();
+
+ // First, get the cert issuer names allowed by the server.
+ std::vector<CertPrincipal> valid_issuers;
+ int n = ca_names->nnames;
+ for (int i = 0; i < n; i++) {
+ // Parse each name into a CertPrincipal object.
+ CertPrincipal p;
+ if (p.ParseDistinguishedName(ca_names->names[i].data,
+ ca_names->names[i].len)) {
+ valid_issuers.push_back(p);
+ }
+ }
+
+ // Now get the available client certs whose issuers are allowed by the server.
+ X509Certificate::GetSSLClientCertificates(that->hostname_,
+ valid_issuers,
+ &that->client_certs_);
+
+ // Tell NSS to suspend the client authentication. We will then abort the
+ // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
+ return SECWouldBlock;
#else
CERTCertificate* cert = NULL;
SECKEYPrivateKey* privkey = NULL;