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 // Helper to export the specified key in the required format. If |
14 bool sensitive) { | 21 // |export_private| is true the full key is exported, otherwise only the |
15 NOTIMPLEMENTED(); | 22 // public part is written. |
16 return NULL; | 23 bool ExportKey(EVP_PKEY* key, bool export_private, std::vector<uint8>* output) { |
24 if (!key) | |
25 return false; | |
26 | |
27 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); | |
28 | |
29 // Call the appropriate function depending on the flag. | |
30 int res = (export_private ? i2d_PKCS8PrivateKeyInfo_bio : i2d_PUBKEY_bio)( | |
bulach
2010/11/17 11:52:30
the object code would probably be the same, by I t
joth
2010/11/17 14:31:24
Once we have the typedef, I think it's even cleare
| |
31 bio.get(), key); | |
32 ClearOpenSSLERRStack(); | |
33 if (!res) | |
34 return false; | |
35 | |
36 char* data = NULL; | |
37 long len = BIO_get_mem_data(bio.get(), &data); | |
38 if (!data || len < 0) | |
39 return false; | |
40 | |
41 STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len); | |
42 return true; | |
17 } | 43 } |
18 | 44 |
45 } // namespace | |
46 | |
19 // static | 47 // static |
20 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 48 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
21 return CreateWithParams(num_bits, | 49 EnsureOpenSSLInit(); |
22 false /* not permanent */, | 50 |
23 false /* not sensitive */); | 51 ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_generate_key(num_bits, 65537L, |
52 NULL, NULL)); | |
53 ClearOpenSSLERRStack(); | |
54 if (!rsa_key.get()) | |
55 return NULL; | |
56 | |
57 scoped_ptr<RSAPrivateKey> self(new RSAPrivateKey); | |
bulach
2010/11/17 11:52:30
not really "self", perhaps new_key ?
joth
2010/11/17 14:31:24
Huh, I've got a habit of using self as a surrogate
| |
58 self->key_ = EVP_PKEY_new(); | |
59 if (!self->key_ || !EVP_PKEY_set1_RSA(self->key_, rsa_key.get())) | |
60 return NULL; | |
61 | |
62 return self.release(); | |
24 } | 63 } |
25 | 64 |
26 // static | 65 // static |
27 RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { | 66 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(); | 67 NOTIMPLEMENTED(); |
37 return NULL; | 68 return NULL; |
38 } | 69 } |
39 | 70 |
40 // static | 71 // static |
41 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( | 72 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( |
42 const std::vector<uint8>& input) { | 73 const std::vector<uint8>& input) { |
43 return CreateFromPrivateKeyInfoWithParams(input, | 74 EnsureOpenSSLInit(); |
44 false /* not permanent */, | 75 |
45 false /* not sensitive */); | 76 // BIO_new_mem_buf is not const aware, but it does not modify the buffer. |
77 char* data = reinterpret_cast<char*>(const_cast<uint8*>(input.data())); | |
78 ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); | |
79 if (!bio.get()) | |
80 return NULL; | |
81 | |
82 // Importing is a little more involved than exporting, as we must first | |
83 // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key | |
84 // Info structure returned. | |
85 ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf( | |
86 d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); | |
87 ClearOpenSSLERRStack(); | |
88 if (!p8inf.get()) | |
89 return NULL; | |
90 | |
91 scoped_ptr<RSAPrivateKey> self(new RSAPrivateKey); | |
bulach
2010/11/17 11:52:30
ditto
joth
2010/11/17 14:31:24
Done.
| |
92 self->key_ = EVP_PKCS82PKEY(p8inf.get()); | |
93 ClearOpenSSLERRStack(); | |
94 if (!self->key_) | |
95 return NULL; | |
96 | |
97 return self.release(); | |
46 } | 98 } |
47 | 99 |
48 // static | 100 // static |
49 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( | 101 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( |
50 const std::vector<uint8>& input) { | 102 const std::vector<uint8>& input) { |
51 return CreateFromPrivateKeyInfoWithParams(input, | 103 NOTIMPLEMENTED(); |
52 true /* permanent */, | 104 return NULL; |
53 true /* seneitive */); | |
54 } | 105 } |
55 | 106 |
56 // static | 107 // static |
57 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( | 108 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( |
58 const std::vector<uint8>& input) { | 109 const std::vector<uint8>& input) { |
59 NOTIMPLEMENTED(); | 110 NOTIMPLEMENTED(); |
60 return NULL; | 111 return NULL; |
61 } | 112 } |
62 | 113 |
63 RSAPrivateKey::RSAPrivateKey() { | 114 RSAPrivateKey::RSAPrivateKey() |
115 : key_(NULL) { | |
64 } | 116 } |
65 | 117 |
66 RSAPrivateKey::~RSAPrivateKey() { | 118 RSAPrivateKey::~RSAPrivateKey() { |
119 if (key_) | |
120 EVP_PKEY_free(key_); | |
bulach
2010/11/17 11:52:30
we should really add release to the ScopedOpenSSL.
joth
2010/11/17 14:31:24
I think you mean reset() ?
I'm doing that in my ne
| |
67 } | 121 } |
68 | 122 |
69 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { | 123 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { |
70 NOTIMPLEMENTED(); | 124 return ExportKey(key_, true /* private */, output); |
71 return false; | |
72 } | 125 } |
73 | 126 |
74 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 127 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
75 NOTIMPLEMENTED(); | 128 return ExportKey(key_, false /* !private */, output); |
76 return false; | |
77 } | 129 } |
78 | 130 |
79 } // namespace base | 131 } // namespace base |
OLD | NEW |