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

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

Issue 2865883002: Unit-test CAPI and CNG SSLPrivateKey implementations. (Closed)
Patch Set: rebase Created 3 years, 7 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/ssl_platform_key_win.h ('k') | net/ssl/ssl_platform_key_win_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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/ssl_platform_key.h" 5 #include "net/ssl/ssl_platform_key_win.h"
6
7 #include <windows.h>
8 #include <NCrypt.h>
9 6
10 #include <algorithm> 7 #include <algorithm>
11 #include <string> 8 #include <string>
12 #include <utility> 9 #include <utility>
13 #include <vector> 10 #include <vector>
14 11
15 #include "base/logging.h" 12 #include "base/logging.h"
16 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
17 #include "crypto/openssl_util.h" 15 #include "crypto/openssl_util.h"
18 #include "crypto/scoped_capi_types.h" 16 #include "crypto/scoped_capi_types.h"
19 #include "crypto/wincrypt_shim.h"
20 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
21 #include "net/cert/x509_certificate.h" 18 #include "net/cert/x509_certificate.h"
19 #include "net/ssl/ssl_platform_key.h"
22 #include "net/ssl/ssl_platform_key_util.h" 20 #include "net/ssl/ssl_platform_key_util.h"
23 #include "net/ssl/ssl_private_key.h" 21 #include "net/ssl/ssl_private_key.h"
24 #include "net/ssl/threaded_ssl_private_key.h" 22 #include "net/ssl/threaded_ssl_private_key.h"
25 #include "third_party/boringssl/src/include/openssl/bn.h" 23 #include "third_party/boringssl/src/include/openssl/bn.h"
26 #include "third_party/boringssl/src/include/openssl/ecdsa.h" 24 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
27 #include "third_party/boringssl/src/include/openssl/evp.h" 25 #include "third_party/boringssl/src/include/openssl/evp.h"
28 26
29 namespace net { 27 namespace net {
30 28
31 namespace { 29 namespace {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 private: 226 private:
229 NCRYPT_KEY_HANDLE key_; 227 NCRYPT_KEY_HANDLE key_;
230 int type_; 228 int type_;
231 size_t max_length_; 229 size_t max_length_;
232 230
233 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG); 231 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG);
234 }; 232 };
235 233
236 } // namespace 234 } // namespace
237 235
236 scoped_refptr<SSLPrivateKey> WrapCAPIPrivateKey(
237 const X509Certificate* certificate,
238 HCRYPTPROV prov,
239 DWORD key_spec) {
240 return make_scoped_refptr(new ThreadedSSLPrivateKey(
241 base::MakeUnique<SSLPlatformKeyCAPI>(prov, key_spec),
242 GetSSLPlatformKeyTaskRunner()));
243 }
244
245 scoped_refptr<SSLPrivateKey> WrapCNGPrivateKey(
246 const X509Certificate* certificate,
247 NCRYPT_KEY_HANDLE key) {
248 // Rather than query the private key for metadata, extract the public key from
249 // the certificate without using Windows APIs. CNG does not consistently work
250 // depending on the system. See https://crbug.com/468345.
251 int key_type;
252 size_t max_length;
253 if (!GetClientCertInfo(certificate, &key_type, &max_length)) {
254 NCryptFreeObject(key);
255 return nullptr;
256 }
257
258 return make_scoped_refptr(new ThreadedSSLPrivateKey(
259 base::MakeUnique<SSLPlatformKeyCNG>(key, key_type, max_length),
260 GetSSLPlatformKeyTaskRunner()));
261 }
262
238 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( 263 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
239 const X509Certificate* certificate) { 264 const X509Certificate* certificate) {
240 // Rather than query the private key for metadata, extract the public key from
241 // the certificate without using Windows APIs. CAPI and CNG do not
242 // consistently work depending on the system. See https://crbug.com/468345.
243 int key_type;
244 size_t max_length;
245 if (!GetClientCertInfo(certificate, &key_type, &max_length))
246 return nullptr;
247
248 PCCERT_CONTEXT cert_context = certificate->os_cert_handle(); 265 PCCERT_CONTEXT cert_context = certificate->os_cert_handle();
249 266
250 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0; 267 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0;
251 DWORD key_spec = 0; 268 DWORD key_spec = 0;
252 BOOL must_free = FALSE; 269 BOOL must_free = FALSE;
253 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; 270 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG;
254 271
255 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr, 272 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr,
256 &prov_or_key, &key_spec, &must_free)) { 273 &prov_or_key, &key_spec, &must_free)) {
257 PLOG(WARNING) << "Could not acquire private key"; 274 PLOG(WARNING) << "Could not acquire private key";
258 return nullptr; 275 return nullptr;
259 } 276 }
260 277
261 // Should never get a cached handle back - ownership must always be 278 // Should never get a cached handle back - ownership must always be
262 // transferred. 279 // transferred.
263 CHECK_EQ(must_free, TRUE); 280 CHECK_EQ(must_free, TRUE);
264 281
265 std::unique_ptr<ThreadedSSLPrivateKey::Delegate> delegate;
266 if (key_spec == CERT_NCRYPT_KEY_SPEC) { 282 if (key_spec == CERT_NCRYPT_KEY_SPEC) {
267 delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length)); 283 return WrapCNGPrivateKey(certificate, prov_or_key);
268 } else { 284 } else {
269 DCHECK_EQ(EVP_PKEY_RSA, key_type); 285 return WrapCAPIPrivateKey(certificate, prov_or_key, key_spec);
270 delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec));
271 } 286 }
272 return make_scoped_refptr(new ThreadedSSLPrivateKey(
273 std::move(delegate), GetSSLPlatformKeyTaskRunner()));
274 } 287 }
275 288
276 } // namespace net 289 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/ssl_platform_key_win.h ('k') | net/ssl/ssl_platform_key_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698