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

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

Issue 2822283002: Remove SSLPrivateKey metadata hooks. (Closed)
Patch Set: emaxx comment Created 3 years, 8 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_util_unittest.cc ('k') | net/ssl/ssl_private_key.h » ('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.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <NCrypt.h> 8 #include <NCrypt.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 15 matching lines...) Expand all
26 #include "third_party/boringssl/src/include/openssl/ecdsa.h" 26 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
27 #include "third_party/boringssl/src/include/openssl/evp.h" 27 #include "third_party/boringssl/src/include/openssl/evp.h"
28 28
29 namespace net { 29 namespace net {
30 30
31 namespace { 31 namespace {
32 32
33 class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate { 33 class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
34 public: 34 public:
35 // Takes ownership of |provider|. 35 // Takes ownership of |provider|.
36 SSLPlatformKeyCAPI(HCRYPTPROV provider, DWORD key_spec, size_t max_length) 36 SSLPlatformKeyCAPI(HCRYPTPROV provider, DWORD key_spec)
37 : provider_(provider), key_spec_(key_spec), max_length_(max_length) {} 37 : provider_(provider), key_spec_(key_spec) {}
38 38
39 ~SSLPlatformKeyCAPI() override {} 39 ~SSLPlatformKeyCAPI() override {}
40 40
41 SSLPrivateKey::Type GetType() override { return SSLPrivateKey::Type::RSA; }
42
43 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { 41 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
44 // If the key is in CAPI, assume conservatively that the CAPI service 42 // If the key is in CAPI, assume conservatively that the CAPI service
45 // provider may only be able to sign pre-TLS-1.2 and SHA-1 hashes. 43 // provider may only be able to sign pre-TLS-1.2 and SHA-1 hashes.
46 static const SSLPrivateKey::Hash kHashes[] = { 44 static const SSLPrivateKey::Hash kHashes[] = {
47 SSLPrivateKey::Hash::SHA1, SSLPrivateKey::Hash::SHA512, 45 SSLPrivateKey::Hash::SHA1, SSLPrivateKey::Hash::SHA512,
48 SSLPrivateKey::Hash::SHA384, SSLPrivateKey::Hash::SHA256}; 46 SSLPrivateKey::Hash::SHA384, SSLPrivateKey::Hash::SHA256};
49 return std::vector<SSLPrivateKey::Hash>(kHashes, 47 return std::vector<SSLPrivateKey::Hash>(kHashes,
50 kHashes + arraysize(kHashes)); 48 kHashes + arraysize(kHashes));
51 } 49 }
52 50
53 size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
54
55 Error SignDigest(SSLPrivateKey::Hash hash, 51 Error SignDigest(SSLPrivateKey::Hash hash,
56 const base::StringPiece& input, 52 const base::StringPiece& input,
57 std::vector<uint8_t>* signature) override { 53 std::vector<uint8_t>* signature) override {
58 ALG_ID hash_alg = 0; 54 ALG_ID hash_alg = 0;
59 switch (hash) { 55 switch (hash) {
60 case SSLPrivateKey::Hash::MD5_SHA1: 56 case SSLPrivateKey::Hash::MD5_SHA1:
61 hash_alg = CALG_SSL3_SHAMD5; 57 hash_alg = CALG_SSL3_SHAMD5;
62 break; 58 break;
63 case SSLPrivateKey::Hash::SHA1: 59 case SSLPrivateKey::Hash::SHA1:
64 hash_alg = CALG_SHA1; 60 hash_alg = CALG_SHA1;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 signature->resize(signature_len); 107 signature->resize(signature_len);
112 108
113 // CryptoAPI signs in little-endian, so reverse it. 109 // CryptoAPI signs in little-endian, so reverse it.
114 std::reverse(signature->begin(), signature->end()); 110 std::reverse(signature->begin(), signature->end());
115 return OK; 111 return OK;
116 } 112 }
117 113
118 private: 114 private:
119 crypto::ScopedHCRYPTPROV provider_; 115 crypto::ScopedHCRYPTPROV provider_;
120 DWORD key_spec_; 116 DWORD key_spec_;
121 size_t max_length_;
122 117
123 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCAPI); 118 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCAPI);
124 }; 119 };
125 120
126 class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate { 121 class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate {
127 public: 122 public:
128 // Takes ownership of |key|. 123 // Takes ownership of |key|.
129 SSLPlatformKeyCNG(NCRYPT_KEY_HANDLE key, 124 SSLPlatformKeyCNG(NCRYPT_KEY_HANDLE key, int type, size_t max_length)
130 SSLPrivateKey::Type type,
131 size_t max_length)
132 : key_(key), type_(type), max_length_(max_length) {} 125 : key_(key), type_(type), max_length_(max_length) {}
133 126
134 ~SSLPlatformKeyCNG() override { NCryptFreeObject(key_); } 127 ~SSLPlatformKeyCNG() override { NCryptFreeObject(key_); }
135 128
136 SSLPrivateKey::Type GetType() override { return type_; }
137
138 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { 129 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
139 // If this is an under 1024-bit RSA key, conservatively prefer to sign 130 // If this is an under 1024-bit RSA key, conservatively prefer to sign
140 // SHA-1 hashes. Older Estonian ID cards can only sign SHA-1 hashes. 131 // SHA-1 hashes. Older Estonian ID cards can only sign SHA-1 hashes.
141 // However, if the server doesn't advertise SHA-1, the remaining hashes 132 // However, if the server doesn't advertise SHA-1, the remaining hashes
142 // might still be supported. 133 // might still be supported.
143 if (type_ == SSLPrivateKey::Type::RSA && max_length_ <= 1024 / 8) { 134 if (type_ == EVP_PKEY_RSA && max_length_ <= 1024 / 8) {
144 static const SSLPrivateKey::Hash kHashesSpecial[] = { 135 static const SSLPrivateKey::Hash kHashesSpecial[] = {
145 SSLPrivateKey::Hash::SHA1, SSLPrivateKey::Hash::SHA512, 136 SSLPrivateKey::Hash::SHA1, SSLPrivateKey::Hash::SHA512,
146 SSLPrivateKey::Hash::SHA384, SSLPrivateKey::Hash::SHA256}; 137 SSLPrivateKey::Hash::SHA384, SSLPrivateKey::Hash::SHA256};
147 return std::vector<SSLPrivateKey::Hash>( 138 return std::vector<SSLPrivateKey::Hash>(
148 kHashesSpecial, kHashesSpecial + arraysize(kHashesSpecial)); 139 kHashesSpecial, kHashesSpecial + arraysize(kHashesSpecial));
149 } 140 }
150 static const SSLPrivateKey::Hash kHashes[] = { 141 static const SSLPrivateKey::Hash kHashes[] = {
151 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384, 142 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
152 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1}; 143 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1};
153 return std::vector<SSLPrivateKey::Hash>(kHashes, 144 return std::vector<SSLPrivateKey::Hash>(kHashes,
154 kHashes + arraysize(kHashes)); 145 kHashes + arraysize(kHashes));
155 } 146 }
156 147
157 size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
158
159 Error SignDigest(SSLPrivateKey::Hash hash, 148 Error SignDigest(SSLPrivateKey::Hash hash,
160 const base::StringPiece& input, 149 const base::StringPiece& input,
161 std::vector<uint8_t>* signature) override { 150 std::vector<uint8_t>* signature) override {
162 crypto::OpenSSLErrStackTracer tracer(FROM_HERE); 151 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
163 152
164 BCRYPT_PKCS1_PADDING_INFO rsa_padding_info = {0}; 153 BCRYPT_PKCS1_PADDING_INFO rsa_padding_info = {0};
165 void* padding_info = nullptr; 154 void* padding_info = nullptr;
166 DWORD flags = 0; 155 DWORD flags = 0;
167 if (type_ == SSLPrivateKey::Type::RSA) { 156 if (type_ == EVP_PKEY_RSA) {
168 switch (hash) { 157 switch (hash) {
169 case SSLPrivateKey::Hash::MD5_SHA1: 158 case SSLPrivateKey::Hash::MD5_SHA1:
170 rsa_padding_info.pszAlgId = nullptr; 159 rsa_padding_info.pszAlgId = nullptr;
171 break; 160 break;
172 case SSLPrivateKey::Hash::SHA1: 161 case SSLPrivateKey::Hash::SHA1:
173 rsa_padding_info.pszAlgId = BCRYPT_SHA1_ALGORITHM; 162 rsa_padding_info.pszAlgId = BCRYPT_SHA1_ALGORITHM;
174 break; 163 break;
175 case SSLPrivateKey::Hash::SHA256: 164 case SSLPrivateKey::Hash::SHA256:
176 rsa_padding_info.pszAlgId = BCRYPT_SHA256_ALGORITHM; 165 rsa_padding_info.pszAlgId = BCRYPT_SHA256_ALGORITHM;
177 break; 166 break;
(...skipping 23 matching lines...) Expand all
201 const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())), 190 const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())),
202 input.size(), signature->data(), signature_len, &signature_len, flags); 191 input.size(), signature->data(), signature_len, &signature_len, flags);
203 if (FAILED(status)) { 192 if (FAILED(status)) {
204 LOG(ERROR) << "NCryptSignHash failed: " << status; 193 LOG(ERROR) << "NCryptSignHash failed: " << status;
205 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 194 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
206 } 195 }
207 signature->resize(signature_len); 196 signature->resize(signature_len);
208 197
209 // CNG emits raw ECDSA signatures, but BoringSSL expects a DER-encoded 198 // CNG emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
210 // ECDSA-Sig-Value. 199 // ECDSA-Sig-Value.
211 if (SSLPrivateKey::IsECDSAType(type_)) { 200 if (type_ == EVP_PKEY_EC) {
212 if (signature->size() % 2 != 0) { 201 if (signature->size() % 2 != 0) {
213 LOG(ERROR) << "Bad signature length"; 202 LOG(ERROR) << "Bad signature length";
214 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 203 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
215 } 204 }
216 size_t order_len = signature->size() / 2; 205 size_t order_len = signature->size() / 2;
217 206
218 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value. 207 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
219 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); 208 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
220 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) || 209 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
221 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) { 210 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
222 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 211 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
223 } 212 }
224 213
225 int len = i2d_ECDSA_SIG(sig.get(), nullptr); 214 int len = i2d_ECDSA_SIG(sig.get(), nullptr);
226 if (len <= 0) 215 if (len <= 0)
227 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 216 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
228 signature->resize(len); 217 signature->resize(len);
229 uint8_t* ptr = signature->data(); 218 uint8_t* ptr = signature->data();
230 len = i2d_ECDSA_SIG(sig.get(), &ptr); 219 len = i2d_ECDSA_SIG(sig.get(), &ptr);
231 if (len <= 0) 220 if (len <= 0)
232 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 221 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
233 signature->resize(len); 222 signature->resize(len);
234 } 223 }
235 224
236 return OK; 225 return OK;
237 } 226 }
238 227
239 private: 228 private:
240 NCRYPT_KEY_HANDLE key_; 229 NCRYPT_KEY_HANDLE key_;
241 SSLPrivateKey::Type type_; 230 int type_;
242 size_t max_length_; 231 size_t max_length_;
243 232
244 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG); 233 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG);
245 }; 234 };
246 235
247 } // namespace 236 } // namespace
248 237
249 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( 238 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
250 const X509Certificate* certificate) { 239 const X509Certificate* certificate) {
251 // Rather than query the private key for metadata, extract the public key from 240 // Rather than query the private key for metadata, extract the public key from
252 // the certificate without using Windows APIs. CAPI and CNG do not 241 // the certificate without using Windows APIs. CAPI and CNG do not
253 // consistently work depending on the system. See https://crbug.com/468345. 242 // consistently work depending on the system. See https://crbug.com/468345.
254 SSLPrivateKey::Type key_type; 243 int key_type;
255 size_t max_length; 244 size_t max_length;
256 if (!GetClientCertInfo(certificate, &key_type, &max_length)) 245 if (!GetClientCertInfo(certificate, &key_type, &max_length))
257 return nullptr; 246 return nullptr;
258 247
259 PCCERT_CONTEXT cert_context = certificate->os_cert_handle(); 248 PCCERT_CONTEXT cert_context = certificate->os_cert_handle();
260 249
261 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0; 250 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0;
262 DWORD key_spec = 0; 251 DWORD key_spec = 0;
263 BOOL must_free = FALSE; 252 BOOL must_free = FALSE;
264 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; 253 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG;
265 254
266 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr, 255 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr,
267 &prov_or_key, &key_spec, &must_free)) { 256 &prov_or_key, &key_spec, &must_free)) {
268 PLOG(WARNING) << "Could not acquire private key"; 257 PLOG(WARNING) << "Could not acquire private key";
269 return nullptr; 258 return nullptr;
270 } 259 }
271 260
272 // Should never get a cached handle back - ownership must always be 261 // Should never get a cached handle back - ownership must always be
273 // transferred. 262 // transferred.
274 CHECK_EQ(must_free, TRUE); 263 CHECK_EQ(must_free, TRUE);
275 264
276 std::unique_ptr<ThreadedSSLPrivateKey::Delegate> delegate; 265 std::unique_ptr<ThreadedSSLPrivateKey::Delegate> delegate;
277 if (key_spec == CERT_NCRYPT_KEY_SPEC) { 266 if (key_spec == CERT_NCRYPT_KEY_SPEC) {
278 delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length)); 267 delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length));
279 } else { 268 } else {
280 DCHECK(SSLPrivateKey::Type::RSA == key_type); 269 DCHECK_EQ(EVP_PKEY_RSA, key_type);
281 delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length)); 270 delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec));
282 } 271 }
283 return make_scoped_refptr(new ThreadedSSLPrivateKey( 272 return make_scoped_refptr(new ThreadedSSLPrivateKey(
284 std::move(delegate), GetSSLPlatformKeyTaskRunner())); 273 std::move(delegate), GetSSLPlatformKeyTaskRunner()));
285 } 274 }
286 275
287 } // namespace net 276 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/ssl_platform_key_util_unittest.cc ('k') | net/ssl/ssl_private_key.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698