Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ssl/client_cert_store_nss.h" | 5 #include "net/ssl/client_cert_store_nss.h" |
| 6 | 6 |
| 7 #include <nss.h> | 7 #include <nss.h> |
| 8 #include <ssl.h> | 8 #include <ssl.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
| 16 #include "base/threading/worker_pool.h" | 16 #include "base/threading/worker_pool.h" |
| 17 #include "crypto/nss_crypto_module_delegate.h" | 17 #include "crypto/nss_crypto_module_delegate.h" |
| 18 #include "net/cert/scoped_nss_types.h" | |
| 18 #include "net/cert/x509_util.h" | 19 #include "net/cert/x509_util.h" |
| 19 #include "net/ssl/ssl_cert_request_info.h" | 20 #include "net/ssl/ssl_cert_request_info.h" |
| 20 | 21 |
| 21 namespace net { | 22 namespace net { |
| 22 | 23 |
| 23 ClientCertStoreNSS::ClientCertStoreNSS( | 24 ClientCertStoreNSS::ClientCertStoreNSS( |
| 24 const PasswordDelegateFactory& password_delegate_factory) | 25 const PasswordDelegateFactory& password_delegate_factory) |
| 25 : password_delegate_factory_(password_delegate_factory) {} | 26 : password_delegate_factory_(password_delegate_factory) {} |
| 26 | 27 |
| 27 ClientCertStoreNSS::~ClientCertStoreNSS() {} | 28 ClientCertStoreNSS::~ClientCertStoreNSS() {} |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 | 88 |
| 88 // Only offer unexpired certificates. | 89 // Only offer unexpired certificates. |
| 89 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) != | 90 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) != |
| 90 secCertTimeValid) { | 91 secCertTimeValid) { |
| 91 DVLOG(2) << "skipped expired cert: " | 92 DVLOG(2) << "skipped expired cert: " |
| 92 << base::StringPiece(handle->nickname); | 93 << base::StringPiece(handle->nickname); |
| 93 continue; | 94 continue; |
| 94 } | 95 } |
| 95 | 96 |
| 96 // Check if the certificate issuer is allowed by the server. | 97 // Check if the certificate issuer is allowed by the server. |
| 97 if (request.cert_authorities.empty() || | 98 if (!request.cert_authorities.empty()) { |
| 98 (!query_nssdb && cert->IsIssuedByEncoded(request.cert_authorities)) || | 99 if ((!query_nssdb && |
| 99 (query_nssdb && | 100 !cert->IsIssuedByEncoded(request.cert_authorities)) || |
| 100 NSS_CmpCertChainWCANames(handle, &ca_names) == SECSuccess)) { | 101 (query_nssdb && |
| 101 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname); | 102 NSS_CmpCertChainWCANames(handle, &ca_names) != SECSuccess)) { |
| 103 DVLOG(2) << "skipped non-matching cert: " | |
| 104 << base::StringPiece(handle->nickname); | |
| 105 continue; | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname); | |
| 110 | |
| 111 if (!query_nssdb) { | |
|
davidben
2015/12/14 22:26:32
This is only false in tests. Which... you could ar
Ryan Sleevi
2015/12/16 01:46:54
Wait, it's false for all tests? There shouldn't be
| |
| 102 filtered_certs->push_back(cert); | 112 filtered_certs->push_back(cert); |
| 103 } else { | 113 continue; |
| 104 DVLOG(2) << "skipped non-matching cert: " | 114 } |
| 115 | |
| 116 // Build a certificate chain from |handle| to include any | |
| 117 // intermediates. Some deployments expect the client to supply intermediates | |
| 118 // out of the local store. https://crbug.com/548631 | |
|
Ryan Sleevi
2015/12/16 01:46:53
// Attempt to construct a complete certificate cha
| |
| 119 ScopedCERTCertificateList chain(CERT_CertChainFromCert( | |
| 120 handle, certUsageSSLClient, PR_FALSE /* includeRoot */)); | |
| 121 if (!chain) { | |
| 122 DVLOG(2) << "could not build chain: " | |
| 105 << base::StringPiece(handle->nickname); | 123 << base::StringPiece(handle->nickname); |
| 124 continue; | |
|
Ryan Sleevi
2015/12/16 01:46:53
Wow, NSS is dumb; it shouldn't choke if it can't b
| |
| 106 } | 125 } |
| 126 std::vector<base::StringPiece> der_chain; | |
| 127 for (int i = 0; i < chain->len; i++) { | |
| 128 der_chain.push_back( | |
| 129 base::StringPiece(reinterpret_cast<const char*>(chain->certs[i].data), | |
| 130 chain->certs[i].len)); | |
| 131 } | |
| 132 scoped_refptr<X509Certificate> full_cert = | |
| 133 X509Certificate::CreateFromDERCertChain(der_chain); | |
| 134 if (!full_cert.get()) { | |
| 135 DVLOG(2) << "could not decode chain: " | |
| 136 << base::StringPiece(handle->nickname); | |
| 137 continue; | |
| 138 } | |
| 139 filtered_certs->push_back(full_cert); | |
| 107 } | 140 } |
| 108 DVLOG(2) << "num_raw:" << num_raw | 141 DVLOG(2) << "num_raw:" << num_raw |
| 109 << " num_filtered:" << filtered_certs->size(); | 142 << " num_filtered:" << filtered_certs->size(); |
| 110 | 143 |
| 111 std::sort(filtered_certs->begin(), filtered_certs->end(), | 144 std::sort(filtered_certs->begin(), filtered_certs->end(), |
| 112 x509_util::ClientCertSorter()); | 145 x509_util::ClientCertSorter()); |
| 113 } | 146 } |
| 114 | 147 |
| 115 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread( | 148 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread( |
| 116 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate, | 149 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 134 } | 167 } |
| 135 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs); | 168 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs); |
| 136 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) { | 169 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) { |
| 137 certs->push_back(X509Certificate::CreateFromHandle( | 170 certs->push_back(X509Certificate::CreateFromHandle( |
| 138 node->cert, X509Certificate::OSCertHandles())); | 171 node->cert, X509Certificate::OSCertHandles())); |
| 139 } | 172 } |
| 140 CERT_DestroyCertList(found_certs); | 173 CERT_DestroyCertList(found_certs); |
| 141 } | 174 } |
| 142 | 175 |
| 143 } // namespace net | 176 } // namespace net |
| OLD | NEW |