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