OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/ssl/ssl_platform_key_util.h" |
| 6 |
| 7 #include <openssl/bytestring.h> |
| 8 #include <openssl/ec_key.h> |
| 9 #include <openssl/evp.h> |
| 10 |
| 11 #include "base/lazy_instance.h" |
| 12 #include "base/logging.h" |
| 13 #include "base/macros.h" |
| 14 #include "base/strings/string_piece.h" |
| 15 #include "base/threading/thread.h" |
| 16 #include "crypto/openssl_util.h" |
| 17 #include "net/cert/asn1_util.h" |
| 18 #include "net/cert/x509_certificate.h" |
| 19 |
| 20 namespace net { |
| 21 |
| 22 namespace { |
| 23 |
| 24 class SSLPlatformKeyTaskRunner { |
| 25 public: |
| 26 SSLPlatformKeyTaskRunner() : worker_thread_("Platform Key Thread") { |
| 27 base::Thread::Options options; |
| 28 options.joinable = false; |
| 29 worker_thread_.StartWithOptions(options); |
| 30 } |
| 31 |
| 32 ~SSLPlatformKeyTaskRunner() {} |
| 33 |
| 34 scoped_refptr<base::SingleThreadTaskRunner> task_runner() { |
| 35 return worker_thread_.task_runner(); |
| 36 } |
| 37 |
| 38 private: |
| 39 base::Thread worker_thread_; |
| 40 |
| 41 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyTaskRunner); |
| 42 }; |
| 43 |
| 44 base::LazyInstance<SSLPlatformKeyTaskRunner>::Leaky g_platform_key_task_runner = |
| 45 LAZY_INSTANCE_INITIALIZER; |
| 46 |
| 47 } // namespace |
| 48 |
| 49 scoped_refptr<base::SingleThreadTaskRunner> GetSSLPlatformKeyTaskRunner() { |
| 50 return g_platform_key_task_runner.Get().task_runner(); |
| 51 } |
| 52 |
| 53 bool GetClientCertInfo(const X509Certificate* certificate, |
| 54 SSLPrivateKey::Type* out_type, |
| 55 size_t* out_max_length) { |
| 56 crypto::OpenSSLErrStackTracer tracker(FROM_HERE); |
| 57 |
| 58 std::string der_encoded; |
| 59 base::StringPiece spki; |
| 60 if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(), |
| 61 &der_encoded) || |
| 62 !asn1::ExtractSPKIFromDERCert(der_encoded, &spki)) { |
| 63 LOG(ERROR) << "Could not extract SPKI from certificate."; |
| 64 return false; |
| 65 } |
| 66 |
| 67 CBS cbs; |
| 68 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size()); |
| 69 bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs)); |
| 70 if (!key || CBS_len(&cbs) != 0) { |
| 71 LOG(ERROR) << "Could not parse public key."; |
| 72 return false; |
| 73 } |
| 74 |
| 75 switch (EVP_PKEY_id(key.get())) { |
| 76 case EVP_PKEY_RSA: |
| 77 *out_type = SSLPrivateKey::Type::RSA; |
| 78 break; |
| 79 |
| 80 case EVP_PKEY_EC: { |
| 81 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key.get()); |
| 82 int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); |
| 83 switch (curve) { |
| 84 case NID_X9_62_prime256v1: |
| 85 *out_type = SSLPrivateKey::Type::ECDSA_P256; |
| 86 break; |
| 87 case NID_secp384r1: |
| 88 *out_type = SSLPrivateKey::Type::ECDSA_P384; |
| 89 break; |
| 90 case NID_secp521r1: |
| 91 *out_type = SSLPrivateKey::Type::ECDSA_P384; |
| 92 break; |
| 93 default: |
| 94 return false; |
| 95 } |
| 96 break; |
| 97 } |
| 98 |
| 99 default: |
| 100 return false; |
| 101 } |
| 102 |
| 103 *out_max_length = EVP_PKEY_size(key.get()); |
| 104 return true; |
| 105 } |
| 106 |
| 107 } // namespace net |
OLD | NEW |