Chromium Code Reviews| 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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1529 CERTCertList** result_certs, | 1529 CERTCertList** result_certs, |
| 1530 void** result_private_key) { | 1530 void** result_private_key) { |
| 1531 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 1531 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 1532 | 1532 |
| 1533 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 1533 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
| 1534 #if defined(OS_WIN) | 1534 #if defined(OS_WIN) |
| 1535 if (that->ssl_config_.send_client_cert) { | 1535 if (that->ssl_config_.send_client_cert) { |
| 1536 if (that->ssl_config_.client_cert) { | 1536 if (that->ssl_config_.client_cert) { |
| 1537 PCCERT_CONTEXT cert_context = | 1537 PCCERT_CONTEXT cert_context = |
| 1538 that->ssl_config_.client_cert->os_cert_handle(); | 1538 that->ssl_config_.client_cert->os_cert_handle(); |
| 1539 if (VLOG_IS_ON(1)) { | 1539 CERT_KEY_CONTEXT* key_context = reinterpret_cast<CERT_KEY_CONTEXT*>( |
| 1540 do { | 1540 PORT_Alloc(sizeof(CERT_KEY_CONTEXT))); |
| 1541 DWORD size_needed = 0; | 1541 if (!key_context) { |
| 1542 BOOL got_info = CertGetCertificateContextProperty( | 1542 LOG(ERROR) << "Internal NSS allocation error"; |
|
wtc
2011/02/04 01:32:16
Remove this error message, partly because PORT_All
| |
| 1543 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size_needed); | 1543 return SECFailure; |
| 1544 if (!got_info) { | 1544 } |
| 1545 VLOG(1) << "Failed to get key prov info size " << GetLastError(); | 1545 memset(key_context, 0, sizeof(*key_context)); |
|
wtc
2011/02/04 01:32:16
You can use PORT_ZAlloc() instead, which returns z
| |
| 1546 break; | 1546 key_context->cbSize = sizeof(*key_context); |
| 1547 } | |
| 1548 std::vector<BYTE> raw_info(size_needed); | |
| 1549 got_info = CertGetCertificateContextProperty( | |
| 1550 cert_context, CERT_KEY_PROV_INFO_PROP_ID, &raw_info[0], | |
| 1551 &size_needed); | |
| 1552 if (!got_info) { | |
| 1553 VLOG(1) << "Failed to get key prov info " << GetLastError(); | |
| 1554 break; | |
| 1555 } | |
| 1556 PCRYPT_KEY_PROV_INFO info = | |
| 1557 reinterpret_cast<PCRYPT_KEY_PROV_INFO>(&raw_info[0]); | |
| 1558 VLOG(1) << "Container Name: " << info->pwszContainerName | |
| 1559 << "\nProvider Name: " << info->pwszProvName | |
| 1560 << "\nProvider Type: " << info->dwProvType | |
| 1561 << "\nFlags: " << info->dwFlags | |
| 1562 << "\nProvider Param Count: " << info->cProvParam | |
| 1563 << "\nKey Specifier: " << info->dwKeySpec; | |
| 1564 } while (false); | |
| 1565 | 1547 |
| 1566 do { | |
| 1567 DWORD size_needed = 0; | |
| 1568 BOOL got_identifier = CertGetCertificateContextProperty( | |
| 1569 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size_needed); | |
| 1570 if (!got_identifier) { | |
| 1571 VLOG(1) << "Failed to get key identifier size " | |
| 1572 << GetLastError(); | |
| 1573 break; | |
| 1574 } | |
| 1575 std::vector<BYTE> raw_id(size_needed); | |
| 1576 got_identifier = CertGetCertificateContextProperty( | |
| 1577 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, &raw_id[0], | |
| 1578 &size_needed); | |
| 1579 if (!got_identifier) { | |
| 1580 VLOG(1) << "Failed to get key identifier " << GetLastError(); | |
| 1581 break; | |
| 1582 } | |
| 1583 VLOG(1) << "Key Identifier: " << base::HexEncode(&raw_id[0], | |
| 1584 size_needed); | |
| 1585 } while (false); | |
| 1586 } | |
| 1587 HCRYPTPROV provider = NULL; | 1548 HCRYPTPROV provider = NULL; |
|
wtc
2011/02/04 01:32:16
Delete 'provider'.
| |
| 1588 DWORD key_spec = AT_KEYEXCHANGE; | |
| 1589 BOOL must_free = FALSE; | 1549 BOOL must_free = FALSE; |
| 1590 BOOL acquired_key = CryptAcquireCertificatePrivateKey( | 1550 BOOL acquired_key = CryptAcquireCertificatePrivateKey( |
| 1591 cert_context, | 1551 cert_context, |
| 1592 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, | 1552 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, |
| 1593 NULL, &provider, &key_spec, &must_free); | 1553 NULL, &key_context->hCryptProv, &key_context->dwKeySpec, |
| 1594 if (acquired_key && provider) { | 1554 &must_free); |
| 1595 DCHECK_NE(key_spec, CERT_NCRYPT_KEY_SPEC); | 1555 if (acquired_key && key_context->hCryptProv) { |
| 1556 DCHECK_NE(key_context->dwKeySpec, CERT_NCRYPT_KEY_SPEC); | |
| 1596 | 1557 |
| 1597 // The certificate cache may have been updated/used, in which case, | 1558 // The certificate cache may have been updated/used, in which case, |
| 1598 // duplicate the existing handle, since NSS will free it when no | 1559 // duplicate the existing handle, since NSS will free it when no |
| 1599 // longer in use. | 1560 // longer in use. |
| 1600 if (!must_free) | 1561 if (!must_free) |
| 1601 CryptContextAddRef(provider, NULL, 0); | 1562 CryptContextAddRef(key_context->hCryptProv, NULL, 0); |
| 1602 | 1563 |
| 1603 SECItem der_cert; | 1564 SECItem der_cert; |
| 1604 der_cert.type = siDERCertBuffer; | 1565 der_cert.type = siDERCertBuffer; |
| 1605 der_cert.data = cert_context->pbCertEncoded; | 1566 der_cert.data = cert_context->pbCertEncoded; |
| 1606 der_cert.len = cert_context->cbCertEncoded; | 1567 der_cert.len = cert_context->cbCertEncoded; |
| 1607 | 1568 |
| 1608 // TODO(rsleevi): Error checking for NSS allocation errors. | 1569 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 1609 *result_certs = CERT_NewCertList(); | 1570 *result_certs = CERT_NewCertList(); |
| 1610 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); | 1571 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); |
| 1611 CERTCertificate* user_cert = CERT_NewTempCertificate( | 1572 CERTCertificate* user_cert = CERT_NewTempCertificate( |
| 1612 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 1573 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1613 CERT_AddCertToListTail(*result_certs, user_cert); | 1574 CERT_AddCertToListTail(*result_certs, user_cert); |
| 1614 | 1575 |
| 1615 // Add the intermediates. | 1576 // Add the intermediates. |
| 1616 X509Certificate::OSCertHandles intermediates = | 1577 X509Certificate::OSCertHandles intermediates = |
| 1617 that->ssl_config_.client_cert->GetIntermediateCertificates(); | 1578 that->ssl_config_.client_cert->GetIntermediateCertificates(); |
| 1618 for (X509Certificate::OSCertHandles::const_iterator it = | 1579 for (X509Certificate::OSCertHandles::const_iterator it = |
| 1619 intermediates.begin(); it != intermediates.end(); ++it) { | 1580 intermediates.begin(); it != intermediates.end(); ++it) { |
| 1620 der_cert.data = (*it)->pbCertEncoded; | 1581 der_cert.data = (*it)->pbCertEncoded; |
| 1621 der_cert.len = (*it)->cbCertEncoded; | 1582 der_cert.len = (*it)->cbCertEncoded; |
| 1622 | 1583 |
| 1623 CERTCertificate* intermediate = CERT_NewTempCertificate( | 1584 CERTCertificate* intermediate = CERT_NewTempCertificate( |
| 1624 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 1585 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1625 CERT_AddCertToListTail(*result_certs, intermediate); | 1586 CERT_AddCertToListTail(*result_certs, intermediate); |
| 1626 } | 1587 } |
| 1627 // TODO(wtc): |key_spec| should be passed along with |provider|. | 1588 *result_private_key = reinterpret_cast<void*>(key_context); |
|
wtc
2011/02/04 01:32:16
I believe this reinterpret_cast<void*> can be remo
| |
| 1628 *result_private_key = reinterpret_cast<void*>(provider); | |
| 1629 return SECSuccess; | 1589 return SECSuccess; |
| 1630 } | 1590 } |
| 1591 PORT_Free(key_context); | |
| 1631 LOG(WARNING) << "Client cert found without private key"; | 1592 LOG(WARNING) << "Client cert found without private key"; |
| 1632 } | 1593 } |
| 1633 // Send no client certificate. | 1594 // Send no client certificate. |
| 1634 return SECFailure; | 1595 return SECFailure; |
| 1635 } | 1596 } |
| 1636 | 1597 |
| 1637 that->client_certs_.clear(); | 1598 that->client_certs_.clear(); |
| 1638 | 1599 |
| 1639 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); | 1600 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); |
| 1640 for (int i = 0; i < ca_names->nnames; ++i) { | 1601 for (int i = 0; i < ca_names->nnames; ++i) { |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2509 case SSL_CONNECTION_VERSION_TLS1_1: | 2470 case SSL_CONNECTION_VERSION_TLS1_1: |
| 2510 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); | 2471 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); |
| 2511 break; | 2472 break; |
| 2512 case SSL_CONNECTION_VERSION_TLS1_2: | 2473 case SSL_CONNECTION_VERSION_TLS1_2: |
| 2513 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); | 2474 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); |
| 2514 break; | 2475 break; |
| 2515 }; | 2476 }; |
| 2516 } | 2477 } |
| 2517 | 2478 |
| 2518 } // namespace net | 2479 } // namespace net |
| OLD | NEW |