| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 GetDefaultCertNickname(), derived from | 5 // This file includes code GetDefaultCertNickname(), derived from |
| 6 // nsNSSCertificate::defaultServerNickName() | 6 // nsNSSCertificate::defaultServerNickName() |
| 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp | 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp |
| 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from | 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from |
| 9 // AuthCertificateCallback() in | 9 // AuthCertificateCallback() in |
| 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 transport_recv_busy_(false), | 202 transport_recv_busy_(false), |
| 203 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete), | 203 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete), |
| 204 transport_(transport_socket), | 204 transport_(transport_socket), |
| 205 hostname_(hostname), | 205 hostname_(hostname), |
| 206 ssl_config_(ssl_config), | 206 ssl_config_(ssl_config), |
| 207 user_connect_callback_(NULL), | 207 user_connect_callback_(NULL), |
| 208 user_read_callback_(NULL), | 208 user_read_callback_(NULL), |
| 209 user_write_callback_(NULL), | 209 user_write_callback_(NULL), |
| 210 user_read_buf_len_(0), | 210 user_read_buf_len_(0), |
| 211 user_write_buf_len_(0), | 211 user_write_buf_len_(0), |
| 212 client_auth_ca_names_(NULL), | |
| 213 client_auth_cert_needed_(false), | 212 client_auth_cert_needed_(false), |
| 214 completed_handshake_(false), | 213 completed_handshake_(false), |
| 215 next_handshake_state_(STATE_NONE), | 214 next_handshake_state_(STATE_NONE), |
| 216 nss_fd_(NULL), | 215 nss_fd_(NULL), |
| 217 nss_bufs_(NULL) { | 216 nss_bufs_(NULL) { |
| 218 EnterFunction(""); | 217 EnterFunction(""); |
| 219 } | 218 } |
| 220 | 219 |
| 221 SSLClientSocketNSS::~SSLClientSocketNSS() { | 220 SSLClientSocketNSS::~SSLClientSocketNSS() { |
| 222 EnterFunction(""); | 221 EnterFunction(""); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 user_read_callback_ = NULL; | 375 user_read_callback_ = NULL; |
| 377 user_write_callback_ = NULL; | 376 user_write_callback_ = NULL; |
| 378 user_read_buf_ = NULL; | 377 user_read_buf_ = NULL; |
| 379 user_read_buf_len_ = 0; | 378 user_read_buf_len_ = 0; |
| 380 user_write_buf_ = NULL; | 379 user_write_buf_ = NULL; |
| 381 user_write_buf_len_ = 0; | 380 user_write_buf_len_ = 0; |
| 382 server_cert_ = NULL; | 381 server_cert_ = NULL; |
| 383 server_cert_verify_result_.Reset(); | 382 server_cert_verify_result_.Reset(); |
| 384 completed_handshake_ = false; | 383 completed_handshake_ = false; |
| 385 nss_bufs_ = NULL; | 384 nss_bufs_ = NULL; |
| 386 if (client_auth_ca_names_) { | 385 client_certs_.clear(); |
| 387 CERT_FreeDistNames(client_auth_ca_names_); | |
| 388 client_auth_ca_names_ = NULL; | |
| 389 } | |
| 390 client_auth_cert_needed_ = false; | 386 client_auth_cert_needed_ = false; |
| 391 | 387 |
| 392 LeaveFunction(""); | 388 LeaveFunction(""); |
| 393 } | 389 } |
| 394 | 390 |
| 395 bool SSLClientSocketNSS::IsConnected() const { | 391 bool SSLClientSocketNSS::IsConnected() const { |
| 396 // Ideally, we should also check if we have received the close_notify alert | 392 // Ideally, we should also check if we have received the close_notify alert |
| 397 // message from the server, and return false in that case. We're not doing | 393 // message from the server, and return false in that case. We're not doing |
| 398 // that, so this function may return a false positive. Since the upper | 394 // that, so this function may return a false positive. Since the upper |
| 399 // layer (HttpNetworkTransaction) needs to handle a persistent connection | 395 // layer (HttpNetworkTransaction) needs to handle a persistent connection |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 ssl_info->cert_status = server_cert_verify_result_.cert_status; | 514 ssl_info->cert_status = server_cert_verify_result_.cert_status; |
| 519 DCHECK(server_cert_ != NULL); | 515 DCHECK(server_cert_ != NULL); |
| 520 ssl_info->cert = server_cert_; | 516 ssl_info->cert = server_cert_; |
| 521 LeaveFunction(""); | 517 LeaveFunction(""); |
| 522 } | 518 } |
| 523 | 519 |
| 524 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 520 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 525 SSLCertRequestInfo* cert_request_info) { | 521 SSLCertRequestInfo* cert_request_info) { |
| 526 EnterFunction(""); | 522 EnterFunction(""); |
| 527 cert_request_info->host_and_port = hostname_; | 523 cert_request_info->host_and_port = hostname_; |
| 528 cert_request_info->client_certs.clear(); | 524 cert_request_info->client_certs = client_certs_; |
| 529 | |
| 530 void* wincx = SSL_RevealPinArg(nss_fd_); | |
| 531 | |
| 532 CERTCertNicknames* names = CERT_GetCertNicknames( | |
| 533 CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, wincx); | |
| 534 | |
| 535 if (names) { | |
| 536 for (int i = 0; i < names->numnicknames; ++i) { | |
| 537 CERTCertificate* cert = CERT_FindUserCertByUsage( | |
| 538 CERT_GetDefaultCertDB(), names->nicknames[i], | |
| 539 certUsageSSLClient, PR_FALSE, wincx); | |
| 540 if (!cert) | |
| 541 continue; | |
| 542 // Only check unexpired certs. | |
| 543 if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) == | |
| 544 secCertTimeValid && | |
| 545 NSS_CmpCertChainWCANames(cert, client_auth_ca_names_) == | |
| 546 SECSuccess) { | |
| 547 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); | |
| 548 if (privkey) { | |
| 549 X509Certificate* x509_cert = X509Certificate::CreateFromHandle( | |
| 550 cert, X509Certificate::SOURCE_LONE_CERT_IMPORT); | |
| 551 cert_request_info->client_certs.push_back(x509_cert); | |
| 552 SECKEY_DestroyPrivateKey(privkey); | |
| 553 continue; | |
| 554 } | |
| 555 } | |
| 556 CERT_DestroyCertificate(cert); | |
| 557 } | |
| 558 CERT_FreeNicknames(names); | |
| 559 } | |
| 560 LeaveFunction(cert_request_info->client_certs.size()); | 525 LeaveFunction(cert_request_info->client_certs.size()); |
| 561 } | 526 } |
| 562 | 527 |
| 563 void SSLClientSocketNSS::DoReadCallback(int rv) { | 528 void SSLClientSocketNSS::DoReadCallback(int rv) { |
| 564 EnterFunction(rv); | 529 EnterFunction(rv); |
| 565 DCHECK(rv != ERR_IO_PENDING); | 530 DCHECK(rv != ERR_IO_PENDING); |
| 566 DCHECK(user_read_callback_); | 531 DCHECK(user_read_callback_); |
| 567 | 532 |
| 568 // Since Run may result in Read being called, clear |user_read_callback_| | 533 // Since Run may result in Read being called, clear |user_read_callback_| |
| 569 // up front. | 534 // up front. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 // static | 837 // static |
| 873 // NSS calls this if a client certificate is needed. | 838 // NSS calls this if a client certificate is needed. |
| 874 // Based on Mozilla's NSS_GetClientAuthData. | 839 // Based on Mozilla's NSS_GetClientAuthData. |
| 875 SECStatus SSLClientSocketNSS::ClientAuthHandler( | 840 SECStatus SSLClientSocketNSS::ClientAuthHandler( |
| 876 void* arg, | 841 void* arg, |
| 877 PRFileDesc* socket, | 842 PRFileDesc* socket, |
| 878 CERTDistNames* ca_names, | 843 CERTDistNames* ca_names, |
| 879 CERTCertificate** result_certificate, | 844 CERTCertificate** result_certificate, |
| 880 SECKEYPrivateKey** result_private_key) { | 845 SECKEYPrivateKey** result_private_key) { |
| 881 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 846 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 847 CERTCertificate* cert = NULL; |
| 848 X509Certificate* x509_cert = NULL; |
| 849 SECKEYPrivateKey* privkey = NULL; |
| 850 void* proto_win = NULL; |
| 851 CERTCertNicknames* names; |
| 882 | 852 |
| 883 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 853 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
| 884 | 854 |
| 885 // Second pass: a client certificate should have been selected. | 855 // Second pass: a client certificate should have been selected. |
| 886 if (that->ssl_config_.send_client_cert) { | 856 if (that->ssl_config_.send_client_cert) { |
| 887 if (that->ssl_config_.client_cert) { | 857 if (that->ssl_config_.client_cert) { |
| 888 void* wincx = SSL_RevealPinArg(socket); | 858 void* wincx = SSL_RevealPinArg(socket); |
| 889 CERTCertificate* cert = CERT_DupCertificate( | 859 CERTCertificate* cert = CERT_DupCertificate( |
| 890 that->ssl_config_.client_cert->os_cert_handle()); | 860 that->ssl_config_.client_cert->os_cert_handle()); |
| 891 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); | 861 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
| 892 if (privkey) { | 862 if (privkey) { |
| 893 // TODO(jsorianopastor): We should wait for server certificate | 863 // TODO(jsorianopastor): We should wait for server certificate |
| 894 // verification before sending our credentials. See | 864 // verification before sending our credentials. See |
| 895 // http://crbug.com/13934. | 865 // http://crbug.com/13934. |
| 896 *result_certificate = cert; | 866 *result_certificate = cert; |
| 897 *result_private_key = privkey; | 867 *result_private_key = privkey; |
| 898 return SECSuccess; | 868 return SECSuccess; |
| 899 } | 869 } |
| 900 LOG(WARNING) << "Client cert found without private key"; | 870 LOG(WARNING) << "Client cert found without private key"; |
| 901 } | 871 } |
| 902 // Send no client certificate. | 872 // Send no client certificate. |
| 903 return SECFailure; | 873 return SECFailure; |
| 904 } | 874 } |
| 875 names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), |
| 876 SEC_CERT_NICKNAMES_USER, proto_win); |
| 905 | 877 |
| 906 PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 878 if (names != NULL) { |
| 907 CERTDistNames* ca_names_copy = PORT_ArenaZNew(arena, CERTDistNames); | 879 for (int i = 0; i < names->numnicknames; i++) { |
| 880 cert = CERT_FindUserCertByUsage( |
| 881 CERT_GetDefaultCertDB(), |
| 882 names->nicknames[i], |
| 883 certUsageSSLClient, |
| 884 PR_FALSE, |
| 885 proto_win); |
| 886 if ( !cert ) |
| 887 continue; |
| 888 // Only check unexpired certs |
| 889 if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) != |
| 890 secCertTimeValid ) { |
| 891 CERT_DestroyCertificate(cert); |
| 892 continue; |
| 893 } |
| 894 if ( NSS_CmpCertChainWCANames(cert, ca_names) == SECSuccess ) { |
| 895 if ( PK11_FindKeyByAnyCert(cert, proto_win) ) { |
| 896 x509_cert = X509Certificate::CreateFromHandle( |
| 897 cert, X509Certificate::SOURCE_LONE_CERT_IMPORT); |
| 898 that->client_certs_.push_back(x509_cert); |
| 899 SECKEY_DestroyPrivateKey(privkey); |
| 900 continue; |
| 901 } |
| 902 } |
| 903 CERT_DestroyCertificate(cert); |
| 904 } |
| 905 CERT_FreeNicknames(names); |
| 906 } |
| 908 | 907 |
| 909 ca_names_copy->arena = arena; | |
| 910 ca_names_copy->head = NULL; | |
| 911 ca_names_copy->nnames = ca_names->nnames; | |
| 912 ca_names_copy->names = PORT_ArenaZNewArray(arena, SECItem, | |
| 913 ca_names->nnames); | |
| 914 for (int i = 0; i < ca_names->nnames; ++i) | |
| 915 SECITEM_CopyItem(arena, &ca_names_copy->names[i], &ca_names->names[i]); | |
| 916 | |
| 917 that->client_auth_ca_names_ = ca_names_copy; | |
| 918 return SECFailure; | 908 return SECFailure; |
| 919 } | 909 } |
| 920 | 910 |
| 921 // static | 911 // static |
| 922 // NSS calls this when handshake is completed. | 912 // NSS calls this when handshake is completed. |
| 923 // After the SSL handshake is finished, use CertVerifier to verify | 913 // After the SSL handshake is finished, use CertVerifier to verify |
| 924 // the saved server certificate. | 914 // the saved server certificate. |
| 925 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 915 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
| 926 void* arg) { | 916 void* arg) { |
| 927 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 917 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 } | 1075 } |
| 1086 PRErrorCode prerr = PR_GetError(); | 1076 PRErrorCode prerr = PR_GetError(); |
| 1087 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1077 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 1088 return ERR_IO_PENDING; | 1078 return ERR_IO_PENDING; |
| 1089 } | 1079 } |
| 1090 LeaveFunction(""); | 1080 LeaveFunction(""); |
| 1091 return NetErrorFromNSPRError(prerr); | 1081 return NetErrorFromNSPRError(prerr); |
| 1092 } | 1082 } |
| 1093 | 1083 |
| 1094 } // namespace net | 1084 } // namespace net |
| OLD | NEW |