OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "base/crypto/rsa_private_key.h" | |
6 | |
7 #include <openssl/evp.h> | |
8 #include <openssl/pkcs12.h> | |
9 #include <openssl/rsa.h> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/openssl_util.h" | |
14 #include "base/stl_util-inl.h" | |
15 | |
16 namespace base { | |
17 | |
18 namespace { | |
19 | |
20 // Function pointer definition, for injecting the required key export function | |
21 // into ExportKey, below. The supplied function should export EVP_PKEY into | |
22 // the supplied BIO, returning 1 on success or 0 on failure. | |
23 typedef int (ExportFunction)(BIO*, EVP_PKEY*); | |
24 | |
25 // Helper to export |key| into |output| via the specified ExportFunction. | |
26 bool ExportKey(EVP_PKEY* key, | |
27 ExportFunction export_fn, | |
28 std::vector<uint8>* output) { | |
29 if (!key) | |
30 return false; | |
31 | |
32 OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
33 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); | |
34 | |
35 int res = export_fn(bio.get(), key); | |
36 if (!res) | |
37 return false; | |
38 | |
39 char* data = NULL; | |
40 long len = BIO_get_mem_data(bio.get(), &data); | |
41 if (!data || len < 0) | |
42 return false; | |
43 | |
44 STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len); | |
45 return true; | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 // static | |
51 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | |
52 OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
53 | |
54 ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_new()); | |
55 ScopedOpenSSL<BIGNUM, BN_free> bn(BN_new()); | |
56 if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L)) | |
57 return NULL; | |
58 | |
59 if (!RSA_generate_key_ex(rsa_key.get(), num_bits, bn.get(), NULL)) | |
60 return NULL; | |
61 | |
62 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | |
63 result->key_ = EVP_PKEY_new(); | |
64 if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_, rsa_key.get())) | |
65 return NULL; | |
66 | |
67 return result.release(); | |
68 } | |
69 | |
70 // static | |
71 RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { | |
72 NOTIMPLEMENTED(); | |
73 return NULL; | |
74 } | |
75 | |
76 // static | |
77 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( | |
78 const std::vector<uint8>& input) { | |
79 OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
80 | |
81 // BIO_new_mem_buf is not const aware, but it does not modify the buffer. | |
82 char* data = reinterpret_cast<char*>(const_cast<uint8*>( | |
83 vector_as_array(&input))); | |
84 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); | |
85 if (!bio.get()) | |
86 return NULL; | |
87 | |
88 // Importing is a little more involved than exporting, as we must first | |
89 // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key | |
90 // Info structure returned. | |
91 ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf( | |
92 d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); | |
93 if (!p8inf.get()) | |
94 return NULL; | |
95 | |
96 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | |
97 result->key_ = EVP_PKCS82PKEY(p8inf.get()); | |
98 if (!result->key_) | |
99 return NULL; | |
100 | |
101 return result.release(); | |
102 } | |
103 | |
104 // static | |
105 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( | |
106 const std::vector<uint8>& input) { | |
107 NOTIMPLEMENTED(); | |
108 return NULL; | |
109 } | |
110 | |
111 // static | |
112 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( | |
113 const std::vector<uint8>& input) { | |
114 NOTIMPLEMENTED(); | |
115 return NULL; | |
116 } | |
117 | |
118 RSAPrivateKey::RSAPrivateKey() | |
119 : key_(NULL) { | |
120 } | |
121 | |
122 RSAPrivateKey::~RSAPrivateKey() { | |
123 if (key_) | |
124 EVP_PKEY_free(key_); | |
125 } | |
126 | |
127 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { | |
128 return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output); | |
129 } | |
130 | |
131 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | |
132 return ExportKey(key_, i2d_PUBKEY_bio, output); | |
133 } | |
134 | |
135 } // namespace base | |
OLD | NEW |