xref: /dragonfly/crypto/libressl/crypto/pem/pvkfmt.c (revision cca6fc52)
1 /* $OpenBSD: pvkfmt.c,v 1.22 2019/07/08 11:56:18 inoguchi Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2005.
4  */
5 /* ====================================================================
6  * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 /* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
60  * and PRIVATEKEYBLOB).
61  */
62 
63 #include <stdlib.h>
64 #include <string.h>
65 
66 #include <openssl/opensslconf.h>
67 
68 #include <openssl/bn.h>
69 #include <openssl/err.h>
70 #include <openssl/pem.h>
71 
72 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
73 #include <openssl/dsa.h>
74 #include <openssl/rsa.h>
75 
76 #include "bn_lcl.h"
77 
78 /* Utility function: read a DWORD (4 byte unsigned integer) in little endian
79  * format
80  */
81 
82 static unsigned int
83 read_ledword(const unsigned char **in)
84 {
85 	const unsigned char *p = *in;
86 	unsigned int ret;
87 
88 	ret = *p++;
89 	ret |= (*p++ << 8);
90 	ret |= (*p++ << 16);
91 	ret |= (*p++ << 24);
92 	*in = p;
93 	return ret;
94 }
95 
96 /* Read a BIGNUM in little endian format. The docs say that this should take up
97  * bitlen/8 bytes.
98  */
99 
100 static int
101 read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
102 {
103 	const unsigned char *p;
104 	unsigned char *tmpbuf, *q;
105 	unsigned int i;
106 
107 	p = *in + nbyte - 1;
108 	tmpbuf = malloc(nbyte);
109 	if (!tmpbuf)
110 		return 0;
111 	q = tmpbuf;
112 	for (i = 0; i < nbyte; i++)
113 		*q++ = *p--;
114 	*r = BN_bin2bn(tmpbuf, nbyte, NULL);
115 	free(tmpbuf);
116 	if (*r) {
117 		*in += nbyte;
118 		return 1;
119 	} else
120 		return 0;
121 }
122 
123 
124 /* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
125 
126 #define MS_PUBLICKEYBLOB	0x6
127 #define MS_PRIVATEKEYBLOB	0x7
128 #define MS_RSA1MAGIC		0x31415352L
129 #define MS_RSA2MAGIC		0x32415352L
130 #define MS_DSS1MAGIC		0x31535344L
131 #define MS_DSS2MAGIC		0x32535344L
132 
133 #define MS_KEYALG_RSA_KEYX	0xa400
134 #define MS_KEYALG_DSS_SIGN	0x2200
135 
136 #define MS_KEYTYPE_KEYX		0x1
137 #define MS_KEYTYPE_SIGN		0x2
138 
139 /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
140 #define MS_PVKMAGIC		0xb0b5f11eL
141 /* Salt length for PVK files */
142 #define PVK_SALTLEN		0x10
143 
144 static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
145     unsigned int bitlen, int ispub);
146 static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
147     unsigned int bitlen, int ispub);
148 
149 static int
150 do_blob_header(const unsigned char **in, unsigned int length,
151     unsigned int *pmagic, unsigned int *pbitlen, int *pisdss, int *pispub)
152 {
153 	const unsigned char *p = *in;
154 
155 	if (length < 16)
156 		return 0;
157 	/* bType */
158 	if (*p == MS_PUBLICKEYBLOB) {
159 		if (*pispub == 0) {
160 			PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
161 			return 0;
162 		}
163 		*pispub = 1;
164 	} else if (*p == MS_PRIVATEKEYBLOB) {
165 		if (*pispub == 1) {
166 			PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
167 			return 0;
168 		}
169 		*pispub = 0;
170 	} else
171 		return 0;
172 	p++;
173 	/* Version */
174 	if (*p++ != 0x2) {
175 		PEMerror(PEM_R_BAD_VERSION_NUMBER);
176 		return 0;
177 	}
178 	/* Ignore reserved, aiKeyAlg */
179 	p += 6;
180 	*pmagic = read_ledword(&p);
181 	*pbitlen = read_ledword(&p);
182 	if (*pbitlen > 65536) {
183 		PEMerror(PEM_R_INCONSISTENT_HEADER);
184 		return 0;
185 	}
186 	*pisdss = 0;
187 	switch (*pmagic) {
188 
189 	case MS_DSS1MAGIC:
190 		*pisdss = 1;
191 	case MS_RSA1MAGIC:
192 		if (*pispub == 0) {
193 			PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
194 			return 0;
195 		}
196 		break;
197 
198 	case MS_DSS2MAGIC:
199 		*pisdss = 1;
200 	case MS_RSA2MAGIC:
201 		if (*pispub == 1) {
202 			PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
203 			return 0;
204 		}
205 		break;
206 
207 	default:
208 		PEMerror(PEM_R_BAD_MAGIC_NUMBER);
209 		return -1;
210 	}
211 	*in = p;
212 	return 1;
213 }
214 
215 static unsigned int
216 blob_length(unsigned bitlen, int isdss, int ispub)
217 {
218 	unsigned int nbyte, hnbyte;
219 
220 	nbyte = (bitlen + 7) >> 3;
221 	hnbyte = (bitlen + 15) >> 4;
222 	if (isdss) {
223 
224 		/* Expected length: 20 for q + 3 components bitlen each + 24
225 		 * for seed structure.
226 		 */
227 		if (ispub)
228 			return 44 + 3 * nbyte;
229 		/* Expected length: 20 for q, priv, 2 bitlen components + 24
230 		 * for seed structure.
231 		 */
232 		else
233 			return 64 + 2 * nbyte;
234 	} else {
235 		/* Expected length: 4 for 'e' + 'n' */
236 		if (ispub)
237 			return 4 + nbyte;
238 		else
239 		/* Expected length: 4 for 'e' and 7 other components.
240 		 * 2 components are bitlen size, 5 are bitlen/2
241 		 */
242 				return 4 + 2*nbyte + 5*hnbyte;
243 	}
244 
245 }
246 
247 static EVP_PKEY *
248 do_b2i(const unsigned char **in, unsigned int length, int ispub)
249 {
250 	const unsigned char *p = *in;
251 	unsigned int bitlen, magic;
252 	int isdss;
253 
254 	if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
255 		PEMerror(PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
256 		return NULL;
257 	}
258 	length -= 16;
259 	if (length < blob_length(bitlen, isdss, ispub)) {
260 		PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
261 		return NULL;
262 	}
263 	if (isdss)
264 		return b2i_dss(&p, length, bitlen, ispub);
265 	else
266 		return b2i_rsa(&p, length, bitlen, ispub);
267 }
268 
269 static EVP_PKEY *
270 do_b2i_bio(BIO *in, int ispub)
271 {
272 	const unsigned char *p;
273 	unsigned char hdr_buf[16], *buf = NULL;
274 	unsigned int bitlen, magic, length;
275 	int isdss;
276 	EVP_PKEY *ret = NULL;
277 
278 	if (BIO_read(in, hdr_buf, 16) != 16) {
279 		PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
280 		return NULL;
281 	}
282 	p = hdr_buf;
283 	if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
284 		return NULL;
285 
286 	length = blob_length(bitlen, isdss, ispub);
287 	buf = malloc(length);
288 	if (!buf) {
289 		PEMerror(ERR_R_MALLOC_FAILURE);
290 		goto err;
291 	}
292 	p = buf;
293 	if (BIO_read(in, buf, length) != (int)length) {
294 		PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
295 		goto err;
296 	}
297 
298 	if (isdss)
299 		ret = b2i_dss(&p, length, bitlen, ispub);
300 	else
301 		ret = b2i_rsa(&p, length, bitlen, ispub);
302 
303  err:
304 	free(buf);
305 	return ret;
306 }
307 
308 static EVP_PKEY *
309 b2i_dss(const unsigned char **in, unsigned int length, unsigned int bitlen,
310     int ispub)
311 {
312 	const unsigned char *p = *in;
313 	EVP_PKEY *ret = NULL;
314 	DSA *dsa = NULL;
315 	BN_CTX *ctx = NULL;
316 	unsigned int nbyte;
317 
318 	nbyte = (bitlen + 7) >> 3;
319 
320 	dsa = DSA_new();
321 	ret = EVP_PKEY_new();
322 	if (!dsa || !ret)
323 		goto err;
324 	if (!read_lebn(&p, nbyte, &dsa->p))
325 		goto err;
326 	if (!read_lebn(&p, 20, &dsa->q))
327 		goto err;
328 	if (!read_lebn(&p, nbyte, &dsa->g))
329 		goto err;
330 	if (ispub) {
331 		if (!read_lebn(&p, nbyte, &dsa->pub_key))
332 			goto err;
333 	} else {
334 		if (!read_lebn(&p, 20, &dsa->priv_key))
335 			goto err;
336 		/* Calculate public key */
337 		if (!(dsa->pub_key = BN_new()))
338 			goto err;
339 		if (!(ctx = BN_CTX_new()))
340 			goto err;
341 		if (!BN_mod_exp_ct(dsa->pub_key, dsa->g,
342 		    dsa->priv_key, dsa->p, ctx))
343 			goto err;
344 		BN_CTX_free(ctx);
345 	}
346 
347 	EVP_PKEY_set1_DSA(ret, dsa);
348 	DSA_free(dsa);
349 	*in = p;
350 	return ret;
351 
352  err:
353 	PEMerror(ERR_R_MALLOC_FAILURE);
354 	DSA_free(dsa);
355 	EVP_PKEY_free(ret);
356 	BN_CTX_free(ctx);
357 	return NULL;
358 }
359 
360 static EVP_PKEY *
361 b2i_rsa(const unsigned char **in, unsigned int length, unsigned int bitlen,
362     int ispub)
363 {
364 	const unsigned char *p = *in;
365 	EVP_PKEY *ret = NULL;
366 	RSA *rsa = NULL;
367 	unsigned int nbyte, hnbyte;
368 
369 	nbyte = (bitlen + 7) >> 3;
370 	hnbyte = (bitlen + 15) >> 4;
371 	rsa = RSA_new();
372 	ret = EVP_PKEY_new();
373 	if (!rsa || !ret)
374 		goto err;
375 	rsa->e = BN_new();
376 	if (!rsa->e)
377 		goto err;
378 	if (!BN_set_word(rsa->e, read_ledword(&p)))
379 		goto err;
380 	if (!read_lebn(&p, nbyte, &rsa->n))
381 		goto err;
382 	if (!ispub) {
383 		if (!read_lebn(&p, hnbyte, &rsa->p))
384 			goto err;
385 		if (!read_lebn(&p, hnbyte, &rsa->q))
386 			goto err;
387 		if (!read_lebn(&p, hnbyte, &rsa->dmp1))
388 			goto err;
389 		if (!read_lebn(&p, hnbyte, &rsa->dmq1))
390 			goto err;
391 		if (!read_lebn(&p, hnbyte, &rsa->iqmp))
392 			goto err;
393 		if (!read_lebn(&p, nbyte, &rsa->d))
394 			goto err;
395 	}
396 
397 	EVP_PKEY_set1_RSA(ret, rsa);
398 	RSA_free(rsa);
399 	*in = p;
400 	return ret;
401 
402  err:
403 	PEMerror(ERR_R_MALLOC_FAILURE);
404 	RSA_free(rsa);
405 	EVP_PKEY_free(ret);
406 	return NULL;
407 }
408 
409 EVP_PKEY *
410 b2i_PrivateKey(const unsigned char **in, long length)
411 {
412 	return do_b2i(in, length, 0);
413 }
414 
415 EVP_PKEY *
416 b2i_PublicKey(const unsigned char **in, long length)
417 {
418 	return do_b2i(in, length, 1);
419 }
420 
421 EVP_PKEY *
422 b2i_PrivateKey_bio(BIO *in)
423 {
424 	return do_b2i_bio(in, 0);
425 }
426 
427 EVP_PKEY *
428 b2i_PublicKey_bio(BIO *in)
429 {
430 	return do_b2i_bio(in, 1);
431 }
432 
433 static void
434 write_ledword(unsigned char **out, unsigned int dw)
435 {
436 	unsigned char *p = *out;
437 
438 	*p++ = dw & 0xff;
439 	*p++ = (dw >> 8) & 0xff;
440 	*p++ = (dw >> 16) & 0xff;
441 	*p++ = (dw >> 24) & 0xff;
442 	*out = p;
443 }
444 
445 static void
446 write_lebn(unsigned char **out, const BIGNUM *bn, int len)
447 {
448 	int nb, i;
449 	unsigned char *p = *out, *q, c;
450 
451 	nb = BN_num_bytes(bn);
452 	BN_bn2bin(bn, p);
453 	q = p + nb - 1;
454 	/* In place byte order reversal */
455 	for (i = 0; i < nb / 2; i++) {
456 		c = *p;
457 		*p++ = *q;
458 		*q-- = c;
459 	}
460 	*out += nb;
461 	/* Pad with zeroes if we have to */
462 	if (len > 0) {
463 		len -= nb;
464 		if (len > 0) {
465 			memset(*out, 0, len);
466 			*out += len;
467 		}
468 	}
469 }
470 
471 
472 static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
473 static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
474 
475 static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
476 static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
477 
478 static int
479 do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
480 {
481 	unsigned char *p;
482 	unsigned int bitlen, magic = 0, keyalg;
483 	int outlen, noinc = 0;
484 
485 	if (pk->type == EVP_PKEY_DSA) {
486 		bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
487 		keyalg = MS_KEYALG_DSS_SIGN;
488 	} else if (pk->type == EVP_PKEY_RSA) {
489 		bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
490 		keyalg = MS_KEYALG_RSA_KEYX;
491 	} else
492 		return -1;
493 	if (bitlen == 0)
494 		return -1;
495 	outlen = 16 + blob_length(bitlen,
496 	    keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
497 	if (out == NULL)
498 		return outlen;
499 	if (*out)
500 		p = *out;
501 	else {
502 		p = malloc(outlen);
503 		if (!p)
504 			return -1;
505 		*out = p;
506 		noinc = 1;
507 	}
508 	if (ispub)
509 		*p++ = MS_PUBLICKEYBLOB;
510 	else
511 		*p++ = MS_PRIVATEKEYBLOB;
512 	*p++ = 0x2;
513 	*p++ = 0;
514 	*p++ = 0;
515 	write_ledword(&p, keyalg);
516 	write_ledword(&p, magic);
517 	write_ledword(&p, bitlen);
518 	if (keyalg == MS_KEYALG_DSS_SIGN)
519 		write_dsa(&p, pk->pkey.dsa, ispub);
520 	else
521 		write_rsa(&p, pk->pkey.rsa, ispub);
522 	if (!noinc)
523 		*out += outlen;
524 	return outlen;
525 }
526 
527 static int
528 do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
529 {
530 	unsigned char *tmp = NULL;
531 	int outlen, wrlen;
532 
533 	outlen = do_i2b(&tmp, pk, ispub);
534 	if (outlen < 0)
535 		return -1;
536 	wrlen = BIO_write(out, tmp, outlen);
537 	free(tmp);
538 	if (wrlen == outlen)
539 		return outlen;
540 	return -1;
541 }
542 
543 static int
544 check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
545 {
546 	int bitlen;
547 
548 	bitlen = BN_num_bits(dsa->p);
549 	if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) ||
550 	    (BN_num_bits(dsa->g) > bitlen))
551 		goto err;
552 	if (ispub) {
553 		if (BN_num_bits(dsa->pub_key) > bitlen)
554 			goto err;
555 		*pmagic = MS_DSS1MAGIC;
556 	} else {
557 		if (BN_num_bits(dsa->priv_key) > 160)
558 			goto err;
559 		*pmagic = MS_DSS2MAGIC;
560 	}
561 
562 	return bitlen;
563 
564  err:
565 	PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS);
566 	return 0;
567 }
568 
569 static int
570 check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
571 {
572 	int nbyte, hnbyte, bitlen;
573 
574 	if (BN_num_bits(rsa->e) > 32)
575 		goto err;
576 	bitlen = BN_num_bits(rsa->n);
577 	nbyte = BN_num_bytes(rsa->n);
578 	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
579 	if (ispub) {
580 		*pmagic = MS_RSA1MAGIC;
581 		return bitlen;
582 	} else {
583 		*pmagic = MS_RSA2MAGIC;
584 		/* For private key each component must fit within nbyte or
585 		 * hnbyte.
586 		 */
587 		if (BN_num_bytes(rsa->d) > nbyte)
588 			goto err;
589 		if ((BN_num_bytes(rsa->iqmp) > hnbyte) ||
590 		    (BN_num_bytes(rsa->p) > hnbyte) ||
591 		    (BN_num_bytes(rsa->q) > hnbyte) ||
592 		    (BN_num_bytes(rsa->dmp1) > hnbyte) ||
593 		    (BN_num_bytes(rsa->dmq1) > hnbyte))
594 			goto err;
595 	}
596 	return bitlen;
597 
598  err:
599 	PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS);
600 	return 0;
601 }
602 
603 static void
604 write_rsa(unsigned char **out, RSA *rsa, int ispub)
605 {
606 	int nbyte, hnbyte;
607 
608 	nbyte = BN_num_bytes(rsa->n);
609 	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
610 	write_lebn(out, rsa->e, 4);
611 	write_lebn(out, rsa->n, -1);
612 	if (ispub)
613 		return;
614 	write_lebn(out, rsa->p, hnbyte);
615 	write_lebn(out, rsa->q, hnbyte);
616 	write_lebn(out, rsa->dmp1, hnbyte);
617 	write_lebn(out, rsa->dmq1, hnbyte);
618 	write_lebn(out, rsa->iqmp, hnbyte);
619 	write_lebn(out, rsa->d, nbyte);
620 }
621 
622 static void
623 write_dsa(unsigned char **out, DSA *dsa, int ispub)
624 {
625 	int nbyte;
626 
627 	nbyte = BN_num_bytes(dsa->p);
628 	write_lebn(out, dsa->p, nbyte);
629 	write_lebn(out, dsa->q, 20);
630 	write_lebn(out, dsa->g, nbyte);
631 	if (ispub)
632 		write_lebn(out, dsa->pub_key, nbyte);
633 	else
634 		write_lebn(out, dsa->priv_key, 20);
635 	/* Set "invalid" for seed structure values */
636 	memset(*out, 0xff, 24);
637 	*out += 24;
638 	return;
639 }
640 
641 int
642 i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
643 {
644 	return do_i2b_bio(out, pk, 0);
645 }
646 
647 int
648 i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
649 {
650 	return do_i2b_bio(out, pk, 1);
651 }
652 
653 #ifndef OPENSSL_NO_RC4
654 
655 static int
656 do_PVK_header(const unsigned char **in, unsigned int length, int skip_magic,
657     unsigned int *psaltlen, unsigned int *pkeylen)
658 {
659 	const unsigned char *p = *in;
660 	unsigned int pvk_magic, is_encrypted;
661 
662 	if (skip_magic) {
663 		if (length < 20) {
664 			PEMerror(PEM_R_PVK_TOO_SHORT);
665 			return 0;
666 		}
667 		length -= 20;
668 	} else {
669 		if (length < 24) {
670 			PEMerror(PEM_R_PVK_TOO_SHORT);
671 			return 0;
672 		}
673 		length -= 24;
674 		pvk_magic = read_ledword(&p);
675 		if (pvk_magic != MS_PVKMAGIC) {
676 			PEMerror(PEM_R_BAD_MAGIC_NUMBER);
677 			return 0;
678 		}
679 	}
680 	/* Skip reserved */
681 	p += 4;
682 	/*keytype = */read_ledword(&p);
683 	is_encrypted = read_ledword(&p);
684 	*psaltlen = read_ledword(&p);
685 	*pkeylen = read_ledword(&p);
686 	if (*psaltlen > 65536 || *pkeylen > 65536) {
687 		PEMerror(PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
688 		return 0;
689 	}
690 
691 	if (is_encrypted && !*psaltlen) {
692 		PEMerror(PEM_R_INCONSISTENT_HEADER);
693 		return 0;
694 	}
695 
696 	*in = p;
697 	return 1;
698 }
699 
700 static int
701 derive_pvk_key(unsigned char *key, const unsigned char *salt,
702     unsigned int saltlen, const unsigned char *pass, int passlen)
703 {
704 	EVP_MD_CTX mctx;
705 	int rv = 1;
706 
707 	EVP_MD_CTX_init(&mctx);
708 	if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) ||
709 	    !EVP_DigestUpdate(&mctx, salt, saltlen) ||
710 	    !EVP_DigestUpdate(&mctx, pass, passlen) ||
711 	    !EVP_DigestFinal_ex(&mctx, key, NULL))
712 		rv = 0;
713 
714 	EVP_MD_CTX_cleanup(&mctx);
715 	return rv;
716 }
717 
718 static EVP_PKEY *
719 do_PVK_body(const unsigned char **in, unsigned int saltlen,
720     unsigned int keylen, pem_password_cb *cb, void *u)
721 {
722 	EVP_PKEY *ret = NULL;
723 	const unsigned char *p = *in;
724 	unsigned int magic;
725 	unsigned char *enctmp = NULL, *q;
726 	EVP_CIPHER_CTX *cctx = NULL;
727 
728 	if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
729 		PEMerror(ERR_R_MALLOC_FAILURE);
730 		goto err;
731 	}
732 	if (saltlen) {
733 		char psbuf[PEM_BUFSIZE];
734 		unsigned char keybuf[20];
735 		int enctmplen, inlen;
736 
737 		if (cb)
738 			inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
739 		else
740 			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
741 		if (inlen <= 0) {
742 			PEMerror(PEM_R_BAD_PASSWORD_READ);
743 			goto err;
744 		}
745 		enctmp = malloc(keylen + 8);
746 		if (!enctmp) {
747 			PEMerror(ERR_R_MALLOC_FAILURE);
748 			goto err;
749 		}
750 		if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf,
751 		    inlen)) {
752 			goto err;
753 		}
754 		p += saltlen;
755 		/* Copy BLOBHEADER across, decrypt rest */
756 		memcpy(enctmp, p, 8);
757 		p += 8;
758 		if (keylen < 8) {
759 			PEMerror(PEM_R_PVK_TOO_SHORT);
760 			goto err;
761 		}
762 		inlen = keylen - 8;
763 		q = enctmp + 8;
764 		if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
765 			goto err;
766 		if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
767 			goto err;
768 		if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
769 			goto err;
770 		magic = read_ledword((const unsigned char **)&q);
771 		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
772 			q = enctmp + 8;
773 			memset(keybuf + 5, 0, 11);
774 			if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf,
775 			    NULL))
776 				goto err;
777 			explicit_bzero(keybuf, 20);
778 			if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
779 				goto err;
780 			if (!EVP_DecryptFinal_ex(cctx, q + enctmplen,
781 			    &enctmplen))
782 				goto err;
783 			magic = read_ledword((const unsigned char **)&q);
784 			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
785 				PEMerror(PEM_R_BAD_DECRYPT);
786 				goto err;
787 			}
788 		} else
789 			explicit_bzero(keybuf, 20);
790 		p = enctmp;
791 	}
792 
793 	ret = b2i_PrivateKey(&p, keylen);
794 
795  err:
796 	EVP_CIPHER_CTX_free(cctx);
797 	if (enctmp && saltlen)
798 		free(enctmp);
799 	return ret;
800 }
801 
802 
803 EVP_PKEY *
804 b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
805 {
806 	unsigned char pvk_hdr[24], *buf = NULL;
807 	const unsigned char *p;
808 	size_t buflen;
809 	EVP_PKEY *ret = NULL;
810 	unsigned int saltlen, keylen;
811 
812 	if (BIO_read(in, pvk_hdr, 24) != 24) {
813 		PEMerror(PEM_R_PVK_DATA_TOO_SHORT);
814 		return NULL;
815 	}
816 	p = pvk_hdr;
817 
818 	if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
819 		return 0;
820 	buflen = keylen + saltlen;
821 	buf = malloc(buflen);
822 	if (!buf) {
823 		PEMerror(ERR_R_MALLOC_FAILURE);
824 		return 0;
825 	}
826 	p = buf;
827 	if (BIO_read(in, buf, buflen) != buflen) {
828 		PEMerror(PEM_R_PVK_DATA_TOO_SHORT);
829 		goto err;
830 	}
831 	ret = do_PVK_body(&p, saltlen, keylen, cb, u);
832 
833  err:
834 	freezero(buf, buflen);
835 	return ret;
836 }
837 
838 static int
839 i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb,
840     void *u)
841 {
842 	int outlen = 24, pklen;
843 	unsigned char *p = NULL, *start = NULL, *salt = NULL;
844 	EVP_CIPHER_CTX *cctx = NULL;
845 
846 	if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
847 		PEMerror(ERR_R_MALLOC_FAILURE);
848 		goto err;
849 	}
850 	if (enclevel != 0)
851 		outlen += PVK_SALTLEN;
852 	pklen = do_i2b(NULL, pk, 0);
853 	if (pklen < 0)
854 		goto err;
855 	outlen += pklen;
856 	start = p = malloc(outlen);
857 	if (!p) {
858 		PEMerror(ERR_R_MALLOC_FAILURE);
859 		goto err;
860 	}
861 
862 	write_ledword(&p, MS_PVKMAGIC);
863 	write_ledword(&p, 0);
864 	if (pk->type == EVP_PKEY_DSA)
865 		write_ledword(&p, MS_KEYTYPE_SIGN);
866 	else
867 		write_ledword(&p, MS_KEYTYPE_KEYX);
868 	write_ledword(&p, enclevel ? 1 : 0);
869 	write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
870 	write_ledword(&p, pklen);
871 	if (enclevel != 0) {
872 		arc4random_buf(p, PVK_SALTLEN);
873 		salt = p;
874 		p += PVK_SALTLEN;
875 	}
876 	do_i2b(&p, pk, 0);
877 	if (enclevel != 0) {
878 		char psbuf[PEM_BUFSIZE];
879 		unsigned char keybuf[20];
880 		int enctmplen, inlen;
881 		if (cb)
882 			inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
883 		else
884 			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
885 		if (inlen <= 0) {
886 			PEMerror(PEM_R_BAD_PASSWORD_READ);
887 			goto err;
888 		}
889 		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
890 		    (unsigned char *)psbuf, inlen))
891 			goto err;
892 		if (enclevel == 1)
893 			memset(keybuf + 5, 0, 11);
894 		p = salt + PVK_SALTLEN + 8;
895 		if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
896 			goto err;
897 		explicit_bzero(keybuf, 20);
898 		if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
899 			goto err;
900 		if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen))
901 			goto err;
902 	}
903 	EVP_CIPHER_CTX_free(cctx);
904 	*out = start;
905 	return outlen;
906 
907  err:
908 	EVP_CIPHER_CTX_free(cctx);
909 	free(start);
910 	return -1;
911 }
912 
913 int
914 i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u)
915 {
916 	unsigned char *tmp = NULL;
917 	int outlen, wrlen;
918 
919 	outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
920 	if (outlen < 0)
921 		return -1;
922 	wrlen = BIO_write(out, tmp, outlen);
923 	free(tmp);
924 	if (wrlen != outlen) {
925 		PEMerror(PEM_R_BIO_WRITE_FAILURE);
926 		return -1;
927 	}
928 	return outlen;
929 }
930 
931 #endif
932 
933 #endif
934