Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 795006: When using SSLClientSocketNSS on Windows, fall back on SSLClientSocketWin... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Log an error message if we can't open the MY system certificate store. Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | net/socket/ssl_client_socket_nss_factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 DCHECK(!user_read_callback_); 533 DCHECK(!user_read_callback_);
534 DCHECK(!user_connect_callback_); 534 DCHECK(!user_connect_callback_);
535 DCHECK(!user_read_buf_); 535 DCHECK(!user_read_buf_);
536 DCHECK(nss_bufs_); 536 DCHECK(nss_bufs_);
537 537
538 user_read_buf_ = buf; 538 user_read_buf_ = buf;
539 user_read_buf_len_ = buf_len; 539 user_read_buf_len_ = buf_len;
540 540
541 int rv = DoReadLoop(OK); 541 int rv = DoReadLoop(OK);
542 542
543 if (rv == ERR_IO_PENDING) 543 if (rv == ERR_IO_PENDING) {
544 user_read_callback_ = callback; 544 user_read_callback_ = callback;
545 else { 545 } else {
546 user_read_buf_ = NULL; 546 user_read_buf_ = NULL;
547 user_read_buf_len_ = 0; 547 user_read_buf_len_ = 0;
548 } 548 }
549 LeaveFunction(rv); 549 LeaveFunction(rv);
550 return rv; 550 return rv;
551 } 551 }
552 552
553 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, 553 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
554 CompletionCallback* callback) { 554 CompletionCallback* callback) {
555 EnterFunction(buf_len); 555 EnterFunction(buf_len);
556 DCHECK(completed_handshake_); 556 DCHECK(completed_handshake_);
557 DCHECK(next_handshake_state_ == STATE_NONE); 557 DCHECK(next_handshake_state_ == STATE_NONE);
558 DCHECK(!user_write_callback_); 558 DCHECK(!user_write_callback_);
559 DCHECK(!user_connect_callback_); 559 DCHECK(!user_connect_callback_);
560 DCHECK(!user_write_buf_); 560 DCHECK(!user_write_buf_);
561 DCHECK(nss_bufs_); 561 DCHECK(nss_bufs_);
562 562
563 user_write_buf_ = buf; 563 user_write_buf_ = buf;
564 user_write_buf_len_ = buf_len; 564 user_write_buf_len_ = buf_len;
565 565
566 int rv = DoWriteLoop(OK); 566 int rv = DoWriteLoop(OK);
567 567
568 if (rv == ERR_IO_PENDING) 568 if (rv == ERR_IO_PENDING) {
569 user_write_callback_ = callback; 569 user_write_callback_ = callback;
570 else { 570 } else {
571 user_write_buf_ = NULL; 571 user_write_buf_ = NULL;
572 user_write_buf_len_ = 0; 572 user_write_buf_len_ = 0;
573 } 573 }
574 LeaveFunction(rv); 574 LeaveFunction(rv);
575 return rv; 575 return rv;
576 } 576 }
577 577
578 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { 578 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
579 return transport_->SetReceiveBufferSize(size); 579 return transport_->SetReceiveBufferSize(size);
580 } 580 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 ssl_info->cert_status = server_cert_verify_result_.cert_status; 691 ssl_info->cert_status = server_cert_verify_result_.cert_status;
692 DCHECK(server_cert_ != NULL); 692 DCHECK(server_cert_ != NULL);
693 ssl_info->cert = server_cert_; 693 ssl_info->cert = server_cert_;
694 694
695 LeaveFunction(""); 695 LeaveFunction("");
696 } 696 }
697 697
698 void SSLClientSocketNSS::GetSSLCertRequestInfo( 698 void SSLClientSocketNSS::GetSSLCertRequestInfo(
699 SSLCertRequestInfo* cert_request_info) { 699 SSLCertRequestInfo* cert_request_info) {
700 EnterFunction(""); 700 EnterFunction("");
701 cert_request_info->host_and_port = hostname_; 701 cert_request_info->host_and_port = hostname_; // TODO(wtc): no port!
702 cert_request_info->client_certs = client_certs_; 702 cert_request_info->client_certs = client_certs_;
703 LeaveFunction(cert_request_info->client_certs.size()); 703 LeaveFunction(cert_request_info->client_certs.size());
704 } 704 }
705 705
706 SSLClientSocket::NextProtoStatus 706 SSLClientSocket::NextProtoStatus
707 SSLClientSocketNSS::GetNextProto(std::string* proto) { 707 SSLClientSocketNSS::GetNextProto(std::string* proto) {
708 #if defined(SSL_NEXT_PROTO_NEGOTIATED) 708 #if defined(SSL_NEXT_PROTO_NEGOTIATED)
709 unsigned char buf[255]; 709 unsigned char buf[255];
710 int state; 710 int state;
711 unsigned len; 711 unsigned len;
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 1087
1088 // static 1088 // static
1089 // NSS calls this if a client certificate is needed. 1089 // NSS calls this if a client certificate is needed.
1090 // Based on Mozilla's NSS_GetClientAuthData. 1090 // Based on Mozilla's NSS_GetClientAuthData.
1091 SECStatus SSLClientSocketNSS::ClientAuthHandler( 1091 SECStatus SSLClientSocketNSS::ClientAuthHandler(
1092 void* arg, 1092 void* arg,
1093 PRFileDesc* socket, 1093 PRFileDesc* socket,
1094 CERTDistNames* ca_names, 1094 CERTDistNames* ca_names,
1095 CERTCertificate** result_certificate, 1095 CERTCertificate** result_certificate,
1096 SECKEYPrivateKey** result_private_key) { 1096 SECKEYPrivateKey** result_private_key) {
1097 #if defined(OS_WIN)
1098 // Not implemented. Send no client certificate.
1099 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1100 return SECFailure;
1101 #else
1102 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); 1097 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1103 1098
1104 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; 1099 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
1105 1100
1101 #if defined(OS_WIN)
1102 if (that->ssl_config_.send_client_cert) {
1103 // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using
1104 // CryptoAPI yet (http://crbug.com/37560), so client_cert must be NULL.
1105 DCHECK(!that->ssl_config_.client_cert);
1106 // Send no client certificate.
1107 return SECFailure;
1108 }
1109
1110 that->client_certs_.clear();
1111
1112 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
1113 for (int i = 0; i < ca_names->nnames; ++i) {
1114 issuer_list[i].cbData = ca_names->names[i].len;
1115 issuer_list[i].pbData = ca_names->names[i].data;
1116 }
1117
1118 // Client certificates of the user are in the "MY" system certificate store.
1119 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
1120 if (!my_cert_store) {
1121 LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
1122 << GetLastError();
1123 return SECFailure;
1124 }
1125
1126 // Enumerate the client certificates.
1127 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
1128 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
1129 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
1130 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
1131 find_by_issuer_para.cIssuer = ca_names->nnames;
1132 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
1133
1134 PCCERT_CHAIN_CONTEXT chain_context = NULL;
1135
1136 for (;;) {
1137 // Find a certificate chain.
1138 chain_context = CertFindChainInStore(my_cert_store,
1139 X509_ASN_ENCODING,
1140 0,
1141 CERT_CHAIN_FIND_BY_ISSUER,
1142 &find_by_issuer_para,
1143 chain_context);
1144 if (!chain_context) {
1145 DWORD err = GetLastError();
1146 if (err != CRYPT_E_NOT_FOUND)
1147 DLOG(ERROR) << "CertFindChainInStore failed: " << err;
1148 break;
1149 }
1150
1151 // Get the leaf certificate.
1152 PCCERT_CONTEXT cert_context =
1153 chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
1154 // Copy it to our own certificate store, so that we can close the "MY"
1155 // certificate store before returning from this function.
1156 PCCERT_CONTEXT cert_context2;
1157 BOOL ok = CertAddCertificateContextToStore(cert_store_, cert_context,
1158 CERT_STORE_ADD_USE_EXISTING,
1159 &cert_context2);
1160 if (!ok) {
1161 NOTREACHED();
1162 continue;
1163 }
1164 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1165 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
1166 net::X509Certificate::OSCertHandles());
1167 that->client_certs_.push_back(cert);
1168 }
1169
1170 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
1171 DCHECK(ok);
1172
1173 // Tell NSS to suspend the client authentication. We will then abort the
1174 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1175 return SECWouldBlock;
1176 #else
1106 CERTCertificate* cert = NULL; 1177 CERTCertificate* cert = NULL;
1107 SECKEYPrivateKey* privkey = NULL; 1178 SECKEYPrivateKey* privkey = NULL;
1108 void* wincx = SSL_RevealPinArg(socket); 1179 void* wincx = SSL_RevealPinArg(socket);
1109 1180
1110 // Second pass: a client certificate should have been selected. 1181 // Second pass: a client certificate should have been selected.
1111 if (that->ssl_config_.send_client_cert) { 1182 if (that->ssl_config_.send_client_cert) {
1112 if (that->ssl_config_.client_cert) { 1183 if (that->ssl_config_.client_cert) {
1113 cert = CERT_DupCertificate( 1184 cert = CERT_DupCertificate(
1114 that->ssl_config_.client_cert->os_cert_handle()); 1185 that->ssl_config_.client_cert->os_cert_handle());
1115 privkey = PK11_FindKeyByAnyCert(cert, wincx); 1186 privkey = PK11_FindKeyByAnyCert(cert, wincx);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 // session with a bad cert. 1368 // session with a bad cert.
1298 InvalidateSessionIfBadCertificate(); 1369 InvalidateSessionIfBadCertificate();
1299 // Exit DoHandshakeLoop and return the result to the caller to Connect. 1370 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1300 DCHECK(next_handshake_state_ == STATE_NONE); 1371 DCHECK(next_handshake_state_ == STATE_NONE);
1301 return result; 1372 return result;
1302 } 1373 }
1303 1374
1304 int SSLClientSocketNSS::DoPayloadRead() { 1375 int SSLClientSocketNSS::DoPayloadRead() {
1305 EnterFunction(user_read_buf_len_); 1376 EnterFunction(user_read_buf_len_);
1306 DCHECK(user_read_buf_); 1377 DCHECK(user_read_buf_);
1307 DCHECK(user_read_buf_len_ > 0); 1378 DCHECK_GT(user_read_buf_len_, 0);
1308 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 1379 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
1309 if (client_auth_cert_needed_) { 1380 if (client_auth_cert_needed_) {
1310 // We don't need to invalidate the non-client-authenticated SSL session 1381 // We don't need to invalidate the non-client-authenticated SSL session
1311 // because the server will renegotiate anyway. 1382 // because the server will renegotiate anyway.
1312 LeaveFunction(""); 1383 LeaveFunction("");
1313 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1384 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1314 } 1385 }
1315 if (rv >= 0) { 1386 if (rv >= 0) {
1316 LogData(user_read_buf_->data(), rv); 1387 LogData(user_read_buf_->data(), rv);
1317 LeaveFunction(""); 1388 LeaveFunction("");
(...skipping 19 matching lines...) Expand all
1337 } 1408 }
1338 PRErrorCode prerr = PR_GetError(); 1409 PRErrorCode prerr = PR_GetError();
1339 if (prerr == PR_WOULD_BLOCK_ERROR) { 1410 if (prerr == PR_WOULD_BLOCK_ERROR) {
1340 return ERR_IO_PENDING; 1411 return ERR_IO_PENDING;
1341 } 1412 }
1342 LeaveFunction(""); 1413 LeaveFunction("");
1343 return MapNSPRError(prerr); 1414 return MapNSPRError(prerr);
1344 } 1415 }
1345 1416
1346 } // namespace net 1417 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | net/socket/ssl_client_socket_nss_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698