summaryrefslogtreecommitdiff
path: root/chromium/net/ssl/ssl_platform_key_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/ssl/ssl_platform_key_win.cc')
-rw-r--r--chromium/net/ssl/ssl_platform_key_win.cc86
1 files changed, 61 insertions, 25 deletions
diff --git a/chromium/net/ssl/ssl_platform_key_win.cc b/chromium/net/ssl/ssl_platform_key_win.cc
index 04a6b11bab5..64b43e6e0b5 100644
--- a/chromium/net/ssl/ssl_platform_key_win.cc
+++ b/chromium/net/ssl/ssl_platform_key_win.cc
@@ -50,12 +50,12 @@ std::string GetCAPIProviderName(HCRYPTPROV provider) {
class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
public:
// Takes ownership of |provider|.
- SSLPlatformKeyCAPI(HCRYPTPROV provider, DWORD key_spec)
- : provider_name_(GetCAPIProviderName(provider)),
- provider_(provider),
+ SSLPlatformKeyCAPI(crypto::ScopedHCRYPTPROV provider, DWORD key_spec)
+ : provider_name_(GetCAPIProviderName(provider.get())),
+ provider_(std::move(provider)),
key_spec_(key_spec) {}
- ~SSLPlatformKeyCAPI() override {}
+ ~SSLPlatformKeyCAPI() override = default;
std::string GetProviderName() override { return "CAPI: " + provider_name_; }
@@ -65,8 +65,10 @@ class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
// Prioritize SHA-1, but if the server doesn't advertise it, leave the other
// algorithms enabled to try.
return {
- SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA256,
- SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA512,
+ SSL_SIGN_RSA_PKCS1_SHA1,
+ SSL_SIGN_RSA_PKCS1_SHA256,
+ SSL_SIGN_RSA_PKCS1_SHA384,
+ SSL_SIGN_RSA_PKCS1_SHA512,
};
}
@@ -104,7 +106,9 @@ class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
}
crypto::ScopedHCRYPTHASH hash_handle;
- if (!CryptCreateHash(provider_, hash_alg, 0, 0, hash_handle.receive())) {
+ if (!CryptCreateHash(
+ provider_.get(), hash_alg, 0, 0,
+ crypto::ScopedHCRYPTHASH::Receiver(hash_handle).get())) {
PLOG(ERROR) << "CreateCreateHash failed";
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
@@ -167,7 +171,7 @@ class ScopedNCRYPT_PROV_HANDLE {
NCRYPT_PROV_HANDLE prov_ = 0;
};
-std::string GetCNGProviderName(NCRYPT_KEY_HANDLE key) {
+std::wstring GetCNGProviderName(NCRYPT_KEY_HANDLE key) {
ScopedNCRYPT_PROV_HANDLE prov;
DWORD prov_len = 0;
SECURITY_STATUS status = NCryptGetProperty(
@@ -175,7 +179,7 @@ std::string GetCNGProviderName(NCRYPT_KEY_HANDLE key) {
reinterpret_cast<BYTE*>(prov.InitializeInto()),
sizeof(*prov.InitializeInto()), &prov_len, NCRYPT_SILENT_FLAG);
if (FAILED(status)) {
- return "(error getting provider)";
+ return L"(error getting provider)";
}
DCHECK_EQ(sizeof(NCRYPT_PROV_HANDLE), prov_len);
@@ -186,14 +190,15 @@ std::string GetCNGProviderName(NCRYPT_KEY_HANDLE key) {
status = NCryptGetProperty(prov.get(), NCRYPT_NAME_PROPERTY, nullptr, 0,
&name_len, NCRYPT_SILENT_FLAG);
if (FAILED(status) || name_len % sizeof(wchar_t) != 0) {
- return "(error getting provider name)";
+ return L"(error getting provider name)";
}
- std::vector<wchar_t> name(name_len / sizeof(wchar_t));
+ std::vector<wchar_t> name;
+ name.reserve(name_len / sizeof(wchar_t));
status = NCryptGetProperty(
prov.get(), NCRYPT_NAME_PROPERTY, reinterpret_cast<BYTE*>(name.data()),
name.size() * sizeof(wchar_t), &name_len, NCRYPT_SILENT_FLAG);
if (FAILED(status)) {
- return "(error getting provider name)";
+ return L"(error getting provider name)";
}
name.resize(name_len / sizeof(wchar_t));
@@ -203,7 +208,7 @@ std::string GetCNGProviderName(NCRYPT_KEY_HANDLE key) {
if (nul != name.end()) {
name.erase(nul, name.end());
}
- return base::WideToUTF8(base::WStringPiece(name.data(), name.size()));
+ return std::wstring(name.begin(), name.end());
}
class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
@@ -217,23 +222,53 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
~SSLPlatformKeyCNG() override { NCryptFreeObject(key_); }
- std::string GetProviderName() override { return "CNG: " + provider_name_; }
+ std::string GetProviderName() override {
+ return "CNG: " + base::WideToUTF8(provider_name_);
+ }
std::vector<uint16_t> GetAlgorithmPreferences() override {
+ // Per TLS 1.3 (RFC 8446), the RSA-PSS code points in TLS correspond to
+ // RSA-PSS with salt length equal to the digest length. TPM 2.0's
+ // TPM_ALG_RSAPSS algorithm, however, uses the maximum possible salt length.
+ // The TPM provider will fail signing requests for other salt lengths and
+ // thus cannot generate TLS-compatible PSS signatures.
+ //
+ // However, as of TPM revision 1.16, TPMs which follow FIPS 186-4 will
+ // instead interpret TPM_ALG_RSAPSS using salt length equal to the digest
+ // length. Those TPMs can generate TLS-compatible PSS signatures. As a
+ // result, if this is a TPM-based key, we only report PSS as supported if
+ // the salt length will match the digest length.
+ bool supports_pss = true;
+ if (provider_name_ == MS_PLATFORM_KEY_STORAGE_PROVIDER) {
+ DWORD salt_size = 0;
+ DWORD size_of_salt_size = sizeof(salt_size);
+ HRESULT status =
+ NCryptGetProperty(key_, NCRYPT_PCP_PSS_SALT_SIZE_PROPERTY,
+ reinterpret_cast<PBYTE>(&salt_size),
+ size_of_salt_size, &size_of_salt_size, 0);
+ if (FAILED(status) || salt_size != NCRYPT_TPM_PSS_SALT_SIZE_HASHSIZE) {
+ supports_pss = false;
+ }
+ }
// If this is an under 1024-bit RSA key, conservatively prefer to sign SHA-1
// hashes. Older Estonian ID cards can only sign SHA-1 hashes. Prioritize
// SHA-1, but if the server doesn't advertise it, leave the other algorithms
// enabled to try.
if (type_ == EVP_PKEY_RSA && max_length_ <= 1024 / 8) {
- return {
- SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA256,
- SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA512,
- // 1024-bit keys are too small for SSL_SIGN_RSA_PSS_SHA512.
- SSL_SIGN_RSA_PSS_SHA256, SSL_SIGN_RSA_PSS_SHA384,
+ std::vector<uint16_t> ret = {
+ SSL_SIGN_RSA_PKCS1_SHA1,
+ SSL_SIGN_RSA_PKCS1_SHA256,
+ SSL_SIGN_RSA_PKCS1_SHA384,
+ SSL_SIGN_RSA_PKCS1_SHA512,
};
+ if (supports_pss) {
+ // 1024-bit keys are too small for SSL_SIGN_RSA_PSS_SHA512.
+ ret.push_back(SSL_SIGN_RSA_PSS_SHA256);
+ ret.push_back(SSL_SIGN_RSA_PSS_SHA384);
+ }
+ return ret;
}
- return SSLPrivateKey::DefaultAlgorithmPreferences(type_,
- true /* supports PSS */);
+ return SSLPrivateKey::DefaultAlgorithmPreferences(type_, supports_pss);
}
Error Sign(uint16_t algorithm,
@@ -336,7 +371,7 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
}
private:
- std::string provider_name_;
+ std::wstring provider_name_;
NCRYPT_KEY_HANDLE key_;
int type_;
size_t max_length_;
@@ -348,10 +383,10 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
scoped_refptr<SSLPrivateKey> WrapCAPIPrivateKey(
const X509Certificate* certificate,
- HCRYPTPROV prov,
+ crypto::ScopedHCRYPTPROV prov,
DWORD key_spec) {
return base::MakeRefCounted<ThreadedSSLPrivateKey>(
- std::make_unique<SSLPlatformKeyCAPI>(prov, key_spec),
+ std::make_unique<SSLPlatformKeyCAPI>(std::move(prov), key_spec),
GetSSLPlatformKeyTaskRunner());
}
@@ -394,7 +429,8 @@ scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
if (key_spec == CERT_NCRYPT_KEY_SPEC) {
return WrapCNGPrivateKey(certificate, prov_or_key);
} else {
- return WrapCAPIPrivateKey(certificate, prov_or_key, key_spec);
+ return WrapCAPIPrivateKey(certificate,
+ crypto::ScopedHCRYPTPROV(prov_or_key), key_spec);
}
}