OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 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 #ifndef CRYPTO_RSA_PRIVATE_KEY_H_ |
| 6 #define CRYPTO_RSA_PRIVATE_KEY_H_ |
| 7 |
| 8 #include "build/build_config.h" |
| 9 |
| 10 #include <list> |
| 11 #include <vector> |
| 12 |
| 13 #include "base/basictypes.h" |
| 14 #include "crypto/crypto_export.h" |
| 15 |
| 16 #if defined(USE_NSS_CERTS) |
| 17 #include "base/gtest_prod_util.h" |
| 18 #endif |
| 19 |
| 20 #if defined(USE_OPENSSL) |
| 21 // Forward declaration for openssl/*.h |
| 22 typedef struct evp_pkey_st EVP_PKEY; |
| 23 #else |
| 24 // Forward declaration. |
| 25 typedef struct PK11SlotInfoStr PK11SlotInfo; |
| 26 typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; |
| 27 typedef struct SECKEYPublicKeyStr SECKEYPublicKey; |
| 28 #endif |
| 29 |
| 30 |
| 31 namespace crypto { |
| 32 |
| 33 // Used internally by RSAPrivateKey for serializing and deserializing |
| 34 // PKCS #8 PrivateKeyInfo and PublicKeyInfo. |
| 35 class PrivateKeyInfoCodec { |
| 36 public: |
| 37 |
| 38 // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8. |
| 39 static const uint8 kRsaAlgorithmIdentifier[]; |
| 40 |
| 41 // ASN.1 tags for some types we use. |
| 42 static const uint8 kBitStringTag = 0x03; |
| 43 static const uint8 kIntegerTag = 0x02; |
| 44 static const uint8 kNullTag = 0x05; |
| 45 static const uint8 kOctetStringTag = 0x04; |
| 46 static const uint8 kSequenceTag = 0x30; |
| 47 |
| 48 // |big_endian| here specifies the byte-significance of the integer components |
| 49 // that will be parsed & serialized (modulus(), etc...) during Import(), |
| 50 // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the |
| 51 // PrivateKeyInfo/PublicKeyInfo (which is always big-endian). |
| 52 explicit PrivateKeyInfoCodec(bool big_endian); |
| 53 |
| 54 ~PrivateKeyInfoCodec(); |
| 55 |
| 56 // Exports the contents of the integer components to the ASN.1 DER encoding |
| 57 // of the PrivateKeyInfo structure to |output|. |
| 58 bool Export(std::vector<uint8>* output); |
| 59 |
| 60 // Exports the contents of the integer components to the ASN.1 DER encoding |
| 61 // of the PublicKeyInfo structure to |output|. |
| 62 bool ExportPublicKeyInfo(std::vector<uint8>* output); |
| 63 |
| 64 // Exports the contents of the integer components to the ASN.1 DER encoding |
| 65 // of the RSAPublicKey structure to |output|. |
| 66 bool ExportPublicKey(std::vector<uint8>* output); |
| 67 |
| 68 // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input| |
| 69 // and populates the integer components with |big_endian_| byte-significance. |
| 70 // IMPORTANT NOTE: This is currently *not* security-approved for importing |
| 71 // keys from unstrusted sources. |
| 72 bool Import(const std::vector<uint8>& input); |
| 73 |
| 74 // Accessors to the contents of the integer components of the PrivateKeyInfo |
| 75 // structure. |
| 76 std::vector<uint8>* modulus() { return &modulus_; }; |
| 77 std::vector<uint8>* public_exponent() { return &public_exponent_; }; |
| 78 std::vector<uint8>* private_exponent() { return &private_exponent_; }; |
| 79 std::vector<uint8>* prime1() { return &prime1_; }; |
| 80 std::vector<uint8>* prime2() { return &prime2_; }; |
| 81 std::vector<uint8>* exponent1() { return &exponent1_; }; |
| 82 std::vector<uint8>* exponent2() { return &exponent2_; }; |
| 83 std::vector<uint8>* coefficient() { return &coefficient_; }; |
| 84 |
| 85 private: |
| 86 // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_| |
| 87 // value. |
| 88 void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out); |
| 89 void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data); |
| 90 |
| 91 // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian| |
| 92 // byte-significance into |data| as an ASN.1 integer. |
| 93 void PrependIntegerImpl(uint8* val, |
| 94 int num_bytes, |
| 95 std::list<uint8>* data, |
| 96 bool big_endian); |
| 97 |
| 98 // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_| |
| 99 // value. |
| 100 bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out); |
| 101 bool ReadIntegerWithExpectedSize(uint8** pos, |
| 102 uint8* end, |
| 103 size_t expected_size, |
| 104 std::vector<uint8>* out); |
| 105 |
| 106 // Reads an ASN.1 integer from |pos|, and stores the result into |out| with |
| 107 // |big_endian| byte-significance. |
| 108 bool ReadIntegerImpl(uint8** pos, |
| 109 uint8* end, |
| 110 std::vector<uint8>* out, |
| 111 bool big_endian); |
| 112 |
| 113 // Prepends the integer stored in |val|, starting a index |start|, for |
| 114 // |num_bytes| bytes onto |data|. |
| 115 void PrependBytes(uint8* val, |
| 116 int start, |
| 117 int num_bytes, |
| 118 std::list<uint8>* data); |
| 119 |
| 120 // Helper to prepend an ASN.1 length field. |
| 121 void PrependLength(size_t size, std::list<uint8>* data); |
| 122 |
| 123 // Helper to prepend an ASN.1 type header. |
| 124 void PrependTypeHeaderAndLength(uint8 type, |
| 125 uint32 length, |
| 126 std::list<uint8>* output); |
| 127 |
| 128 // Helper to prepend an ASN.1 bit string |
| 129 void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output); |
| 130 |
| 131 // Read an ASN.1 length field. This also checks that the length does not |
| 132 // extend beyond |end|. |
| 133 bool ReadLength(uint8** pos, uint8* end, uint32* result); |
| 134 |
| 135 // Read an ASN.1 type header and its length. |
| 136 bool ReadTypeHeaderAndLength(uint8** pos, |
| 137 uint8* end, |
| 138 uint8 expected_tag, |
| 139 uint32* length); |
| 140 |
| 141 // Read an ASN.1 sequence declaration. This consumes the type header and |
| 142 // length field, but not the contents of the sequence. |
| 143 bool ReadSequence(uint8** pos, uint8* end); |
| 144 |
| 145 // Read the RSA AlgorithmIdentifier. |
| 146 bool ReadAlgorithmIdentifier(uint8** pos, uint8* end); |
| 147 |
| 148 // Read one of the two version fields in PrivateKeyInfo. |
| 149 bool ReadVersion(uint8** pos, uint8* end); |
| 150 |
| 151 // The byte-significance of the stored components (modulus, etc..). |
| 152 bool big_endian_; |
| 153 |
| 154 // Component integers of the PrivateKeyInfo |
| 155 std::vector<uint8> modulus_; |
| 156 std::vector<uint8> public_exponent_; |
| 157 std::vector<uint8> private_exponent_; |
| 158 std::vector<uint8> prime1_; |
| 159 std::vector<uint8> prime2_; |
| 160 std::vector<uint8> exponent1_; |
| 161 std::vector<uint8> exponent2_; |
| 162 std::vector<uint8> coefficient_; |
| 163 |
| 164 DISALLOW_COPY_AND_ASSIGN(PrivateKeyInfoCodec); |
| 165 }; |
| 166 |
| 167 // Encapsulates an RSA private key. Can be used to generate new keys, export |
| 168 // keys to other formats, or to extract a public key. |
| 169 // TODO(hclam): This class should be ref-counted so it can be reused easily. |
| 170 class CRYPTO_EXPORT RSAPrivateKey { |
| 171 public: |
| 172 ~RSAPrivateKey(); |
| 173 |
| 174 // Create a new random instance. Can return NULL if initialization fails. |
| 175 static RSAPrivateKey* Create(uint16 num_bits); |
| 176 |
| 177 // Create a new instance by importing an existing private key. The format is |
| 178 // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if |
| 179 // initialization fails. |
| 180 static RSAPrivateKey* CreateFromPrivateKeyInfo( |
| 181 const std::vector<uint8>& input); |
| 182 |
| 183 #if defined(USE_OPENSSL) |
| 184 // Create a new instance from an existing EVP_PKEY, taking a |
| 185 // reference to it. |key| must be an RSA key. Returns NULL on |
| 186 // failure. |
| 187 static RSAPrivateKey* CreateFromKey(EVP_PKEY* key); |
| 188 #else |
| 189 // Create a new instance by referencing an existing private key |
| 190 // structure. Does not import the key. |
| 191 static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key); |
| 192 #endif |
| 193 |
| 194 #if defined(USE_OPENSSL) |
| 195 EVP_PKEY* key() { return key_; } |
| 196 #else |
| 197 SECKEYPrivateKey* key() { return key_; } |
| 198 SECKEYPublicKey* public_key() { return public_key_; } |
| 199 #endif |
| 200 |
| 201 // Creates a copy of the object. |
| 202 RSAPrivateKey* Copy() const; |
| 203 |
| 204 // Exports the private key to a PKCS #1 PrivateKey block. |
| 205 bool ExportPrivateKey(std::vector<uint8>* output) const; |
| 206 |
| 207 // Exports the public key to an X509 SubjectPublicKeyInfo block. |
| 208 bool ExportPublicKey(std::vector<uint8>* output) const; |
| 209 |
| 210 private: |
| 211 #if defined(USE_NSS_CERTS) |
| 212 FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey); |
| 213 FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey); |
| 214 #endif |
| 215 |
| 216 // Constructor is private. Use one of the Create*() methods above instead. |
| 217 RSAPrivateKey(); |
| 218 |
| 219 #if defined(USE_OPENSSL) |
| 220 EVP_PKEY* key_; |
| 221 #else |
| 222 SECKEYPrivateKey* key_; |
| 223 SECKEYPublicKey* public_key_; |
| 224 #endif |
| 225 |
| 226 DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey); |
| 227 }; |
| 228 |
| 229 } // namespace crypto |
| 230 |
| 231 #endif // CRYPTO_RSA_PRIVATE_KEY_H_ |
OLD | NEW |