Chromium Code Reviews| 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 |