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) 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. modulus()76 std::vector<uint8>* modulus() { return &modulus_; }; public_exponent()77 std::vector<uint8>* public_exponent() { return &public_exponent_; }; private_exponent()78 std::vector<uint8>* private_exponent() { return &private_exponent_; }; prime1()79 std::vector<uint8>* prime1() { return &prime1_; }; prime2()80 std::vector<uint8>* prime2() { return &prime2_; }; exponent1()81 std::vector<uint8>* exponent1() { return &exponent1_; }; exponent2()82 std::vector<uint8>* exponent2() { return &exponent2_; }; coefficient()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_NSS) 184 // Create a new random instance in |slot|. Can return NULL if initialization 185 // fails. The created key is permanent and is not exportable in plaintext 186 // form. 187 static RSAPrivateKey* CreateSensitive(PK11SlotInfo* slot, uint16 num_bits); 188 189 // Create a new instance in |slot| by importing an existing private key. The 190 // format is an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can 191 // return NULL if initialization fails. 192 // The created key is permanent and is not exportable in plaintext form. 193 static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo( 194 PK11SlotInfo* slot, 195 const std::vector<uint8>& input); 196 197 // Create a new instance by referencing an existing private key 198 // structure. Does not import the key. 199 static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key); 200 201 // Import an existing public key, and then search for the private 202 // half in the key database. The format of the public key blob is is 203 // an X509 SubjectPublicKeyInfo block. This can return NULL if 204 // initialization fails or the private key cannot be found. The 205 // caller takes ownership of the returned object, but nothing new is 206 // created in the key database. 207 static RSAPrivateKey* FindFromPublicKeyInfo( 208 const std::vector<uint8>& input); 209 210 // Import an existing public key, and then search for the private 211 // half in the slot specified by |slot|. The format of the public 212 // key blob is is an X509 SubjectPublicKeyInfo block. This can return 213 // NULL if initialization fails or the private key cannot be found. 214 // The caller takes ownership of the returned object, but nothing new 215 // is created in the slot. 216 static RSAPrivateKey* FindFromPublicKeyInfoInSlot( 217 const std::vector<uint8>& input, 218 PK11SlotInfo* slot); 219 #endif 220 221 #if defined(USE_OPENSSL) key()222 EVP_PKEY* key() { return key_; } 223 #else key()224 SECKEYPrivateKey* key() { return key_; } public_key()225 SECKEYPublicKey* public_key() { return public_key_; } 226 #endif 227 228 // Creates a copy of the object. 229 RSAPrivateKey* Copy() const; 230 231 // Exports the private key to a PKCS #1 PrivateKey block. 232 bool ExportPrivateKey(std::vector<uint8>* output) const; 233 234 // Exports the public key to an X509 SubjectPublicKeyInfo block. 235 bool ExportPublicKey(std::vector<uint8>* output) const; 236 237 private: 238 #if defined(USE_NSS) 239 FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey); 240 FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey); 241 #endif 242 243 // Constructor is private. Use one of the Create*() or Find*() 244 // methods above instead. 245 RSAPrivateKey(); 246 247 #if !defined(USE_OPENSSL) 248 // Shared helper for Create() and CreateSensitive(). 249 // TODO(cmasone): consider replacing |permanent| and |sensitive| with a 250 // flags arg created by ORing together some enumerated values. 251 // Note: |permanent| is only supported when USE_NSS is defined. 252 static RSAPrivateKey* CreateWithParams(PK11SlotInfo* slot, 253 uint16 num_bits, 254 bool permanent, 255 bool sensitive); 256 257 // Shared helper for CreateFromPrivateKeyInfo() and 258 // CreateSensitiveFromPrivateKeyInfo(). 259 // Note: |permanent| is only supported when USE_NSS is defined. 260 static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams( 261 PK11SlotInfo* slot, 262 const std::vector<uint8>& input, 263 bool permanent, 264 bool sensitive); 265 #endif 266 267 #if defined(USE_NSS) 268 // Import an existing public key. The format of the public key blob 269 // is an X509 SubjectPublicKeyInfo block. This can return NULL if 270 // initialization fails. The caller takes ownership of the returned 271 // object. Note that this method doesn't initialize the |key_| member. 272 static RSAPrivateKey* InitPublicPart(const std::vector<uint8>& input); 273 #endif 274 275 #if defined(USE_OPENSSL) 276 EVP_PKEY* key_; 277 #else 278 SECKEYPrivateKey* key_; 279 SECKEYPublicKey* public_key_; 280 #endif 281 282 DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey); 283 }; 284 285 } // namespace crypto 286 287 #endif // CRYPTO_RSA_PRIVATE_KEY_H_ 288