Chromium Code Reviews| Index: net/ssl/client_cert_store_nss.cc |
| diff --git a/net/ssl/client_cert_store_nss.cc b/net/ssl/client_cert_store_nss.cc |
| index e46458ad99e166657007407f056cecac79ff4a5f..5d9b7ba7304515e756c597b78a92b307bf0ac81b 100644 |
| --- a/net/ssl/client_cert_store_nss.cc |
| +++ b/net/ssl/client_cert_store_nss.cc |
| @@ -10,6 +10,7 @@ |
| #include <algorithm> |
| #include <memory> |
| #include <utility> |
| +#include <vector> |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| @@ -18,8 +19,10 @@ |
| #include "base/strings/string_piece.h" |
| #include "base/threading/worker_pool.h" |
| #include "crypto/nss_crypto_module_delegate.h" |
| +#include "net/cert/scoped_nss_types.h" |
| #include "net/cert/x509_util.h" |
| #include "net/ssl/ssl_cert_request_info.h" |
| +#include "net/third_party/nss/ssl/cmpcert.h" |
| namespace net { |
| @@ -63,26 +66,6 @@ void ClientCertStoreNSS::FilterCertsOnWorkerThread( |
| filtered_certs->clear(); |
| - // Create a "fake" CERTDistNames structure. No public API exists to create |
| - // one from a list of issuers. |
| - CERTDistNames ca_names; |
| - ca_names.arena = NULL; |
| - ca_names.nnames = 0; |
| - ca_names.names = NULL; |
| - ca_names.head = NULL; |
| - |
| - std::vector<SECItem> ca_names_items(request.cert_authorities.size()); |
| - for (size_t i = 0; i < request.cert_authorities.size(); ++i) { |
| - const std::string& authority = request.cert_authorities[i]; |
| - ca_names_items[i].type = siBuffer; |
| - ca_names_items[i].data = |
| - reinterpret_cast<unsigned char*>(const_cast<char*>(authority.data())); |
| - ca_names_items[i].len = static_cast<unsigned int>(authority.size()); |
| - } |
| - ca_names.nnames = static_cast<int>(ca_names_items.size()); |
| - if (!ca_names_items.empty()) |
| - ca_names.names = &ca_names_items[0]; |
| - |
| size_t num_raw = 0; |
| for (const auto& cert : certs) { |
| ++num_raw; |
| @@ -96,16 +79,32 @@ void ClientCertStoreNSS::FilterCertsOnWorkerThread( |
| continue; |
| } |
| - // Check if the certificate issuer is allowed by the server. |
| - if (!request.cert_authorities.empty() && |
| - NSS_CmpCertChainWCANames(handle, &ca_names) != SECSuccess) { |
| + std::vector<ScopedCERTCertificate> chain; |
| + if (!MatchClientCertificateIssuers(handle, request.cert_authorities, |
| + &chain)) { |
| DVLOG(2) << "skipped non-matching cert: " |
| << base::StringPiece(handle->nickname); |
| continue; |
| } |
| DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname); |
| - filtered_certs->push_back(cert); |
| + |
| + std::vector<base::StringPiece> der_chain; |
| + for (const auto& chain_cert : chain) { |
| + der_chain.push_back(base::StringPiece( |
| + reinterpret_cast<const char*>(chain_cert->derCert.data), |
| + chain_cert->derCert.len)); |
| + } |
| + |
| + scoped_refptr<X509Certificate> full_cert = |
| + X509Certificate::CreateFromDERCertChain(der_chain); |
| + if (!full_cert.get()) { |
| + DVLOG(2) << "could not decode chain: " |
| + << base::StringPiece(handle->nickname); |
| + continue; |
| + } |
|
Ryan Sleevi
2016/07/29 00:37:44
Why do you indirect through the DER, when we've go
davidben
2016/07/29 15:14:11
You know, the for loop is actually much much less
|
| + |
| + filtered_certs->push_back(full_cert); |
| } |
| DVLOG(2) << "num_raw:" << num_raw |
| << " num_filtered:" << filtered_certs->size(); |