| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 // negotiated protocol stored in |next_proto|. | 422 // negotiated protocol stored in |next_proto|. |
| 423 SSLClientSocket::NextProtoStatus next_proto_status; | 423 SSLClientSocket::NextProtoStatus next_proto_status; |
| 424 std::string next_proto; | 424 std::string next_proto; |
| 425 // If the server supports NPN, the protocols supported by the server. | 425 // If the server supports NPN, the protocols supported by the server. |
| 426 std::string server_protos; | 426 std::string server_protos; |
| 427 | 427 |
| 428 // True if a channel ID was sent. | 428 // True if a channel ID was sent. |
| 429 bool channel_id_sent; | 429 bool channel_id_sent; |
| 430 | 430 |
| 431 // If the peer requests client certificate authentication, the set of | 431 // If the peer requests client certificate authentication, the set of |
| 432 // certificates that matched the peer's criteria. | 432 // certificates that matched the peer's criteria. This should be soon removed |
| 433 // as being tracked in http://crbug.com/166642. |
| 433 CertificateList client_certs; | 434 CertificateList client_certs; |
| 434 | 435 |
| 436 // List of DER-encoded X.509 DistinguishedName of certificate authorities |
| 437 // allowed by the server. |
| 438 std::vector<std::string> cert_authorities; |
| 439 |
| 435 // Set when the handshake fully completes. | 440 // Set when the handshake fully completes. |
| 436 // | 441 // |
| 437 // The server certificate is first received from NSS as an NSS certificate | 442 // The server certificate is first received from NSS as an NSS certificate |
| 438 // chain (|server_cert_chain|) and then converted into a platform-specific | 443 // chain (|server_cert_chain|) and then converted into a platform-specific |
| 439 // X509Certificate object (|server_cert|). It's possible for some | 444 // X509Certificate object (|server_cert|). It's possible for some |
| 440 // certificates to be successfully parsed by NSS, and not by the platform | 445 // certificates to be successfully parsed by NSS, and not by the platform |
| 441 // libraries (i.e.: when running within a sandbox, different parsing | 446 // libraries (i.e.: when running within a sandbox, different parsing |
| 442 // algorithms, etc), so it's not safe to assume that |server_cert| will | 447 // algorithms, etc), so it's not safe to assume that |server_cert| will |
| 443 // always be non-NULL. | 448 // always be non-NULL. |
| 444 PeerCertificateChain server_cert_chain; | 449 PeerCertificateChain server_cert_chain; |
| (...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 } | 1299 } |
| 1295 LOG(WARNING) << "Client cert found without private key"; | 1300 LOG(WARNING) << "Client cert found without private key"; |
| 1296 } | 1301 } |
| 1297 | 1302 |
| 1298 // Send no client certificate. | 1303 // Send no client certificate. |
| 1299 core->AddCertProvidedEvent(0); | 1304 core->AddCertProvidedEvent(0); |
| 1300 return SECFailure; | 1305 return SECFailure; |
| 1301 } | 1306 } |
| 1302 | 1307 |
| 1303 core->nss_handshake_state_.client_certs.clear(); | 1308 core->nss_handshake_state_.client_certs.clear(); |
| 1309 core->nss_handshake_state_.cert_authorities.clear(); |
| 1304 | 1310 |
| 1305 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); | 1311 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); |
| 1306 for (int i = 0; i < ca_names->nnames; ++i) { | 1312 for (int i = 0; i < ca_names->nnames; ++i) { |
| 1307 issuer_list[i].cbData = ca_names->names[i].len; | 1313 issuer_list[i].cbData = ca_names->names[i].len; |
| 1308 issuer_list[i].pbData = ca_names->names[i].data; | 1314 issuer_list[i].pbData = ca_names->names[i].data; |
| 1315 core->nss_handshake_state_.cert_authorities.push_back(std::string( |
| 1316 reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1317 static_cast<size_t>(ca_names->names[i].len))); |
| 1309 } | 1318 } |
| 1310 | 1319 |
| 1320 // Retrieve the list of matching client certificates. This is to be moved out |
| 1321 // of here as a part of refactoring effort being tracked in |
| 1322 // http://crbug.com/166642. |
| 1323 |
| 1311 // Client certificates of the user are in the "MY" system certificate store. | 1324 // Client certificates of the user are in the "MY" system certificate store. |
| 1312 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY"); | 1325 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY"); |
| 1313 if (!my_cert_store) { | 1326 if (!my_cert_store) { |
| 1314 PLOG(ERROR) << "Could not open the \"MY\" system certificate store"; | 1327 PLOG(ERROR) << "Could not open the \"MY\" system certificate store"; |
| 1315 | 1328 |
| 1316 core->AddCertProvidedEvent(0); | 1329 core->AddCertProvidedEvent(0); |
| 1317 return SECFailure; | 1330 return SECFailure; |
| 1318 } | 1331 } |
| 1319 | 1332 |
| 1320 // Enumerate the client certificates. | 1333 // Enumerate the client certificates. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 if (chain) | 1486 if (chain) |
| 1474 CFRelease(chain); | 1487 CFRelease(chain); |
| 1475 } | 1488 } |
| 1476 | 1489 |
| 1477 // Send no client certificate. | 1490 // Send no client certificate. |
| 1478 core->AddCertProvidedEvent(0); | 1491 core->AddCertProvidedEvent(0); |
| 1479 return SECFailure; | 1492 return SECFailure; |
| 1480 } | 1493 } |
| 1481 | 1494 |
| 1482 core->nss_handshake_state_.client_certs.clear(); | 1495 core->nss_handshake_state_.client_certs.clear(); |
| 1496 core->nss_handshake_state_.cert_authorities.clear(); |
| 1483 | 1497 |
| 1484 // First, get the cert issuer names allowed by the server. | 1498 // Retrieve the cert issuers accepted by the server. This information is |
| 1499 // currently (temporarily) being saved both in |valid_issuers| and |
| 1500 // |cert_authorities|, the latter being the target solution. The refactoring |
| 1501 // effort is being tracked in http://crbug.com/166642. |
| 1485 std::vector<CertPrincipal> valid_issuers; | 1502 std::vector<CertPrincipal> valid_issuers; |
| 1486 int n = ca_names->nnames; | 1503 int n = ca_names->nnames; |
| 1487 for (int i = 0; i < n; i++) { | 1504 for (int i = 0; i < n; i++) { |
| 1488 // Parse each name into a CertPrincipal object. | 1505 // Add the DER-encoded issuer DistinguishedName to |cert_authorities|. |
| 1506 core->nss_handshake_state_.cert_authorities.push_back(std::string( |
| 1507 reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1508 static_cast<size_t>(ca_names->names[i].len))); |
| 1509 // Add the CertPrincipal object representing the issuer to |
| 1510 // |valid_issuers|. |
| 1489 CertPrincipal p; | 1511 CertPrincipal p; |
| 1490 if (p.ParseDistinguishedName(ca_names->names[i].data, | 1512 if (p.ParseDistinguishedName(ca_names->names[i].data, |
| 1491 ca_names->names[i].len)) { | 1513 ca_names->names[i].len)) { |
| 1492 valid_issuers.push_back(p); | 1514 valid_issuers.push_back(p); |
| 1493 } | 1515 } |
| 1494 } | 1516 } |
| 1495 | 1517 |
| 1496 // Now get the available client certs whose issuers are allowed by the server. | 1518 // Now get the available client certs whose issuers are allowed by the server. |
| 1497 X509Certificate::GetSSLClientCertificates( | 1519 X509Certificate::GetSSLClientCertificates( |
| 1498 core->host_and_port_.host(), valid_issuers, | 1520 core->host_and_port_.host(), valid_issuers, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1555 | 1577 |
| 1556 core->PostOrRunCallback( | 1578 core->PostOrRunCallback( |
| 1557 FROM_HERE, | 1579 FROM_HERE, |
| 1558 base::Bind(&AddLogEvent, core->weak_net_log_, | 1580 base::Bind(&AddLogEvent, core->weak_net_log_, |
| 1559 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); | 1581 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); |
| 1560 | 1582 |
| 1561 // Regular client certificate requested. | 1583 // Regular client certificate requested. |
| 1562 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; | 1584 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; |
| 1563 void* wincx = SSL_RevealPinArg(socket); | 1585 void* wincx = SSL_RevealPinArg(socket); |
| 1564 | 1586 |
| 1565 // Second pass: a client certificate should have been selected. | |
| 1566 if (core->ssl_config_.send_client_cert) { | 1587 if (core->ssl_config_.send_client_cert) { |
| 1588 // Second pass: a client certificate should have been selected. |
| 1567 if (core->ssl_config_.client_cert) { | 1589 if (core->ssl_config_.client_cert) { |
| 1568 CERTCertificate* cert = CERT_DupCertificate( | 1590 CERTCertificate* cert = CERT_DupCertificate( |
| 1569 core->ssl_config_.client_cert->os_cert_handle()); | 1591 core->ssl_config_.client_cert->os_cert_handle()); |
| 1570 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); | 1592 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
| 1571 if (privkey) { | 1593 if (privkey) { |
| 1572 // TODO(jsorianopastor): We should wait for server certificate | 1594 // TODO(jsorianopastor): We should wait for server certificate |
| 1573 // verification before sending our credentials. See | 1595 // verification before sending our credentials. See |
| 1574 // http://crbug.com/13934. | 1596 // http://crbug.com/13934. |
| 1575 *result_certificate = cert; | 1597 *result_certificate = cert; |
| 1576 *result_private_key = privkey; | 1598 *result_private_key = privkey; |
| 1577 // A cert_count of -1 means the number of certificates is unknown. | 1599 // A cert_count of -1 means the number of certificates is unknown. |
| 1578 // NSS will construct the certificate chain. | 1600 // NSS will construct the certificate chain. |
| 1579 core->AddCertProvidedEvent(-1); | 1601 core->AddCertProvidedEvent(-1); |
| 1580 | 1602 |
| 1581 return SECSuccess; | 1603 return SECSuccess; |
| 1582 } | 1604 } |
| 1583 LOG(WARNING) << "Client cert found without private key"; | 1605 LOG(WARNING) << "Client cert found without private key"; |
| 1584 } | 1606 } |
| 1585 // Send no client certificate. | 1607 // Send no client certificate. |
| 1586 core->AddCertProvidedEvent(0); | 1608 core->AddCertProvidedEvent(0); |
| 1587 return SECFailure; | 1609 return SECFailure; |
| 1588 } | 1610 } |
| 1589 | 1611 |
| 1612 // First pass: client certificate is needed. |
| 1590 core->nss_handshake_state_.client_certs.clear(); | 1613 core->nss_handshake_state_.client_certs.clear(); |
| 1614 core->nss_handshake_state_.cert_authorities.clear(); |
| 1591 | 1615 |
| 1592 // Iterate over all client certificates. | 1616 // Retrieve the DER-encoded DistinguishedName of the cert issuers accepted by |
| 1617 // the server and save them in |cert_authorities|. |
| 1618 for (int i = 0; i < ca_names->nnames; i++) { |
| 1619 core->nss_handshake_state_.cert_authorities.push_back(std::string( |
| 1620 reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1621 static_cast<size_t>(ca_names->names[i].len))); |
| 1622 } |
| 1623 |
| 1624 // Iterate over all client certificates and put the ones matching the server |
| 1625 // criteria in |nss_handshake_state_.client_certs|. This is to be moved out of |
| 1626 // here as a part of refactoring effort being tracked in |
| 1627 // http://crbug.com/166642. |
| 1593 CERTCertList* client_certs = CERT_FindUserCertsByUsage( | 1628 CERTCertList* client_certs = CERT_FindUserCertsByUsage( |
| 1594 CERT_GetDefaultCertDB(), certUsageSSLClient, | 1629 CERT_GetDefaultCertDB(), certUsageSSLClient, |
| 1595 PR_FALSE, PR_FALSE, wincx); | 1630 PR_FALSE, PR_FALSE, wincx); |
| 1596 if (client_certs) { | 1631 if (client_certs) { |
| 1597 for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs); | 1632 for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs); |
| 1598 !CERT_LIST_END(node, client_certs); | 1633 !CERT_LIST_END(node, client_certs); |
| 1599 node = CERT_LIST_NEXT(node)) { | 1634 node = CERT_LIST_NEXT(node)) { |
| 1600 // Only offer unexpired certificates. | 1635 // Only offer unexpired certificates. |
| 1601 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) != | 1636 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) != |
| 1602 secCertTimeValid) { | 1637 secCertTimeValid) { |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 | 2807 |
| 2773 LeaveFunction(""); | 2808 LeaveFunction(""); |
| 2774 return true; | 2809 return true; |
| 2775 } | 2810 } |
| 2776 | 2811 |
| 2777 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 2812 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 2778 SSLCertRequestInfo* cert_request_info) { | 2813 SSLCertRequestInfo* cert_request_info) { |
| 2779 EnterFunction(""); | 2814 EnterFunction(""); |
| 2780 // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair | 2815 // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair |
| 2781 cert_request_info->host_and_port = host_and_port_.ToString(); | 2816 cert_request_info->host_and_port = host_and_port_.ToString(); |
| 2817 cert_request_info->cert_authorities = core_->state().cert_authorities; |
| 2818 // This should be removed as being tracked in http://crbug.com/166642. |
| 2782 cert_request_info->client_certs = core_->state().client_certs; | 2819 cert_request_info->client_certs = core_->state().client_certs; |
| 2783 LeaveFunction(cert_request_info->client_certs.size()); | 2820 LeaveFunction(cert_request_info->client_certs.size()); |
| 2784 } | 2821 } |
| 2785 | 2822 |
| 2786 int SSLClientSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, | 2823 int SSLClientSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, |
| 2787 bool has_context, | 2824 bool has_context, |
| 2788 const base::StringPiece& context, | 2825 const base::StringPiece& context, |
| 2789 unsigned char* out, | 2826 unsigned char* out, |
| 2790 unsigned int outlen) { | 2827 unsigned int outlen) { |
| 2791 if (!IsConnected()) | 2828 if (!IsConnected()) |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3460 EnsureThreadIdAssigned(); | 3497 EnsureThreadIdAssigned(); |
| 3461 base::AutoLock auto_lock(lock_); | 3498 base::AutoLock auto_lock(lock_); |
| 3462 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 3499 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 3463 } | 3500 } |
| 3464 | 3501 |
| 3465 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 3502 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
| 3466 return server_bound_cert_service_; | 3503 return server_bound_cert_service_; |
| 3467 } | 3504 } |
| 3468 | 3505 |
| 3469 } // namespace net | 3506 } // namespace net |
| OLD | NEW |