1 // Copyright (c) 2011 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.
5 #include "crypto/rsa_private_key.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/string_util.h"
14 // This file manually encodes and decodes RSA private keys using PrivateKeyInfo
15 // from PKCS #8 and RSAPrivateKey from PKCS #1. These structures are:
17 // PrivateKeyInfo ::= SEQUENCE {
19 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
20 // privateKey PrivateKey,
21 // attributes [0] IMPLICIT Attributes OPTIONAL
24 // RSAPrivateKey ::= SEQUENCE {
27 // publicExponent INTEGER,
28 // privateExponent INTEGER,
33 // coefficient INTEGER
37 // Helper for error handling during key import.
38 #define READ_ASSERT(truth) \
47 const uint8
PrivateKeyInfoCodec::kRsaAlgorithmIdentifier
[] = {
48 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
52 PrivateKeyInfoCodec::PrivateKeyInfoCodec(bool big_endian
)
53 : big_endian_(big_endian
) {}
55 PrivateKeyInfoCodec::~PrivateKeyInfoCodec() {}
57 bool PrivateKeyInfoCodec::Export(std::vector
<uint8
>* output
) {
58 std::list
<uint8
> content
;
60 // Version (always zero)
63 PrependInteger(coefficient_
, &content
);
64 PrependInteger(exponent2_
, &content
);
65 PrependInteger(exponent1_
, &content
);
66 PrependInteger(prime2_
, &content
);
67 PrependInteger(prime1_
, &content
);
68 PrependInteger(private_exponent_
, &content
);
69 PrependInteger(public_exponent_
, &content
);
70 PrependInteger(modulus_
, &content
);
71 PrependInteger(&version
, 1, &content
);
72 PrependTypeHeaderAndLength(kSequenceTag
, content
.size(), &content
);
73 PrependTypeHeaderAndLength(kOctetStringTag
, content
.size(), &content
);
76 for (size_t i
= sizeof(kRsaAlgorithmIdentifier
); i
> 0; --i
)
77 content
.push_front(kRsaAlgorithmIdentifier
[i
- 1]);
79 PrependInteger(&version
, 1, &content
);
80 PrependTypeHeaderAndLength(kSequenceTag
, content
.size(), &content
);
82 // Copy everying into the output.
83 output
->reserve(content
.size());
84 output
->assign(content
.begin(), content
.end());
89 bool PrivateKeyInfoCodec::ExportPublicKeyInfo(std::vector
<uint8
>* output
) {
90 // Create a sequence with the modulus (n) and public exponent (e).
91 std::vector
<uint8
> bit_string
;
92 if (!ExportPublicKey(&bit_string
))
95 // Add the sequence as the contents of a bit string.
96 std::list
<uint8
> content
;
97 PrependBitString(&bit_string
[0], static_cast<int>(bit_string
.size()),
100 // Add the RSA algorithm OID.
101 for (size_t i
= sizeof(kRsaAlgorithmIdentifier
); i
> 0; --i
)
102 content
.push_front(kRsaAlgorithmIdentifier
[i
- 1]);
104 // Finally, wrap everything in a sequence.
105 PrependTypeHeaderAndLength(kSequenceTag
, content
.size(), &content
);
107 // Copy everything into the output.
108 output
->reserve(content
.size());
109 output
->assign(content
.begin(), content
.end());
114 bool PrivateKeyInfoCodec::ExportPublicKey(std::vector
<uint8
>* output
) {
115 // Create a sequence with the modulus (n) and public exponent (e).
116 std::list
<uint8
> content
;
117 PrependInteger(&public_exponent_
[0],
118 static_cast<int>(public_exponent_
.size()),
120 PrependInteger(&modulus_
[0], static_cast<int>(modulus_
.size()), &content
);
121 PrependTypeHeaderAndLength(kSequenceTag
, content
.size(), &content
);
123 // Copy everything into the output.
124 output
->reserve(content
.size());
125 output
->assign(content
.begin(), content
.end());
130 bool PrivateKeyInfoCodec::Import(const std::vector
<uint8
>& input
) {
135 // Parse the private key info up to the public key values, ignoring
136 // the subsequent private key values.
137 uint8
* src
= const_cast<uint8
*>(&input
.front());
138 uint8
* end
= src
+ input
.size();
139 if (!ReadSequence(&src
, end
) ||
140 !ReadVersion(&src
, end
) ||
141 !ReadAlgorithmIdentifier(&src
, end
) ||
142 !ReadTypeHeaderAndLength(&src
, end
, kOctetStringTag
, NULL
) ||
143 !ReadSequence(&src
, end
) ||
144 !ReadVersion(&src
, end
) ||
145 !ReadInteger(&src
, end
, &modulus_
))
148 int mod_size
= modulus_
.size();
149 READ_ASSERT(mod_size
% 2 == 0);
150 int primes_size
= mod_size
/ 2;
152 if (!ReadIntegerWithExpectedSize(&src
, end
, 4, &public_exponent_
) ||
153 !ReadIntegerWithExpectedSize(&src
, end
, mod_size
, &private_exponent_
) ||
154 !ReadIntegerWithExpectedSize(&src
, end
, primes_size
, &prime1_
) ||
155 !ReadIntegerWithExpectedSize(&src
, end
, primes_size
, &prime2_
) ||
156 !ReadIntegerWithExpectedSize(&src
, end
, primes_size
, &exponent1_
) ||
157 !ReadIntegerWithExpectedSize(&src
, end
, primes_size
, &exponent2_
) ||
158 !ReadIntegerWithExpectedSize(&src
, end
, primes_size
, &coefficient_
))
161 READ_ASSERT(src
== end
);
167 void PrivateKeyInfoCodec::PrependInteger(const std::vector
<uint8
>& in
,
168 std::list
<uint8
>* out
) {
169 uint8
* ptr
= const_cast<uint8
*>(&in
.front());
170 PrependIntegerImpl(ptr
, in
.size(), out
, big_endian_
);
173 // Helper to prepend an ASN.1 integer.
174 void PrivateKeyInfoCodec::PrependInteger(uint8
* val
,
176 std::list
<uint8
>* data
) {
177 PrependIntegerImpl(val
, num_bytes
, data
, big_endian_
);
180 void PrivateKeyInfoCodec::PrependIntegerImpl(uint8
* val
,
182 std::list
<uint8
>* data
,
184 // Reverse input if little-endian.
185 std::vector
<uint8
> tmp
;
187 tmp
.assign(val
, val
+ num_bytes
);
188 std::reverse(tmp
.begin(), tmp
.end());
192 // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes
193 // from the most-significant end of the integer.
195 while (start
< (num_bytes
- 1) && val
[start
] == 0x00) {
199 PrependBytes(val
, start
, num_bytes
, data
);
201 // ASN.1 integers are signed. To encode a positive integer whose sign bit
202 // (the most significant bit) would otherwise be set and make the number
203 // negative, ASN.1 requires a leading null byte to force the integer to be
205 uint8 front
= data
->front();
206 if ((front
& 0x80) != 0) {
207 data
->push_front(0x00);
211 PrependTypeHeaderAndLength(kIntegerTag
, num_bytes
, data
);
214 bool PrivateKeyInfoCodec::ReadInteger(uint8
** pos
,
216 std::vector
<uint8
>* out
) {
217 return ReadIntegerImpl(pos
, end
, out
, big_endian_
);
220 bool PrivateKeyInfoCodec::ReadIntegerWithExpectedSize(uint8
** pos
,
222 size_t expected_size
,
223 std::vector
<uint8
>* out
) {
224 std::vector
<uint8
> temp
;
225 if (!ReadIntegerImpl(pos
, end
, &temp
, true)) // Big-Endian
228 int pad
= expected_size
- temp
.size();
230 if (out
->size() == expected_size
+ 1) {
231 READ_ASSERT(out
->front() == 0x00);
235 READ_ASSERT(out
->size() <= expected_size
);
238 out
->insert(out
->end(), pad
, 0x00);
239 out
->insert(out
->end(), temp
.begin(), temp
.end());
241 // Reverse output if little-endian.
243 std::reverse(out
->begin(), out
->end());
247 bool PrivateKeyInfoCodec::ReadIntegerImpl(uint8
** pos
,
249 std::vector
<uint8
>* out
,
252 if (!ReadTypeHeaderAndLength(pos
, end
, kIntegerTag
, &length
) || !length
)
255 // The first byte can be zero to force positiveness. We can ignore this.
262 out
->insert(out
->end(), *pos
, (*pos
) + length
);
266 // Reverse output if little-endian.
268 std::reverse(out
->begin(), out
->end());
272 void PrivateKeyInfoCodec::PrependBytes(uint8
* val
,
275 std::list
<uint8
>* data
) {
276 while (num_bytes
> 0) {
278 data
->push_front(val
[start
+ num_bytes
]);
282 void PrivateKeyInfoCodec::PrependLength(size_t size
, std::list
<uint8
>* data
) {
283 // The high bit is used to indicate whether additional octets are needed to
284 // represent the length.
286 data
->push_front(static_cast<uint8
>(size
));
290 data
->push_front(static_cast<uint8
>(size
& 0xFF));
294 CHECK_LE(num_bytes
, 4);
295 data
->push_front(0x80 | num_bytes
);
299 void PrivateKeyInfoCodec::PrependTypeHeaderAndLength(uint8 type
,
301 std::list
<uint8
>* output
) {
302 PrependLength(length
, output
);
303 output
->push_front(type
);
306 void PrivateKeyInfoCodec::PrependBitString(uint8
* val
,
308 std::list
<uint8
>* output
) {
309 // Start with the data.
310 PrependBytes(val
, 0, num_bytes
, output
);
312 output
->push_front(0);
314 PrependLength(num_bytes
+ 1, output
);
315 // Finally, add the bit string tag.
316 output
->push_front((uint8
) kBitStringTag
);
319 bool PrivateKeyInfoCodec::ReadLength(uint8
** pos
, uint8
* end
, uint32
* result
) {
320 READ_ASSERT(*pos
< end
);
323 // If the MSB is not set, the length is just the byte itself.
324 if (!(**pos
& 0x80)) {
328 // Otherwise, the lower 7 indicate the length of the length.
329 int length_of_length
= **pos
& 0x7F;
330 READ_ASSERT(length_of_length
<= 4);
332 READ_ASSERT(*pos
+ length_of_length
< end
);
335 for (int i
= 0; i
< length_of_length
; ++i
) {
342 READ_ASSERT(*pos
+ length
<= end
);
343 if (result
) *result
= length
;
347 bool PrivateKeyInfoCodec::ReadTypeHeaderAndLength(uint8
** pos
,
351 READ_ASSERT(*pos
< end
);
352 READ_ASSERT(**pos
== expected_tag
);
355 return ReadLength(pos
, end
, length
);
358 bool PrivateKeyInfoCodec::ReadSequence(uint8
** pos
, uint8
* end
) {
359 return ReadTypeHeaderAndLength(pos
, end
, kSequenceTag
, NULL
);
362 bool PrivateKeyInfoCodec::ReadAlgorithmIdentifier(uint8
** pos
, uint8
* end
) {
363 READ_ASSERT(*pos
+ sizeof(kRsaAlgorithmIdentifier
) < end
);
364 READ_ASSERT(memcmp(*pos
, kRsaAlgorithmIdentifier
,
365 sizeof(kRsaAlgorithmIdentifier
)) == 0);
366 (*pos
) += sizeof(kRsaAlgorithmIdentifier
);
370 bool PrivateKeyInfoCodec::ReadVersion(uint8
** pos
, uint8
* end
) {
372 if (!ReadTypeHeaderAndLength(pos
, end
, kIntegerTag
, &length
))
375 // The version should be zero.
376 for (uint32 i
= 0; i
< length
; ++i
) {
377 READ_ASSERT(**pos
== 0x00);
384 } // namespace crypto