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