OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/openssl_platform_key.h" | 5 #include "net/ssl/openssl_platform_key.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <NCrypt.h> | 8 #include <NCrypt.h> |
9 | 9 |
10 #include <string.h> | 10 #include <string.h> |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include <openssl/bn.h> | 15 #include <openssl/bn.h> |
| 16 #include <openssl/digest.h> |
16 #include <openssl/ec_key.h> | 17 #include <openssl/ec_key.h> |
17 #include <openssl/err.h> | 18 #include <openssl/err.h> |
18 #include <openssl/engine.h> | 19 #include <openssl/engine.h> |
19 #include <openssl/evp.h> | 20 #include <openssl/evp.h> |
20 #include <openssl/md5.h> | 21 #include <openssl/md5.h> |
| 22 #include <openssl/obj_mac.h> |
21 #include <openssl/rsa.h> | 23 #include <openssl/rsa.h> |
22 #include <openssl/sha.h> | 24 #include <openssl/sha.h> |
23 | 25 |
24 #include "base/debug/debugger.h" | 26 #include "base/debug/debugger.h" |
25 #include "base/debug/stack_trace.h" | 27 #include "base/debug/stack_trace.h" |
26 #include "base/lazy_instance.h" | 28 #include "base/lazy_instance.h" |
27 #include "base/logging.h" | 29 #include "base/logging.h" |
28 #include "base/memory/scoped_ptr.h" | 30 #include "base/memory/scoped_ptr.h" |
29 #include "base/win/windows_version.h" | 31 #include "base/win/windows_version.h" |
30 #include "crypto/scoped_capi_types.h" | 32 #include "crypto/scoped_capi_types.h" |
31 #include "crypto/wincrypt_shim.h" | 33 #include "crypto/wincrypt_shim.h" |
32 #include "net/base/net_errors.h" | 34 #include "net/base/net_errors.h" |
33 #include "net/cert/x509_certificate.h" | 35 #include "net/cert/x509_certificate.h" |
34 #include "net/ssl/openssl_ssl_util.h" | 36 #include "net/ssl/openssl_ssl_util.h" |
35 | 37 |
36 // TODO(davidben): The key needs to inform the choice of hash function in | |
37 // TLS 1.2. See https://crbug.com/278370. | |
38 | |
39 namespace net { | 38 namespace net { |
40 | 39 |
41 namespace { | 40 namespace { |
42 | 41 |
43 using NCryptFreeObjectFunc = SECURITY_STATUS(WINAPI*)(NCRYPT_HANDLE); | 42 using NCryptFreeObjectFunc = SECURITY_STATUS(WINAPI*)(NCRYPT_HANDLE); |
44 using NCryptGetPropertyFunc = | 43 using NCryptGetPropertyFunc = |
45 SECURITY_STATUS(WINAPI*)(NCRYPT_HANDLE, // hObject | 44 SECURITY_STATUS(WINAPI*)(NCRYPT_HANDLE, // hObject |
46 LPCWSTR, // pszProperty | 45 LPCWSTR, // pszProperty |
47 PBYTE, // pbOutput | 46 PBYTE, // pbOutput |
48 DWORD, // cbOutput | 47 DWORD, // cbOutput |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 uint8_t* out, | 375 uint8_t* out, |
377 size_t max_out, | 376 size_t max_out, |
378 const uint8_t* in, | 377 const uint8_t* in, |
379 size_t in_len, | 378 size_t in_len, |
380 int padding) { | 379 int padding) { |
381 NOTIMPLEMENTED(); | 380 NOTIMPLEMENTED(); |
382 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_ALGORITHM_TYPE); | 381 OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_ALGORITHM_TYPE); |
383 return 0; | 382 return 0; |
384 } | 383 } |
385 | 384 |
| 385 int RsaMethodSupportsDigest(const RSA* rsa, const EVP_MD* md) { |
| 386 const KeyExData* ex_data = RsaGetExData(rsa); |
| 387 if (!ex_data) { |
| 388 NOTREACHED(); |
| 389 return 0; |
| 390 } |
| 391 |
| 392 int hash_nid = EVP_MD_type(md); |
| 393 if (ex_data->key->dwKeySpec == CERT_NCRYPT_KEY_SPEC) { |
| 394 // Only hashes which appear in RsaSignPKCS1 are supported. |
| 395 if (hash_nid != NID_sha1 && hash_nid != NID_sha256 && |
| 396 hash_nid != NID_sha384 && hash_nid != NID_sha512) { |
| 397 return 0; |
| 398 } |
| 399 |
| 400 // If the key is a 1024-bit RSA, assume conservatively that it may only be |
| 401 // able to sign SHA-1 hashes. This is the case for older Estonian ID cards |
| 402 // that have 1024-bit RSA keys. |
| 403 // |
| 404 // CNG does provide NCryptIsAlgSupported and NCryptEnumAlgorithms functions, |
| 405 // however they seem to both return NTE_NOT_SUPPORTED when querying the |
| 406 // NCRYPT_PROV_HANDLE at the key's NCRYPT_PROVIDER_HANDLE_PROPERTY. |
| 407 if (ex_data->key_length <= 1024 && hash_nid != NID_sha1) |
| 408 return 0; |
| 409 |
| 410 return 1; |
| 411 } else { |
| 412 // If the key is in CAPI, assume conservatively that the CAPI service |
| 413 // provider may only be able to sign SHA-1 hashes. |
| 414 return hash_nid == NID_sha1; |
| 415 } |
| 416 } |
| 417 |
386 const RSA_METHOD win_rsa_method = { | 418 const RSA_METHOD win_rsa_method = { |
387 { | 419 { |
388 0, // references | 420 0, // references |
389 1, // is_static | 421 1, // is_static |
390 }, | 422 }, |
391 nullptr, // app_data | 423 nullptr, // app_data |
392 | 424 |
393 nullptr, // init | 425 nullptr, // init |
394 nullptr, // finish | 426 nullptr, // finish |
395 RsaMethodSize, | 427 RsaMethodSize, |
396 RsaMethodSign, | 428 RsaMethodSign, |
397 nullptr, // verify | 429 nullptr, // verify |
398 RsaMethodEncrypt, | 430 RsaMethodEncrypt, |
399 RsaMethodSignRaw, | 431 RsaMethodSignRaw, |
400 RsaMethodDecrypt, | 432 RsaMethodDecrypt, |
401 RsaMethodVerifyRaw, | 433 RsaMethodVerifyRaw, |
402 nullptr, // private_transform | 434 nullptr, // private_transform |
403 nullptr, // mod_exp | 435 nullptr, // mod_exp |
404 nullptr, // bn_mod_exp | 436 nullptr, // bn_mod_exp |
405 RSA_FLAG_OPAQUE, | 437 RSA_FLAG_OPAQUE, |
406 nullptr, // keygen | 438 nullptr, // keygen |
| 439 RsaMethodSupportsDigest, |
407 }; | 440 }; |
408 | 441 |
409 // Custom ECDSA_METHOD that uses the platform APIs. | 442 // Custom ECDSA_METHOD that uses the platform APIs. |
410 // Note that for now, only signing through ECDSA_sign() is really supported. | 443 // Note that for now, only signing through ECDSA_sign() is really supported. |
411 // all other method pointers are either stubs returning errors, or no-ops. | 444 // all other method pointers are either stubs returning errors, or no-ops. |
412 | 445 |
413 const KeyExData* EcKeyGetExData(const EC_KEY* ec_key) { | 446 const KeyExData* EcKeyGetExData(const EC_KEY* ec_key) { |
414 return reinterpret_cast<const KeyExData*>(EC_KEY_get_ex_data( | 447 return reinterpret_cast<const KeyExData*>(EC_KEY_get_ex_data( |
415 ec_key, global_boringssl_engine.Get().ec_key_ex_index())); | 448 ec_key, global_boringssl_engine.Get().ec_key_ex_index())); |
416 } | 449 } |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 case EVP_PKEY_RSA: | 701 case EVP_PKEY_RSA: |
669 return CreateRSAWrapper(key.Pass(), key_length); | 702 return CreateRSAWrapper(key.Pass(), key_length); |
670 case EVP_PKEY_EC: | 703 case EVP_PKEY_EC: |
671 return CreateECDSAWrapper(key.Pass(), key_length); | 704 return CreateECDSAWrapper(key.Pass(), key_length); |
672 default: | 705 default: |
673 return nullptr; | 706 return nullptr; |
674 } | 707 } |
675 } | 708 } |
676 | 709 |
677 } // namespace net | 710 } // namespace net |
OLD | NEW |