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 |