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

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

Issue 2927193003: ClientCertStoreWin: do client cert and key lookup on SSLPlatformKeyTaskRunner. (Closed)
Patch Set: . Created 3 years, 6 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_win.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_win.h" 5 #include "net/ssl/client_cert_store_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #define SECURITY_WIN32 // Needs to be defined before including security.h 10 #define SECURITY_WIN32 // Needs to be defined before including security.h
11 #include <windows.h> 11 #include <windows.h>
12 #include <security.h> 12 #include <security.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
16 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
19 #include "base/numerics/safe_conversions.h" 19 #include "base/numerics/safe_conversions.h"
20 #include "base/task_runner_util.h" 20 #include "base/task_runner_util.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "crypto/wincrypt_shim.h" 22 #include "crypto/wincrypt_shim.h"
23 #include "net/cert/x509_util.h" 23 #include "net/cert/x509_util.h"
24 #include "net/cert/x509_util_win.h" 24 #include "net/cert/x509_util_win.h"
25 #include "net/ssl/ssl_platform_key_util.h"
25 #include "net/ssl/ssl_platform_key_win.h" 26 #include "net/ssl/ssl_platform_key_win.h"
26 #include "net/ssl/ssl_private_key.h" 27 #include "net/ssl/ssl_private_key.h"
27 28
28 namespace net { 29 namespace net {
29 30
30 namespace { 31 namespace {
31 32
32 class ClientCertIdentityWin : public ClientCertIdentity { 33 class ClientCertIdentityWin : public ClientCertIdentity {
33 public: 34 public:
34 // Takes ownership of |cert_context|. 35 // Takes ownership of |cert_context|.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 // CertFindChainInStore()? 99 // CertFindChainInStore()?
99 DWORD size = 0; 100 DWORD size = 0;
100 if (!CertGetCertificateContextProperty( 101 if (!CertGetCertificateContextProperty(
101 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) { 102 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) {
102 return FALSE; 103 return FALSE;
103 } 104 }
104 105
105 return TRUE; 106 return TRUE;
106 } 107 }
107 108
108 void GetClientCertsImpl(HCERTSTORE cert_store, 109 ClientCertIdentityList GetClientCertsImpl(HCERTSTORE cert_store,
109 const SSLCertRequestInfo& request, 110 const SSLCertRequestInfo& request) {
110 ClientCertIdentityList* selected_identities) { 111 ClientCertIdentityList selected_identities;
111 selected_identities->clear();
112 112
113 scoped_refptr<base::SingleThreadTaskRunner> current_thread = 113 scoped_refptr<base::SingleThreadTaskRunner> current_thread =
114 base::ThreadTaskRunnerHandle::Get(); 114 base::ThreadTaskRunnerHandle::Get();
115 115
116 const size_t auth_count = request.cert_authorities.size(); 116 const size_t auth_count = request.cert_authorities.size();
117 std::vector<CERT_NAME_BLOB> issuers(auth_count); 117 std::vector<CERT_NAME_BLOB> issuers(auth_count);
118 for (size_t i = 0; i < auth_count; ++i) { 118 for (size_t i = 0; i < auth_count; ++i) {
119 issuers[i].cbData = static_cast<DWORD>(request.cert_authorities[i].size()); 119 issuers[i].cbData = static_cast<DWORD>(request.cert_authorities[i].size());
120 issuers[i].pbData = reinterpret_cast<BYTE*>( 120 issuers[i].pbData = reinterpret_cast<BYTE*>(
121 const_cast<char*>(request.cert_authorities[i].data())); 121 const_cast<char*>(request.cert_authorities[i].data()));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 // USE_BYTE_CERTS. Remove it once the non-byte-certs code is also removed. 191 // USE_BYTE_CERTS. Remove it once the non-byte-certs code is also removed.
192 // TODO(svaldez): cert currently wraps cert_context2 which may be backed 192 // TODO(svaldez): cert currently wraps cert_context2 which may be backed
193 // by a smartcard with threading difficulties. Instead, create a fresh 193 // by a smartcard with threading difficulties. Instead, create a fresh
194 // X509Certificate with CreateFromBytes and route cert_context2 into the 194 // X509Certificate with CreateFromBytes and route cert_context2 into the
195 // SSLPrivateKey. Probably changing CertificateList to be a 195 // SSLPrivateKey. Probably changing CertificateList to be a
196 // pair<X509Certificate, SSLPrivateKeyCallback>. 196 // pair<X509Certificate, SSLPrivateKeyCallback>.
197 scoped_refptr<X509Certificate> cert = 197 scoped_refptr<X509Certificate> cert =
198 x509_util::CreateX509CertificateFromCertContexts(cert_context2, 198 x509_util::CreateX509CertificateFromCertContexts(cert_context2,
199 intermediates); 199 intermediates);
200 if (cert) { 200 if (cert) {
201 selected_identities->push_back(base::MakeUnique<ClientCertIdentityWin>( 201 selected_identities.push_back(base::MakeUnique<ClientCertIdentityWin>(
202 std::move(cert), 202 std::move(cert),
203 cert_context2, // Takes ownership of |cert_context2|. 203 cert_context2, // Takes ownership of |cert_context2|.
204 current_thread)); // The key must be acquired on the same thread, as 204 current_thread)); // The key must be acquired on the same thread, as
205 // the PCCERT_CONTEXT may not be thread safe. 205 // the PCCERT_CONTEXT may not be thread safe.
206 } 206 }
207 for (size_t i = 0; i < intermediates.size(); ++i) 207 for (size_t i = 0; i < intermediates.size(); ++i)
208 CertFreeCertificateContext(intermediates[i]); 208 CertFreeCertificateContext(intermediates[i]);
209 } 209 }
210 210
211 std::sort(selected_identities->begin(), selected_identities->end(), 211 std::sort(selected_identities.begin(), selected_identities.end(),
212 ClientCertIdentitySorter()); 212 ClientCertIdentitySorter());
213 return selected_identities;
213 } 214 }
214 215
215 } // namespace 216 } // namespace
216 217
217 ClientCertStoreWin::ClientCertStoreWin() {} 218 ClientCertStoreWin::ClientCertStoreWin() {}
218 219
219 ClientCertStoreWin::ClientCertStoreWin(HCERTSTORE cert_store) { 220 ClientCertStoreWin::ClientCertStoreWin(HCERTSTORE cert_store) {
220 DCHECK(cert_store); 221 DCHECK(cert_store);
221 cert_store_.reset(cert_store); 222 cert_store_.reset(cert_store);
222 } 223 }
223 224
224 ClientCertStoreWin::~ClientCertStoreWin() {} 225 ClientCertStoreWin::~ClientCertStoreWin() {}
225 226
226 void ClientCertStoreWin::GetClientCerts( 227 void ClientCertStoreWin::GetClientCerts(
227 const SSLCertRequestInfo& request, 228 const SSLCertRequestInfo& request,
228 const ClientCertListCallback& callback) { 229 const ClientCertListCallback& callback) {
229 ClientCertIdentityList selected_identities;
230 if (cert_store_) { 230 if (cert_store_) {
231 // Use the existing client cert store. Note: Under some situations, 231 // Use the existing client cert store. Note: Under some situations,
232 // it's possible for this to return certificates that aren't usable 232 // it's possible for this to return certificates that aren't usable
233 // (see below). 233 // (see below).
234 GetClientCertsImpl(cert_store_, request, &selected_identities); 234 // When using caller provided HCERTSTORE, assume that it should be accessed
235 callback.Run(std::move(selected_identities)); 235 // on the current thread.
236 callback.Run(GetClientCertsImpl(cert_store_, request));
236 return; 237 return;
237 } 238 }
238 239
240 #if BUILDFLAG(USE_BYTE_CERTS)
241 if (base::PostTaskAndReplyWithResult(
242 GetSSLPlatformKeyTaskRunner().get(), FROM_HERE,
243 // Caller is responsible for keeping the |request| alive
244 // until the callback is run, so ConstRef is safe.
245 base::Bind(&ClientCertStoreWin::GetClientCertsWithMyCertStore,
246 base::ConstRef(request)),
247 callback)) {
248 return;
249 }
250
251 // If the task could not be posted, behave as if there were no certificates.
252 callback.Run(ClientCertIdentityList());
253 #else
254 // When using PCERT_CONTEXT based X509Certificate, must do this on the same
255 // thread.
256 callback.Run(GetClientCertsWithMyCertStore(request));
257 #endif
258 }
259
260 // static
261 ClientCertIdentityList ClientCertStoreWin::GetClientCertsWithMyCertStore(
262 const SSLCertRequestInfo& request) {
239 // Always open a new instance of the "MY" store, to ensure that there 263 // Always open a new instance of the "MY" store, to ensure that there
240 // are no previously cached certificates being reused after they're 264 // are no previously cached certificates being reused after they're
241 // no longer available (some smartcard providers fail to update the "MY" 265 // no longer available (some smartcard providers fail to update the "MY"
242 // store handles and instead interpose CertOpenSystemStore). 266 // store handles and instead interpose CertOpenSystemStore).
243 ScopedHCERTSTORE my_cert_store(CertOpenSystemStore(NULL, L"MY")); 267 ScopedHCERTSTORE my_cert_store(CertOpenSystemStore(NULL, L"MY"));
244 if (!my_cert_store) { 268 if (!my_cert_store) {
245 PLOG(ERROR) << "Could not open the \"MY\" system certificate store: "; 269 PLOG(ERROR) << "Could not open the \"MY\" system certificate store: ";
246 callback.Run(ClientCertIdentityList()); 270 return ClientCertIdentityList();
247 return;
248 } 271 }
249 272 return GetClientCertsImpl(my_cert_store, request);
250 GetClientCertsImpl(my_cert_store, request, &selected_identities);
251 callback.Run(std::move(selected_identities));
252 } 273 }
253 274
254 bool ClientCertStoreWin::SelectClientCertsForTesting( 275 bool ClientCertStoreWin::SelectClientCertsForTesting(
255 const CertificateList& input_certs, 276 const CertificateList& input_certs,
256 const SSLCertRequestInfo& request, 277 const SSLCertRequestInfo& request,
257 ClientCertIdentityList* selected_identities) { 278 ClientCertIdentityList* selected_identities) {
258 ScopedHCERTSTORE test_store(CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, 279 ScopedHCERTSTORE test_store(CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0,
259 NULL)); 280 NULL));
260 if (!test_store) 281 if (!test_store)
261 return false; 282 return false;
(...skipping 18 matching lines...) Expand all
280 // would be discarded by the filtering routines. 301 // would be discarded by the filtering routines.
281 CRYPT_KEY_PROV_INFO private_key_data; 302 CRYPT_KEY_PROV_INFO private_key_data;
282 memset(&private_key_data, 0, sizeof(private_key_data)); 303 memset(&private_key_data, 0, sizeof(private_key_data));
283 if (!CertSetCertificateContextProperty(cert, 304 if (!CertSetCertificateContextProperty(cert,
284 CERT_KEY_PROV_INFO_PROP_ID, 305 CERT_KEY_PROV_INFO_PROP_ID,
285 0, &private_key_data)) { 306 0, &private_key_data)) {
286 return false; 307 return false;
287 } 308 }
288 } 309 }
289 310
290 GetClientCertsImpl(test_store.get(), request, selected_identities); 311 *selected_identities = GetClientCertsImpl(test_store.get(), request);
291 return true; 312 return true;
292 } 313 }
293 314
294 } // namespace net 315 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/client_cert_store_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698