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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/socket/ssl_client_socket_nss.cc
===================================================================
--- net/socket/ssl_client_socket_nss.cc (revision 41189)
+++ net/socket/ssl_client_socket_nss.cc (working copy)
@@ -540,9 +540,9 @@
int rv = DoReadLoop(OK);
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
user_read_callback_ = callback;
- else {
+ } else {
user_read_buf_ = NULL;
user_read_buf_len_ = 0;
}
@@ -565,9 +565,9 @@
int rv = DoWriteLoop(OK);
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
user_write_callback_ = callback;
- else {
+ } else {
user_write_buf_ = NULL;
user_write_buf_len_ = 0;
}
@@ -698,7 +698,7 @@
void SSLClientSocketNSS::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
EnterFunction("");
- cert_request_info->host_and_port = hostname_;
+ cert_request_info->host_and_port = hostname_; // TODO(wtc): no port!
cert_request_info->client_certs = client_certs_;
LeaveFunction(cert_request_info->client_certs.size());
}
@@ -1094,15 +1094,86 @@
CERTDistNames* ca_names,
CERTCertificate** result_certificate,
SECKEYPrivateKey** result_private_key) {
-#if defined(OS_WIN)
- // Not implemented. Send no client certificate.
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-#else
SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
+#if defined(OS_WIN)
+ if (that->ssl_config_.send_client_cert) {
+ // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using
+ // CryptoAPI yet (http://crbug.com/37560), so client_cert must be NULL.
+ DCHECK(!that->ssl_config_.client_cert);
+ // Send no client certificate.
+ return SECFailure;
+ }
+
+ that->client_certs_.clear();
+
+ std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
+ for (int i = 0; i < ca_names->nnames; ++i) {
+ issuer_list[i].cbData = ca_names->names[i].len;
+ issuer_list[i].pbData = ca_names->names[i].data;
+ }
+
+ // Client certificates of the user are in the "MY" system certificate store.
+ HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
+ if (!my_cert_store) {
+ LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
+ << GetLastError();
+ return SECFailure;
+ }
+
+ // Enumerate the client certificates.
+ CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
+ memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
+ find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
+ find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
+ find_by_issuer_para.cIssuer = ca_names->nnames;
+ find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
+
+ PCCERT_CHAIN_CONTEXT chain_context = NULL;
+
+ for (;;) {
+ // Find a certificate chain.
+ chain_context = CertFindChainInStore(my_cert_store,
+ X509_ASN_ENCODING,
+ 0,
+ CERT_CHAIN_FIND_BY_ISSUER,
+ &find_by_issuer_para,
+ chain_context);
+ if (!chain_context) {
+ DWORD err = GetLastError();
+ if (err != CRYPT_E_NOT_FOUND)
+ DLOG(ERROR) << "CertFindChainInStore failed: " << err;
+ break;
+ }
+
+ // Get the leaf certificate.
+ PCCERT_CONTEXT cert_context =
+ chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
+ // Copy it to our own certificate store, so that we can close the "MY"
+ // certificate store before returning from this function.
+ PCCERT_CONTEXT cert_context2;
+ BOOL ok = CertAddCertificateContextToStore(cert_store_, cert_context,
+ CERT_STORE_ADD_USE_EXISTING,
+ &cert_context2);
+ if (!ok) {
+ NOTREACHED();
+ continue;
+ }
+ scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
+ cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
+ net::X509Certificate::OSCertHandles());
+ that->client_certs_.push_back(cert);
+ }
+
+ BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
+ DCHECK(ok);
+
+ // Tell NSS to suspend the client authentication. We will then abort the
+ // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
+ return SECWouldBlock;
+#else
CERTCertificate* cert = NULL;
SECKEYPrivateKey* privkey = NULL;
void* wincx = SSL_RevealPinArg(socket);
@@ -1304,7 +1375,7 @@
int SSLClientSocketNSS::DoPayloadRead() {
EnterFunction(user_read_buf_len_);
DCHECK(user_read_buf_);
- DCHECK(user_read_buf_len_ > 0);
+ DCHECK_GT(user_read_buf_len_, 0);
int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
if (client_auth_cert_needed_) {
// We don't need to invalidate the non-client-authenticated SSL session
« 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