| 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 #include "net/socket/ssl_client_socket_win.h" | 5 #include "net/socket/ssl_client_socket_win.h" |
| 6 | 6 |
| 7 #include <schnlsp.h> | 7 #include <schnlsp.h> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/lazy_instance.h" |
| 11 #include "base/lock.h" | 12 #include "base/lock.h" |
| 12 #include "base/singleton.h" | |
| 13 #include "base/stl_util-inl.h" | 13 #include "base/stl_util-inl.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "net/base/cert_verifier.h" | 16 #include "net/base/cert_verifier.h" |
| 17 #include "net/base/connection_type_histograms.h" | 17 #include "net/base/connection_type_histograms.h" |
| 18 #include "net/base/host_port_pair.h" | 18 #include "net/base/host_port_pair.h" |
| 19 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
| 20 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "net/base/ssl_cert_request_info.h" | 22 #include "net/base/ssl_cert_request_info.h" |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 Lock lock_; | 187 Lock lock_; |
| 188 | 188 |
| 189 // Anonymous (no client certificate) CredHandles for all possible | 189 // Anonymous (no client certificate) CredHandles for all possible |
| 190 // combinations of SSL versions. Defined as an array for fast lookup. | 190 // combinations of SSL versions. Defined as an array for fast lookup. |
| 191 CredHandleClass anonymous_creds_[SSL_VERSION_MASKS]; | 191 CredHandleClass anonymous_creds_[SSL_VERSION_MASKS]; |
| 192 | 192 |
| 193 // CredHandles that use a client certificate. | 193 // CredHandles that use a client certificate. |
| 194 CredHandleMap client_cert_creds_; | 194 CredHandleMap client_cert_creds_; |
| 195 }; | 195 }; |
| 196 | 196 |
| 197 static base::LazyInstance<CredHandleTable> g_cred_handle_table( |
| 198 base::LINKER_INITIALIZED); |
| 199 |
| 197 // static | 200 // static |
| 198 int CredHandleTable::InitializeHandle(CredHandle* handle, | 201 int CredHandleTable::InitializeHandle(CredHandle* handle, |
| 199 PCCERT_CONTEXT client_cert, | 202 PCCERT_CONTEXT client_cert, |
| 200 int ssl_version_mask) { | 203 int ssl_version_mask) { |
| 201 SCHANNEL_CRED schannel_cred = {0}; | 204 SCHANNEL_CRED schannel_cred = {0}; |
| 202 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; | 205 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; |
| 203 if (client_cert) { | 206 if (client_cert) { |
| 204 schannel_cred.cCreds = 1; | 207 schannel_cred.cCreds = 1; |
| 205 schannel_cred.paCred = &client_cert; | 208 schannel_cred.paCred = &client_cert; |
| 206 // Schannel will make its own copy of client_cert. | 209 // Schannel will make its own copy of client_cert. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 // TLS-intolerant servers). These CredHandles are initialized only when | 281 // TLS-intolerant servers). These CredHandles are initialized only when |
| 279 // needed. | 282 // needed. |
| 280 | 283 |
| 281 static int GetCredHandle(PCCERT_CONTEXT client_cert, | 284 static int GetCredHandle(PCCERT_CONTEXT client_cert, |
| 282 int ssl_version_mask, | 285 int ssl_version_mask, |
| 283 CredHandle** handle_ptr) { | 286 CredHandle** handle_ptr) { |
| 284 if (ssl_version_mask <= 0 || ssl_version_mask >= SSL_VERSION_MASKS) { | 287 if (ssl_version_mask <= 0 || ssl_version_mask >= SSL_VERSION_MASKS) { |
| 285 NOTREACHED(); | 288 NOTREACHED(); |
| 286 return ERR_UNEXPECTED; | 289 return ERR_UNEXPECTED; |
| 287 } | 290 } |
| 288 return Singleton<CredHandleTable>::get()->GetHandle(client_cert, | 291 return g_cred_handle_table.Get().GetHandle(client_cert, |
| 289 ssl_version_mask, | 292 ssl_version_mask, |
| 290 handle_ptr); | 293 handle_ptr); |
| 291 } | 294 } |
| 292 | 295 |
| 293 //----------------------------------------------------------------------------- | 296 //----------------------------------------------------------------------------- |
| 294 | 297 |
| 295 // This callback is intended to be used with CertFindChainInStore. In addition | 298 // This callback is intended to be used with CertFindChainInStore. In addition |
| 296 // to filtering by extended/enhanced key usage, we do not show expired | 299 // to filtering by extended/enhanced key usage, we do not show expired |
| 297 // certificates and require digital signature usage in the key usage | 300 // certificates and require digital signature usage in the key usage |
| 298 // extension. | 301 // extension. |
| 299 // | 302 // |
| 300 // This matches our behavior on Mac OS X and that of NSS. It also matches the | 303 // This matches our behavior on Mac OS X and that of NSS. It also matches the |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 CERT_STORE_ADD_USE_EXISTING, | 352 CERT_STORE_ADD_USE_EXISTING, |
| 350 ©); | 353 ©); |
| 351 DCHECK(ok); | 354 DCHECK(ok); |
| 352 return ok ? copy : NULL; | 355 return ok ? copy : NULL; |
| 353 } | 356 } |
| 354 | 357 |
| 355 private: | 358 private: |
| 356 HCERTSTORE store_; | 359 HCERTSTORE store_; |
| 357 }; | 360 }; |
| 358 | 361 |
| 362 static base::LazyInstance<ClientCertStore> g_client_cert_store( |
| 363 base::LINKER_INITIALIZED); |
| 364 |
| 359 //----------------------------------------------------------------------------- | 365 //----------------------------------------------------------------------------- |
| 360 | 366 |
| 361 // Size of recv_buffer_ | 367 // Size of recv_buffer_ |
| 362 // | 368 // |
| 363 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to | 369 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to |
| 364 // have room for a full SSL record, with the header and trailer. Here is the | 370 // have room for a full SSL record, with the header and trailer. Here is the |
| 365 // breakdown of the size: | 371 // breakdown of the size: |
| 366 // 5: SSL record header | 372 // 5: SSL record header |
| 367 // 16K: SSL record maximum size | 373 // 16K: SSL record maximum size |
| 368 // 64: >= SSL record trailer (16 or 20 have been observed) | 374 // 64: >= SSL record trailer (16 or 20 have been observed) |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 DLOG(ERROR) << "CertFindChainInStore failed: " << err; | 506 DLOG(ERROR) << "CertFindChainInStore failed: " << err; |
| 501 break; | 507 break; |
| 502 } | 508 } |
| 503 | 509 |
| 504 // Get the leaf certificate. | 510 // Get the leaf certificate. |
| 505 PCCERT_CONTEXT cert_context = | 511 PCCERT_CONTEXT cert_context = |
| 506 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; | 512 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; |
| 507 // Copy it to our own certificate store, so that we can close the "MY" | 513 // Copy it to our own certificate store, so that we can close the "MY" |
| 508 // certificate store before returning from this function. | 514 // certificate store before returning from this function. |
| 509 PCCERT_CONTEXT cert_context2 = | 515 PCCERT_CONTEXT cert_context2 = |
| 510 Singleton<ClientCertStore>::get()->CopyCertContext(cert_context); | 516 g_client_cert_store.Get().CopyCertContext(cert_context); |
| 511 if (!cert_context2) { | 517 if (!cert_context2) { |
| 512 NOTREACHED(); | 518 NOTREACHED(); |
| 513 continue; | 519 continue; |
| 514 } | 520 } |
| 515 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( | 521 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |
| 516 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, | 522 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, |
| 517 X509Certificate::OSCertHandles()); | 523 X509Certificate::OSCertHandles()); |
| 518 cert_request_info->client_certs.push_back(cert); | 524 cert_request_info->client_certs.push_back(cert); |
| 519 CertFreeCertificateContext(cert_context2); | 525 CertFreeCertificateContext(cert_context2); |
| 520 } | 526 } |
| (...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); | 1511 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); |
| 1506 } | 1512 } |
| 1507 | 1513 |
| 1508 void SSLClientSocketWin::FreeSendBuffer() { | 1514 void SSLClientSocketWin::FreeSendBuffer() { |
| 1509 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1515 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
| 1510 DCHECK(status == SEC_E_OK); | 1516 DCHECK(status == SEC_E_OK); |
| 1511 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1517 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
| 1512 } | 1518 } |
| 1513 | 1519 |
| 1514 } // namespace net | 1520 } // namespace net |
| OLD | NEW |