Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |