Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: net/ssl/client_cert_store_nss.cc

Issue 2185403003: Return the certificate chain in ClientCertStoreNSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add missing file Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 10 #include <algorithm>
11 #include <memory> 11 #include <memory>
12 #include <utility> 12 #include <utility>
13 #include <vector>
13 14
14 #include "base/bind.h" 15 #include "base/bind.h"
15 #include "base/bind_helpers.h" 16 #include "base/bind_helpers.h"
16 #include "base/location.h" 17 #include "base/location.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
19 #include "base/threading/worker_pool.h" 20 #include "base/threading/worker_pool.h"
20 #include "crypto/nss_crypto_module_delegate.h" 21 #include "crypto/nss_crypto_module_delegate.h"
22 #include "net/cert/scoped_nss_types.h"
21 #include "net/cert/x509_util.h" 23 #include "net/cert/x509_util.h"
22 #include "net/ssl/ssl_cert_request_info.h" 24 #include "net/ssl/ssl_cert_request_info.h"
25 #include "net/third_party/nss/ssl/cmpcert.h"
23 26
24 namespace net { 27 namespace net {
25 28
26 ClientCertStoreNSS::ClientCertStoreNSS( 29 ClientCertStoreNSS::ClientCertStoreNSS(
27 const PasswordDelegateFactory& password_delegate_factory) 30 const PasswordDelegateFactory& password_delegate_factory)
28 : password_delegate_factory_(password_delegate_factory) {} 31 : password_delegate_factory_(password_delegate_factory) {}
29 32
30 ClientCertStoreNSS::~ClientCertStoreNSS() {} 33 ClientCertStoreNSS::~ClientCertStoreNSS() {}
31 34
32 void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request, 35 void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request,
(...skipping 23 matching lines...) Expand all
56 59
57 // static 60 // static
58 void ClientCertStoreNSS::FilterCertsOnWorkerThread( 61 void ClientCertStoreNSS::FilterCertsOnWorkerThread(
59 const CertificateList& certs, 62 const CertificateList& certs,
60 const SSLCertRequestInfo& request, 63 const SSLCertRequestInfo& request,
61 CertificateList* filtered_certs) { 64 CertificateList* filtered_certs) {
62 DCHECK(filtered_certs); 65 DCHECK(filtered_certs);
63 66
64 filtered_certs->clear(); 67 filtered_certs->clear();
65 68
66 // Create a "fake" CERTDistNames structure. No public API exists to create
67 // one from a list of issuers.
68 CERTDistNames ca_names;
69 ca_names.arena = NULL;
70 ca_names.nnames = 0;
71 ca_names.names = NULL;
72 ca_names.head = NULL;
73
74 std::vector<SECItem> ca_names_items(request.cert_authorities.size());
75 for (size_t i = 0; i < request.cert_authorities.size(); ++i) {
76 const std::string& authority = request.cert_authorities[i];
77 ca_names_items[i].type = siBuffer;
78 ca_names_items[i].data =
79 reinterpret_cast<unsigned char*>(const_cast<char*>(authority.data()));
80 ca_names_items[i].len = static_cast<unsigned int>(authority.size());
81 }
82 ca_names.nnames = static_cast<int>(ca_names_items.size());
83 if (!ca_names_items.empty())
84 ca_names.names = &ca_names_items[0];
85
86 size_t num_raw = 0; 69 size_t num_raw = 0;
87 for (const auto& cert : certs) { 70 for (const auto& cert : certs) {
88 ++num_raw; 71 ++num_raw;
89 X509Certificate::OSCertHandle handle = cert->os_cert_handle(); 72 X509Certificate::OSCertHandle handle = cert->os_cert_handle();
90 73
91 // Only offer unexpired certificates. 74 // Only offer unexpired certificates.
92 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) != 75 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) !=
93 secCertTimeValid) { 76 secCertTimeValid) {
94 DVLOG(2) << "skipped expired cert: " 77 DVLOG(2) << "skipped expired cert: "
95 << base::StringPiece(handle->nickname); 78 << base::StringPiece(handle->nickname);
96 continue; 79 continue;
97 } 80 }
98 81
99 // Check if the certificate issuer is allowed by the server. 82 std::vector<ScopedCERTCertificate> chain;
100 if (!request.cert_authorities.empty() && 83 if (!MatchClientCertificateIssuers(handle, request.cert_authorities,
101 NSS_CmpCertChainWCANames(handle, &ca_names) != SECSuccess) { 84 &chain)) {
102 DVLOG(2) << "skipped non-matching cert: " 85 DVLOG(2) << "skipped non-matching cert: "
103 << base::StringPiece(handle->nickname); 86 << base::StringPiece(handle->nickname);
104 continue; 87 continue;
105 } 88 }
106 89
107 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname); 90 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname);
108 filtered_certs->push_back(cert); 91
92 std::vector<base::StringPiece> der_chain;
93 for (const auto& chain_cert : chain) {
94 der_chain.push_back(base::StringPiece(
95 reinterpret_cast<const char*>(chain_cert->derCert.data),
96 chain_cert->derCert.len));
97 }
98
99 scoped_refptr<X509Certificate> full_cert =
100 X509Certificate::CreateFromDERCertChain(der_chain);
101 if (!full_cert.get()) {
102 DVLOG(2) << "could not decode chain: "
103 << base::StringPiece(handle->nickname);
104 continue;
105 }
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
106
107 filtered_certs->push_back(full_cert);
109 } 108 }
110 DVLOG(2) << "num_raw:" << num_raw 109 DVLOG(2) << "num_raw:" << num_raw
111 << " num_filtered:" << filtered_certs->size(); 110 << " num_filtered:" << filtered_certs->size();
112 111
113 std::sort(filtered_certs->begin(), filtered_certs->end(), 112 std::sort(filtered_certs->begin(), filtered_certs->end(),
114 x509_util::ClientCertSorter()); 113 x509_util::ClientCertSorter());
115 } 114 }
116 115
117 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread( 116 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread(
118 std::unique_ptr<crypto::CryptoModuleBlockingPasswordDelegate> 117 std::unique_ptr<crypto::CryptoModuleBlockingPasswordDelegate>
(...skipping 19 matching lines...) Expand all
138 } 137 }
139 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs); 138 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs);
140 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) { 139 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) {
141 certs->push_back(X509Certificate::CreateFromHandle( 140 certs->push_back(X509Certificate::CreateFromHandle(
142 node->cert, X509Certificate::OSCertHandles())); 141 node->cert, X509Certificate::OSCertHandles()));
143 } 142 }
144 CERT_DestroyCertList(found_certs); 143 CERT_DestroyCertList(found_certs);
145 } 144 }
146 145
147 } // namespace net 146 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698