Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(717)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 8662036: Support EC certs in OriginBoundCertService and OriginBoundCertStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 #include "base/bind.h" 67 #include "base/bind.h"
68 #include "base/compiler_specific.h" 68 #include "base/compiler_specific.h"
69 #include "base/logging.h" 69 #include "base/logging.h"
70 #include "base/memory/singleton.h" 70 #include "base/memory/singleton.h"
71 #include "base/metrics/histogram.h" 71 #include "base/metrics/histogram.h"
72 #include "base/string_number_conversions.h" 72 #include "base/string_number_conversions.h"
73 #include "base/string_util.h" 73 #include "base/string_util.h"
74 #include "base/stringprintf.h" 74 #include "base/stringprintf.h"
75 #include "base/threading/thread_restrictions.h" 75 #include "base/threading/thread_restrictions.h"
76 #include "base/values.h" 76 #include "base/values.h"
77 #include "crypto/ec_private_key.h"
77 #include "crypto/rsa_private_key.h" 78 #include "crypto/rsa_private_key.h"
78 #include "crypto/scoped_nss_types.h" 79 #include "crypto/scoped_nss_types.h"
79 #include "net/base/address_list.h" 80 #include "net/base/address_list.h"
80 #include "net/base/asn1_util.h" 81 #include "net/base/asn1_util.h"
81 #include "net/base/cert_status_flags.h" 82 #include "net/base/cert_status_flags.h"
82 #include "net/base/cert_verifier.h" 83 #include "net/base/cert_verifier.h"
83 #include "net/base/connection_type_histograms.h" 84 #include "net/base/connection_type_histograms.h"
84 #include "net/base/dns_util.h" 85 #include "net/base/dns_util.h"
85 #include "net/base/dnsrr_resolver.h" 86 #include "net/base/dnsrr_resolver.h"
86 #include "net/base/dnssec_chain_verifier.h" 87 #include "net/base/dnssec_chain_verifier.h"
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 cert_item.len = ob_cert_.size(); 1539 cert_item.len = ob_cert_.size();
1539 *cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 1540 *cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
1540 &cert_item, 1541 &cert_item,
1541 NULL, 1542 NULL,
1542 PR_FALSE, 1543 PR_FALSE,
1543 PR_TRUE); 1544 PR_TRUE);
1544 if (*cert == NULL) 1545 if (*cert == NULL)
1545 return MapNSSError(PORT_GetError()); 1546 return MapNSSError(PORT_GetError());
1546 1547
1547 // Set the private key. 1548 // Set the private key.
1548 SECItem der_private_key_info; 1549 switch (ob_cert_type_) {
1549 der_private_key_info.data = (unsigned char*)ob_private_key_.data(); 1550 case ORIGIN_BOUND_RSA_CERT:
wtc 2011/11/30 23:23:40 Format this as follows: case ORIGIN_BOUND_RSA_C
mattm 2011/12/02 01:55:59 Done.
1550 der_private_key_info.len = ob_private_key_.size(); 1551 {
1551 const unsigned int key_usage = KU_DIGITAL_SIGNATURE; 1552 SECItem der_private_key_info;
1552 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 1553 der_private_key_info.data = (unsigned char*)ob_private_key_.data();
1553 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 1554 der_private_key_info.len = ob_private_key_.size();
1554 slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, 1555 const unsigned int key_usage = KU_DIGITAL_SIGNATURE;
1555 key_usage, key, NULL); 1556 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
1557 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
1558 slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
1559 key_usage, key, NULL);
1556 1560
1557 if (rv != SECSuccess) { 1561 if (rv != SECSuccess) {
1558 int error = MapNSSError(PORT_GetError()); 1562 int error = MapNSSError(PORT_GetError());
1559 CERT_DestroyCertificate(*cert); 1563 CERT_DestroyCertificate(*cert);
1560 *cert = NULL; 1564 *cert = NULL;
1561 return error; 1565 return error;
1566 }
1567 break;
1568 }
1569
1570 case ORIGIN_BOUND_EC_CERT:
1571 {
1572 // TODO(mattm): provide a static method on ECPrivateKey to generate a
1573 // SECKEYPrivateKey directly?
wtc 2011/11/30 23:23:40 IMPORTANT: Yes, we should do something along that
mattm 2011/12/02 01:55:59 Done. (It's still a fair bit of common code, so I
1574 std::vector<uint8> spki(
1575 (*cert)->derPublicKey.data,
1576 (*cert)->derPublicKey.data + (*cert)->derPublicKey.len);
1577 std::vector<uint8> private_key_info(ob_private_key_.begin(),
1578 ob_private_key_.end());
1579 scoped_ptr<crypto::ECPrivateKey> ec_key_pair(
1580 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
1581 OriginBoundCertService::kEPKIPassword, private_key_info, spki));
1582 if (!ec_key_pair.get()) {
1583 CERT_DestroyCertificate(*cert);
1584 *cert = NULL;
1585 return MapNSSError(PORT_GetError());
1586 }
1587 *key = SECKEY_CopyPrivateKey(ec_key_pair->key());
1588 if (!*key) {
1589 CERT_DestroyCertificate(*cert);
1590 *cert = NULL;
1591 return MapNSSError(PORT_GetError());
1592 }
1593 break;
1594 }
1595
1596 default:
1597 NOTREACHED();
wtc 2011/11/30 23:23:40 Nit: add a break statement to the default case. B
mattm 2011/12/02 01:55:59 Done.
1562 } 1598 }
1563 1599
1564 return OK; 1600 return OK;
1565 } 1601 }
1566 1602
1567 int SSLClientSocketNSS::DoGetOBCertComplete(int result) { 1603 int SSLClientSocketNSS::DoGetOBCertComplete(int result) {
1568 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, 1604 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT,
1569 result); 1605 result);
1570 client_auth_cert_needed_ = false; 1606 client_auth_cert_needed_ = false;
1571 ob_cert_request_handle_ = NULL; 1607 ob_cert_request_handle_ = NULL;
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) { 2142 bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) {
2107 PRBool xtn_negotiated = PR_FALSE; 2143 PRBool xtn_negotiated = PR_FALSE;
2108 SECStatus rv = SSL_HandshakeNegotiatedExtension( 2144 SECStatus rv = SSL_HandshakeNegotiatedExtension(
2109 socket, ssl_ob_cert_xtn, &xtn_negotiated); 2145 socket, ssl_ob_cert_xtn, &xtn_negotiated);
2110 DCHECK_EQ(SECSuccess, rv); 2146 DCHECK_EQ(SECSuccess, rv);
2111 2147
2112 return xtn_negotiated ? true : false; 2148 return xtn_negotiated ? true : false;
2113 } 2149 }
2114 2150
2115 SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler( 2151 SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler(
2152 const std::vector<OriginBoundCertType>& requested_types,
2116 CERTCertificate** result_certificate, 2153 CERTCertificate** result_certificate,
2117 SECKEYPrivateKey** result_private_key) { 2154 SECKEYPrivateKey** result_private_key) {
2118 ob_cert_xtn_negotiated_ = true; 2155 ob_cert_xtn_negotiated_ = true;
2119 2156
2120 // We have negotiated the origin-bound certificate extension. 2157 // We have negotiated the origin-bound certificate extension.
2121 std::string origin = "https://" + host_and_port_.ToString(); 2158 std::string origin = "https://" + host_and_port_.ToString();
2122 net_log_.BeginEvent(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, NULL); 2159 net_log_.BeginEvent(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, NULL);
2123 int error = origin_bound_cert_service_->GetOriginBoundCert( 2160 int error = origin_bound_cert_service_->GetOriginBoundCert(
2124 origin, 2161 origin,
2162 requested_types,
2163 &ob_cert_type_,
2125 &ob_private_key_, 2164 &ob_private_key_,
2126 &ob_cert_, 2165 &ob_cert_,
2127 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, 2166 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
2128 base::Unretained(this)), 2167 base::Unretained(this)),
2129 &ob_cert_request_handle_); 2168 &ob_cert_request_handle_);
2130 2169
2131 if (error == ERR_IO_PENDING) { 2170 if (error == ERR_IO_PENDING) {
2132 // Asynchronous case. 2171 // Asynchronous case.
2133 client_auth_cert_needed_ = true; 2172 client_auth_cert_needed_ = true;
2134 return SECWouldBlock; 2173 return SECWouldBlock;
(...skipping 29 matching lines...) Expand all
2164 CERTCertList** result_certs, 2203 CERTCertList** result_certs,
2165 void** result_private_key, 2204 void** result_private_key,
2166 CERTCertificate** result_nss_certificate, 2205 CERTCertificate** result_nss_certificate,
2167 SECKEYPrivateKey** result_nss_private_key) { 2206 SECKEYPrivateKey** result_nss_private_key) {
2168 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); 2207 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2169 2208
2170 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); 2209 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL);
2171 2210
2172 // Check if an origin-bound certificate is requested. 2211 // Check if an origin-bound certificate is requested.
2173 if (OriginBoundCertNegotiated(socket)) { 2212 if (OriginBoundCertNegotiated(socket)) {
2213 // TODO(mattm): Once NSS supports it, pass the actual requested types.
2214 std::vector<OriginBoundCertType> requested_types;
2215 requested_types.push_back(ORIGIN_BOUND_RSA_CERT);
2174 return that->OriginBoundClientAuthHandler( 2216 return that->OriginBoundClientAuthHandler(
2175 result_nss_certificate, result_nss_private_key); 2217 requested_types, result_nss_certificate, result_nss_private_key);
2176 } 2218 }
2177 2219
2178 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; 2220 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
2179 #if defined(OS_WIN) 2221 #if defined(OS_WIN)
2180 if (that->ssl_config_.send_client_cert) { 2222 if (that->ssl_config_.send_client_cert) {
2181 if (that->ssl_config_.client_cert) { 2223 if (that->ssl_config_.client_cert) {
2182 PCCERT_CONTEXT cert_context = 2224 PCCERT_CONTEXT cert_context =
2183 that->ssl_config_.client_cert->os_cert_handle(); 2225 that->ssl_config_.client_cert->os_cert_handle();
2184 2226
2185 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; 2227 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0;
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 PRFileDesc* socket, 2511 PRFileDesc* socket,
2470 CERTDistNames* ca_names, 2512 CERTDistNames* ca_names,
2471 CERTCertificate** result_certificate, 2513 CERTCertificate** result_certificate,
2472 SECKEYPrivateKey** result_private_key) { 2514 SECKEYPrivateKey** result_private_key) {
2473 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); 2515 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2474 2516
2475 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); 2517 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL);
2476 2518
2477 // Check if an origin-bound certificate is requested. 2519 // Check if an origin-bound certificate is requested.
2478 if (OriginBoundCertNegotiated(socket)) { 2520 if (OriginBoundCertNegotiated(socket)) {
2521 // TODO(mattm): Once NSS supports it, pass the actual requested types.
2522 std::vector<OriginBoundCertType> requested_types;
2523 requested_types.push_back(ORIGIN_BOUND_RSA_CERT);
wtc 2011/11/30 23:23:40 I think we should add both the EC and RSA cert typ
mattm 2011/12/02 01:55:59 Done.
2479 return that->OriginBoundClientAuthHandler( 2524 return that->OriginBoundClientAuthHandler(
2480 result_certificate, result_private_key); 2525 requested_types, result_certificate, result_private_key);
2481 } 2526 }
2482 2527
2483 // Regular client certificate requested. 2528 // Regular client certificate requested.
2484 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; 2529 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
2485 void* wincx = SSL_RevealPinArg(socket); 2530 void* wincx = SSL_RevealPinArg(socket);
2486 2531
2487 // Second pass: a client certificate should have been selected. 2532 // Second pass: a client certificate should have been selected.
2488 if (that->ssl_config_.send_client_cert) { 2533 if (that->ssl_config_.send_client_cert) {
2489 if (that->ssl_config_.client_cert) { 2534 if (that->ssl_config_.client_cert) {
2490 CERTCertificate* cert = CERT_DupCertificate( 2535 CERTCertificate* cert = CERT_DupCertificate(
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2616 valid_thread_id_ = base::PlatformThread::CurrentId(); 2661 valid_thread_id_ = base::PlatformThread::CurrentId();
2617 } 2662 }
2618 2663
2619 bool SSLClientSocketNSS::CalledOnValidThread() const { 2664 bool SSLClientSocketNSS::CalledOnValidThread() const {
2620 EnsureThreadIdAssigned(); 2665 EnsureThreadIdAssigned();
2621 base::AutoLock auto_lock(lock_); 2666 base::AutoLock auto_lock(lock_);
2622 return valid_thread_id_ == base::PlatformThread::CurrentId(); 2667 return valid_thread_id_ == base::PlatformThread::CurrentId();
2623 } 2668 }
2624 2669
2625 } // namespace net 2670 } // namespace net
OLDNEW
« net/socket/ssl_client_socket_nss.h ('K') | « net/socket/ssl_client_socket_nss.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698