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