blob: 295810f29cc183336600c6963206b6bd056603f2 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/ssl/openssl_client_key_store.h"
#include <utility>
#include "base/memory/singleton.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_private_key.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/x509.h"
namespace net {
namespace {
// Serializes the SubjectPublicKeyInfo for |cert|.
bool GetCertificateSPKI(const X509Certificate* cert, std::string* spki) {
bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert->os_cert_handle()));
if (!pkey) {
LOG(ERROR) << "Can't extract private key from certificate!";
return false;
}
bssl::ScopedCBB cbb;
uint8_t* der;
size_t der_len;
if (!CBB_init(cbb.get(), 0) ||
!EVP_marshal_public_key(cbb.get(), pkey.get()) ||
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
spki->assign(reinterpret_cast<char*>(der),
reinterpret_cast<char*>(der) + der_len);
OPENSSL_free(der);
return true;
}
} // namespace
OpenSSLClientKeyStore* OpenSSLClientKeyStore::GetInstance() {
return base::Singleton<OpenSSLClientKeyStore>::get();
}
bool OpenSSLClientKeyStore::RecordClientCertPrivateKey(
const X509Certificate* client_cert,
scoped_refptr<SSLPrivateKey> private_key) {
DCHECK(client_cert);
DCHECK(private_key);
std::string spki;
if (!GetCertificateSPKI(client_cert, &spki))
return false;
key_map_[spki] = std::move(private_key);
return true;
}
scoped_refptr<SSLPrivateKey> OpenSSLClientKeyStore::FetchClientCertPrivateKey(
const X509Certificate* client_cert) {
DCHECK(client_cert);
std::string spki;
if (!GetCertificateSPKI(client_cert, &spki))
return nullptr;
auto iter = key_map_.find(spki);
if (iter == key_map_.end())
return nullptr;
return iter->second;
}
void OpenSSLClientKeyStore::Flush() {
key_map_.clear();
}
OpenSSLClientKeyStore::OpenSSLClientKeyStore() {}
OpenSSLClientKeyStore::~OpenSSLClientKeyStore() {}
} // namespace net