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