| 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 |