OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/crypto/rsa_private_key.h" | 5 #include "base/crypto/rsa_private_key.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/crypto/cssm_init.h" | 9 #include "base/crypto/cssm_init.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
12 | 12 |
13 namespace { | |
14 | |
15 // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8. | |
16 const uint8 kRsaAlgorithmIdentifier[] = { | |
17 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, | |
18 0x05, 0x00 | |
19 }; | |
20 | |
21 // ASN.1 tags for some types we use. | |
22 const uint8 kSequenceTag = 0x30; | |
23 const uint8 kIntegerTag = 0x02; | |
24 const uint8 kNullTag = 0x05; | |
25 const uint8 kOctetStringTag = 0x04; | |
26 const uint8 kBitStringTag = 0x03; | |
27 | |
28 // Helper for error handling during key import. | |
29 #define READ_ASSERT(truth) \ | |
30 if (!(truth)) { \ | |
31 NOTREACHED(); \ | |
32 return false; \ | |
33 } | |
34 | |
35 static void PrependBytesInOrder(uint8* val, int start, int num_bytes, | |
36 std::list<uint8>* data) { | |
37 while(num_bytes > start) { | |
38 --num_bytes; | |
39 data->push_front(val[num_bytes]); | |
40 } | |
41 } | |
42 | |
43 // Helper to prepend an ASN.1 length field. | |
44 static void PrependLength(size_t size, std::list<uint8>* data) { | |
45 // The high bit is used to indicate whether additional octets are needed to | |
46 // represent the length. | |
47 if (size < 0x80) { | |
48 data->push_front(static_cast<uint8>(size)); | |
49 } else { | |
50 uint8 num_bytes = 0; | |
51 while (size > 0) { | |
52 data->push_front(static_cast<uint8>(size & 0xFF)); | |
53 size >>= 8; | |
54 num_bytes++; | |
55 } | |
56 CHECK(num_bytes <= 4); | |
57 data->push_front(0x80 | num_bytes); | |
58 } | |
59 } | |
60 | |
61 // Helper to prepend an ASN.1 type header. | |
62 static void PrependTypeHeaderAndLength(uint8 type, uint32 length, | |
63 std::list<uint8>* output) { | |
64 PrependLength(length, output); | |
65 output->push_front(type); | |
66 } | |
67 | |
68 // Helper to prepend an ASN.1 bit string | |
69 static void PrependBitString(uint8* val, int num_bytes, | |
70 std::list<uint8>* output) { | |
71 // Start with the data. | |
72 PrependBytesInOrder(val, 0, num_bytes, output); | |
73 // Zero unused bits. | |
74 output->push_front(0); | |
75 // Add the length. | |
76 PrependLength(num_bytes + 1, output); | |
77 // Finally, add the bit string tag. | |
78 output->push_front(kBitStringTag); | |
79 } | |
80 | |
81 // Helper to prepend an ASN.1 integer. | |
82 static void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data) { | |
83 // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes | |
84 // from the most-significant end of the integer. | |
85 int start = 0; | |
86 while (start < (num_bytes - 1) && val[start] == 0x00) | |
87 start++; | |
88 | |
89 PrependBytesInOrder(val, start, num_bytes, data); | |
90 | |
91 // ASN.1 integers are signed. To encode a positive integer whose sign bit | |
92 // (the most significant bit) would otherwise be set and make the number | |
93 // negative, ASN.1 requires a leading null byte to force the integer to be | |
94 // positive. | |
95 if ((val[start] & 0x80) != 0) { | |
96 data->push_front(0x00); | |
97 num_bytes++; | |
98 } | |
99 | |
100 PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data); | |
101 } | |
102 | |
103 // Read an ASN.1 length field. This also checks that the length does not extend | |
104 // beyond |end|. | |
105 static bool ReadLength(uint8** pos, uint8* end, uint32* result) { | |
106 READ_ASSERT(*pos < end); | |
107 int length = 0; | |
108 | |
109 // If the MSB is not set, the length is just the byte itself. | |
110 if (!(**pos & 0x80)) { | |
111 length = **pos; | |
112 (*pos)++; | |
113 } else { | |
114 // Otherwise, the lower 7 indicate the length of the length. | |
115 int length_of_length = **pos & 0x7F; | |
116 READ_ASSERT(length_of_length <= 4); | |
117 (*pos)++; | |
118 READ_ASSERT(*pos + length_of_length < end); | |
119 | |
120 length = 0; | |
121 for (int i = 0; i < length_of_length; ++i) { | |
122 length <<= 8; | |
123 length |= **pos; | |
124 (*pos)++; | |
125 } | |
126 } | |
127 | |
128 READ_ASSERT(*pos + length <= end); | |
129 if (result) *result = length; | |
130 return true; | |
131 } | |
132 | |
133 // Read an ASN.1 type header and its length. | |
134 static bool ReadTypeHeaderAndLength(uint8** pos, uint8* end, | |
135 uint8 expected_tag, uint32* length) { | |
136 READ_ASSERT(*pos < end); | |
137 READ_ASSERT(**pos == expected_tag); | |
138 (*pos)++; | |
139 | |
140 return ReadLength(pos, end, length); | |
141 } | |
142 | |
143 // Read an ASN.1 sequence declaration. This consumes the type header and length | |
144 // field, but not the contents of the sequence. | |
145 static bool ReadSequence(uint8** pos, uint8* end) { | |
146 return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL); | |
147 } | |
148 | |
149 // Read the RSA AlgorithmIdentifier. | |
150 static bool ReadAlgorithmIdentifier(uint8** pos, uint8* end) { | |
151 READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end); | |
152 READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier, | |
153 sizeof(kRsaAlgorithmIdentifier)) == 0); | |
154 (*pos) += sizeof(kRsaAlgorithmIdentifier); | |
155 return true; | |
156 } | |
157 | |
158 // Read one of the two version fields in PrivateKeyInfo. | |
159 static bool ReadVersion(uint8** pos, uint8* end) { | |
160 uint32 length = 0; | |
161 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) | |
162 return false; | |
163 | |
164 // The version should be zero. | |
165 for (uint32 i = 0; i < length; ++i) { | |
166 READ_ASSERT(**pos == 0x00); | |
167 (*pos)++; | |
168 } | |
169 | |
170 return true; | |
171 } | |
172 | |
173 // Read an ASN.1 integer. | |
174 static bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out) { | |
175 uint32 length = 0; | |
176 if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length) || !length) | |
177 return false; | |
178 | |
179 // The first byte can be zero to force positiveness. We can ignore this. | |
180 if (**pos == 0x00) { | |
181 ++(*pos); | |
182 --length; | |
183 } | |
184 | |
185 if (length) | |
186 out->insert(out->end(), *pos, (*pos) + length); | |
187 | |
188 (*pos) += length; | |
189 return true; | |
190 } | |
191 | |
192 } // namespace | |
193 | |
194 namespace base { | 13 namespace base { |
195 | 14 |
196 // static | 15 // static |
197 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 16 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
198 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 17 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
199 | 18 |
200 CSSM_CC_HANDLE cc_handle; | 19 CSSM_CC_HANDLE cc_handle; |
201 CSSM_RETURN crtn; | 20 CSSM_RETURN crtn; |
202 crtn = CSSM_CSP_CreateKeyGenContext(result->csp_handle(), CSSM_ALGID_RSA, | 21 crtn = CSSM_CSP_CreateKeyGenContext(result->csp_handle(), CSSM_ALGID_RSA, |
203 num_bits, NULL, NULL, NULL, NULL, NULL, | 22 num_bits, NULL, NULL, NULL, NULL, NULL, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 if (!key_.KeyData.Data || !key_.KeyData.Length) { | 130 if (!key_.KeyData.Data || !key_.KeyData.Length) { |
312 return false; | 131 return false; |
313 } | 132 } |
314 output->clear(); | 133 output->clear(); |
315 output->insert(output->end(), key_.KeyData.Data, | 134 output->insert(output->end(), key_.KeyData.Data, |
316 key_.KeyData.Data + key_.KeyData.Length); | 135 key_.KeyData.Data + key_.KeyData.Length); |
317 return true; | 136 return true; |
318 } | 137 } |
319 | 138 |
320 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 139 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
321 if (!key_.KeyData.Data || !key_.KeyData.Length) { | 140 PrivateKeyInfoCodec private_key_info(true); |
322 return false; | 141 std::vector<uint8> private_key_data; |
323 } | 142 private_key_data.assign(key_.KeyData.Data, |
324 | 143 key_.KeyData.Data + key_.KeyData.Length); |
325 // Parse the private key info up to the public key values, ignoring | 144 return (private_key_info.Import(private_key_data) && |
326 // the subsequent private key values. | 145 private_key_info.ExportPublicKeyInfo(output)); |
327 uint8* src = key_.KeyData.Data; | |
328 uint8* end = src + key_.KeyData.Length; | |
329 std::vector<uint8> modulus; | |
330 std::vector<uint8> public_exponent; | |
331 if (!ReadSequence(&src, end) || | |
332 !ReadVersion(&src, end) || | |
333 !ReadAlgorithmIdentifier(&src, end) || | |
334 !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) || | |
335 !ReadSequence(&src, end) || | |
336 !ReadVersion(&src, end) || | |
337 !ReadInteger(&src, end, &modulus) || | |
338 !ReadInteger(&src, end, &public_exponent)) | |
339 return false; | |
340 | |
341 // Create a sequence with the modulus (n) and public exponent (e). | |
342 std::list<uint8> content; | |
343 PrependInteger(&public_exponent[0], static_cast<int>(public_exponent.size()), | |
344 &content); | |
345 PrependInteger(&modulus[0], static_cast<int>(modulus.size()), &content); | |
346 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
347 | |
348 // Copy the sequence with n and e into a buffer. | |
349 std::vector<uint8> bit_string; | |
350 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) | |
351 bit_string.push_back(*i); | |
352 content.clear(); | |
353 // Add the sequence as the contents of a bit string. | |
354 PrependBitString(&bit_string[0], static_cast<int>(bit_string.size()), | |
355 &content); | |
356 | |
357 // Add the RSA algorithm OID. | |
358 for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) | |
359 content.push_front(kRsaAlgorithmIdentifier[i - 1]); | |
360 | |
361 // Finally, wrap everything in a sequence. | |
362 PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); | |
363 | |
364 // Copy everything into the output. | |
365 output->reserve(content.size()); | |
366 for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) | |
367 output->push_back(*i); | |
368 | |
369 return true; | |
370 } | 146 } |
371 | 147 |
372 } // namespace base | 148 } // namespace base |
OLD | NEW |