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

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

Issue 112533002: Add ClientCertStoreChromeOS which only returns the certs for a given user. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: explicits Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « net/ssl/client_cert_store_nss.h ('k') | no next file » | 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 "base/bind.h" 10 #include "base/bind.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string_piece.h"
14 #include "base/threading/worker_pool.h" 15 #include "base/threading/worker_pool.h"
15 #include "crypto/nss_crypto_module_delegate.h" 16 #include "crypto/nss_crypto_module_delegate.h"
16 #include "net/cert/x509_util.h" 17 #include "net/cert/x509_util.h"
17 18
18 namespace net { 19 namespace net {
19 20
20 namespace { 21 ClientCertStoreNSS::ClientCertStoreNSS(
22 const PasswordDelegateFactory& password_delegate_factory)
23 : password_delegate_factory_(password_delegate_factory) {}
21 24
22 // Examines the certificates in |cert_list| to find all certificates that match 25 ClientCertStoreNSS::~ClientCertStoreNSS() {}
23 // the client certificate request in |request|, storing the matching 26
24 // certificates in |selected_certs|. 27 void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request,
25 // If |query_nssdb| is true, NSS will be queried to construct full certificate 28 CertificateList* selected_certs,
26 // chains. If it is false, only the certificate will be considered. 29 const base::Closure& callback) {
27 void GetClientCertsImpl(CERTCertList* cert_list, 30 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate;
28 const SSLCertRequestInfo& request, 31 if (!password_delegate_factory_.is_null()) {
29 bool query_nssdb, 32 password_delegate.reset(
30 CertificateList* selected_certs) { 33 password_delegate_factory_.Run(request.host_and_port));
34 }
35 if (base::WorkerPool::PostTaskAndReply(
36 FROM_HERE,
37 base::Bind(&ClientCertStoreNSS::GetClientCertsOnWorkerThread,
38 // Caller is responsible for keeping the ClientCertStore
39 // alive until the callback is run.
40 base::Unretained(this),
41 base::Passed(&password_delegate),
42 &request,
43 selected_certs),
44 callback,
45 true))
46 return;
47 selected_certs->clear();
48 callback.Run();
49 }
50
51 void ClientCertStoreNSS::GetClientCertsImpl(CERTCertList* cert_list,
52 const SSLCertRequestInfo& request,
53 bool query_nssdb,
54 CertificateList* selected_certs) {
31 DCHECK(cert_list); 55 DCHECK(cert_list);
32 DCHECK(selected_certs); 56 DCHECK(selected_certs);
33 57
34 selected_certs->clear(); 58 selected_certs->clear();
35 59
36 // Create a "fake" CERTDistNames structure. No public API exists to create 60 // Create a "fake" CERTDistNames structure. No public API exists to create
37 // one from a list of issuers. 61 // one from a list of issuers.
38 CERTDistNames ca_names; 62 CERTDistNames ca_names;
39 ca_names.arena = NULL; 63 ca_names.arena = NULL;
40 ca_names.nnames = 0; 64 ca_names.nnames = 0;
41 ca_names.names = NULL; 65 ca_names.names = NULL;
42 ca_names.head = NULL; 66 ca_names.head = NULL;
43 67
44 std::vector<SECItem> ca_names_items(request.cert_authorities.size()); 68 std::vector<SECItem> ca_names_items(request.cert_authorities.size());
45 for (size_t i = 0; i < request.cert_authorities.size(); ++i) { 69 for (size_t i = 0; i < request.cert_authorities.size(); ++i) {
46 const std::string& authority = request.cert_authorities[i]; 70 const std::string& authority = request.cert_authorities[i];
47 ca_names_items[i].type = siBuffer; 71 ca_names_items[i].type = siBuffer;
48 ca_names_items[i].data = 72 ca_names_items[i].data =
49 reinterpret_cast<unsigned char*>(const_cast<char*>(authority.data())); 73 reinterpret_cast<unsigned char*>(const_cast<char*>(authority.data()));
50 ca_names_items[i].len = static_cast<unsigned int>(authority.size()); 74 ca_names_items[i].len = static_cast<unsigned int>(authority.size());
51 } 75 }
52 ca_names.nnames = static_cast<int>(ca_names_items.size()); 76 ca_names.nnames = static_cast<int>(ca_names_items.size());
53 if (!ca_names_items.empty()) 77 if (!ca_names_items.empty())
54 ca_names.names = &ca_names_items[0]; 78 ca_names.names = &ca_names_items[0];
55 79
80 size_t num_raw = 0;
56 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); 81 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
57 !CERT_LIST_END(node, cert_list); 82 !CERT_LIST_END(node, cert_list);
58 node = CERT_LIST_NEXT(node)) { 83 node = CERT_LIST_NEXT(node)) {
84 ++num_raw;
59 // Only offer unexpired certificates. 85 // Only offer unexpired certificates.
60 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) != 86 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) !=
61 secCertTimeValid) { 87 secCertTimeValid) {
88 DVLOG(2) << "skipped expired cert: "
89 << base::StringPiece(node->cert->nickname);
62 continue; 90 continue;
63 } 91 }
64 92
65 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( 93 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
66 node->cert, X509Certificate::OSCertHandles()); 94 node->cert, X509Certificate::OSCertHandles());
67 95
68 // Check if the certificate issuer is allowed by the server. 96 // Check if the certificate issuer is allowed by the server.
69 if (request.cert_authorities.empty() || 97 if (request.cert_authorities.empty() ||
70 (!query_nssdb && 98 (!query_nssdb &&
71 cert->IsIssuedByEncoded(request.cert_authorities)) || 99 cert->IsIssuedByEncoded(request.cert_authorities)) ||
72 (query_nssdb && 100 (query_nssdb &&
73 NSS_CmpCertChainWCANames(node->cert, &ca_names) == SECSuccess)) { 101 NSS_CmpCertChainWCANames(node->cert, &ca_names) == SECSuccess)) {
102 DVLOG(2) << "matched cert: " << base::StringPiece(node->cert->nickname);
74 selected_certs->push_back(cert); 103 selected_certs->push_back(cert);
75 } 104 }
105 else
106 DVLOG(2) << "skipped non-matching cert: "
107 << base::StringPiece(node->cert->nickname);
76 } 108 }
109 DVLOG(2) << "num_raw:" << num_raw
110 << " num_selected:" << selected_certs->size();
77 111
78 std::sort(selected_certs->begin(), selected_certs->end(), 112 std::sort(selected_certs->begin(), selected_certs->end(),
79 x509_util::ClientCertSorter()); 113 x509_util::ClientCertSorter());
80 } 114 }
81 115
82 void GetClientCertsOnWorkerThread( 116 void ClientCertStoreNSS::GetClientCertsOnWorkerThread(
83 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate, 117 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate,
84 const SSLCertRequestInfo* request, 118 const SSLCertRequestInfo* request,
85 CertificateList* selected_certs) { 119 CertificateList* selected_certs) {
86 CERTCertList* client_certs = CERT_FindUserCertsByUsage( 120 CERTCertList* client_certs = CERT_FindUserCertsByUsage(
87 CERT_GetDefaultCertDB(), 121 CERT_GetDefaultCertDB(),
88 certUsageSSLClient, 122 certUsageSSLClient,
89 PR_FALSE, 123 PR_FALSE,
90 PR_FALSE, 124 PR_FALSE,
91 password_delegate.get()); 125 password_delegate.get());
92 // It is ok for a user not to have any client certs. 126 // It is ok for a user not to have any client certs.
93 if (!client_certs) { 127 if (!client_certs) {
128 DVLOG(2) << "No client certs found.";
94 selected_certs->clear(); 129 selected_certs->clear();
95 return; 130 return;
96 } 131 }
97 132
98 GetClientCertsImpl(client_certs, *request, true, selected_certs); 133 GetClientCertsImpl(client_certs, *request, true, selected_certs);
99 CERT_DestroyCertList(client_certs); 134 CERT_DestroyCertList(client_certs);
100 } 135 }
101 136
102 } // namespace
103
104 ClientCertStoreNSS::ClientCertStoreNSS(
105 const PasswordDelegateFactory& password_delegate_factory)
106 : password_delegate_factory_(password_delegate_factory) {}
107
108 ClientCertStoreNSS::~ClientCertStoreNSS() {}
109
110 void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request,
111 CertificateList* selected_certs,
112 const base::Closure& callback) {
113 scoped_ptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate;
114 if (!password_delegate_factory_.is_null()) {
115 password_delegate.reset(
116 password_delegate_factory_.Run(request.host_and_port));
117 }
118 if (!base::WorkerPool::PostTaskAndReply(
119 FROM_HERE,
120 base::Bind(&GetClientCertsOnWorkerThread,
121 base::Passed(&password_delegate),
122 &request,
123 selected_certs),
124 callback,
125 true)) {
126 selected_certs->clear();
127 callback.Run();
128 }
129 }
130
131 bool ClientCertStoreNSS::SelectClientCertsForTesting( 137 bool ClientCertStoreNSS::SelectClientCertsForTesting(
132 const CertificateList& input_certs, 138 const CertificateList& input_certs,
133 const SSLCertRequestInfo& request, 139 const SSLCertRequestInfo& request,
134 CertificateList* selected_certs) { 140 CertificateList* selected_certs) {
135 CERTCertList* cert_list = CERT_NewCertList(); 141 CERTCertList* cert_list = CERT_NewCertList();
136 if (!cert_list) 142 if (!cert_list)
137 return false; 143 return false;
138 for (size_t i = 0; i < input_certs.size(); ++i) { 144 for (size_t i = 0; i < input_certs.size(); ++i) {
139 CERT_AddCertToListTail( 145 CERT_AddCertToListTail(
140 cert_list, CERT_DupCertificate(input_certs[i]->os_cert_handle())); 146 cert_list, CERT_DupCertificate(input_certs[i]->os_cert_handle()));
141 } 147 }
142 148
143 GetClientCertsImpl(cert_list, request, false, selected_certs); 149 GetClientCertsImpl(cert_list, request, false, selected_certs);
144 CERT_DestroyCertList(cert_list); 150 CERT_DestroyCertList(cert_list);
145 return true; 151 return true;
146 } 152 }
147 153
148 } // namespace net 154 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/client_cert_store_nss.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698