/src/openssl30/crypto/pem/pvkfmt.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | /* |
11 | | * Support for PVK format keys and related structures (such a PUBLICKEYBLOB |
12 | | * and PRIVATEKEYBLOB). |
13 | | */ |
14 | | |
15 | | /* |
16 | | * RSA and DSA low level APIs are deprecated for public use, but still ok for |
17 | | * internal use. |
18 | | */ |
19 | | #include "internal/deprecated.h" |
20 | | |
21 | | #include <openssl/pem.h> |
22 | | #include <openssl/rand.h> |
23 | | #include <openssl/bn.h> |
24 | | #include <openssl/dsa.h> |
25 | | #include <openssl/rsa.h> |
26 | | #include "internal/cryptlib.h" |
27 | | #include "crypto/pem.h" |
28 | | #include "crypto/evp.h" |
29 | | |
30 | | /* |
31 | | * Utility function: read a DWORD (4 byte unsigned integer) in little endian |
32 | | * format |
33 | | */ |
34 | | |
35 | | static unsigned int read_ledword(const unsigned char **in) |
36 | 16.6k | { |
37 | 16.6k | const unsigned char *p = *in; |
38 | 16.6k | unsigned int ret; |
39 | | |
40 | 16.6k | ret = (unsigned int)*p++; |
41 | 16.6k | ret |= (unsigned int)*p++ << 8; |
42 | 16.6k | ret |= (unsigned int)*p++ << 16; |
43 | 16.6k | ret |= (unsigned int)*p++ << 24; |
44 | 16.6k | *in = p; |
45 | 16.6k | return ret; |
46 | 16.6k | } |
47 | | |
48 | | /* |
49 | | * Read a BIGNUM in little endian format. The docs say that this should take |
50 | | * up bitlen/8 bytes. |
51 | | */ |
52 | | |
53 | | static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) |
54 | 3.33k | { |
55 | 3.33k | *r = BN_lebin2bn(*in, nbyte, NULL); |
56 | 3.33k | if (*r == NULL) |
57 | 0 | return 0; |
58 | 3.33k | *in += nbyte; |
59 | 3.33k | return 1; |
60 | 3.33k | } |
61 | | |
62 | | /* |
63 | | * Create an EVP_PKEY from a type specific key. |
64 | | * This takes ownership of |key|, as long as the |evp_type| is acceptable |
65 | | * (EVP_PKEY_RSA or EVP_PKEY_DSA), even if the resulting EVP_PKEY wasn't |
66 | | * created. |
67 | | */ |
68 | | #define isdss_to_evp_type(isdss) \ |
69 | 0 | (isdss == 0 ? EVP_PKEY_RSA : isdss == 1 ? EVP_PKEY_DSA : EVP_PKEY_NONE) |
70 | | static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) |
71 | 0 | { |
72 | 0 | EVP_PKEY *pkey = NULL; |
73 | | |
74 | | /* |
75 | | * It's assumed that if |key| is NULL, something went wrong elsewhere |
76 | | * and suitable errors are already reported. |
77 | | */ |
78 | 0 | if (key == NULL) |
79 | 0 | return NULL; |
80 | | |
81 | 0 | if (!ossl_assert(evp_type == EVP_PKEY_RSA || evp_type == EVP_PKEY_DSA)) { |
82 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_INTERNAL_ERROR); |
83 | 0 | return NULL; |
84 | 0 | } |
85 | | |
86 | 0 | if ((pkey = EVP_PKEY_new()) != NULL) { |
87 | 0 | switch (evp_type) { |
88 | 0 | case EVP_PKEY_RSA: |
89 | 0 | if (EVP_PKEY_set1_RSA(pkey, key)) |
90 | 0 | break; |
91 | 0 | EVP_PKEY_free(pkey); |
92 | 0 | pkey = NULL; |
93 | 0 | break; |
94 | 0 | #ifndef OPENSSL_NO_DSA |
95 | 0 | case EVP_PKEY_DSA: |
96 | 0 | if (EVP_PKEY_set1_DSA(pkey, key)) |
97 | 0 | break; |
98 | 0 | EVP_PKEY_free(pkey); |
99 | 0 | pkey = NULL; |
100 | 0 | break; |
101 | 0 | #endif |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | 0 | switch (evp_type) { |
106 | 0 | case EVP_PKEY_RSA: |
107 | 0 | RSA_free(key); |
108 | 0 | break; |
109 | 0 | #ifndef OPENSSL_NO_DSA |
110 | 0 | case EVP_PKEY_DSA: |
111 | 0 | DSA_free(key); |
112 | 0 | break; |
113 | 0 | #endif |
114 | 0 | } |
115 | | |
116 | 0 | if (pkey == NULL) |
117 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
118 | 0 | return pkey; |
119 | 0 | } |
120 | | |
121 | | /* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ |
122 | | |
123 | 1.88k | # define MS_PUBLICKEYBLOB 0x6 |
124 | 1.02k | # define MS_PRIVATEKEYBLOB 0x7 |
125 | 2.67k | # define MS_RSA1MAGIC 0x31415352L |
126 | 2.39k | # define MS_RSA2MAGIC 0x32415352L |
127 | 169 | # define MS_DSS1MAGIC 0x31535344L |
128 | 934 | # define MS_DSS2MAGIC 0x32535344L |
129 | | |
130 | 0 | # define MS_KEYALG_RSA_KEYX 0xa400 |
131 | 0 | # define MS_KEYALG_DSS_SIGN 0x2200 |
132 | | |
133 | 0 | # define MS_KEYTYPE_KEYX 0x1 |
134 | 0 | # define MS_KEYTYPE_SIGN 0x2 |
135 | | |
136 | | /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ |
137 | 4.34k | # define MS_PVKMAGIC 0xb0b5f11eL |
138 | | /* Salt length for PVK files */ |
139 | 0 | # define PVK_SALTLEN 0x10 |
140 | | /* Maximum length in PVK header */ |
141 | 400 | # define PVK_MAX_KEYLEN 102400 |
142 | | /* Maximum salt length */ |
143 | 166 | # define PVK_MAX_SALTLEN 10240 |
144 | | |
145 | | /* |
146 | | * Read the MSBLOB header and get relevant data from it. |
147 | | * |
148 | | * |pisdss| and |pispub| have a double role, as they can be used for |
149 | | * discovery as well as to check the the blob meets expectations. |
150 | | * |*pisdss| is the indicator for whether the key is a DSA key or not. |
151 | | * |*pispub| is the indicator for whether the key is public or not. |
152 | | * In both cases, the following input values apply: |
153 | | * |
154 | | * 0 Expected to not be what the variable indicates. |
155 | | * 1 Expected to be what the variable indicates. |
156 | | * -1 No expectations, this function will assign 0 or 1 depending on |
157 | | * header data. |
158 | | */ |
159 | | int ossl_do_blob_header(const unsigned char **in, unsigned int length, |
160 | | unsigned int *pmagic, unsigned int *pbitlen, |
161 | | int *pisdss, int *pispub) |
162 | 11.2k | { |
163 | 11.2k | const unsigned char *p = *in; |
164 | | |
165 | 11.2k | if (length < 16) |
166 | 8 | return 0; |
167 | | /* bType */ |
168 | 11.2k | switch (*p) { |
169 | 1.88k | case MS_PUBLICKEYBLOB: |
170 | 1.88k | if (*pispub == 0) { |
171 | 3 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); |
172 | 3 | return 0; |
173 | 3 | } |
174 | 1.88k | *pispub = 1; |
175 | 1.88k | break; |
176 | | |
177 | 1.02k | case MS_PRIVATEKEYBLOB: |
178 | 1.02k | if (*pispub == 1) { |
179 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); |
180 | 0 | return 0; |
181 | 0 | } |
182 | 1.02k | *pispub = 0; |
183 | 1.02k | break; |
184 | | |
185 | 8.30k | default: |
186 | 8.30k | return 0; |
187 | 11.2k | } |
188 | 2.90k | p++; |
189 | | /* Version */ |
190 | 2.90k | if (*p++ != 0x2) { |
191 | 159 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER); |
192 | 159 | return 0; |
193 | 159 | } |
194 | | /* Ignore reserved, aiKeyAlg */ |
195 | 2.74k | p += 6; |
196 | 2.74k | *pmagic = read_ledword(&p); |
197 | 2.74k | *pbitlen = read_ledword(&p); |
198 | | |
199 | | /* Consistency check for private vs public */ |
200 | 2.74k | switch (*pmagic) { |
201 | 85 | case MS_DSS1MAGIC: |
202 | 1.38k | case MS_RSA1MAGIC: |
203 | 1.38k | if (*pispub == 0) { |
204 | 6 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); |
205 | 6 | return 0; |
206 | 6 | } |
207 | 1.37k | break; |
208 | | |
209 | 1.37k | case MS_DSS2MAGIC: |
210 | 766 | case MS_RSA2MAGIC: |
211 | 766 | if (*pispub == 1) { |
212 | 4 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); |
213 | 4 | return 0; |
214 | 4 | } |
215 | 762 | break; |
216 | | |
217 | 762 | default: |
218 | 599 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); |
219 | 599 | return -1; |
220 | 2.74k | } |
221 | | |
222 | | /* Check that we got the expected type */ |
223 | 2.13k | switch (*pmagic) { |
224 | 84 | case MS_DSS1MAGIC: |
225 | 509 | case MS_DSS2MAGIC: |
226 | 509 | if (*pisdss == 0) { |
227 | 11 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB); |
228 | 11 | return 0; |
229 | 11 | } |
230 | 498 | *pisdss = 1; |
231 | 498 | break; |
232 | 1.29k | case MS_RSA1MAGIC: |
233 | 1.62k | case MS_RSA2MAGIC: |
234 | 1.62k | if (*pisdss == 1) { |
235 | 10 | ERR_raise(ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB); |
236 | 10 | return 0; |
237 | 10 | } |
238 | 1.61k | *pisdss = 0; |
239 | 1.61k | break; |
240 | | |
241 | 0 | default: |
242 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); |
243 | 0 | return -1; |
244 | 2.13k | } |
245 | 2.11k | *in = p; |
246 | 2.11k | return 1; |
247 | 2.13k | } |
248 | | |
249 | | unsigned int ossl_blob_length(unsigned bitlen, int isdss, int ispub) |
250 | 1.28k | { |
251 | 1.28k | unsigned int nbyte = (bitlen + 7) >> 3; |
252 | 1.28k | unsigned int hnbyte = (bitlen + 15) >> 4; |
253 | | |
254 | 1.28k | if (isdss) { |
255 | | |
256 | | /* |
257 | | * Expected length: 20 for q + 3 components bitlen each + 24 for seed |
258 | | * structure. |
259 | | */ |
260 | 465 | if (ispub) |
261 | 63 | return 44 + 3 * nbyte; |
262 | | /* |
263 | | * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed |
264 | | * structure. |
265 | | */ |
266 | 402 | else |
267 | 402 | return 64 + 2 * nbyte; |
268 | 820 | } else { |
269 | | /* Expected length: 4 for 'e' + 'n' */ |
270 | 820 | if (ispub) |
271 | 646 | return 4 + nbyte; |
272 | 174 | else |
273 | | /* |
274 | | * Expected length: 4 for 'e' and 7 other components. 2 |
275 | | * components are bitlen size, 5 are bitlen/2 |
276 | | */ |
277 | 174 | return 4 + 2 * nbyte + 5 * hnbyte; |
278 | 820 | } |
279 | | |
280 | 1.28k | } |
281 | | |
282 | | static void *do_b2i_key(const unsigned char **in, unsigned int length, |
283 | | int *isdss, int *ispub) |
284 | 81 | { |
285 | 81 | const unsigned char *p = *in; |
286 | 81 | unsigned int bitlen, magic; |
287 | 81 | void *key = NULL; |
288 | | |
289 | 81 | if (ossl_do_blob_header(&p, length, &magic, &bitlen, isdss, ispub) <= 0) { |
290 | 46 | ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); |
291 | 46 | return NULL; |
292 | 46 | } |
293 | 35 | length -= 16; |
294 | 35 | if (length < ossl_blob_length(bitlen, *isdss, *ispub)) { |
295 | 28 | ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); |
296 | 28 | return NULL; |
297 | 28 | } |
298 | 7 | if (!*isdss) |
299 | 2 | key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub); |
300 | 5 | #ifndef OPENSSL_NO_DSA |
301 | 5 | else |
302 | 5 | key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub); |
303 | 7 | #endif |
304 | | |
305 | 7 | if (key == NULL) { |
306 | 3 | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); |
307 | 3 | return NULL; |
308 | 3 | } |
309 | | |
310 | 4 | return key; |
311 | 7 | } |
312 | | |
313 | | EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub) |
314 | 0 | { |
315 | 0 | int isdss = -1; |
316 | 0 | void *key = do_b2i_key(in, length, &isdss, ispub); |
317 | |
|
318 | 0 | return evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); |
319 | 0 | } |
320 | | |
321 | | EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub) |
322 | 0 | { |
323 | 0 | const unsigned char *p; |
324 | 0 | unsigned char hdr_buf[16], *buf = NULL; |
325 | 0 | unsigned int bitlen, magic, length; |
326 | 0 | int isdss = -1; |
327 | 0 | void *key = NULL; |
328 | 0 | EVP_PKEY *pkey = NULL; |
329 | |
|
330 | 0 | if (BIO_read(in, hdr_buf, 16) != 16) { |
331 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); |
332 | 0 | return NULL; |
333 | 0 | } |
334 | 0 | p = hdr_buf; |
335 | 0 | if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, ispub) <= 0) |
336 | 0 | return NULL; |
337 | | |
338 | 0 | length = ossl_blob_length(bitlen, isdss, *ispub); |
339 | 0 | if (length > BLOB_MAX_LENGTH) { |
340 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG); |
341 | 0 | return NULL; |
342 | 0 | } |
343 | 0 | buf = OPENSSL_malloc(length); |
344 | 0 | if (buf == NULL) { |
345 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
346 | 0 | goto err; |
347 | 0 | } |
348 | 0 | p = buf; |
349 | 0 | if (BIO_read(in, buf, length) != (int)length) { |
350 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); |
351 | 0 | goto err; |
352 | 0 | } |
353 | | |
354 | 0 | if (!isdss) |
355 | 0 | key = ossl_b2i_RSA_after_header(&p, bitlen, *ispub); |
356 | 0 | #ifndef OPENSSL_NO_DSA |
357 | 0 | else |
358 | 0 | key = ossl_b2i_DSA_after_header(&p, bitlen, *ispub); |
359 | 0 | #endif |
360 | |
|
361 | 0 | if (key == NULL) { |
362 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); |
363 | 0 | goto err; |
364 | 0 | } |
365 | | |
366 | 0 | pkey = evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); |
367 | 0 | err: |
368 | 0 | OPENSSL_free(buf); |
369 | 0 | return pkey; |
370 | 0 | } |
371 | | |
372 | | #ifndef OPENSSL_NO_DSA |
373 | | DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen, |
374 | | int ispub) |
375 | 0 | { |
376 | 0 | const unsigned char *p = *in; |
377 | 0 | DSA *dsa = NULL; |
378 | 0 | BN_CTX *ctx = NULL; |
379 | 0 | BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL; |
380 | 0 | BIGNUM *pub_key = NULL; |
381 | 0 | unsigned int nbyte = (bitlen + 7) >> 3; |
382 | |
|
383 | 0 | dsa = DSA_new(); |
384 | 0 | if (dsa == NULL) |
385 | 0 | goto memerr; |
386 | 0 | if (!read_lebn(&p, nbyte, &pbn)) |
387 | 0 | goto memerr; |
388 | | |
389 | 0 | if (!read_lebn(&p, 20, &qbn)) |
390 | 0 | goto memerr; |
391 | | |
392 | 0 | if (!read_lebn(&p, nbyte, &gbn)) |
393 | 0 | goto memerr; |
394 | | |
395 | 0 | if (ispub) { |
396 | 0 | if (!read_lebn(&p, nbyte, &pub_key)) |
397 | 0 | goto memerr; |
398 | 0 | } else { |
399 | 0 | if (!read_lebn(&p, 20, &priv_key)) |
400 | 0 | goto memerr; |
401 | | |
402 | | /* Set constant time flag before public key calculation */ |
403 | 0 | BN_set_flags(priv_key, BN_FLG_CONSTTIME); |
404 | | |
405 | | /* Calculate public key */ |
406 | 0 | pub_key = BN_new(); |
407 | 0 | if (pub_key == NULL) |
408 | 0 | goto memerr; |
409 | 0 | if ((ctx = BN_CTX_new()) == NULL) |
410 | 0 | goto memerr; |
411 | | |
412 | 0 | if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx)) |
413 | 0 | goto memerr; |
414 | | |
415 | 0 | BN_CTX_free(ctx); |
416 | 0 | ctx = NULL; |
417 | 0 | } |
418 | 0 | if (!DSA_set0_pqg(dsa, pbn, qbn, gbn)) |
419 | 0 | goto memerr; |
420 | 0 | pbn = qbn = gbn = NULL; |
421 | 0 | if (!DSA_set0_key(dsa, pub_key, priv_key)) |
422 | 0 | goto memerr; |
423 | 0 | pub_key = priv_key = NULL; |
424 | |
|
425 | 0 | *in = p; |
426 | 0 | return dsa; |
427 | | |
428 | 0 | memerr: |
429 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
430 | 0 | DSA_free(dsa); |
431 | 0 | BN_free(pbn); |
432 | 0 | BN_free(qbn); |
433 | 0 | BN_free(gbn); |
434 | 0 | BN_free(pub_key); |
435 | 0 | BN_free(priv_key); |
436 | 0 | BN_CTX_free(ctx); |
437 | 0 | return NULL; |
438 | 0 | } |
439 | | #endif |
440 | | |
441 | | RSA *ossl_b2i_RSA_after_header(const unsigned char **in, unsigned int bitlen, |
442 | | int ispub) |
443 | 0 | { |
444 | 0 | const unsigned char *pin = *in; |
445 | 0 | BIGNUM *e = NULL, *n = NULL, *d = NULL; |
446 | 0 | BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; |
447 | 0 | RSA *rsa = NULL; |
448 | 0 | unsigned int nbyte = (bitlen + 7) >> 3; |
449 | 0 | unsigned int hnbyte = (bitlen + 15) >> 4; |
450 | |
|
451 | 0 | rsa = RSA_new(); |
452 | 0 | if (rsa == NULL) |
453 | 0 | goto memerr; |
454 | 0 | e = BN_new(); |
455 | 0 | if (e == NULL) |
456 | 0 | goto memerr; |
457 | 0 | if (!BN_set_word(e, read_ledword(&pin))) |
458 | 0 | goto memerr; |
459 | 0 | if (!read_lebn(&pin, nbyte, &n)) |
460 | 0 | goto memerr; |
461 | 0 | if (!ispub) { |
462 | 0 | if (!read_lebn(&pin, hnbyte, &p)) |
463 | 0 | goto memerr; |
464 | 0 | if (!read_lebn(&pin, hnbyte, &q)) |
465 | 0 | goto memerr; |
466 | 0 | if (!read_lebn(&pin, hnbyte, &dmp1)) |
467 | 0 | goto memerr; |
468 | 0 | if (!read_lebn(&pin, hnbyte, &dmq1)) |
469 | 0 | goto memerr; |
470 | 0 | if (!read_lebn(&pin, hnbyte, &iqmp)) |
471 | 0 | goto memerr; |
472 | 0 | if (!read_lebn(&pin, nbyte, &d)) |
473 | 0 | goto memerr; |
474 | 0 | if (!RSA_set0_factors(rsa, p, q)) |
475 | 0 | goto memerr; |
476 | 0 | p = q = NULL; |
477 | 0 | if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) |
478 | 0 | goto memerr; |
479 | 0 | dmp1 = dmq1 = iqmp = NULL; |
480 | 0 | } |
481 | 0 | if (!RSA_set0_key(rsa, n, e, d)) |
482 | 0 | goto memerr; |
483 | 0 | n = e = d = NULL; |
484 | |
|
485 | 0 | *in = pin; |
486 | 0 | return rsa; |
487 | 0 | memerr: |
488 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
489 | 0 | BN_free(e); |
490 | 0 | BN_free(n); |
491 | 0 | BN_free(p); |
492 | 0 | BN_free(q); |
493 | 0 | BN_free(dmp1); |
494 | 0 | BN_free(dmq1); |
495 | 0 | BN_free(iqmp); |
496 | 0 | BN_free(d); |
497 | 0 | RSA_free(rsa); |
498 | 0 | return NULL; |
499 | 0 | } |
500 | | |
501 | | EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) |
502 | 0 | { |
503 | 0 | int ispub = 0; |
504 | |
|
505 | 0 | return ossl_b2i(in, length, &ispub); |
506 | 0 | } |
507 | | |
508 | | EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) |
509 | 0 | { |
510 | 0 | int ispub = 1; |
511 | |
|
512 | 0 | return ossl_b2i(in, length, &ispub); |
513 | 0 | } |
514 | | |
515 | | EVP_PKEY *b2i_PrivateKey_bio(BIO *in) |
516 | 0 | { |
517 | 0 | int ispub = 0; |
518 | |
|
519 | 0 | return ossl_b2i_bio(in, &ispub); |
520 | 0 | } |
521 | | |
522 | | EVP_PKEY *b2i_PublicKey_bio(BIO *in) |
523 | 0 | { |
524 | 0 | int ispub = 1; |
525 | |
|
526 | 0 | return ossl_b2i_bio(in, &ispub); |
527 | 0 | } |
528 | | |
529 | | static void write_ledword(unsigned char **out, unsigned int dw) |
530 | 0 | { |
531 | 0 | unsigned char *p = *out; |
532 | |
|
533 | 0 | *p++ = dw & 0xff; |
534 | 0 | *p++ = (dw >> 8) & 0xff; |
535 | 0 | *p++ = (dw >> 16) & 0xff; |
536 | 0 | *p++ = (dw >> 24) & 0xff; |
537 | 0 | *out = p; |
538 | 0 | } |
539 | | |
540 | | static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) |
541 | 0 | { |
542 | 0 | BN_bn2lebinpad(bn, *out, len); |
543 | 0 | *out += len; |
544 | 0 | } |
545 | | |
546 | | static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *magic); |
547 | | static void write_rsa(unsigned char **out, const RSA *rsa, int ispub); |
548 | | |
549 | | #ifndef OPENSSL_NO_DSA |
550 | | static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *magic); |
551 | | static void write_dsa(unsigned char **out, const DSA *dsa, int ispub); |
552 | | #endif |
553 | | |
554 | | static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) |
555 | 0 | { |
556 | 0 | unsigned char *p; |
557 | 0 | unsigned int bitlen = 0, magic = 0, keyalg = 0; |
558 | 0 | int outlen = -1, noinc = 0; |
559 | |
|
560 | 0 | if (EVP_PKEY_is_a(pk, "RSA")) { |
561 | 0 | bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic); |
562 | 0 | keyalg = MS_KEYALG_RSA_KEYX; |
563 | 0 | #ifndef OPENSSL_NO_DSA |
564 | 0 | } else if (EVP_PKEY_is_a(pk, "DSA")) { |
565 | 0 | bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic); |
566 | 0 | keyalg = MS_KEYALG_DSS_SIGN; |
567 | 0 | #endif |
568 | 0 | } |
569 | 0 | if (bitlen == 0) { |
570 | 0 | goto end; |
571 | 0 | } |
572 | 0 | outlen = 16 |
573 | 0 | + ossl_blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); |
574 | 0 | if (out == NULL) |
575 | 0 | goto end; |
576 | 0 | if (*out) |
577 | 0 | p = *out; |
578 | 0 | else { |
579 | 0 | if ((p = OPENSSL_malloc(outlen)) == NULL) { |
580 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
581 | 0 | outlen = -1; |
582 | 0 | goto end; |
583 | 0 | } |
584 | 0 | *out = p; |
585 | 0 | noinc = 1; |
586 | 0 | } |
587 | 0 | if (ispub) |
588 | 0 | *p++ = MS_PUBLICKEYBLOB; |
589 | 0 | else |
590 | 0 | *p++ = MS_PRIVATEKEYBLOB; |
591 | 0 | *p++ = 0x2; |
592 | 0 | *p++ = 0; |
593 | 0 | *p++ = 0; |
594 | 0 | write_ledword(&p, keyalg); |
595 | 0 | write_ledword(&p, magic); |
596 | 0 | write_ledword(&p, bitlen); |
597 | 0 | if (keyalg == MS_KEYALG_RSA_KEYX) |
598 | 0 | write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub); |
599 | 0 | #ifndef OPENSSL_NO_DSA |
600 | 0 | else |
601 | 0 | write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub); |
602 | 0 | #endif |
603 | 0 | if (!noinc) |
604 | 0 | *out += outlen; |
605 | 0 | end: |
606 | 0 | return outlen; |
607 | 0 | } |
608 | | |
609 | | static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub) |
610 | 0 | { |
611 | 0 | unsigned char *tmp = NULL; |
612 | 0 | int outlen, wrlen; |
613 | |
|
614 | 0 | outlen = do_i2b(&tmp, pk, ispub); |
615 | 0 | if (outlen < 0) |
616 | 0 | return -1; |
617 | 0 | wrlen = BIO_write(out, tmp, outlen); |
618 | 0 | OPENSSL_free(tmp); |
619 | 0 | if (wrlen == outlen) |
620 | 0 | return outlen; |
621 | 0 | return -1; |
622 | 0 | } |
623 | | |
624 | | static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *pmagic) |
625 | 0 | { |
626 | 0 | int nbyte, hnbyte, bitlen; |
627 | 0 | const BIGNUM *e; |
628 | |
|
629 | 0 | RSA_get0_key(rsa, NULL, &e, NULL); |
630 | 0 | if (BN_num_bits(e) > 32) |
631 | 0 | goto badkey; |
632 | 0 | bitlen = RSA_bits(rsa); |
633 | 0 | nbyte = RSA_size(rsa); |
634 | 0 | hnbyte = (bitlen + 15) >> 4; |
635 | 0 | if (ispub) { |
636 | 0 | *pmagic = MS_RSA1MAGIC; |
637 | 0 | return bitlen; |
638 | 0 | } else { |
639 | 0 | const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1; |
640 | |
|
641 | 0 | *pmagic = MS_RSA2MAGIC; |
642 | | |
643 | | /* |
644 | | * For private key each component must fit within nbyte or hnbyte. |
645 | | */ |
646 | 0 | RSA_get0_key(rsa, NULL, NULL, &d); |
647 | 0 | if (BN_num_bytes(d) > nbyte) |
648 | 0 | goto badkey; |
649 | 0 | RSA_get0_factors(rsa, &p, &q); |
650 | 0 | RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); |
651 | 0 | if ((BN_num_bytes(iqmp) > hnbyte) |
652 | 0 | || (BN_num_bytes(p) > hnbyte) |
653 | 0 | || (BN_num_bytes(q) > hnbyte) |
654 | 0 | || (BN_num_bytes(dmp1) > hnbyte) |
655 | 0 | || (BN_num_bytes(dmq1) > hnbyte)) |
656 | 0 | goto badkey; |
657 | 0 | } |
658 | 0 | return bitlen; |
659 | 0 | badkey: |
660 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); |
661 | 0 | return 0; |
662 | 0 | } |
663 | | |
664 | | static void write_rsa(unsigned char **out, const RSA *rsa, int ispub) |
665 | 0 | { |
666 | 0 | int nbyte, hnbyte; |
667 | 0 | const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; |
668 | |
|
669 | 0 | nbyte = RSA_size(rsa); |
670 | 0 | hnbyte = (RSA_bits(rsa) + 15) >> 4; |
671 | 0 | RSA_get0_key(rsa, &n, &e, &d); |
672 | 0 | write_lebn(out, e, 4); |
673 | 0 | write_lebn(out, n, nbyte); |
674 | 0 | if (ispub) |
675 | 0 | return; |
676 | 0 | RSA_get0_factors(rsa, &p, &q); |
677 | 0 | RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); |
678 | 0 | write_lebn(out, p, hnbyte); |
679 | 0 | write_lebn(out, q, hnbyte); |
680 | 0 | write_lebn(out, dmp1, hnbyte); |
681 | 0 | write_lebn(out, dmq1, hnbyte); |
682 | 0 | write_lebn(out, iqmp, hnbyte); |
683 | 0 | write_lebn(out, d, nbyte); |
684 | 0 | } |
685 | | |
686 | | #ifndef OPENSSL_NO_DSA |
687 | | static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *pmagic) |
688 | 0 | { |
689 | 0 | int bitlen; |
690 | 0 | const BIGNUM *p = NULL, *q = NULL, *g = NULL; |
691 | 0 | const BIGNUM *pub_key = NULL, *priv_key = NULL; |
692 | |
|
693 | 0 | DSA_get0_pqg(dsa, &p, &q, &g); |
694 | 0 | DSA_get0_key(dsa, &pub_key, &priv_key); |
695 | 0 | bitlen = BN_num_bits(p); |
696 | 0 | if ((bitlen & 7) || (BN_num_bits(q) != 160) |
697 | 0 | || (BN_num_bits(g) > bitlen)) |
698 | 0 | goto badkey; |
699 | 0 | if (ispub) { |
700 | 0 | if (BN_num_bits(pub_key) > bitlen) |
701 | 0 | goto badkey; |
702 | 0 | *pmagic = MS_DSS1MAGIC; |
703 | 0 | } else { |
704 | 0 | if (BN_num_bits(priv_key) > 160) |
705 | 0 | goto badkey; |
706 | 0 | *pmagic = MS_DSS2MAGIC; |
707 | 0 | } |
708 | | |
709 | 0 | return bitlen; |
710 | 0 | badkey: |
711 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); |
712 | 0 | return 0; |
713 | 0 | } |
714 | | |
715 | | static void write_dsa(unsigned char **out, const DSA *dsa, int ispub) |
716 | 0 | { |
717 | 0 | int nbyte; |
718 | 0 | const BIGNUM *p = NULL, *q = NULL, *g = NULL; |
719 | 0 | const BIGNUM *pub_key = NULL, *priv_key = NULL; |
720 | |
|
721 | 0 | DSA_get0_pqg(dsa, &p, &q, &g); |
722 | 0 | DSA_get0_key(dsa, &pub_key, &priv_key); |
723 | 0 | nbyte = BN_num_bytes(p); |
724 | 0 | write_lebn(out, p, nbyte); |
725 | 0 | write_lebn(out, q, 20); |
726 | 0 | write_lebn(out, g, nbyte); |
727 | 0 | if (ispub) |
728 | 0 | write_lebn(out, pub_key, nbyte); |
729 | 0 | else |
730 | 0 | write_lebn(out, priv_key, 20); |
731 | | /* Set "invalid" for seed structure values */ |
732 | 0 | memset(*out, 0xff, 24); |
733 | 0 | *out += 24; |
734 | 0 | return; |
735 | 0 | } |
736 | | #endif |
737 | | |
738 | | int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk) |
739 | 0 | { |
740 | 0 | return do_i2b_bio(out, pk, 0); |
741 | 0 | } |
742 | | |
743 | | int i2b_PublicKey_bio(BIO *out, const EVP_PKEY *pk) |
744 | 0 | { |
745 | 0 | return do_i2b_bio(out, pk, 1); |
746 | 0 | } |
747 | | |
748 | | int ossl_do_PVK_header(const unsigned char **in, unsigned int length, |
749 | | int skip_magic, |
750 | | unsigned int *psaltlen, unsigned int *pkeylen) |
751 | 4.34k | { |
752 | 4.34k | const unsigned char *p = *in; |
753 | 4.34k | unsigned int pvk_magic, is_encrypted; |
754 | | |
755 | 4.34k | if (skip_magic) { |
756 | 0 | if (length < 20) { |
757 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); |
758 | 0 | return 0; |
759 | 0 | } |
760 | 4.34k | } else { |
761 | 4.34k | if (length < 24) { |
762 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); |
763 | 0 | return 0; |
764 | 0 | } |
765 | 4.34k | pvk_magic = read_ledword(&p); |
766 | 4.34k | if (pvk_magic != MS_PVKMAGIC) { |
767 | 4.14k | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER); |
768 | 4.14k | return 0; |
769 | 4.14k | } |
770 | 4.34k | } |
771 | | /* Skip reserved */ |
772 | 200 | p += 4; |
773 | | /* |
774 | | * keytype = |
775 | 200 | */ read_ledword(&p); |
776 | 200 | is_encrypted = read_ledword(&p); |
777 | 200 | *psaltlen = read_ledword(&p); |
778 | 200 | *pkeylen = read_ledword(&p); |
779 | | |
780 | 200 | if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN) |
781 | 58 | return 0; |
782 | | |
783 | 142 | if (is_encrypted && *psaltlen == 0) { |
784 | 10 | ERR_raise(ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER); |
785 | 10 | return 0; |
786 | 10 | } |
787 | | |
788 | 132 | *in = p; |
789 | 132 | return 1; |
790 | 142 | } |
791 | | |
792 | | #ifndef OPENSSL_NO_RC4 |
793 | | static int derive_pvk_key(unsigned char *key, |
794 | | const unsigned char *salt, unsigned int saltlen, |
795 | | const unsigned char *pass, int passlen, |
796 | | OSSL_LIB_CTX *libctx, const char *propq) |
797 | 0 | { |
798 | 0 | EVP_MD_CTX *mctx = EVP_MD_CTX_new(); |
799 | 0 | int rv = 0; |
800 | 0 | EVP_MD *sha1 = NULL; |
801 | |
|
802 | 0 | if ((sha1 = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL) |
803 | 0 | goto err; |
804 | | |
805 | 0 | if (mctx == NULL |
806 | 0 | || !EVP_DigestInit_ex(mctx, sha1, NULL) |
807 | 0 | || !EVP_DigestUpdate(mctx, salt, saltlen) |
808 | 0 | || !EVP_DigestUpdate(mctx, pass, passlen) |
809 | 0 | || !EVP_DigestFinal_ex(mctx, key, NULL)) |
810 | 0 | goto err; |
811 | | |
812 | 0 | rv = 1; |
813 | 0 | err: |
814 | 0 | EVP_MD_CTX_free(mctx); |
815 | 0 | EVP_MD_free(sha1); |
816 | 0 | return rv; |
817 | 0 | } |
818 | | #endif |
819 | | |
820 | | static void *do_PVK_body_key(const unsigned char **in, |
821 | | unsigned int saltlen, unsigned int keylen, |
822 | | pem_password_cb *cb, void *u, |
823 | | int *isdss, int *ispub, |
824 | | OSSL_LIB_CTX *libctx, const char *propq) |
825 | 91 | { |
826 | 91 | const unsigned char *p = *in; |
827 | 91 | unsigned char *enctmp = NULL; |
828 | 91 | unsigned char keybuf[20]; |
829 | 91 | void *key = NULL; |
830 | 91 | #ifndef OPENSSL_NO_RC4 |
831 | 91 | EVP_CIPHER *rc4 = NULL; |
832 | 91 | #endif |
833 | 91 | EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new(); |
834 | | |
835 | 91 | if (cctx == NULL) { |
836 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
837 | 0 | goto err; |
838 | 0 | } |
839 | | |
840 | 91 | if (saltlen) { |
841 | 10 | #ifndef OPENSSL_NO_RC4 |
842 | 10 | unsigned int magic; |
843 | 10 | char psbuf[PEM_BUFSIZE]; |
844 | 10 | int enctmplen, inlen; |
845 | 10 | unsigned char *q; |
846 | | |
847 | 10 | if (cb) |
848 | 10 | inlen = cb(psbuf, PEM_BUFSIZE, 0, u); |
849 | 0 | else |
850 | 0 | inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); |
851 | 10 | if (inlen < 0) { |
852 | 10 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); |
853 | 10 | goto err; |
854 | 10 | } |
855 | 0 | enctmp = OPENSSL_malloc(keylen + 8); |
856 | 0 | if (enctmp == NULL) { |
857 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
858 | 0 | goto err; |
859 | 0 | } |
860 | 0 | if (!derive_pvk_key(keybuf, p, saltlen, |
861 | 0 | (unsigned char *)psbuf, inlen, libctx, propq)) |
862 | 0 | goto err; |
863 | 0 | p += saltlen; |
864 | | /* Copy BLOBHEADER across, decrypt rest */ |
865 | 0 | memcpy(enctmp, p, 8); |
866 | 0 | p += 8; |
867 | 0 | if (keylen < 8) { |
868 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT); |
869 | 0 | goto err; |
870 | 0 | } |
871 | 0 | inlen = keylen - 8; |
872 | 0 | q = enctmp + 8; |
873 | 0 | if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL) |
874 | 0 | goto err; |
875 | 0 | if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) |
876 | 0 | goto err; |
877 | 0 | if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) |
878 | 0 | goto err; |
879 | 0 | if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen)) |
880 | 0 | goto err; |
881 | 0 | magic = read_ledword((const unsigned char **)&q); |
882 | 0 | if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { |
883 | 0 | q = enctmp + 8; |
884 | 0 | memset(keybuf + 5, 0, 11); |
885 | 0 | if (!EVP_DecryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) |
886 | 0 | goto err; |
887 | 0 | if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen)) |
888 | 0 | goto err; |
889 | 0 | if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen)) |
890 | 0 | goto err; |
891 | 0 | magic = read_ledword((const unsigned char **)&q); |
892 | 0 | if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { |
893 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_DECRYPT); |
894 | 0 | goto err; |
895 | 0 | } |
896 | 0 | } |
897 | 0 | p = enctmp; |
898 | | #else |
899 | | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); |
900 | | goto err; |
901 | | #endif |
902 | 0 | } |
903 | | |
904 | 81 | key = do_b2i_key(&p, keylen, isdss, ispub); |
905 | 91 | err: |
906 | 91 | EVP_CIPHER_CTX_free(cctx); |
907 | 91 | #ifndef OPENSSL_NO_RC4 |
908 | 91 | EVP_CIPHER_free(rc4); |
909 | 91 | #endif |
910 | 91 | if (enctmp != NULL) { |
911 | 0 | OPENSSL_cleanse(keybuf, sizeof(keybuf)); |
912 | 0 | OPENSSL_free(enctmp); |
913 | 0 | } |
914 | 91 | return key; |
915 | 81 | } |
916 | | |
917 | | static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u, |
918 | | int *isdss, int *ispub, |
919 | | OSSL_LIB_CTX *libctx, const char *propq) |
920 | 17.0k | { |
921 | 17.0k | unsigned char pvk_hdr[24], *buf = NULL; |
922 | 17.0k | const unsigned char *p; |
923 | 17.0k | int buflen; |
924 | 17.0k | void *key = NULL; |
925 | 17.0k | unsigned int saltlen, keylen; |
926 | | |
927 | 17.0k | if (BIO_read(in, pvk_hdr, 24) != 24) { |
928 | 7.97k | ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT); |
929 | 7.97k | return NULL; |
930 | 7.97k | } |
931 | 9.07k | p = pvk_hdr; |
932 | | |
933 | 9.07k | if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen)) |
934 | 8.87k | return 0; |
935 | 194 | buflen = (int)keylen + saltlen; |
936 | 194 | buf = OPENSSL_malloc(buflen); |
937 | 194 | if (buf == NULL) { |
938 | 3 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
939 | 3 | return 0; |
940 | 3 | } |
941 | 191 | p = buf; |
942 | 191 | if (BIO_read(in, buf, buflen) != buflen) { |
943 | 100 | ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT); |
944 | 100 | goto err; |
945 | 100 | } |
946 | 91 | key = do_PVK_body_key(&p, saltlen, keylen, cb, u, isdss, ispub, libctx, propq); |
947 | | |
948 | 191 | err: |
949 | 191 | OPENSSL_clear_free(buf, buflen); |
950 | 191 | return key; |
951 | 91 | } |
952 | | |
953 | | #ifndef OPENSSL_NO_DSA |
954 | | DSA *b2i_DSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, |
955 | | OSSL_LIB_CTX *libctx, const char *propq) |
956 | 9.59k | { |
957 | 9.59k | int isdss = 1; |
958 | 9.59k | int ispub = 0; /* PVK keys are always private */ |
959 | | |
960 | 9.59k | return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq); |
961 | 9.59k | } |
962 | | |
963 | | DSA *b2i_DSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u) |
964 | 0 | { |
965 | 0 | return b2i_DSA_PVK_bio_ex(in, cb, u, NULL, NULL); |
966 | 0 | } |
967 | | #endif |
968 | | |
969 | | RSA *b2i_RSA_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, |
970 | | OSSL_LIB_CTX *libctx, const char *propq) |
971 | 7.44k | { |
972 | 7.44k | int isdss = 0; |
973 | 7.44k | int ispub = 0; /* PVK keys are always private */ |
974 | | |
975 | 7.44k | return do_PVK_key_bio(in, cb, u, &isdss, &ispub, libctx, propq); |
976 | 7.44k | } |
977 | | |
978 | | RSA *b2i_RSA_PVK_bio(BIO *in, pem_password_cb *cb, void *u) |
979 | 0 | { |
980 | 0 | return b2i_RSA_PVK_bio_ex(in, cb, u, NULL, NULL); |
981 | 0 | } |
982 | | |
983 | | EVP_PKEY *b2i_PVK_bio_ex(BIO *in, pem_password_cb *cb, void *u, |
984 | | OSSL_LIB_CTX *libctx, const char *propq) |
985 | 0 | { |
986 | 0 | int isdss = -1; |
987 | 0 | int ispub = -1; |
988 | 0 | void *key = do_PVK_key_bio(in, cb, u, &isdss, &ispub, NULL, NULL); |
989 | |
|
990 | 0 | return evp_pkey_new0_key(key, isdss_to_evp_type(isdss)); |
991 | 0 | } |
992 | | |
993 | | EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) |
994 | 0 | { |
995 | 0 | return b2i_PVK_bio_ex(in, cb, u, NULL, NULL); |
996 | 0 | } |
997 | | |
998 | | static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, |
999 | | pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, |
1000 | | const char *propq) |
1001 | 0 | { |
1002 | 0 | int ret = -1; |
1003 | 0 | int outlen = 24, pklen; |
1004 | 0 | unsigned char *p = NULL, *start = NULL; |
1005 | 0 | EVP_CIPHER_CTX *cctx = NULL; |
1006 | 0 | #ifndef OPENSSL_NO_RC4 |
1007 | 0 | unsigned char *salt = NULL; |
1008 | 0 | EVP_CIPHER *rc4 = NULL; |
1009 | 0 | #endif |
1010 | |
|
1011 | 0 | if (enclevel) |
1012 | 0 | outlen += PVK_SALTLEN; |
1013 | 0 | pklen = do_i2b(NULL, pk, 0); |
1014 | 0 | if (pklen < 0) |
1015 | 0 | return -1; |
1016 | 0 | outlen += pklen; |
1017 | 0 | if (out == NULL) |
1018 | 0 | return outlen; |
1019 | 0 | if (*out != NULL) { |
1020 | 0 | p = *out; |
1021 | 0 | } else { |
1022 | 0 | start = p = OPENSSL_malloc(outlen); |
1023 | 0 | if (p == NULL) { |
1024 | 0 | ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); |
1025 | 0 | return -1; |
1026 | 0 | } |
1027 | 0 | } |
1028 | | |
1029 | 0 | cctx = EVP_CIPHER_CTX_new(); |
1030 | 0 | if (cctx == NULL) |
1031 | 0 | goto error; |
1032 | | |
1033 | 0 | write_ledword(&p, MS_PVKMAGIC); |
1034 | 0 | write_ledword(&p, 0); |
1035 | 0 | if (EVP_PKEY_get_id(pk) == EVP_PKEY_RSA) |
1036 | 0 | write_ledword(&p, MS_KEYTYPE_KEYX); |
1037 | 0 | #ifndef OPENSSL_NO_DSA |
1038 | 0 | else |
1039 | 0 | write_ledword(&p, MS_KEYTYPE_SIGN); |
1040 | 0 | #endif |
1041 | 0 | write_ledword(&p, enclevel ? 1 : 0); |
1042 | 0 | write_ledword(&p, enclevel ? PVK_SALTLEN : 0); |
1043 | 0 | write_ledword(&p, pklen); |
1044 | 0 | if (enclevel) { |
1045 | 0 | #ifndef OPENSSL_NO_RC4 |
1046 | 0 | if (RAND_bytes_ex(libctx, p, PVK_SALTLEN, 0) <= 0) |
1047 | 0 | goto error; |
1048 | 0 | salt = p; |
1049 | 0 | p += PVK_SALTLEN; |
1050 | 0 | #endif |
1051 | 0 | } |
1052 | 0 | do_i2b(&p, pk, 0); |
1053 | 0 | if (enclevel != 0) { |
1054 | 0 | #ifndef OPENSSL_NO_RC4 |
1055 | 0 | char psbuf[PEM_BUFSIZE]; |
1056 | 0 | unsigned char keybuf[20]; |
1057 | 0 | int enctmplen, inlen; |
1058 | 0 | if (cb) |
1059 | 0 | inlen = cb(psbuf, PEM_BUFSIZE, 1, u); |
1060 | 0 | else |
1061 | 0 | inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); |
1062 | 0 | if (inlen <= 0) { |
1063 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); |
1064 | 0 | goto error; |
1065 | 0 | } |
1066 | 0 | if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, |
1067 | 0 | (unsigned char *)psbuf, inlen, libctx, propq)) |
1068 | 0 | goto error; |
1069 | 0 | if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL) |
1070 | 0 | goto error; |
1071 | 0 | if (enclevel == 1) |
1072 | 0 | memset(keybuf + 5, 0, 11); |
1073 | 0 | p = salt + PVK_SALTLEN + 8; |
1074 | 0 | if (!EVP_EncryptInit_ex(cctx, rc4, NULL, keybuf, NULL)) |
1075 | 0 | goto error; |
1076 | 0 | OPENSSL_cleanse(keybuf, 20); |
1077 | 0 | if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8)) |
1078 | 0 | goto error; |
1079 | 0 | if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen)) |
1080 | 0 | goto error; |
1081 | | #else |
1082 | | ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER); |
1083 | | goto error; |
1084 | | #endif |
1085 | 0 | } |
1086 | | |
1087 | 0 | if (*out == NULL) |
1088 | 0 | *out = start; |
1089 | 0 | ret = outlen; |
1090 | 0 | error: |
1091 | 0 | EVP_CIPHER_CTX_free(cctx); |
1092 | 0 | #ifndef OPENSSL_NO_RC4 |
1093 | 0 | EVP_CIPHER_free(rc4); |
1094 | 0 | #endif |
1095 | 0 | if (*out == NULL) |
1096 | 0 | OPENSSL_free(start); |
1097 | |
|
1098 | 0 | return ret; |
1099 | 0 | } |
1100 | | |
1101 | | int i2b_PVK_bio_ex(BIO *out, const EVP_PKEY *pk, int enclevel, |
1102 | | pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, |
1103 | | const char *propq) |
1104 | 0 | { |
1105 | 0 | unsigned char *tmp = NULL; |
1106 | 0 | int outlen, wrlen; |
1107 | |
|
1108 | 0 | outlen = i2b_PVK(&tmp, pk, enclevel, cb, u, libctx, propq); |
1109 | 0 | if (outlen < 0) |
1110 | 0 | return -1; |
1111 | 0 | wrlen = BIO_write(out, tmp, outlen); |
1112 | 0 | OPENSSL_free(tmp); |
1113 | 0 | if (wrlen == outlen) { |
1114 | 0 | return outlen; |
1115 | 0 | } |
1116 | 0 | ERR_raise(ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE); |
1117 | 0 | return -1; |
1118 | 0 | } |
1119 | | |
1120 | | int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel, |
1121 | | pem_password_cb *cb, void *u) |
1122 | 0 | { |
1123 | 0 | return i2b_PVK_bio_ex(out, pk, enclevel, cb, u, NULL, NULL); |
1124 | 0 | } |
1125 | | |