xref: /aosp_15_r20/external/cronet/crypto/rsa_private_key.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "crypto/rsa_private_key.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
14*6777b538SAndroid Build Coastguard Worker #include "crypto/openssl_util.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/bn.h"
16*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/bytestring.h"
17*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/evp.h"
18*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/mem.h"
19*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/rsa.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace crypto {
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker // static
Create(uint16_t num_bits)24*6777b538SAndroid Build Coastguard Worker std::unique_ptr<RSAPrivateKey> RSAPrivateKey::Create(uint16_t num_bits) {
25*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<RSA> rsa_key(RSA_new());
28*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<BIGNUM> bn(BN_new());
29*6777b538SAndroid Build Coastguard Worker   if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L))
30*6777b538SAndroid Build Coastguard Worker     return nullptr;
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker   if (!RSA_generate_key_ex(rsa_key.get(), num_bits, bn.get(), nullptr))
33*6777b538SAndroid Build Coastguard Worker     return nullptr;
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<RSAPrivateKey> result(new RSAPrivateKey);
36*6777b538SAndroid Build Coastguard Worker   result->key_.reset(EVP_PKEY_new());
37*6777b538SAndroid Build Coastguard Worker   if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_.get(), rsa_key.get()))
38*6777b538SAndroid Build Coastguard Worker     return nullptr;
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   return result;
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker // static
CreateFromPrivateKeyInfo(base::span<const uint8_t> input)44*6777b538SAndroid Build Coastguard Worker std::unique_ptr<RSAPrivateKey> RSAPrivateKey::CreateFromPrivateKeyInfo(
45*6777b538SAndroid Build Coastguard Worker     base::span<const uint8_t> input) {
46*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   CBS cbs;
49*6777b538SAndroid Build Coastguard Worker   CBS_init(&cbs, input.data(), input.size());
50*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs));
51*6777b538SAndroid Build Coastguard Worker   if (!pkey || CBS_len(&cbs) != 0 || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA)
52*6777b538SAndroid Build Coastguard Worker     return nullptr;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<RSAPrivateKey> result(new RSAPrivateKey);
55*6777b538SAndroid Build Coastguard Worker   result->key_ = std::move(pkey);
56*6777b538SAndroid Build Coastguard Worker   return result;
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker // static
CreateFromKey(EVP_PKEY * key)60*6777b538SAndroid Build Coastguard Worker std::unique_ptr<RSAPrivateKey> RSAPrivateKey::CreateFromKey(EVP_PKEY* key) {
61*6777b538SAndroid Build Coastguard Worker   DCHECK(key);
62*6777b538SAndroid Build Coastguard Worker   if (EVP_PKEY_id(key) != EVP_PKEY_RSA)
63*6777b538SAndroid Build Coastguard Worker     return nullptr;
64*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<RSAPrivateKey> copy(new RSAPrivateKey);
65*6777b538SAndroid Build Coastguard Worker   copy->key_ = bssl::UpRef(key);
66*6777b538SAndroid Build Coastguard Worker   return copy;
67*6777b538SAndroid Build Coastguard Worker }
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker RSAPrivateKey::RSAPrivateKey() = default;
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker RSAPrivateKey::~RSAPrivateKey() = default;
72*6777b538SAndroid Build Coastguard Worker 
Copy() const73*6777b538SAndroid Build Coastguard Worker std::unique_ptr<RSAPrivateKey> RSAPrivateKey::Copy() const {
74*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<RSAPrivateKey> copy(new RSAPrivateKey);
75*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(key_.get()));
76*6777b538SAndroid Build Coastguard Worker   if (!rsa)
77*6777b538SAndroid Build Coastguard Worker     return nullptr;
78*6777b538SAndroid Build Coastguard Worker   copy->key_.reset(EVP_PKEY_new());
79*6777b538SAndroid Build Coastguard Worker   if (!EVP_PKEY_set1_RSA(copy->key_.get(), rsa.get()))
80*6777b538SAndroid Build Coastguard Worker     return nullptr;
81*6777b538SAndroid Build Coastguard Worker   return copy;
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker 
ExportPrivateKey(std::vector<uint8_t> * output) const84*6777b538SAndroid Build Coastguard Worker bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8_t>* output) const {
85*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
86*6777b538SAndroid Build Coastguard Worker   uint8_t *der;
87*6777b538SAndroid Build Coastguard Worker   size_t der_len;
88*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
89*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 0) ||
90*6777b538SAndroid Build Coastguard Worker       !EVP_marshal_private_key(cbb.get(), key_.get()) ||
91*6777b538SAndroid Build Coastguard Worker       !CBB_finish(cbb.get(), &der, &der_len)) {
92*6777b538SAndroid Build Coastguard Worker     return false;
93*6777b538SAndroid Build Coastguard Worker   }
94*6777b538SAndroid Build Coastguard Worker   output->assign(der, der + der_len);
95*6777b538SAndroid Build Coastguard Worker   OPENSSL_free(der);
96*6777b538SAndroid Build Coastguard Worker   return true;
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker 
ExportPublicKey(std::vector<uint8_t> * output) const99*6777b538SAndroid Build Coastguard Worker bool RSAPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) const {
100*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
101*6777b538SAndroid Build Coastguard Worker   uint8_t *der;
102*6777b538SAndroid Build Coastguard Worker   size_t der_len;
103*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
104*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 0) ||
105*6777b538SAndroid Build Coastguard Worker       !EVP_marshal_public_key(cbb.get(), key_.get()) ||
106*6777b538SAndroid Build Coastguard Worker       !CBB_finish(cbb.get(), &der, &der_len)) {
107*6777b538SAndroid Build Coastguard Worker     return false;
108*6777b538SAndroid Build Coastguard Worker   }
109*6777b538SAndroid Build Coastguard Worker   output->assign(der, der + der_len);
110*6777b538SAndroid Build Coastguard Worker   OPENSSL_free(der);
111*6777b538SAndroid Build Coastguard Worker   return true;
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker }  // namespace crypto
115