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