1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
2 | * project 2000. |
3 | */ |
4 | /* ==================================================================== |
5 | * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in |
16 | * the documentation and/or other materials provided with the |
17 | * distribution. |
18 | * |
19 | * 3. All advertising materials mentioning features or use of this |
20 | * software must display the following acknowledgment: |
21 | * "This product includes software developed by the OpenSSL Project |
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
23 | * |
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
25 | * endorse or promote products derived from this software without |
26 | * prior written permission. For written permission, please contact |
27 | * licensing@OpenSSL.org. |
28 | * |
29 | * 5. Products derived from this software may not be called "OpenSSL" |
30 | * nor may "OpenSSL" appear in their names without prior written |
31 | * permission of the OpenSSL Project. |
32 | * |
33 | * 6. Redistributions of any form whatsoever must retain the following |
34 | * acknowledgment: |
35 | * "This product includes software developed by the OpenSSL Project |
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
37 | * |
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
50 | * ==================================================================== |
51 | * |
52 | * This product includes cryptographic software written by Eric Young |
53 | * (eay@cryptsoft.com). This product includes software written by Tim |
54 | * Hudson (tjh@cryptsoft.com). */ |
55 | |
56 | #include <openssl/rsa.h> |
57 | |
58 | #include <assert.h> |
59 | #include <limits.h> |
60 | #include <string.h> |
61 | |
62 | #include <openssl/bn.h> |
63 | #include <openssl/bytestring.h> |
64 | #include <openssl/err.h> |
65 | #include <openssl/mem.h> |
66 | |
67 | #include "../fipsmodule/rsa/internal.h" |
68 | #include "../bytestring/internal.h" |
69 | #include "../internal.h" |
70 | |
71 | |
72 | static int parse_integer(CBS *cbs, BIGNUM **out) { |
73 | assert(*out == NULL); |
74 | *out = BN_new(); |
75 | if (*out == NULL) { |
76 | return 0; |
77 | } |
78 | return BN_parse_asn1_unsigned(cbs, *out); |
79 | } |
80 | |
81 | static int marshal_integer(CBB *cbb, BIGNUM *bn) { |
82 | if (bn == NULL) { |
83 | // An RSA object may be missing some components. |
84 | OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); |
85 | return 0; |
86 | } |
87 | return BN_marshal_asn1(cbb, bn); |
88 | } |
89 | |
90 | RSA *RSA_parse_public_key(CBS *cbs) { |
91 | RSA *ret = RSA_new(); |
92 | if (ret == NULL) { |
93 | return NULL; |
94 | } |
95 | CBS child; |
96 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
97 | !parse_integer(&child, &ret->n) || |
98 | !parse_integer(&child, &ret->e) || |
99 | CBS_len(&child) != 0) { |
100 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); |
101 | RSA_free(ret); |
102 | return NULL; |
103 | } |
104 | |
105 | if (!BN_is_odd(ret->e) || |
106 | BN_num_bits(ret->e) < 2) { |
107 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); |
108 | RSA_free(ret); |
109 | return NULL; |
110 | } |
111 | |
112 | return ret; |
113 | } |
114 | |
115 | RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) { |
116 | CBS cbs; |
117 | CBS_init(&cbs, in, in_len); |
118 | RSA *ret = RSA_parse_public_key(&cbs); |
119 | if (ret == NULL || CBS_len(&cbs) != 0) { |
120 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); |
121 | RSA_free(ret); |
122 | return NULL; |
123 | } |
124 | return ret; |
125 | } |
126 | |
127 | int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) { |
128 | CBB child; |
129 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
130 | !marshal_integer(&child, rsa->n) || |
131 | !marshal_integer(&child, rsa->e) || |
132 | !CBB_flush(cbb)) { |
133 | OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); |
134 | return 0; |
135 | } |
136 | return 1; |
137 | } |
138 | |
139 | int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, |
140 | const RSA *rsa) { |
141 | CBB cbb; |
142 | CBB_zero(&cbb); |
143 | if (!CBB_init(&cbb, 0) || |
144 | !RSA_marshal_public_key(&cbb, rsa) || |
145 | !CBB_finish(&cbb, out_bytes, out_len)) { |
146 | OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); |
147 | CBB_cleanup(&cbb); |
148 | return 0; |
149 | } |
150 | return 1; |
151 | } |
152 | |
153 | // kVersionTwoPrime is the value of the version field for a two-prime |
154 | // RSAPrivateKey structure (RFC 3447). |
155 | static const uint64_t kVersionTwoPrime = 0; |
156 | |
157 | RSA *RSA_parse_private_key(CBS *cbs) { |
158 | RSA *ret = RSA_new(); |
159 | if (ret == NULL) { |
160 | return NULL; |
161 | } |
162 | |
163 | CBS child; |
164 | uint64_t version; |
165 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
166 | !CBS_get_asn1_uint64(&child, &version)) { |
167 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); |
168 | goto err; |
169 | } |
170 | |
171 | if (version != kVersionTwoPrime) { |
172 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION); |
173 | goto err; |
174 | } |
175 | |
176 | if (!parse_integer(&child, &ret->n) || |
177 | !parse_integer(&child, &ret->e) || |
178 | !parse_integer(&child, &ret->d) || |
179 | !parse_integer(&child, &ret->p) || |
180 | !parse_integer(&child, &ret->q) || |
181 | !parse_integer(&child, &ret->dmp1) || |
182 | !parse_integer(&child, &ret->dmq1) || |
183 | !parse_integer(&child, &ret->iqmp)) { |
184 | goto err; |
185 | } |
186 | |
187 | if (CBS_len(&child) != 0) { |
188 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); |
189 | goto err; |
190 | } |
191 | |
192 | if (!RSA_check_key(ret)) { |
193 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); |
194 | goto err; |
195 | } |
196 | |
197 | return ret; |
198 | |
199 | err: |
200 | RSA_free(ret); |
201 | return NULL; |
202 | } |
203 | |
204 | RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) { |
205 | CBS cbs; |
206 | CBS_init(&cbs, in, in_len); |
207 | RSA *ret = RSA_parse_private_key(&cbs); |
208 | if (ret == NULL || CBS_len(&cbs) != 0) { |
209 | OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); |
210 | RSA_free(ret); |
211 | return NULL; |
212 | } |
213 | return ret; |
214 | } |
215 | |
216 | int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) { |
217 | CBB child; |
218 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
219 | !CBB_add_asn1_uint64(&child, kVersionTwoPrime) || |
220 | !marshal_integer(&child, rsa->n) || |
221 | !marshal_integer(&child, rsa->e) || |
222 | !marshal_integer(&child, rsa->d) || |
223 | !marshal_integer(&child, rsa->p) || |
224 | !marshal_integer(&child, rsa->q) || |
225 | !marshal_integer(&child, rsa->dmp1) || |
226 | !marshal_integer(&child, rsa->dmq1) || |
227 | !marshal_integer(&child, rsa->iqmp) || |
228 | !CBB_flush(cbb)) { |
229 | OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); |
230 | return 0; |
231 | } |
232 | return 1; |
233 | } |
234 | |
235 | int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, |
236 | const RSA *rsa) { |
237 | CBB cbb; |
238 | CBB_zero(&cbb); |
239 | if (!CBB_init(&cbb, 0) || |
240 | !RSA_marshal_private_key(&cbb, rsa) || |
241 | !CBB_finish(&cbb, out_bytes, out_len)) { |
242 | OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); |
243 | CBB_cleanup(&cbb); |
244 | return 0; |
245 | } |
246 | return 1; |
247 | } |
248 | |
249 | RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { |
250 | if (len < 0) { |
251 | return NULL; |
252 | } |
253 | CBS cbs; |
254 | CBS_init(&cbs, *inp, (size_t)len); |
255 | RSA *ret = RSA_parse_public_key(&cbs); |
256 | if (ret == NULL) { |
257 | return NULL; |
258 | } |
259 | if (out != NULL) { |
260 | RSA_free(*out); |
261 | *out = ret; |
262 | } |
263 | *inp = CBS_data(&cbs); |
264 | return ret; |
265 | } |
266 | |
267 | int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { |
268 | CBB cbb; |
269 | if (!CBB_init(&cbb, 0) || |
270 | !RSA_marshal_public_key(&cbb, in)) { |
271 | CBB_cleanup(&cbb); |
272 | return -1; |
273 | } |
274 | return CBB_finish_i2d(&cbb, outp); |
275 | } |
276 | |
277 | RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { |
278 | if (len < 0) { |
279 | return NULL; |
280 | } |
281 | CBS cbs; |
282 | CBS_init(&cbs, *inp, (size_t)len); |
283 | RSA *ret = RSA_parse_private_key(&cbs); |
284 | if (ret == NULL) { |
285 | return NULL; |
286 | } |
287 | if (out != NULL) { |
288 | RSA_free(*out); |
289 | *out = ret; |
290 | } |
291 | *inp = CBS_data(&cbs); |
292 | return ret; |
293 | } |
294 | |
295 | int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { |
296 | CBB cbb; |
297 | if (!CBB_init(&cbb, 0) || |
298 | !RSA_marshal_private_key(&cbb, in)) { |
299 | CBB_cleanup(&cbb); |
300 | return -1; |
301 | } |
302 | return CBB_finish_i2d(&cbb, outp); |
303 | } |
304 | |
305 | RSA *RSAPublicKey_dup(const RSA *rsa) { |
306 | uint8_t *der; |
307 | size_t der_len; |
308 | if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) { |
309 | return NULL; |
310 | } |
311 | RSA *ret = RSA_public_key_from_bytes(der, der_len); |
312 | OPENSSL_free(der); |
313 | return ret; |
314 | } |
315 | |
316 | RSA *RSAPrivateKey_dup(const RSA *rsa) { |
317 | uint8_t *der; |
318 | size_t der_len; |
319 | if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) { |
320 | return NULL; |
321 | } |
322 | RSA *ret = RSA_private_key_from_bytes(der, der_len); |
323 | OPENSSL_free(der); |
324 | return ret; |
325 | } |
326 | |