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 |