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

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

Issue 1526783002: Build a chain in ClientCertStoreNSS to send intermediates to the server. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: WIP test does not work Created 4 years, 10 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
« no previous file with comments | « net/ssl/client_cert_store_nss.h ('k') | net/ssl/client_cert_store_nss_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/strings/string_piece.h" 18 #include "base/strings/string_piece.h"
19 #include "base/threading/worker_pool.h" 19 #include "base/threading/worker_pool.h"
20 #include "crypto/nss_crypto_module_delegate.h" 20 #include "crypto/nss_crypto_module_delegate.h"
21 #include "net/cert/scoped_nss_types.h"
21 #include "net/cert/x509_util.h" 22 #include "net/cert/x509_util.h"
22 #include "net/ssl/ssl_cert_request_info.h" 23 #include "net/ssl/ssl_cert_request_info.h"
23 24
24 namespace net { 25 namespace net {
25 26
26 ClientCertStoreNSS::ClientCertStoreNSS( 27 ClientCertStoreNSS::ClientCertStoreNSS(
27 const PasswordDelegateFactory& password_delegate_factory) 28 const PasswordDelegateFactory& password_delegate_factory)
28 : password_delegate_factory_(password_delegate_factory) {} 29 : password_delegate_factory_(password_delegate_factory) {}
29 30
30 ClientCertStoreNSS::~ClientCertStoreNSS() {} 31 ClientCertStoreNSS::~ClientCertStoreNSS() {}
(...skipping 19 matching lines...) Expand all
50 // If the task could not be posted, behave as if there were no certificates 51 // If the task could not be posted, behave as if there were no certificates
51 // which requires to clear |selected_certs|. 52 // which requires to clear |selected_certs|.
52 selected_certs->clear(); 53 selected_certs->clear();
53 callback.Run(); 54 callback.Run();
54 } 55 }
55 56
56 // static 57 // static
57 void ClientCertStoreNSS::FilterCertsOnWorkerThread( 58 void ClientCertStoreNSS::FilterCertsOnWorkerThread(
58 const CertificateList& certs, 59 const CertificateList& certs,
59 const SSLCertRequestInfo& request, 60 const SSLCertRequestInfo& request,
60 bool query_nssdb,
61 CertificateList* filtered_certs) { 61 CertificateList* filtered_certs) {
62 DCHECK(filtered_certs); 62 DCHECK(filtered_certs);
63 63
64 filtered_certs->clear(); 64 filtered_certs->clear();
65 65
66 // Create a "fake" CERTDistNames structure. No public API exists to create 66 // Create a "fake" CERTDistNames structure. No public API exists to create
67 // one from a list of issuers. 67 // one from a list of issuers.
68 CERTDistNames ca_names; 68 CERTDistNames ca_names;
69 ca_names.arena = NULL; 69 ca_names.arena = NULL;
70 ca_names.nnames = 0; 70 ca_names.nnames = 0;
(...skipping 19 matching lines...) Expand all
90 90
91 // Only offer unexpired certificates. 91 // Only offer unexpired certificates.
92 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) != 92 if (CERT_CheckCertValidTimes(handle, PR_Now(), PR_TRUE) !=
93 secCertTimeValid) { 93 secCertTimeValid) {
94 DVLOG(2) << "skipped expired cert: " 94 DVLOG(2) << "skipped expired cert: "
95 << base::StringPiece(handle->nickname); 95 << base::StringPiece(handle->nickname);
96 continue; 96 continue;
97 } 97 }
98 98
99 // Check if the certificate issuer is allowed by the server. 99 // Check if the certificate issuer is allowed by the server.
100 if (request.cert_authorities.empty() || 100 if (!request.cert_authorities.empty() &&
101 (!query_nssdb && cert->IsIssuedByEncoded(request.cert_authorities)) || 101 NSS_CmpCertChainWCANames(handle, &ca_names) != SECSuccess) {
102 (query_nssdb &&
103 NSS_CmpCertChainWCANames(handle, &ca_names) == SECSuccess)) {
104 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname);
105 filtered_certs->push_back(cert);
106 } else {
107 DVLOG(2) << "skipped non-matching cert: " 102 DVLOG(2) << "skipped non-matching cert: "
108 << base::StringPiece(handle->nickname); 103 << base::StringPiece(handle->nickname);
104 continue;
109 } 105 }
106
107 DVLOG(2) << "matched cert: " << base::StringPiece(handle->nickname);
108
109 // Build a certificate chain from |handle| to include any
110 // intermediates. Some deployments expect the client to supply intermediates
111 // out of the local store. https://crbug.com/548631
Ryan Sleevi 2016/02/05 23:51:24 Blah, I remember what the 'bug' was now. So NSS_C
112 ScopedCERTCertificateList chain(CERT_CertChainFromCert(
113 handle, certUsageSSLClient, PR_FALSE /* includeRoot */));
114 if (!chain) {
115 DVLOG(2) << "could not build chain: "
116 << base::StringPiece(handle->nickname);
117 continue;
118 }
119 std::vector<base::StringPiece> der_chain;
120 for (int i = 0; i < chain->len; i++) {
121 der_chain.push_back(
122 base::StringPiece(reinterpret_cast<const char*>(chain->certs[i].data),
123 chain->certs[i].len));
124 }
125 scoped_refptr<X509Certificate> full_cert =
126 X509Certificate::CreateFromDERCertChain(der_chain);
Ryan Sleevi 2016/02/05 23:51:24 This actually forces NSS through a full reparse an
127 if (!full_cert.get()) {
128 DVLOG(2) << "could not decode chain: "
129 << base::StringPiece(handle->nickname);
130 continue;
131 }
132 filtered_certs->push_back(full_cert);
110 } 133 }
111 DVLOG(2) << "num_raw:" << num_raw 134 DVLOG(2) << "num_raw:" << num_raw
112 << " num_filtered:" << filtered_certs->size(); 135 << " num_filtered:" << filtered_certs->size();
113 136
114 std::sort(filtered_certs->begin(), filtered_certs->end(), 137 std::sort(filtered_certs->begin(), filtered_certs->end(),
115 x509_util::ClientCertSorter()); 138 x509_util::ClientCertSorter());
116 } 139 }
117 140
118 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread( 141 void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread(
119 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate, 142 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate,
120 const SSLCertRequestInfo* request, 143 const SSLCertRequestInfo* request,
121 CertificateList* selected_certs) { 144 CertificateList* selected_certs) {
122 CertificateList platform_certs; 145 CertificateList platform_certs;
123 GetPlatformCertsOnWorkerThread(std::move(password_delegate), &platform_certs); 146 GetPlatformCertsOnWorkerThread(std::move(password_delegate), &platform_certs);
124 FilterCertsOnWorkerThread(platform_certs, *request, true, selected_certs); 147 FilterCertsOnWorkerThread(platform_certs, *request, selected_certs);
125 } 148 }
126 149
127 // static 150 // static
128 void ClientCertStoreNSS::GetPlatformCertsOnWorkerThread( 151 void ClientCertStoreNSS::GetPlatformCertsOnWorkerThread(
129 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate, 152 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate,
130 net::CertificateList* certs) { 153 net::CertificateList* certs) {
131 CERTCertList* found_certs = 154 CERTCertList* found_certs =
132 CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), certUsageSSLClient, 155 CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), certUsageSSLClient,
133 PR_FALSE, PR_FALSE, password_delegate.get()); 156 PR_FALSE, PR_FALSE, password_delegate.get());
134 if (!found_certs) { 157 if (!found_certs) {
135 DVLOG(2) << "No client certs found."; 158 DVLOG(2) << "No client certs found.";
136 return; 159 return;
137 } 160 }
138 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs); 161 for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs);
139 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) { 162 !CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) {
140 certs->push_back(X509Certificate::CreateFromHandle( 163 certs->push_back(X509Certificate::CreateFromHandle(
141 node->cert, X509Certificate::OSCertHandles())); 164 node->cert, X509Certificate::OSCertHandles()));
142 } 165 }
143 CERT_DestroyCertList(found_certs); 166 CERT_DestroyCertList(found_certs);
144 } 167 }
145 168
146 } // namespace net 169 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/client_cert_store_nss.h ('k') | net/ssl/client_cert_store_nss_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698