Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 414 if (verifier.rrtype() != kDNS_CAA) | 414 if (verifier.rrtype() != kDNS_CAA) |
| 415 return DNSVR_CONTINUE; | 415 return DNSVR_CONTINUE; |
| 416 | 416 |
| 417 DNSValidationResult r = VerifyCAARecords( | 417 DNSValidationResult r = VerifyCAARecords( |
| 418 server_cert_nss, verifier.rrdatas(), port); | 418 server_cert_nss, verifier.rrdatas(), port); |
| 419 SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE); | 419 SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE); |
| 420 | 420 |
| 421 return r; | 421 return r; |
| 422 } | 422 } |
| 423 | 423 |
| 424 // Client-side error mapping functions. | |
| 425 | |
| 426 // Map NSS error code to network error code. | |
| 427 int MapNSSClientError(PRErrorCode err) { | |
| 428 switch (err) { | |
| 429 case SSL_ERROR_BAD_CERT_ALERT: | |
| 430 case SSL_ERROR_UNSUPPORTED_CERT_ALERT: | |
| 431 case SSL_ERROR_REVOKED_CERT_ALERT: | |
| 432 case SSL_ERROR_EXPIRED_CERT_ALERT: | |
| 433 case SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT: | |
| 434 case SSL_ERROR_UNKNOWN_CA_ALERT: | |
| 435 case SSL_ERROR_ACCESS_DENIED_ALERT: | |
| 436 return ERR_BAD_SSL_CLIENT_AUTH_CERT; | |
| 437 default: | |
| 438 return MapNSSError(err); | |
| 439 } | |
| 440 } | |
| 441 | |
| 442 // Map NSS error code from the first SSL handshake to network error code. | |
| 443 int MapNSSClientHandshakeError(PRErrorCode err) { | |
| 444 switch (err) { | |
| 445 // If the server closed on us, it is a protocol error. | |
| 446 // Some TLS-intolerant servers do this when we request TLS. | |
| 447 case PR_END_OF_FILE_ERROR: | |
| 448 return ERR_SSL_PROTOCOL_ERROR; | |
| 449 default: | |
| 450 return MapNSSClientError(err); | |
| 451 } | |
| 452 } | |
| 453 | |
| 424 } // namespace | 454 } // namespace |
| 425 | 455 |
| 426 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, | 456 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, |
| 427 const HostPortPair& host_and_port, | 457 const HostPortPair& host_and_port, |
| 428 const SSLConfig& ssl_config, | 458 const SSLConfig& ssl_config, |
| 429 SSLHostInfo* ssl_host_info, | 459 SSLHostInfo* ssl_host_info, |
| 430 const SSLClientSocketContext& context) | 460 const SSLClientSocketContext& context) |
| 431 : transport_send_busy_(false), | 461 : transport_send_busy_(false), |
| 432 transport_recv_busy_(false), | 462 transport_recv_busy_(false), |
| 433 transport_recv_eof_(false), | 463 transport_recv_eof_(false), |
| (...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1553 if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( | 1583 if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
| 1554 ServerBoundCertService::kEPKIPassword, | 1584 ServerBoundCertService::kEPKIPassword, |
| 1555 reinterpret_cast<const unsigned char*>( | 1585 reinterpret_cast<const unsigned char*>( |
| 1556 domain_bound_private_key_.data()), | 1586 domain_bound_private_key_.data()), |
| 1557 domain_bound_private_key_.size(), | 1587 domain_bound_private_key_.size(), |
| 1558 &(*cert)->subjectPublicKeyInfo, | 1588 &(*cert)->subjectPublicKeyInfo, |
| 1559 false, | 1589 false, |
| 1560 false, | 1590 false, |
| 1561 key, | 1591 key, |
| 1562 &public_key)) { | 1592 &public_key)) { |
| 1593 int error = MapNSSError(PORT_GetError()); | |
|
wtc
2012/05/29 23:41:00
Get the NSS error code first, otherwise it could b
| |
| 1563 CERT_DestroyCertificate(*cert); | 1594 CERT_DestroyCertificate(*cert); |
| 1564 *cert = NULL; | 1595 *cert = NULL; |
| 1565 return MapNSSError(PORT_GetError()); | 1596 return error; |
| 1566 } | 1597 } |
| 1567 SECKEY_DestroyPublicKey(public_key); | 1598 SECKEY_DestroyPublicKey(public_key); |
| 1568 break; | 1599 break; |
| 1569 } | 1600 } |
| 1570 | 1601 |
| 1571 default: | 1602 default: |
| 1572 NOTREACHED(); | 1603 NOTREACHED(); |
| 1573 return ERR_INVALID_ARGUMENT; | 1604 return ERR_INVALID_ARGUMENT; |
| 1574 } | 1605 } |
| 1575 | 1606 |
| 1576 return OK; | 1607 return OK; |
| 1577 } | 1608 } |
| 1578 | 1609 |
| 1579 int SSLClientSocketNSS::DoGetDBCertComplete(int result) { | 1610 int SSLClientSocketNSS::DoGetDBCertComplete(int result) { |
| 1580 SECStatus rv; | 1611 SECStatus rv; |
| 1581 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, | 1612 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, |
| 1582 result); | 1613 result); |
| 1583 client_auth_cert_needed_ = false; | 1614 client_auth_cert_needed_ = false; |
| 1584 domain_bound_cert_request_handle_ = NULL; | 1615 domain_bound_cert_request_handle_ = NULL; |
| 1585 | 1616 |
| 1586 if (result != OK) { | 1617 if (result != OK) { |
| 1587 // Failed to get a DBC. Proceed without. | 1618 // Failed to get a DBC. Proceed without. |
| 1588 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, NULL, NULL, NULL); | 1619 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, NULL, NULL, NULL); |
| 1589 if (rv != SECSuccess) | 1620 if (rv != SECSuccess) |
| 1590 return MapNSSError(PORT_GetError()); | 1621 return HandleNSSError(PORT_GetError(), true); |
| 1591 GotoState(STATE_HANDSHAKE); | 1622 GotoState(STATE_HANDSHAKE); |
| 1592 return OK; | 1623 return OK; |
| 1593 } | 1624 } |
| 1594 | 1625 |
| 1595 CERTCertificate* cert; | 1626 CERTCertificate* cert; |
| 1596 SECKEYPrivateKey* key; | 1627 SECKEYPrivateKey* key; |
| 1597 int error = ImportDBCertAndKey(&cert, &key); | 1628 int error = ImportDBCertAndKey(&cert, &key); |
| 1598 if (error != OK) | 1629 if (error != OK) |
| 1599 return error; | 1630 return error; |
| 1600 | 1631 |
| 1601 CERTCertificateList* cert_chain = CERT_CertChainFromCert(cert, | 1632 CERTCertificateList* cert_chain = CERT_CertChainFromCert(cert, |
| 1602 certUsageSSLClient, | 1633 certUsageSSLClient, |
| 1603 PR_FALSE); | 1634 PR_FALSE); |
| 1604 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED, | 1635 net_log_.AddEvent(NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED, |
| 1605 make_scoped_refptr(new NetLogIntegerParameter("cert_count", | 1636 make_scoped_refptr(new NetLogIntegerParameter("cert_count", |
| 1606 cert_chain->len))); | 1637 cert_chain->len))); |
| 1607 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); | 1638 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); |
| 1608 if (rv != SECSuccess) | 1639 if (rv != SECSuccess) |
| 1609 return MapNSSError(PORT_GetError()); | 1640 return HandleNSSError(PORT_GetError(), true); |
| 1610 | 1641 |
| 1611 GotoState(STATE_HANDSHAKE); | 1642 GotoState(STATE_HANDSHAKE); |
| 1612 set_domain_bound_cert_type(domain_bound_cert_type_); | 1643 set_domain_bound_cert_type(domain_bound_cert_type_); |
| 1613 return OK; | 1644 return OK; |
| 1614 } | 1645 } |
| 1615 | 1646 |
| 1616 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { | 1647 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { |
| 1617 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), | 1648 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), |
| 1618 server_cert_nss_, | 1649 server_cert_nss_, |
| 1619 host_and_port_.port()); | 1650 host_and_port_.port()); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2011 } | 2042 } |
| 2012 recv_buffer_ = NULL; | 2043 recv_buffer_ = NULL; |
| 2013 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); | 2044 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); |
| 2014 transport_recv_busy_ = false; | 2045 transport_recv_busy_ = false; |
| 2015 OnRecvComplete(result); | 2046 OnRecvComplete(result); |
| 2016 LeaveFunction(""); | 2047 LeaveFunction(""); |
| 2017 } | 2048 } |
| 2018 | 2049 |
| 2019 int SSLClientSocketNSS::HandleNSSError(PRErrorCode nss_error, | 2050 int SSLClientSocketNSS::HandleNSSError(PRErrorCode nss_error, |
| 2020 bool handshake_error) { | 2051 bool handshake_error) { |
| 2021 int net_error = handshake_error ? MapNSSHandshakeError(nss_error) : | 2052 int net_error = handshake_error ? MapNSSClientHandshakeError(nss_error) : |
| 2022 MapNSSError(nss_error); | 2053 MapNSSClientError(nss_error); |
| 2023 | 2054 |
| 2024 #if defined(OS_WIN) | 2055 #if defined(OS_WIN) |
| 2025 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate | 2056 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate |
| 2026 // os_cert_handle() as an optimization. However, if the certificate | 2057 // os_cert_handle() as an optimization. However, if the certificate |
| 2027 // private key is stored on a smart card, and the smart card is removed, | 2058 // private key is stored on a smart card, and the smart card is removed, |
| 2028 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, | 2059 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, |
| 2029 // preventing client certificate authentication. Because the | 2060 // preventing client certificate authentication. Because the |
| 2030 // X509Certificate may outlive the individual SSLClientSocketNSS, due to | 2061 // X509Certificate may outlive the individual SSLClientSocketNSS, due to |
| 2031 // caching in X509Certificate, this failure ends up preventing client | 2062 // caching in X509Certificate, this failure ends up preventing client |
| 2032 // certificate authentication with the same certificate for all future | 2063 // certificate authentication with the same certificate for all future |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2639 EnsureThreadIdAssigned(); | 2670 EnsureThreadIdAssigned(); |
| 2640 base::AutoLock auto_lock(lock_); | 2671 base::AutoLock auto_lock(lock_); |
| 2641 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2672 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 2642 } | 2673 } |
| 2643 | 2674 |
| 2644 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 2675 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
| 2645 return server_bound_cert_service_; | 2676 return server_bound_cert_service_; |
| 2646 } | 2677 } |
| 2647 | 2678 |
| 2648 } // namespace net | 2679 } // namespace net |
| OLD | NEW |