| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 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/openssl_client_key_store.h" | |
| 6 | |
| 7 #include <openssl/evp.h> | |
| 8 #include <openssl/x509.h> | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "base/memory/singleton.h" | |
| 13 #include "net/cert/x509_certificate.h" | |
| 14 | |
| 15 namespace net { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // Return the EVP_PKEY holding the public key of a given certificate. | |
| 20 // |cert| is a certificate. | |
| 21 // Returns a scoped EVP_PKEY for it. | |
| 22 crypto::ScopedEVP_PKEY GetOpenSSLPublicKey(const X509Certificate* cert) { | |
| 23 // X509_PUBKEY_get() increments the reference count of its result. | |
| 24 // Unlike X509_get_X509_PUBKEY() which simply returns a direct pointer. | |
| 25 EVP_PKEY* pkey = | |
| 26 X509_PUBKEY_get(X509_get_X509_PUBKEY(cert->os_cert_handle())); | |
| 27 if (!pkey) | |
| 28 LOG(ERROR) << "Can't extract private key from certificate!"; | |
| 29 return crypto::ScopedEVP_PKEY(pkey); | |
| 30 } | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 OpenSSLClientKeyStore::OpenSSLClientKeyStore() { | |
| 35 } | |
| 36 | |
| 37 OpenSSLClientKeyStore::~OpenSSLClientKeyStore() { | |
| 38 } | |
| 39 | |
| 40 OpenSSLClientKeyStore::KeyPair::KeyPair(EVP_PKEY* pub_key, EVP_PKEY* priv_key) | |
| 41 : public_key(EVP_PKEY_up_ref(pub_key)), | |
| 42 private_key(EVP_PKEY_up_ref(priv_key)) { | |
| 43 } | |
| 44 | |
| 45 OpenSSLClientKeyStore::KeyPair::~KeyPair() { | |
| 46 } | |
| 47 | |
| 48 OpenSSLClientKeyStore::KeyPair::KeyPair(const KeyPair& other) | |
| 49 : public_key(EVP_PKEY_up_ref(other.public_key.get())), | |
| 50 private_key(EVP_PKEY_up_ref(other.private_key.get())) { | |
| 51 } | |
| 52 | |
| 53 void OpenSSLClientKeyStore::KeyPair::operator=(KeyPair other) { | |
| 54 swap(other); | |
| 55 } | |
| 56 | |
| 57 void OpenSSLClientKeyStore::KeyPair::swap(KeyPair& other) { | |
| 58 using std::swap; | |
| 59 swap(public_key, other.public_key); | |
| 60 swap(private_key, other.private_key); | |
| 61 } | |
| 62 | |
| 63 int OpenSSLClientKeyStore::FindKeyPairIndex(EVP_PKEY* public_key) { | |
| 64 if (!public_key) | |
| 65 return -1; | |
| 66 for (size_t n = 0; n < pairs_.size(); ++n) { | |
| 67 if (EVP_PKEY_cmp(pairs_[n].public_key.get(), public_key) == 1) | |
| 68 return static_cast<int>(n); | |
| 69 } | |
| 70 return -1; | |
| 71 } | |
| 72 | |
| 73 void OpenSSLClientKeyStore::AddKeyPair(EVP_PKEY* pub_key, | |
| 74 EVP_PKEY* private_key) { | |
| 75 int index = FindKeyPairIndex(pub_key); | |
| 76 if (index < 0) | |
| 77 pairs_.push_back(KeyPair(pub_key, private_key)); | |
| 78 } | |
| 79 | |
| 80 // Common code for OpenSSLClientKeyStore. Shared by all OpenSSL-based | |
| 81 // builds. | |
| 82 bool OpenSSLClientKeyStore::RecordClientCertPrivateKey( | |
| 83 const X509Certificate* client_cert, | |
| 84 EVP_PKEY* private_key) { | |
| 85 // Sanity check. | |
| 86 if (!client_cert || !private_key) | |
| 87 return false; | |
| 88 | |
| 89 // Get public key from certificate. | |
| 90 crypto::ScopedEVP_PKEY pub_key(GetOpenSSLPublicKey(client_cert)); | |
| 91 if (!pub_key.get()) | |
| 92 return false; | |
| 93 | |
| 94 AddKeyPair(pub_key.get(), private_key); | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 crypto::ScopedEVP_PKEY OpenSSLClientKeyStore::FetchClientCertPrivateKey( | |
| 99 const X509Certificate* client_cert) { | |
| 100 if (!client_cert) | |
| 101 return crypto::ScopedEVP_PKEY(); | |
| 102 | |
| 103 crypto::ScopedEVP_PKEY pub_key(GetOpenSSLPublicKey(client_cert)); | |
| 104 if (!pub_key.get()) | |
| 105 return crypto::ScopedEVP_PKEY(); | |
| 106 | |
| 107 int index = FindKeyPairIndex(pub_key.get()); | |
| 108 if (index < 0) | |
| 109 return crypto::ScopedEVP_PKEY(); | |
| 110 | |
| 111 return crypto::ScopedEVP_PKEY( | |
| 112 EVP_PKEY_up_ref(pairs_[index].private_key.get())); | |
| 113 } | |
| 114 | |
| 115 void OpenSSLClientKeyStore::Flush() { | |
| 116 pairs_.clear(); | |
| 117 } | |
| 118 | |
| 119 OpenSSLClientKeyStore* OpenSSLClientKeyStore::GetInstance() { | |
| 120 return base::Singleton<OpenSSLClientKeyStore>::get(); | |
| 121 } | |
| 122 | |
| 123 } // namespace net | |
| 124 | |
| 125 | |
| OLD | NEW |