| Index: net/socket/ssl_client_socket_nss.cc
|
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
|
| index 2595350e7548256bfcf2f76827236ee2bde15d8e..0e4ea7f8abc1050f1bd04f1118e1cc0a00ae55b3 100644
|
| --- a/net/socket/ssl_client_socket_nss.cc
|
| +++ b/net/socket/ssl_client_socket_nss.cc
|
| @@ -74,6 +74,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"
|
| @@ -1545,20 +1546,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;
|
| @@ -2113,6 +2142,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;
|
| @@ -2122,6 +2152,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,
|
| @@ -2171,8 +2203,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;
|
| @@ -2476,8 +2512,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.
|
|
|