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