summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/ssl_client_socket_nss.cc70
-rw-r--r--net/socket/ssl_client_socket_nss.h7
2 files changed, 60 insertions, 17 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 16b8da2..d2991ba 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -75,6 +75,7 @@
#include "base/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
+#include "crypto/ec_private_key.h"
#include "crypto/rsa_private_key.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/address_list.h"
@@ -1549,20 +1550,48 @@ int SSLClientSocketNSS::ImportOBCertAndKey(CERTCertificate** cert,
return MapNSSError(PORT_GetError());
// Set the private key.
- SECItem der_private_key_info;
- der_private_key_info.data = (unsigned char*)ob_private_key_.data();
- der_private_key_info.len = ob_private_key_.size();
- const unsigned int key_usage = KU_DIGITAL_SIGNATURE;
- crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
- SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
- slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
- key_usage, key, NULL);
+ switch (ob_cert_type_) {
+ case CLIENT_CERT_RSA_SIGN: {
+ SECItem der_private_key_info;
+ der_private_key_info.data = (unsigned char*)ob_private_key_.data();
+ der_private_key_info.len = ob_private_key_.size();
+ const unsigned int key_usage = KU_DIGITAL_SIGNATURE;
+ crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
+ SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+ slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
+ key_usage, key, NULL);
+
+ if (rv != SECSuccess) {
+ int error = MapNSSError(PORT_GetError());
+ CERT_DestroyCertificate(*cert);
+ *cert = NULL;
+ return error;
+ }
+ break;
+ }
- if (rv != SECSuccess) {
- int error = MapNSSError(PORT_GetError());
- CERT_DestroyCertificate(*cert);
- *cert = NULL;
- return error;
+ case CLIENT_CERT_ECDSA_SIGN: {
+ SECKEYPublicKey* public_key = NULL;
+ if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo(
+ OriginBoundCertService::kEPKIPassword,
+ reinterpret_cast<const unsigned char*>(ob_private_key_.data()),
+ ob_private_key_.size(),
+ &(*cert)->subjectPublicKeyInfo,
+ false,
+ false,
+ key,
+ &public_key)) {
+ CERT_DestroyCertificate(*cert);
+ *cert = NULL;
+ return MapNSSError(PORT_GetError());
+ }
+ SECKEY_DestroyPublicKey(public_key);
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ return ERR_INVALID_ARGUMENT;
}
return OK;
@@ -2117,6 +2146,7 @@ bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) {
}
SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler(
+ const std::vector<uint8>& requested_cert_types,
CERTCertificate** result_certificate,
SECKEYPrivateKey** result_private_key) {
ob_cert_xtn_negotiated_ = true;
@@ -2126,6 +2156,8 @@ SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler(
net_log_.BeginEvent(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, NULL);
int error = origin_bound_cert_service_->GetOriginBoundCert(
origin,
+ requested_cert_types,
+ &ob_cert_type_,
&ob_private_key_,
&ob_cert_,
base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
@@ -2175,8 +2207,12 @@ SECStatus SSLClientSocketNSS::PlatformClientAuthHandler(
// Check if an origin-bound certificate is requested.
if (OriginBoundCertNegotiated(socket)) {
+ // TODO(mattm): Once NSS supports it, pass the actual requested types.
+ std::vector<uint8> requested_cert_types;
+ requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN);
+ requested_cert_types.push_back(CLIENT_CERT_RSA_SIGN);
return that->OriginBoundClientAuthHandler(
- result_nss_certificate, result_nss_private_key);
+ requested_cert_types, result_nss_certificate, result_nss_private_key);
}
that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
@@ -2480,8 +2516,12 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler(
// Check if an origin-bound certificate is requested.
if (OriginBoundCertNegotiated(socket)) {
+ // TODO(mattm): Once NSS supports it, pass the actual requested types.
+ std::vector<uint8> requested_cert_types;
+ requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN);
+ requested_cert_types.push_back(CLIENT_CERT_RSA_SIGN);
return that->OriginBoundClientAuthHandler(
- result_certificate, result_private_key);
+ requested_cert_types, 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 0eddd76..7b56844 100644
--- a/net/socket/ssl_client_socket_nss.h
+++ b/net/socket/ssl_client_socket_nss.h
@@ -167,8 +167,10 @@ class SSLClientSocketNSS : public SSLClientSocket {
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);
+ SECStatus OriginBoundClientAuthHandler(
+ const std::vector<uint8>& requested_cert_types,
+ CERTCertificate** result_certificate,
+ SECKEYPrivateKey** result_private_key);
#if defined(NSS_PLATFORM_CLIENT_AUTH)
// On platforms where we use the native certificate store, NSS calls this
// instead when client authentication is requested. At most one of
@@ -259,6 +261,7 @@ class SSLClientSocketNSS : public SSLClientSocket {
// For origin bound certificates in client auth.
bool ob_cert_xtn_negotiated_;
OriginBoundCertService* origin_bound_cert_service_;
+ SSLClientCertType ob_cert_type_;
std::string ob_private_key_;
std::string ob_cert_;
OriginBoundCertService::RequestHandle ob_cert_request_handle_;