blob: d601aa8e427009d2b5d759206158898b7524934f [file] [log] [blame]
Avi Drissman201a9a832022-09-13 19:39:251// Copyright 2011 The Chromium Authors
[email protected]70372d42010-10-22 13:12:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4b559b4d2011-04-14 17:37:145#include "crypto/rsa_private_key.h"
[email protected]70372d42010-10-22 13:12:346
avidd373b8b2015-12-21 21:34:437#include <stdint.h>
[email protected]1f923942010-11-17 14:39:228
thakisd1a18472016-04-08 22:30:419#include <memory>
davidben74f67442016-10-01 01:45:2210#include <utility>
thakisd1a18472016-04-08 22:30:4111
Hans Wennborg4d0e1802020-04-24 20:19:4312#include "base/check.h"
Maksim Ivanovbc9778222020-06-29 17:53:1613#include "base/containers/span.h"
[email protected]4b559b4d2011-04-14 17:37:1414#include "crypto/openssl_util.h"
tfarina29a3a1742016-10-28 18:47:3315#include "third_party/boringssl/src/include/openssl/bn.h"
16#include "third_party/boringssl/src/include/openssl/bytestring.h"
17#include "third_party/boringssl/src/include/openssl/evp.h"
18#include "third_party/boringssl/src/include/openssl/mem.h"
19#include "third_party/boringssl/src/include/openssl/rsa.h"
[email protected]70372d42010-10-22 13:12:3420
[email protected]4b559b4d2011-04-14 17:37:1421namespace crypto {
[email protected]70372d42010-10-22 13:12:3422
[email protected]70372d42010-10-22 13:12:3423// static
rsleevid1afa1e2016-06-22 04:00:4824std::unique_ptr<RSAPrivateKey> RSAPrivateKey::Create(uint16_t num_bits) {
[email protected]be796bb2010-11-18 15:43:4325 OpenSSLErrStackTracer err_tracer(FROM_HERE);
[email protected]fed406f82010-12-08 15:40:4526
davidben74f67442016-10-01 01:45:2227 bssl::UniquePtr<RSA> rsa_key(RSA_new());
28 bssl::UniquePtr<BIGNUM> bn(BN_new());
[email protected]fed406f82010-12-08 15:40:4529 if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L))
rsleevid1afa1e2016-06-22 04:00:4830 return nullptr;
[email protected]fed406f82010-12-08 15:40:4531
rsleevid1afa1e2016-06-22 04:00:4832 if (!RSA_generate_key_ex(rsa_key.get(), num_bits, bn.get(), nullptr))
33 return nullptr;
[email protected]1f923942010-11-17 14:39:2234
thakisd1a18472016-04-08 22:30:4135 std::unique_ptr<RSAPrivateKey> result(new RSAPrivateKey);
davidben74f67442016-10-01 01:45:2236 result->key_.reset(EVP_PKEY_new());
37 if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_.get(), rsa_key.get()))
rsleevid1afa1e2016-06-22 04:00:4838 return nullptr;
[email protected]1f923942010-11-17 14:39:2239
rsleevid1afa1e2016-06-22 04:00:4840 return result;
[email protected]70372d42010-10-22 13:12:3441}
42
43// static
rsleevid1afa1e2016-06-22 04:00:4844std::unique_ptr<RSAPrivateKey> RSAPrivateKey::CreateFromPrivateKeyInfo(
Maksim Ivanovbc9778222020-06-29 17:53:1645 base::span<const uint8_t> input) {
[email protected]d641b6e2011-07-20 11:07:1646 OpenSSLErrStackTracer err_tracer(FROM_HERE);
[email protected]1f923942010-11-17 14:39:2247
davidben7dad2a32016-03-01 23:47:4748 CBS cbs;
49 CBS_init(&cbs, input.data(), input.size());
davidben74f67442016-10-01 01:45:2250 bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs));
davidben7dad2a32016-03-01 23:47:4751 if (!pkey || CBS_len(&cbs) != 0 || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA)
52 return nullptr;
[email protected]1f923942010-11-17 14:39:2253
thakisd1a18472016-04-08 22:30:4154 std::unique_ptr<RSAPrivateKey> result(new RSAPrivateKey);
davidben74f67442016-10-01 01:45:2255 result->key_ = std::move(pkey);
rsleevid1afa1e2016-06-22 04:00:4856 return result;
[email protected]70372d42010-10-22 13:12:3457}
58
dougsteeddb7726ae2014-09-10 23:21:4859// static
rsleevid1afa1e2016-06-22 04:00:4860std::unique_ptr<RSAPrivateKey> RSAPrivateKey::CreateFromKey(EVP_PKEY* key) {
dougsteeddb7726ae2014-09-10 23:21:4861 DCHECK(key);
David Benjamin4ba5e7f92022-07-15 15:08:0162 if (EVP_PKEY_id(key) != EVP_PKEY_RSA)
rsleevid1afa1e2016-06-22 04:00:4863 return nullptr;
64 std::unique_ptr<RSAPrivateKey> copy(new RSAPrivateKey);
David Benjamin139c5572018-07-06 23:53:4265 copy->key_ = bssl::UpRef(key);
dougsteeddb7726ae2014-09-10 23:21:4866 return copy;
67}
68
Chris Watkinsa850a302017-11-30 03:53:4969RSAPrivateKey::RSAPrivateKey() = default;
[email protected]70372d42010-10-22 13:12:3470
Chris Watkinsa850a302017-11-30 03:53:4971RSAPrivateKey::~RSAPrivateKey() = default;
[email protected]70372d42010-10-22 13:12:3472
rsleevid1afa1e2016-06-22 04:00:4873std::unique_ptr<RSAPrivateKey> RSAPrivateKey::Copy() const {
74 std::unique_ptr<RSAPrivateKey> copy(new RSAPrivateKey);
davidben74f67442016-10-01 01:45:2275 bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(key_.get()));
[email protected]58782882011-12-03 01:12:0876 if (!rsa)
rsleevid1afa1e2016-06-22 04:00:4877 return nullptr;
davidben74f67442016-10-01 01:45:2278 copy->key_.reset(EVP_PKEY_new());
79 if (!EVP_PKEY_set1_RSA(copy->key_.get(), rsa.get()))
rsleevid1afa1e2016-06-22 04:00:4880 return nullptr;
81 return copy;
[email protected]58782882011-12-03 01:12:0882}
83
avidd373b8b2015-12-21 21:34:4384bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8_t>* output) const {
davidben212cdf62016-06-07 17:11:0985 OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidben7dad2a32016-03-01 23:47:4786 uint8_t *der;
87 size_t der_len;
davidben74f67442016-10-01 01:45:2288 bssl::ScopedCBB cbb;
davidben7dad2a32016-03-01 23:47:4789 if (!CBB_init(cbb.get(), 0) ||
davidben74f67442016-10-01 01:45:2290 !EVP_marshal_private_key(cbb.get(), key_.get()) ||
davidben7dad2a32016-03-01 23:47:4791 !CBB_finish(cbb.get(), &der, &der_len)) {
92 return false;
93 }
94 output->assign(der, der + der_len);
95 OPENSSL_free(der);
96 return true;
[email protected]70372d42010-10-22 13:12:3497}
98
avidd373b8b2015-12-21 21:34:4399bool RSAPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) const {
davidben212cdf62016-06-07 17:11:09100 OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidben7dad2a32016-03-01 23:47:47101 uint8_t *der;
102 size_t der_len;
davidben74f67442016-10-01 01:45:22103 bssl::ScopedCBB cbb;
davidben7dad2a32016-03-01 23:47:47104 if (!CBB_init(cbb.get(), 0) ||
davidben74f67442016-10-01 01:45:22105 !EVP_marshal_public_key(cbb.get(), key_.get()) ||
davidben7dad2a32016-03-01 23:47:47106 !CBB_finish(cbb.get(), &der, &der_len)) {
107 return false;
108 }
109 output->assign(der, der + der_len);
110 OPENSSL_free(der);
111 return true;
[email protected]70372d42010-10-22 13:12:34112}
113
[email protected]4b559b4d2011-04-14 17:37:14114} // namespace crypto