| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 #endif | 313 #endif |
| 314 | 314 |
| 315 } // namespace | 315 } // namespace |
| 316 | 316 |
| 317 #if defined(OS_WIN) | 317 #if defined(OS_WIN) |
| 318 // static | 318 // static |
| 319 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL; | 319 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL; |
| 320 #endif | 320 #endif |
| 321 | 321 |
| 322 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, | 322 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, |
| 323 const std::string& hostname, | 323 const HostPortPair& host_port_pair, |
| 324 const SSLConfig& ssl_config) | 324 const SSLConfig& ssl_config) |
| 325 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( | 325 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( |
| 326 this, &SSLClientSocketNSS::BufferSendComplete)), | 326 this, &SSLClientSocketNSS::BufferSendComplete)), |
| 327 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( | 327 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( |
| 328 this, &SSLClientSocketNSS::BufferRecvComplete)), | 328 this, &SSLClientSocketNSS::BufferRecvComplete)), |
| 329 transport_send_busy_(false), | 329 transport_send_busy_(false), |
| 330 transport_recv_busy_(false), | 330 transport_recv_busy_(false), |
| 331 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( | 331 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( |
| 332 this, &SSLClientSocketNSS::OnHandshakeIOComplete)), | 332 this, &SSLClientSocketNSS::OnHandshakeIOComplete)), |
| 333 transport_(transport_socket), | 333 transport_(transport_socket), |
| 334 hostname_(hostname), | 334 host_port_pair_(host_port_pair), |
| 335 ssl_config_(ssl_config), | 335 ssl_config_(ssl_config), |
| 336 user_connect_callback_(NULL), | 336 user_connect_callback_(NULL), |
| 337 user_read_callback_(NULL), | 337 user_read_callback_(NULL), |
| 338 user_write_callback_(NULL), | 338 user_write_callback_(NULL), |
| 339 user_read_buf_len_(0), | 339 user_read_buf_len_(0), |
| 340 user_write_buf_len_(0), | 340 user_write_buf_len_(0), |
| 341 server_cert_nss_(NULL), | 341 server_cert_nss_(NULL), |
| 342 client_auth_cert_needed_(false), | 342 client_auth_cert_needed_(false), |
| 343 handshake_callback_called_(false), | 343 handshake_callback_called_(false), |
| 344 completed_handshake_(false), | 344 completed_handshake_(false), |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 LOG(INFO) << "SSL_ENABLE_DEFLATE failed. Old system nss?"; | 497 LOG(INFO) << "SSL_ENABLE_DEFLATE failed. Old system nss?"; |
| 498 #endif | 498 #endif |
| 499 | 499 |
| 500 #ifdef SSL_ENABLE_FALSE_START | 500 #ifdef SSL_ENABLE_FALSE_START |
| 501 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, PR_TRUE); | 501 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, PR_TRUE); |
| 502 if (rv != SECSuccess) | 502 if (rv != SECSuccess) |
| 503 LOG(INFO) << "SSL_ENABLE_FALSE_START failed. Old system nss?"; | 503 LOG(INFO) << "SSL_ENABLE_FALSE_START failed. Old system nss?"; |
| 504 #endif | 504 #endif |
| 505 | 505 |
| 506 #ifdef SSL_ENABLE_RENEGOTIATION | 506 #ifdef SSL_ENABLE_RENEGOTIATION |
| 507 if (SSLConfigService::IsKnownStrictTLSServer(hostname_)) { | 507 if (SSLConfigService::IsKnownStrictTLSServer(host_port_pair_.host())) { |
| 508 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); | 508 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); |
| 509 if (rv != SECSuccess) | 509 if (rv != SECSuccess) |
| 510 LOG(INFO) << "SSL_REQUIRE_SAFE_NEGOTIATION failed."; | 510 LOG(INFO) << "SSL_REQUIRE_SAFE_NEGOTIATION failed."; |
| 511 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, | 511 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
| 512 SSL_RENEGOTIATE_REQUIRES_XTN); | 512 SSL_RENEGOTIATE_REQUIRES_XTN); |
| 513 } else { | 513 } else { |
| 514 // We allow servers to request renegotiation. Since we're a client, | 514 // We allow servers to request renegotiation. Since we're a client, |
| 515 // prohibiting this is rather a waste of time. Only servers are in a | 515 // prohibiting this is rather a waste of time. Only servers are in a |
| 516 // position to prevent renegotiation attacks. | 516 // position to prevent renegotiation attacks. |
| 517 // http://extendedsubset.com/?p=8 | 517 // http://extendedsubset.com/?p=8 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 544 | 544 |
| 545 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this); | 545 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this); |
| 546 if (rv != SECSuccess) | 546 if (rv != SECSuccess) |
| 547 return ERR_UNEXPECTED; | 547 return ERR_UNEXPECTED; |
| 548 | 548 |
| 549 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); | 549 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); |
| 550 if (rv != SECSuccess) | 550 if (rv != SECSuccess) |
| 551 return ERR_UNEXPECTED; | 551 return ERR_UNEXPECTED; |
| 552 | 552 |
| 553 // Tell SSL the hostname we're trying to connect to. | 553 // Tell SSL the hostname we're trying to connect to. |
| 554 SSL_SetURL(nss_fd_, hostname_.c_str()); | 554 SSL_SetURL(nss_fd_, host_port_pair_.host().c_str()); |
| 555 | 555 |
| 556 // Set the peer ID for session reuse. This is necessary when we create an | 556 // Set the peer ID for session reuse. This is necessary when we create an |
| 557 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address | 557 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address |
| 558 // rather than the destination server's address in that case. | 558 // rather than the destination server's address in that case. |
| 559 // TODO(wtc): port in |peer_address| is not the server's port when a proxy is | 559 std::string peer_id = host_port_pair_.ToString(); |
| 560 // used. | |
| 561 std::string peer_id = StringPrintf("%s:%d", hostname_.c_str(), | |
| 562 peer_address.GetPort()); | |
| 563 rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); | 560 rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); |
| 564 if (rv != SECSuccess) | 561 if (rv != SECSuccess) |
| 565 LOG(INFO) << "SSL_SetSockPeerID failed: peer_id=" << peer_id; | 562 LOG(INFO) << "SSL_SetSockPeerID failed: peer_id=" << peer_id; |
| 566 | 563 |
| 567 // Tell SSL we're a client; needed if not letting NSPR do socket I/O | 564 // Tell SSL we're a client; needed if not letting NSPR do socket I/O |
| 568 SSL_ResetHandshake(nss_fd_, 0); | 565 SSL_ResetHandshake(nss_fd_, 0); |
| 569 | 566 |
| 570 return OK; | 567 return OK; |
| 571 } | 568 } |
| 572 | 569 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 // renegotiation (RFC 5746). | 788 // renegotiation (RFC 5746). |
| 792 void SSLClientSocketNSS::CheckSecureRenegotiation() const { | 789 void SSLClientSocketNSS::CheckSecureRenegotiation() const { |
| 793 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6. | 790 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6. |
| 794 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test | 791 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test |
| 795 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension. | 792 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension. |
| 796 #if defined(SSL_MAX_EXTENSIONS) | 793 #if defined(SSL_MAX_EXTENSIONS) |
| 797 PRBool received_renego_info; | 794 PRBool received_renego_info; |
| 798 if (SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn, | 795 if (SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn, |
| 799 &received_renego_info) == SECSuccess && | 796 &received_renego_info) == SECSuccess && |
| 800 !received_renego_info) { | 797 !received_renego_info) { |
| 801 LOG(INFO) << "The server " << hostname_ | 798 LOG(INFO) << "The server " << host_port_pair_.ToString() |
| 802 << " does not support the TLS renegotiation_info extension."; | 799 << " does not support the TLS renegotiation_info extension."; |
| 803 } | 800 } |
| 804 #endif | 801 #endif |
| 805 } | 802 } |
| 806 | 803 |
| 807 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { | 804 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { |
| 808 EnterFunction(""); | 805 EnterFunction(""); |
| 809 ssl_info->Reset(); | 806 ssl_info->Reset(); |
| 810 // A temporary CHECK for tracking down http://crbug.com/49862. | 807 // A temporary CHECK for tracking down http://crbug.com/49862. |
| 811 CHECK(server_cert_); | 808 CHECK(server_cert_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 | 852 |
| 856 if (ssl_config_.ssl3_fallback) | 853 if (ssl_config_.ssl3_fallback) |
| 857 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; | 854 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; |
| 858 | 855 |
| 859 LeaveFunction(""); | 856 LeaveFunction(""); |
| 860 } | 857 } |
| 861 | 858 |
| 862 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 859 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 863 SSLCertRequestInfo* cert_request_info) { | 860 SSLCertRequestInfo* cert_request_info) { |
| 864 EnterFunction(""); | 861 EnterFunction(""); |
| 865 cert_request_info->host_and_port = hostname_; // TODO(wtc): no port! | 862 cert_request_info->host_and_port = host_port_pair_.ToString(); |
| 866 cert_request_info->client_certs = client_certs_; | 863 cert_request_info->client_certs = client_certs_; |
| 867 LeaveFunction(cert_request_info->client_certs.size()); | 864 LeaveFunction(cert_request_info->client_certs.size()); |
| 868 } | 865 } |
| 869 | 866 |
| 870 SSLClientSocket::NextProtoStatus | 867 SSLClientSocket::NextProtoStatus |
| 871 SSLClientSocketNSS::GetNextProto(std::string* proto) { | 868 SSLClientSocketNSS::GetNextProto(std::string* proto) { |
| 872 #if defined(SSL_NEXT_PROTO_NEGOTIATED) | 869 #if defined(SSL_NEXT_PROTO_NEGOTIATED) |
| 873 unsigned char buf[255]; | 870 unsigned char buf[255]; |
| 874 int state; | 871 int state; |
| 875 unsigned len; | 872 unsigned len; |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 for (int i = 0; i < n; i++) { | 1359 for (int i = 0; i < n; i++) { |
| 1363 // Parse each name into a CertPrincipal object. | 1360 // Parse each name into a CertPrincipal object. |
| 1364 CertPrincipal p; | 1361 CertPrincipal p; |
| 1365 if (p.ParseDistinguishedName(ca_names->names[i].data, | 1362 if (p.ParseDistinguishedName(ca_names->names[i].data, |
| 1366 ca_names->names[i].len)) { | 1363 ca_names->names[i].len)) { |
| 1367 valid_issuers.push_back(p); | 1364 valid_issuers.push_back(p); |
| 1368 } | 1365 } |
| 1369 } | 1366 } |
| 1370 | 1367 |
| 1371 // Now get the available client certs whose issuers are allowed by the server. | 1368 // Now get the available client certs whose issuers are allowed by the server. |
| 1372 X509Certificate::GetSSLClientCertificates(that->hostname_, | 1369 X509Certificate::GetSSLClientCertificates(that->host_port_pair_.host(), |
| 1373 valid_issuers, | 1370 valid_issuers, |
| 1374 &that->client_certs_); | 1371 &that->client_certs_); |
| 1375 | 1372 |
| 1376 // Tell NSS to suspend the client authentication. We will then abort the | 1373 // Tell NSS to suspend the client authentication. We will then abort the |
| 1377 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1374 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
| 1378 return SECWouldBlock; | 1375 return SECWouldBlock; |
| 1379 #else | 1376 #else |
| 1380 CERTCertificate* cert = NULL; | 1377 CERTCertificate* cert = NULL; |
| 1381 SECKEYPrivateKey* privkey = NULL; | 1378 SECKEYPrivateKey* privkey = NULL; |
| 1382 void* wincx = SSL_RevealPinArg(socket); | 1379 void* wincx = SSL_RevealPinArg(socket); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 int SSLClientSocketNSS::DoVerifyCert(int result) { | 1493 int SSLClientSocketNSS::DoVerifyCert(int result) { |
| 1497 DCHECK(server_cert_); | 1494 DCHECK(server_cert_); |
| 1498 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1495 GotoState(STATE_VERIFY_CERT_COMPLETE); |
| 1499 int flags = 0; | 1496 int flags = 0; |
| 1500 | 1497 |
| 1501 if (ssl_config_.rev_checking_enabled) | 1498 if (ssl_config_.rev_checking_enabled) |
| 1502 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; | 1499 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; |
| 1503 if (ssl_config_.verify_ev_cert) | 1500 if (ssl_config_.verify_ev_cert) |
| 1504 flags |= X509Certificate::VERIFY_EV_CERT; | 1501 flags |= X509Certificate::VERIFY_EV_CERT; |
| 1505 verifier_.reset(new CertVerifier); | 1502 verifier_.reset(new CertVerifier); |
| 1506 return verifier_->Verify(server_cert_, hostname_, flags, | 1503 return verifier_->Verify(server_cert_, host_port_pair_.host(), flags, |
| 1507 &server_cert_verify_result_, | 1504 &server_cert_verify_result_, |
| 1508 &handshake_io_callback_); | 1505 &handshake_io_callback_); |
| 1509 } | 1506 } |
| 1510 | 1507 |
| 1511 // Derived from AuthCertificateCallback() in | 1508 // Derived from AuthCertificateCallback() in |
| 1512 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. | 1509 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 1513 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 1510 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { |
| 1514 DCHECK(verifier_.get()); | 1511 DCHECK(verifier_.get()); |
| 1515 verifier_.reset(); | 1512 verifier_.reset(); |
| 1516 | 1513 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 PRErrorCode prerr = PR_GetError(); | 1605 PRErrorCode prerr = PR_GetError(); |
| 1609 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1606 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 1610 LeaveFunction(""); | 1607 LeaveFunction(""); |
| 1611 return ERR_IO_PENDING; | 1608 return ERR_IO_PENDING; |
| 1612 } | 1609 } |
| 1613 LeaveFunction(""); | 1610 LeaveFunction(""); |
| 1614 return MapNSPRError(prerr); | 1611 return MapNSPRError(prerr); |
| 1615 } | 1612 } |
| 1616 | 1613 |
| 1617 } // namespace net | 1614 } // namespace net |
| OLD | NEW |