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 // 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 |