OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/crypto/rsa_private_key.h" | 5 #include "base/crypto/rsa_private_key.h" |
6 | 6 |
7 #include <openssl/evp.h> | |
8 #include <openssl/pkcs12.h> | |
9 #include <openssl/rsa.h> | |
10 | |
7 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/openssl_util.h" | |
13 #include "base/scoped_ptr.h" | |
14 #include "base/stl_util-inl.h" | |
8 | 15 |
9 namespace base { | 16 namespace base { |
10 | 17 |
11 // static | 18 namespace { |
12 RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, | 19 |
13 bool permanent, | 20 // Function pointer definition, for injecting the required key export function |
14 bool sensitive) { | 21 // into ExportKey, below. The supplied function should export EVP_PKEY into |
15 NOTIMPLEMENTED(); | 22 // the supplied BIO, returning 1 on success or 0 on failure. |
16 return NULL; | 23 typedef int (ExportFunction)(BIO*, EVP_PKEY*); |
24 | |
25 // Helper to export the specified key in the required format. If | |
26 // |export_private| is true the full key is exported, otherwise only the | |
agl
2010/11/17 14:32:32
export_private doesn't appear to be an argument.
| |
27 // public part is written. | |
28 bool ExportKey(EVP_PKEY* key, | |
29 ExportFunction export_fn, | |
30 std::vector<uint8>* output) { | |
31 if (!key) | |
32 return false; | |
33 | |
34 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); | |
35 | |
36 int res = export_fn(bio.get(), key); | |
37 ClearOpenSSLERRStack(); | |
38 if (!res) | |
39 return false; | |
40 | |
41 char* data = NULL; | |
42 long len = BIO_get_mem_data(bio.get(), &data); | |
43 if (!data || len < 0) | |
44 return false; | |
45 | |
46 STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len); | |
47 return true; | |
17 } | 48 } |
18 | 49 |
50 } // namespace | |
51 | |
19 // static | 52 // static |
20 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 53 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
21 return CreateWithParams(num_bits, | 54 EnsureOpenSSLInit(); |
22 false /* not permanent */, | 55 |
23 false /* not sensitive */); | 56 ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_generate_key(num_bits, 65537L, |
57 NULL, NULL)); | |
58 ClearOpenSSLERRStack(); | |
59 if (!rsa_key.get()) | |
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(); | |
24 } | 68 } |
25 | 69 |
26 // static | 70 // static |
27 RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { | 71 RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { |
28 return CreateWithParams(num_bits, | |
29 true /* permanent */, | |
30 true /* sensitive */); | |
31 } | |
32 | |
33 // static | |
34 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( | |
35 const std::vector<uint8>& input, bool permanent, bool sensitive) { | |
36 NOTIMPLEMENTED(); | 72 NOTIMPLEMENTED(); |
37 return NULL; | 73 return NULL; |
38 } | 74 } |
39 | 75 |
40 // static | 76 // static |
41 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( | 77 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( |
42 const std::vector<uint8>& input) { | 78 const std::vector<uint8>& input) { |
43 return CreateFromPrivateKeyInfoWithParams(input, | 79 EnsureOpenSSLInit(); |
44 false /* not permanent */, | 80 |
45 false /* not sensitive */); | 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*>(input.data())); | |
83 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); | |
84 if (!bio.get()) | |
85 return NULL; | |
86 | |
87 // Importing is a little more involved than exporting, as we must first | |
88 // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key | |
89 // Info structure returned. | |
90 ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf( | |
91 d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); | |
92 ClearOpenSSLERRStack(); | |
93 if (!p8inf.get()) | |
94 return NULL; | |
95 | |
96 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | |
97 result->key_ = EVP_PKCS82PKEY(p8inf.get()); | |
98 ClearOpenSSLERRStack(); | |
99 if (!result->key_) | |
100 return NULL; | |
101 | |
102 return result.release(); | |
46 } | 103 } |
47 | 104 |
48 // static | 105 // static |
49 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( | 106 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( |
50 const std::vector<uint8>& input) { | 107 const std::vector<uint8>& input) { |
51 return CreateFromPrivateKeyInfoWithParams(input, | 108 NOTIMPLEMENTED(); |
52 true /* permanent */, | 109 return NULL; |
53 true /* seneitive */); | |
54 } | 110 } |
55 | 111 |
56 // static | 112 // static |
57 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( | 113 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( |
58 const std::vector<uint8>& input) { | 114 const std::vector<uint8>& input) { |
59 NOTIMPLEMENTED(); | 115 NOTIMPLEMENTED(); |
60 return NULL; | 116 return NULL; |
61 } | 117 } |
62 | 118 |
63 RSAPrivateKey::RSAPrivateKey() { | 119 RSAPrivateKey::RSAPrivateKey() |
120 : key_(NULL) { | |
64 } | 121 } |
65 | 122 |
66 RSAPrivateKey::~RSAPrivateKey() { | 123 RSAPrivateKey::~RSAPrivateKey() { |
124 if (key_) | |
125 EVP_PKEY_free(key_); | |
67 } | 126 } |
68 | 127 |
69 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { | 128 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { |
70 NOTIMPLEMENTED(); | 129 return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output); |
71 return false; | |
72 } | 130 } |
73 | 131 |
74 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 132 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
75 NOTIMPLEMENTED(); | 133 return ExportKey(key_, i2d_PUBKEY_bio, output); |
76 return false; | |
77 } | 134 } |
78 | 135 |
79 } // namespace base | 136 } // namespace base |
OLD | NEW |