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

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

Issue 2391213002: Report curve types in ECDSA SSLPrivateKeys. (Closed)
Patch Set: rebase Created 4 years, 2 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>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include <openssl/bn.h> 15 #include <openssl/bn.h>
16 #include <openssl/ecdsa.h> 16 #include <openssl/ecdsa.h>
17 #include <openssl/evp.h> 17 #include <openssl/evp.h>
18 #include <openssl/x509.h> 18 #include <openssl/x509.h>
19 19
20 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "base/macros.h" 21 #include "base/macros.h"
22 #include "base/sequenced_task_runner.h" 22 #include "base/sequenced_task_runner.h"
23 #include "crypto/openssl_util.h" 23 #include "crypto/openssl_util.h"
24 #include "crypto/scoped_capi_types.h" 24 #include "crypto/scoped_capi_types.h"
25 #include "crypto/wincrypt_shim.h" 25 #include "crypto/wincrypt_shim.h"
26 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
27 #include "net/cert/x509_certificate.h" 27 #include "net/cert/x509_certificate.h"
28 #include "net/ssl/ssl_platform_key_task_runner.h" 28 #include "net/ssl/ssl_platform_key_util.h"
29 #include "net/ssl/ssl_private_key.h" 29 #include "net/ssl/ssl_private_key.h"
30 #include "net/ssl/threaded_ssl_private_key.h" 30 #include "net/ssl/threaded_ssl_private_key.h"
31 31
32 namespace net { 32 namespace net {
33 33
34 namespace { 34 namespace {
35 35
36 class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate { 36 class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate {
37 public: 37 public:
38 // Takes ownership of |provider|. 38 // Takes ownership of |provider|.
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())), 204 const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())),
205 input.size(), signature->data(), signature_len, &signature_len, flags); 205 input.size(), signature->data(), signature_len, &signature_len, flags);
206 if (FAILED(status)) { 206 if (FAILED(status)) {
207 LOG(ERROR) << "NCryptSignHash failed: " << status; 207 LOG(ERROR) << "NCryptSignHash failed: " << status;
208 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 208 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
209 } 209 }
210 signature->resize(signature_len); 210 signature->resize(signature_len);
211 211
212 // CNG emits raw ECDSA signatures, but BoringSSL expects a DER-encoded 212 // CNG emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
213 // ECDSA-Sig-Value. 213 // ECDSA-Sig-Value.
214 if (type_ == SSLPrivateKey::Type::ECDSA) { 214 if (SSLPrivateKey::IsECDSAType(type_)) {
215 if (signature->size() % 2 != 0) { 215 if (signature->size() % 2 != 0) {
216 LOG(ERROR) << "Bad signature length"; 216 LOG(ERROR) << "Bad signature length";
217 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 217 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
218 } 218 }
219 size_t order_len = signature->size() / 2; 219 size_t order_len = signature->size() / 2;
220 220
221 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value. 221 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
222 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); 222 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
223 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) || 223 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
224 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) { 224 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
(...skipping 15 matching lines...) Expand all
240 } 240 }
241 241
242 private: 242 private:
243 NCRYPT_KEY_HANDLE key_; 243 NCRYPT_KEY_HANDLE key_;
244 SSLPrivateKey::Type type_; 244 SSLPrivateKey::Type type_;
245 size_t max_length_; 245 size_t max_length_;
246 246
247 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG); 247 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyCNG);
248 }; 248 };
249 249
250 // Determines the key type and maximum signature length of |certificate|'s
251 // public key.
252 bool GetKeyInfo(const X509Certificate* certificate,
253 SSLPrivateKey::Type* out_type,
254 size_t* out_max_length) {
255 crypto::OpenSSLErrStackTracer tracker(FROM_HERE);
256
257 std::string der_encoded;
258 if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(),
259 &der_encoded))
260 return false;
261 const uint8_t* bytes = reinterpret_cast<const uint8_t*>(der_encoded.data());
262 bssl::UniquePtr<X509> x509(d2i_X509(nullptr, &bytes, der_encoded.size()));
263 if (!x509)
264 return false;
265 bssl::UniquePtr<EVP_PKEY> key(X509_get_pubkey(x509.get()));
266 if (!key)
267 return false;
268 switch (EVP_PKEY_id(key.get())) {
269 case EVP_PKEY_RSA:
270 *out_type = SSLPrivateKey::Type::RSA;
271 break;
272 case EVP_PKEY_EC:
273 *out_type = SSLPrivateKey::Type::ECDSA;
274 break;
275 default:
276 return false;
277 }
278 *out_max_length = EVP_PKEY_size(key.get());
279 return true;
280 }
281
282 } // namespace 250 } // namespace
283 251
284 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( 252 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
285 X509Certificate* certificate) { 253 X509Certificate* certificate) {
286 // Rather than query the private key for metadata, extract the public key from 254 // Rather than query the private key for metadata, extract the public key from
287 // the certificate without using Windows APIs. CAPI and CNG do not 255 // the certificate without using Windows APIs. CAPI and CNG do not
288 // consistently work depending on the system. See https://crbug.com/468345. 256 // consistently work depending on the system. See https://crbug.com/468345.
289 SSLPrivateKey::Type key_type; 257 SSLPrivateKey::Type key_type;
290 size_t max_length; 258 size_t max_length;
291 if (!GetKeyInfo(certificate, &key_type, &max_length)) 259 if (!GetClientCertInfo(certificate, &key_type, &max_length))
292 return nullptr; 260 return nullptr;
293 261
294 PCCERT_CONTEXT cert_context = certificate->os_cert_handle(); 262 PCCERT_CONTEXT cert_context = certificate->os_cert_handle();
295 263
296 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0; 264 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE prov_or_key = 0;
297 DWORD key_spec = 0; 265 DWORD key_spec = 0;
298 BOOL must_free = FALSE; 266 BOOL must_free = FALSE;
299 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; 267 DWORD flags = CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG;
300 268
301 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr, 269 if (!CryptAcquireCertificatePrivateKey(cert_context, flags, nullptr,
(...skipping 11 matching lines...) Expand all
313 delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length)); 281 delegate.reset(new SSLPlatformKeyCNG(prov_or_key, key_type, max_length));
314 } else { 282 } else {
315 DCHECK(SSLPrivateKey::Type::RSA == key_type); 283 DCHECK(SSLPrivateKey::Type::RSA == key_type);
316 delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length)); 284 delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length));
317 } 285 }
318 return make_scoped_refptr(new ThreadedSSLPrivateKey( 286 return make_scoped_refptr(new ThreadedSSLPrivateKey(
319 std::move(delegate), GetSSLPlatformKeyTaskRunner())); 287 std::move(delegate), GetSSLPlatformKeyTaskRunner()));
320 } 288 }
321 289
322 } // namespace net 290 } // 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