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 |