blob: 9c8bfd4424de0ab66e9f4e9aacdf44881682a67e [file] [log] [blame]
[email protected]28ae8fe2009-06-05 18:25:061// Copyright (c) 2009 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 BASE_CRYPTO_RSA_PRIVATE_KEY_H_
6#define BASE_CRYPTO_RSA_PRIVATE_KEY_H_
7
8#include "build/build_config.h"
9
[email protected]71a9f842009-09-24 01:21:1210#if defined(USE_NSS)
[email protected]13555c122009-10-08 01:18:0211// Forward declaration.
12struct SECKEYPrivateKeyStr;
13struct SECKEYPublicKeyStr;
[email protected]71a9f842009-09-24 01:21:1214#elif defined(OS_MACOSX)
[email protected]0691bdf42009-10-02 21:05:0115#include <Security/cssm.h>
[email protected]28ae8fe2009-06-05 18:25:0616#endif
17
[email protected]308379a52009-10-07 02:46:3118#include <list>
[email protected]28ae8fe2009-06-05 18:25:0619#include <vector>
20
21#include "base/basictypes.h"
22
[email protected]692033a2010-04-09 18:40:5023#if defined(OS_WIN)
24#include "base/crypto/scoped_capi_types.h"
25#endif
26
[email protected]28ae8fe2009-06-05 18:25:0627namespace base {
28
[email protected]308379a52009-10-07 02:46:3129// Used internally by RSAPrivateKey for serializing and deserializing
30// PKCS #8 PrivateKeyInfo and PublicKeyInfo.
31class PrivateKeyInfoCodec {
32 public:
33
34 // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8.
35 static const uint8 kRsaAlgorithmIdentifier[];
36
37 // ASN.1 tags for some types we use.
38 static const uint8 kBitStringTag = 0x03;
39 static const uint8 kIntegerTag = 0x02;
40 static const uint8 kNullTag = 0x05;
41 static const uint8 kOctetStringTag = 0x04;
42 static const uint8 kSequenceTag = 0x30;
[email protected]90a28472009-10-20 20:39:5243
[email protected]308379a52009-10-07 02:46:3144 // |big_endian| here specifies the byte-significance of the integer components
45 // that will be parsed & serialized (modulus(), etc...) during Import(),
46 // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the
47 // PrivateKeyInfo/PublicKeyInfo (which is always big-endian).
48 explicit PrivateKeyInfoCodec(bool big_endian) : big_endian_(big_endian) {}
49
50 // Exports the contents of the integer components to the ASN.1 DER encoding
51 // of the PrivateKeyInfo structure to |output|.
52 bool Export(std::vector<uint8>* output);
53
54 // Exports the contents of the integer components to the ASN.1 DER encoding
55 // of the PublicKeyInfo structure to |output|.
56 bool ExportPublicKeyInfo(std::vector<uint8>* output);
57
58 // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input|
59 // and populates the integer components with |big_endian_| byte-significance.
[email protected]90a28472009-10-20 20:39:5260 // IMPORTANT NOTE: This is currently *not* security-approved for importing
61 // keys from unstrusted sources.
[email protected]308379a52009-10-07 02:46:3162 bool Import(const std::vector<uint8>& input);
63
64 // Accessors to the contents of the integer components of the PrivateKeyInfo
65 // structure.
66 std::vector<uint8>* modulus() { return &modulus_; };
67 std::vector<uint8>* public_exponent() { return &public_exponent_; };
68 std::vector<uint8>* private_exponent() { return &private_exponent_; };
69 std::vector<uint8>* prime1() { return &prime1_; };
70 std::vector<uint8>* prime2() { return &prime2_; };
71 std::vector<uint8>* exponent1() { return &exponent1_; };
72 std::vector<uint8>* exponent2() { return &exponent2_; };
73 std::vector<uint8>* coefficient() { return &coefficient_; };
74
75 private:
76 // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_|
77 // value.
78 void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out);
79 void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data);
[email protected]90a28472009-10-20 20:39:5280
[email protected]308379a52009-10-07 02:46:3181 // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian|
82 // byte-significance into |data| as an ASN.1 integer.
83 void PrependIntegerImpl(uint8* val,
84 int num_bytes,
85 std::list<uint8>* data,
86 bool big_endian);
87
88 // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_|
89 // value.
90 bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out);
91 bool ReadIntegerWithExpectedSize(uint8** pos,
92 uint8* end,
93 size_t expected_size,
94 std::vector<uint8>* out);
95
96 // Reads an ASN.1 integer from |pos|, and stores the result into |out| with
97 // |big_endian| byte-significance.
98 bool ReadIntegerImpl(uint8** pos,
99 uint8* end,
[email protected]90a28472009-10-20 20:39:52100 std::vector<uint8>* out,
[email protected]308379a52009-10-07 02:46:31101 bool big_endian);
[email protected]90a28472009-10-20 20:39:52102
[email protected]308379a52009-10-07 02:46:31103 // Prepends the integer stored in |val|, starting a index |start|, for
104 // |num_bytes| bytes onto |data|.
105 void PrependBytes(uint8* val,
106 int start,
107 int num_bytes,
108 std::list<uint8>* data);
109
110 // Helper to prepend an ASN.1 length field.
111 void PrependLength(size_t size, std::list<uint8>* data);
112
113 // Helper to prepend an ASN.1 type header.
114 void PrependTypeHeaderAndLength(uint8 type,
115 uint32 length,
116 std::list<uint8>* output);
117
118 // Helper to prepend an ASN.1 bit string
119 void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output);
120
121 // Read an ASN.1 length field. This also checks that the length does not
122 // extend beyond |end|.
123 bool ReadLength(uint8** pos, uint8* end, uint32* result);
124
125 // Read an ASN.1 type header and its length.
126 bool ReadTypeHeaderAndLength(uint8** pos,
127 uint8* end,
128 uint8 expected_tag,
129 uint32* length);
130
131 // Read an ASN.1 sequence declaration. This consumes the type header and
132 // length field, but not the contents of the sequence.
133 bool ReadSequence(uint8** pos, uint8* end);
134
135 // Read the RSA AlgorithmIdentifier.
136 bool ReadAlgorithmIdentifier(uint8** pos, uint8* end);
137
138 // Read one of the two version fields in PrivateKeyInfo.
139 bool ReadVersion(uint8** pos, uint8* end);
140
141 // The byte-significance of the stored components (modulus, etc..).
142 bool big_endian_;
143
144 // Component integers of the PrivateKeyInfo
145 std::vector<uint8> modulus_;
146 std::vector<uint8> public_exponent_;
147 std::vector<uint8> private_exponent_;
148 std::vector<uint8> prime1_;
149 std::vector<uint8> prime2_;
150 std::vector<uint8> exponent1_;
151 std::vector<uint8> exponent2_;
152 std::vector<uint8> coefficient_;
153
154 DISALLOW_COPY_AND_ASSIGN(PrivateKeyInfoCodec);
155};
156
[email protected]28ae8fe2009-06-05 18:25:06157// Encapsulates an RSA private key. Can be used to generate new keys, export
158// keys to other formats, or to extract a public key.
159class RSAPrivateKey {
160 public:
161 // Create a new random instance. Can return NULL if initialization fails.
162 static RSAPrivateKey* Create(uint16 num_bits);
163
164 // Create a new instance by importing an existing private key. The format is
165 // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if
166 // initialization fails.
167 static RSAPrivateKey* CreateFromPrivateKeyInfo(
168 const std::vector<uint8>& input);
169
170 ~RSAPrivateKey();
171
[email protected]71a9f842009-09-24 01:21:12172#if defined(USE_NSS)
[email protected]13555c122009-10-08 01:18:02173 SECKEYPrivateKeyStr* key() { return key_; }
[email protected]71a9f842009-09-24 01:21:12174#elif defined(OS_WIN)
[email protected]28ae8fe2009-06-05 18:25:06175 HCRYPTPROV provider() { return provider_; }
176 HCRYPTKEY key() { return key_; }
[email protected]0691bdf42009-10-02 21:05:01177#elif defined(OS_MACOSX)
[email protected]0691bdf42009-10-02 21:05:01178 CSSM_KEY_PTR key() { return &key_; }
[email protected]28ae8fe2009-06-05 18:25:06179#endif
180
181 // Exports the private key to a PKCS #1 PrivateKey block.
182 bool ExportPrivateKey(std::vector<uint8>* output);
183
184 // Exports the public key to an X509 SubjectPublicKeyInfo block.
185 bool ExportPublicKey(std::vector<uint8>* output);
186
187private:
188 // Constructor is private. Use Create() or CreateFromPrivateKeyInfo()
189 // instead.
190 RSAPrivateKey();
191
[email protected]71a9f842009-09-24 01:21:12192#if defined(USE_NSS)
[email protected]13555c122009-10-08 01:18:02193 SECKEYPrivateKeyStr* key_;
194 SECKEYPublicKeyStr* public_key_;
[email protected]71a9f842009-09-24 01:21:12195#elif defined(OS_WIN)
[email protected]28ae8fe2009-06-05 18:25:06196 bool InitProvider();
197
[email protected]692033a2010-04-09 18:40:50198 ScopedHCRYPTPROV provider_;
199 ScopedHCRYPTKEY key_;
[email protected]0691bdf42009-10-02 21:05:01200#elif defined(OS_MACOSX)
201 CSSM_KEY key_;
[email protected]28ae8fe2009-06-05 18:25:06202#endif
203
204 DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey);
205};
206
207} // namespace base
208
209#endif // BASE_CRYPTO_RSA_PRIVATE_KEY_H_