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 CLIENT_CERT_RSA_SIGN: { |
1550 der_private_key_info.len = ob_private_key_.size(); | 1551 SECItem der_private_key_info; |
1551 const unsigned int key_usage = KU_DIGITAL_SIGNATURE; | 1552 der_private_key_info.data = (unsigned char*)ob_private_key_.data(); |
1552 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); | 1553 der_private_key_info.len = ob_private_key_.size(); |
1553 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( | 1554 const unsigned int key_usage = KU_DIGITAL_SIGNATURE; |
1554 slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, | 1555 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
1555 key_usage, key, NULL); | 1556 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( |
| 1557 slot.get(), &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, |
| 1558 key_usage, key, NULL); |
1556 | 1559 |
1557 if (rv != SECSuccess) { | 1560 if (rv != SECSuccess) { |
1558 int error = MapNSSError(PORT_GetError()); | 1561 int error = MapNSSError(PORT_GetError()); |
1559 CERT_DestroyCertificate(*cert); | 1562 CERT_DestroyCertificate(*cert); |
1560 *cert = NULL; | 1563 *cert = NULL; |
1561 return error; | 1564 return error; |
| 1565 } |
| 1566 break; |
| 1567 } |
| 1568 |
| 1569 case CLIENT_CERT_ECDSA_SIGN: { |
| 1570 SECKEYPublicKey* public_key = NULL; |
| 1571 if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
| 1572 OriginBoundCertService::kEPKIPassword, |
| 1573 reinterpret_cast<const unsigned char*>(ob_private_key_.data()), |
| 1574 ob_private_key_.size(), |
| 1575 &(*cert)->subjectPublicKeyInfo, |
| 1576 false, |
| 1577 false, |
| 1578 key, |
| 1579 &public_key)) { |
| 1580 CERT_DestroyCertificate(*cert); |
| 1581 *cert = NULL; |
| 1582 return MapNSSError(PORT_GetError()); |
| 1583 } |
| 1584 SECKEY_DestroyPublicKey(public_key); |
| 1585 break; |
| 1586 } |
| 1587 |
| 1588 default: |
| 1589 NOTREACHED(); |
| 1590 return ERR_INVALID_ARGUMENT; |
1562 } | 1591 } |
1563 | 1592 |
1564 return OK; | 1593 return OK; |
1565 } | 1594 } |
1566 | 1595 |
1567 int SSLClientSocketNSS::DoGetOBCertComplete(int result) { | 1596 int SSLClientSocketNSS::DoGetOBCertComplete(int result) { |
1568 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, | 1597 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, |
1569 result); | 1598 result); |
1570 client_auth_cert_needed_ = false; | 1599 client_auth_cert_needed_ = false; |
1571 ob_cert_request_handle_ = NULL; | 1600 ob_cert_request_handle_ = NULL; |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) { | 2135 bool SSLClientSocketNSS::OriginBoundCertNegotiated(PRFileDesc* socket) { |
2107 PRBool xtn_negotiated = PR_FALSE; | 2136 PRBool xtn_negotiated = PR_FALSE; |
2108 SECStatus rv = SSL_HandshakeNegotiatedExtension( | 2137 SECStatus rv = SSL_HandshakeNegotiatedExtension( |
2109 socket, ssl_ob_cert_xtn, &xtn_negotiated); | 2138 socket, ssl_ob_cert_xtn, &xtn_negotiated); |
2110 DCHECK_EQ(SECSuccess, rv); | 2139 DCHECK_EQ(SECSuccess, rv); |
2111 | 2140 |
2112 return xtn_negotiated ? true : false; | 2141 return xtn_negotiated ? true : false; |
2113 } | 2142 } |
2114 | 2143 |
2115 SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler( | 2144 SECStatus SSLClientSocketNSS::OriginBoundClientAuthHandler( |
| 2145 const std::vector<uint8>& requested_cert_types, |
2116 CERTCertificate** result_certificate, | 2146 CERTCertificate** result_certificate, |
2117 SECKEYPrivateKey** result_private_key) { | 2147 SECKEYPrivateKey** result_private_key) { |
2118 ob_cert_xtn_negotiated_ = true; | 2148 ob_cert_xtn_negotiated_ = true; |
2119 | 2149 |
2120 // We have negotiated the origin-bound certificate extension. | 2150 // We have negotiated the origin-bound certificate extension. |
2121 std::string origin = "https://" + host_and_port_.ToString(); | 2151 std::string origin = "https://" + host_and_port_.ToString(); |
2122 net_log_.BeginEvent(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, NULL); | 2152 net_log_.BeginEvent(NetLog::TYPE_SSL_GET_ORIGIN_BOUND_CERT, NULL); |
2123 int error = origin_bound_cert_service_->GetOriginBoundCert( | 2153 int error = origin_bound_cert_service_->GetOriginBoundCert( |
2124 origin, | 2154 origin, |
| 2155 requested_cert_types, |
| 2156 &ob_cert_type_, |
2125 &ob_private_key_, | 2157 &ob_private_key_, |
2126 &ob_cert_, | 2158 &ob_cert_, |
2127 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, | 2159 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, |
2128 base::Unretained(this)), | 2160 base::Unretained(this)), |
2129 &ob_cert_request_handle_); | 2161 &ob_cert_request_handle_); |
2130 | 2162 |
2131 if (error == ERR_IO_PENDING) { | 2163 if (error == ERR_IO_PENDING) { |
2132 // Asynchronous case. | 2164 // Asynchronous case. |
2133 client_auth_cert_needed_ = true; | 2165 client_auth_cert_needed_ = true; |
2134 return SECWouldBlock; | 2166 return SECWouldBlock; |
(...skipping 29 matching lines...) Expand all Loading... |
2164 CERTCertList** result_certs, | 2196 CERTCertList** result_certs, |
2165 void** result_private_key, | 2197 void** result_private_key, |
2166 CERTCertificate** result_nss_certificate, | 2198 CERTCertificate** result_nss_certificate, |
2167 SECKEYPrivateKey** result_nss_private_key) { | 2199 SECKEYPrivateKey** result_nss_private_key) { |
2168 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2200 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
2169 | 2201 |
2170 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); | 2202 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); |
2171 | 2203 |
2172 // Check if an origin-bound certificate is requested. | 2204 // Check if an origin-bound certificate is requested. |
2173 if (OriginBoundCertNegotiated(socket)) { | 2205 if (OriginBoundCertNegotiated(socket)) { |
| 2206 // TODO(mattm): Once NSS supports it, pass the actual requested types. |
| 2207 std::vector<uint8> requested_cert_types; |
| 2208 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 2209 requested_cert_types.push_back(CLIENT_CERT_RSA_SIGN); |
2174 return that->OriginBoundClientAuthHandler( | 2210 return that->OriginBoundClientAuthHandler( |
2175 result_nss_certificate, result_nss_private_key); | 2211 requested_cert_types, result_nss_certificate, result_nss_private_key); |
2176 } | 2212 } |
2177 | 2213 |
2178 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 2214 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
2179 #if defined(OS_WIN) | 2215 #if defined(OS_WIN) |
2180 if (that->ssl_config_.send_client_cert) { | 2216 if (that->ssl_config_.send_client_cert) { |
2181 if (that->ssl_config_.client_cert) { | 2217 if (that->ssl_config_.client_cert) { |
2182 PCCERT_CONTEXT cert_context = | 2218 PCCERT_CONTEXT cert_context = |
2183 that->ssl_config_.client_cert->os_cert_handle(); | 2219 that->ssl_config_.client_cert->os_cert_handle(); |
2184 | 2220 |
2185 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; | 2221 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2469 PRFileDesc* socket, | 2505 PRFileDesc* socket, |
2470 CERTDistNames* ca_names, | 2506 CERTDistNames* ca_names, |
2471 CERTCertificate** result_certificate, | 2507 CERTCertificate** result_certificate, |
2472 SECKEYPrivateKey** result_private_key) { | 2508 SECKEYPrivateKey** result_private_key) { |
2473 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2509 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
2474 | 2510 |
2475 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); | 2511 that->net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED, NULL); |
2476 | 2512 |
2477 // Check if an origin-bound certificate is requested. | 2513 // Check if an origin-bound certificate is requested. |
2478 if (OriginBoundCertNegotiated(socket)) { | 2514 if (OriginBoundCertNegotiated(socket)) { |
| 2515 // TODO(mattm): Once NSS supports it, pass the actual requested types. |
| 2516 std::vector<uint8> requested_cert_types; |
| 2517 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 2518 requested_cert_types.push_back(CLIENT_CERT_RSA_SIGN); |
2479 return that->OriginBoundClientAuthHandler( | 2519 return that->OriginBoundClientAuthHandler( |
2480 result_certificate, result_private_key); | 2520 requested_cert_types, result_certificate, result_private_key); |
2481 } | 2521 } |
2482 | 2522 |
2483 // Regular client certificate requested. | 2523 // Regular client certificate requested. |
2484 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 2524 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
2485 void* wincx = SSL_RevealPinArg(socket); | 2525 void* wincx = SSL_RevealPinArg(socket); |
2486 | 2526 |
2487 // Second pass: a client certificate should have been selected. | 2527 // Second pass: a client certificate should have been selected. |
2488 if (that->ssl_config_.send_client_cert) { | 2528 if (that->ssl_config_.send_client_cert) { |
2489 if (that->ssl_config_.client_cert) { | 2529 if (that->ssl_config_.client_cert) { |
2490 CERTCertificate* cert = CERT_DupCertificate( | 2530 CERTCertificate* cert = CERT_DupCertificate( |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2656 valid_thread_id_ = base::PlatformThread::CurrentId(); |
2617 } | 2657 } |
2618 | 2658 |
2619 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2659 bool SSLClientSocketNSS::CalledOnValidThread() const { |
2620 EnsureThreadIdAssigned(); | 2660 EnsureThreadIdAssigned(); |
2621 base::AutoLock auto_lock(lock_); | 2661 base::AutoLock auto_lock(lock_); |
2622 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2662 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2623 } | 2663 } |
2624 | 2664 |
2625 } // namespace net | 2665 } // namespace net |
OLD | NEW |