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 | |
374 // Size of recv_buffer_ | 340 // Size of recv_buffer_ |
375 // | 341 // |
376 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to | 342 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to |
377 // have room for a full SSL record, with the header and trailer. Here is the | 343 // have room for a full SSL record, with the header and trailer. Here is the |
378 // breakdown of the size: | 344 // breakdown of the size: |
379 // 5: SSL record header | 345 // 5: SSL record header |
380 // 16K: SSL record maximum size | 346 // 16K: SSL record maximum size |
381 // 64: >= SSL record trailer (16 or 20 have been observed) | 347 // 64: >= SSL record trailer (16 or 20 have been observed) |
382 static const int kRecvBufferSize = (5 + 16*1024 + 64); | 348 static const int kRecvBufferSize = (5 + 16*1024 + 64); |
383 | 349 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 if (!chain_context) { | 481 if (!chain_context) { |
516 DWORD err = GetLastError(); | 482 DWORD err = GetLastError(); |
517 if (err != CRYPT_E_NOT_FOUND) | 483 if (err != CRYPT_E_NOT_FOUND) |
518 DLOG(ERROR) << "CertFindChainInStore failed: " << err; | 484 DLOG(ERROR) << "CertFindChainInStore failed: " << err; |
519 break; | 485 break; |
520 } | 486 } |
521 | 487 |
522 // Get the leaf certificate. | 488 // Get the leaf certificate. |
523 PCCERT_CONTEXT cert_context = | 489 PCCERT_CONTEXT cert_context = |
524 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; | 490 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; |
525 // Copy it to our own certificate store, so that we can close the "MY" | 491 // Copy the certificate into a NULL store, so that we can close the "MY" |
526 // certificate store before returning from this function. | 492 // store before returning from this function. |
527 PCCERT_CONTEXT cert_context2 = | 493 PCCERT_CONTEXT cert_context2 = NULL; |
528 g_client_cert_store.Get().CopyCertContext(cert_context); | 494 BOOL ok = CertAddCertificateContextToStore(NULL, cert_context, |
529 if (!cert_context2) { | 495 CERT_STORE_ADD_USE_EXISTING, |
| 496 &cert_context2); |
| 497 if (!ok) { |
530 NOTREACHED(); | 498 NOTREACHED(); |
531 continue; | 499 continue; |
532 } | 500 } |
533 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( | 501 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |
534 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, | 502 cert_context2, X509Certificate::OSCertHandles()); |
535 X509Certificate::OSCertHandles()); | |
536 cert_request_info->client_certs.push_back(cert); | 503 cert_request_info->client_certs.push_back(cert); |
537 CertFreeCertificateContext(cert_context2); | 504 CertFreeCertificateContext(cert_context2); |
538 } | 505 } |
539 | 506 |
540 FreeContextBuffer(issuer_list.aIssuers); | 507 FreeContextBuffer(issuer_list.aIssuers); |
541 | 508 |
542 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); | 509 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); |
543 DCHECK(ok); | 510 DCHECK(ok); |
544 } | 511 } |
545 | 512 |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 return MapSecurityError(status); | 1474 return MapSecurityError(status); |
1508 } | 1475 } |
1509 if (renegotiating_ && | 1476 if (renegotiating_ && |
1510 X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(), | 1477 X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(), |
1511 server_cert_handle)) { | 1478 server_cert_handle)) { |
1512 // We already verified the server certificate. Either it is good or the | 1479 // We already verified the server certificate. Either it is good or the |
1513 // user has accepted the certificate error. | 1480 // user has accepted the certificate error. |
1514 DidCompleteRenegotiation(); | 1481 DidCompleteRenegotiation(); |
1515 } else { | 1482 } else { |
1516 server_cert_ = X509Certificate::CreateFromHandle( | 1483 server_cert_ = X509Certificate::CreateFromHandle( |
1517 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, | 1484 server_cert_handle, X509Certificate::OSCertHandles()); |
1518 X509Certificate::OSCertHandles()); | |
1519 | 1485 |
1520 next_state_ = STATE_VERIFY_CERT; | 1486 next_state_ = STATE_VERIFY_CERT; |
1521 } | 1487 } |
1522 CertFreeCertificateContext(server_cert_handle); | 1488 CertFreeCertificateContext(server_cert_handle); |
1523 return OK; | 1489 return OK; |
1524 } | 1490 } |
1525 | 1491 |
1526 // Called when a renegotiation is completed. |result| is the verification | 1492 // Called when a renegotiation is completed. |result| is the verification |
1527 // result of the server certificate received during renegotiation. | 1493 // result of the server certificate received during renegotiation. |
1528 void SSLClientSocketWin::DidCompleteRenegotiation() { | 1494 void SSLClientSocketWin::DidCompleteRenegotiation() { |
(...skipping 17 matching lines...) Expand all Loading... |
1546 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); | 1512 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); |
1547 } | 1513 } |
1548 | 1514 |
1549 void SSLClientSocketWin::FreeSendBuffer() { | 1515 void SSLClientSocketWin::FreeSendBuffer() { |
1550 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1516 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
1551 DCHECK(status == SEC_E_OK); | 1517 DCHECK(status == SEC_E_OK); |
1552 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1518 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
1553 } | 1519 } |
1554 | 1520 |
1555 } // namespace net | 1521 } // namespace net |
OLD | NEW |