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

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