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