OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 if (!CertGetCertificateContextProperty( | 330 if (!CertGetCertificateContextProperty( |
331 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) { | 331 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) { |
332 return FALSE; | 332 return FALSE; |
333 } | 333 } |
334 | 334 |
335 return TRUE; | 335 return TRUE; |
336 } | 336 } |
337 | 337 |
338 //----------------------------------------------------------------------------- | 338 //----------------------------------------------------------------------------- |
339 | 339 |
| 340 // A memory certificate store for client certificates. This allows us to |
| 341 // close the "MY" system certificate store when we finish searching for |
| 342 // client certificates. |
| 343 class ClientCertStore { |
| 344 public: |
| 345 ClientCertStore() { |
| 346 store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); |
| 347 } |
| 348 |
| 349 ~ClientCertStore() { |
| 350 if (store_) { |
| 351 BOOL ok = CertCloseStore(store_, CERT_CLOSE_STORE_CHECK_FLAG); |
| 352 DCHECK(ok); |
| 353 } |
| 354 } |
| 355 |
| 356 PCCERT_CONTEXT CopyCertContext(PCCERT_CONTEXT client_cert) { |
| 357 PCCERT_CONTEXT copy; |
| 358 BOOL ok = CertAddCertificateContextToStore(store_, client_cert, |
| 359 CERT_STORE_ADD_USE_EXISTING, |
| 360 ©); |
| 361 DCHECK(ok); |
| 362 return ok ? copy : NULL; |
| 363 } |
| 364 |
| 365 private: |
| 366 HCERTSTORE store_; |
| 367 }; |
| 368 |
| 369 static base::LazyInstance<ClientCertStore> g_client_cert_store( |
| 370 base::LINKER_INITIALIZED); |
| 371 |
| 372 //----------------------------------------------------------------------------- |
| 373 |
340 // Size of recv_buffer_ | 374 // Size of recv_buffer_ |
341 // | 375 // |
342 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to | 376 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to |
343 // have room for a full SSL record, with the header and trailer. Here is the | 377 // have room for a full SSL record, with the header and trailer. Here is the |
344 // breakdown of the size: | 378 // breakdown of the size: |
345 // 5: SSL record header | 379 // 5: SSL record header |
346 // 16K: SSL record maximum size | 380 // 16K: SSL record maximum size |
347 // 64: >= SSL record trailer (16 or 20 have been observed) | 381 // 64: >= SSL record trailer (16 or 20 have been observed) |
348 static const int kRecvBufferSize = (5 + 16*1024 + 64); | 382 static const int kRecvBufferSize = (5 + 16*1024 + 64); |
349 | 383 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 if (!chain_context) { | 515 if (!chain_context) { |
482 DWORD err = GetLastError(); | 516 DWORD err = GetLastError(); |
483 if (err != CRYPT_E_NOT_FOUND) | 517 if (err != CRYPT_E_NOT_FOUND) |
484 DLOG(ERROR) << "CertFindChainInStore failed: " << err; | 518 DLOG(ERROR) << "CertFindChainInStore failed: " << err; |
485 break; | 519 break; |
486 } | 520 } |
487 | 521 |
488 // Get the leaf certificate. | 522 // Get the leaf certificate. |
489 PCCERT_CONTEXT cert_context = | 523 PCCERT_CONTEXT cert_context = |
490 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; | 524 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; |
491 // Copy the certificate into a NULL store, so that we can close the "MY" | 525 // Copy it to our own certificate store, so that we can close the "MY" |
492 // store before returning from this function. | 526 // certificate store before returning from this function. |
493 PCCERT_CONTEXT cert_context2 = NULL; | 527 PCCERT_CONTEXT cert_context2 = |
494 BOOL ok = CertAddCertificateContextToStore(NULL, cert_context, | 528 g_client_cert_store.Get().CopyCertContext(cert_context); |
495 CERT_STORE_ADD_USE_EXISTING, | 529 if (!cert_context2) { |
496 &cert_context2); | |
497 if (!ok) { | |
498 NOTREACHED(); | 530 NOTREACHED(); |
499 continue; | 531 continue; |
500 } | 532 } |
501 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( | 533 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |
502 cert_context2, X509Certificate::OSCertHandles()); | 534 cert_context2, X509Certificate::OSCertHandles()); |
503 cert_request_info->client_certs.push_back(cert); | 535 cert_request_info->client_certs.push_back(cert); |
504 CertFreeCertificateContext(cert_context2); | 536 CertFreeCertificateContext(cert_context2); |
505 } | 537 } |
506 | 538 |
507 FreeContextBuffer(issuer_list.aIssuers); | 539 FreeContextBuffer(issuer_list.aIssuers); |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); | 1544 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); |
1513 } | 1545 } |
1514 | 1546 |
1515 void SSLClientSocketWin::FreeSendBuffer() { | 1547 void SSLClientSocketWin::FreeSendBuffer() { |
1516 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1548 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
1517 DCHECK(status == SEC_E_OK); | 1549 DCHECK(status == SEC_E_OK); |
1518 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1550 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
1519 } | 1551 } |
1520 | 1552 |
1521 } // namespace net | 1553 } // namespace net |
OLD | NEW |