diff options
Diffstat (limited to 'src/lib/libssl/src/crypto/pkcs7/pk7_doit.c')
| -rw-r--r-- | src/lib/libssl/src/crypto/pkcs7/pk7_doit.c | 486 |
1 files changed, 295 insertions, 191 deletions
diff --git a/src/lib/libssl/src/crypto/pkcs7/pk7_doit.c b/src/lib/libssl/src/crypto/pkcs7/pk7_doit.c index a03d7ebedf..451de84489 100644 --- a/src/lib/libssl/src/crypto/pkcs7/pk7_doit.c +++ b/src/lib/libssl/src/crypto/pkcs7/pk7_doit.c | |||
| @@ -138,6 +138,121 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) | |||
| 138 | 138 | ||
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, | ||
| 142 | unsigned char *key, int keylen) | ||
| 143 | { | ||
| 144 | EVP_PKEY_CTX *pctx = NULL; | ||
| 145 | EVP_PKEY *pkey = NULL; | ||
| 146 | unsigned char *ek = NULL; | ||
| 147 | int ret = 0; | ||
| 148 | size_t eklen; | ||
| 149 | |||
| 150 | pkey = X509_get_pubkey(ri->cert); | ||
| 151 | |||
| 152 | if (!pkey) | ||
| 153 | return 0; | ||
| 154 | |||
| 155 | pctx = EVP_PKEY_CTX_new(pkey, NULL); | ||
| 156 | if (!pctx) | ||
| 157 | return 0; | ||
| 158 | |||
| 159 | if (EVP_PKEY_encrypt_init(pctx) <= 0) | ||
| 160 | goto err; | ||
| 161 | |||
| 162 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
| 163 | EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) | ||
| 164 | { | ||
| 165 | PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); | ||
| 166 | goto err; | ||
| 167 | } | ||
| 168 | |||
| 169 | if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) | ||
| 170 | goto err; | ||
| 171 | |||
| 172 | ek = OPENSSL_malloc(eklen); | ||
| 173 | |||
| 174 | if (ek == NULL) | ||
| 175 | { | ||
| 176 | PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); | ||
| 177 | goto err; | ||
| 178 | } | ||
| 179 | |||
| 180 | if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) | ||
| 181 | goto err; | ||
| 182 | |||
| 183 | ASN1_STRING_set0(ri->enc_key, ek, eklen); | ||
| 184 | ek = NULL; | ||
| 185 | |||
| 186 | ret = 1; | ||
| 187 | |||
| 188 | err: | ||
| 189 | if (pkey) | ||
| 190 | EVP_PKEY_free(pkey); | ||
| 191 | if (pctx) | ||
| 192 | EVP_PKEY_CTX_free(pctx); | ||
| 193 | if (ek) | ||
| 194 | OPENSSL_free(ek); | ||
| 195 | return ret; | ||
| 196 | |||
| 197 | } | ||
| 198 | |||
| 199 | |||
| 200 | static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, | ||
| 201 | PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) | ||
| 202 | { | ||
| 203 | EVP_PKEY_CTX *pctx = NULL; | ||
| 204 | unsigned char *ek = NULL; | ||
| 205 | size_t eklen; | ||
| 206 | |||
| 207 | int ret = 0; | ||
| 208 | |||
| 209 | pctx = EVP_PKEY_CTX_new(pkey, NULL); | ||
| 210 | if (!pctx) | ||
| 211 | return 0; | ||
| 212 | |||
| 213 | if (EVP_PKEY_decrypt_init(pctx) <= 0) | ||
| 214 | goto err; | ||
| 215 | |||
| 216 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, | ||
| 217 | EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) | ||
| 218 | { | ||
| 219 | PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); | ||
| 220 | goto err; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (EVP_PKEY_decrypt(pctx, NULL, &eklen, | ||
| 224 | ri->enc_key->data, ri->enc_key->length) <= 0) | ||
| 225 | goto err; | ||
| 226 | |||
| 227 | ek = OPENSSL_malloc(eklen); | ||
| 228 | |||
| 229 | if (ek == NULL) | ||
| 230 | { | ||
| 231 | PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); | ||
| 232 | goto err; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (EVP_PKEY_decrypt(pctx, ek, &eklen, | ||
| 236 | ri->enc_key->data, ri->enc_key->length) <= 0) | ||
| 237 | { | ||
| 238 | PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); | ||
| 239 | goto err; | ||
| 240 | } | ||
| 241 | |||
| 242 | ret = 1; | ||
| 243 | |||
| 244 | *pek = ek; | ||
| 245 | *peklen = eklen; | ||
| 246 | |||
| 247 | err: | ||
| 248 | if (pctx) | ||
| 249 | EVP_PKEY_CTX_free(pctx); | ||
| 250 | if (!ret && ek) | ||
| 251 | OPENSSL_free(ek); | ||
| 252 | |||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 141 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | 256 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) |
| 142 | { | 257 | { |
| 143 | int i; | 258 | int i; |
| @@ -148,7 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 148 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; | 263 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; |
| 149 | X509_ALGOR *xalg=NULL; | 264 | X509_ALGOR *xalg=NULL; |
| 150 | PKCS7_RECIP_INFO *ri=NULL; | 265 | PKCS7_RECIP_INFO *ri=NULL; |
| 151 | EVP_PKEY *pkey; | ||
| 152 | ASN1_OCTET_STRING *os=NULL; | 266 | ASN1_OCTET_STRING *os=NULL; |
| 153 | 267 | ||
| 154 | i=OBJ_obj2nid(p7->type); | 268 | i=OBJ_obj2nid(p7->type); |
| @@ -187,6 +301,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 187 | xa = p7->d.digest->md; | 301 | xa = p7->d.digest->md; |
| 188 | os = PKCS7_get_octet_string(p7->d.digest->contents); | 302 | os = PKCS7_get_octet_string(p7->d.digest->contents); |
| 189 | break; | 303 | break; |
| 304 | case NID_pkcs7_data: | ||
| 305 | break; | ||
| 190 | default: | 306 | default: |
| 191 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); | 307 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
| 192 | goto err; | 308 | goto err; |
| @@ -204,8 +320,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 204 | unsigned char key[EVP_MAX_KEY_LENGTH]; | 320 | unsigned char key[EVP_MAX_KEY_LENGTH]; |
| 205 | unsigned char iv[EVP_MAX_IV_LENGTH]; | 321 | unsigned char iv[EVP_MAX_IV_LENGTH]; |
| 206 | int keylen,ivlen; | 322 | int keylen,ivlen; |
| 207 | int jj,max; | ||
| 208 | unsigned char *tmp; | ||
| 209 | EVP_CIPHER_CTX *ctx; | 323 | EVP_CIPHER_CTX *ctx; |
| 210 | 324 | ||
| 211 | if ((btmp=BIO_new(BIO_f_cipher())) == NULL) | 325 | if ((btmp=BIO_new(BIO_f_cipher())) == NULL) |
| @@ -234,52 +348,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 234 | goto err; | 348 | goto err; |
| 235 | } | 349 | } |
| 236 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) | 350 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) |
| 237 | goto err; | 351 | goto err; |
| 238 | } | 352 | } |
| 239 | 353 | ||
| 240 | /* Lets do the pub key stuff :-) */ | 354 | /* Lets do the pub key stuff :-) */ |
| 241 | max=0; | ||
| 242 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | 355 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
| 243 | { | 356 | { |
| 244 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 357 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 245 | if (ri->cert == NULL) | 358 | if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) |
| 246 | { | ||
| 247 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); | ||
| 248 | goto err; | ||
| 249 | } | ||
| 250 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) | ||
| 251 | goto err; | ||
| 252 | jj=EVP_PKEY_size(pkey); | ||
| 253 | EVP_PKEY_free(pkey); | ||
| 254 | if (max < jj) max=jj; | ||
| 255 | } | ||
| 256 | if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) | ||
| 257 | { | ||
| 258 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); | ||
| 259 | goto err; | ||
| 260 | } | ||
| 261 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | ||
| 262 | { | ||
| 263 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | ||
| 264 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) | ||
| 265 | goto err; | ||
| 266 | jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); | ||
| 267 | EVP_PKEY_free(pkey); | ||
| 268 | if (jj <= 0) | ||
| 269 | { | ||
| 270 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); | ||
| 271 | OPENSSL_free(tmp); | ||
| 272 | goto err; | 359 | goto err; |
| 273 | } | ||
| 274 | if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) | ||
| 275 | { | ||
| 276 | PKCS7err(PKCS7_F_PKCS7_DATAINIT, | ||
| 277 | ERR_R_MALLOC_FAILURE); | ||
| 278 | OPENSSL_free(tmp); | ||
| 279 | goto err; | ||
| 280 | } | ||
| 281 | } | 360 | } |
| 282 | OPENSSL_free(tmp); | ||
| 283 | OPENSSL_cleanse(key, keylen); | 361 | OPENSSL_cleanse(key, keylen); |
| 284 | 362 | ||
| 285 | if (out == NULL) | 363 | if (out == NULL) |
| @@ -303,7 +381,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 303 | BIO_set_mem_eof_return(bio,0); | 381 | BIO_set_mem_eof_return(bio,0); |
| 304 | } | 382 | } |
| 305 | } | 383 | } |
| 306 | BIO_push(out,bio); | 384 | if (out) |
| 385 | BIO_push(out,bio); | ||
| 386 | else | ||
| 387 | out = bio; | ||
| 307 | bio=NULL; | 388 | bio=NULL; |
| 308 | if (0) | 389 | if (0) |
| 309 | { | 390 | { |
| @@ -333,7 +414,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 333 | { | 414 | { |
| 334 | int i,j; | 415 | int i,j; |
| 335 | BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; | 416 | BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; |
| 336 | unsigned char *tmp=NULL; | ||
| 337 | X509_ALGOR *xa; | 417 | X509_ALGOR *xa; |
| 338 | ASN1_OCTET_STRING *data_body=NULL; | 418 | ASN1_OCTET_STRING *data_body=NULL; |
| 339 | const EVP_MD *evp_md; | 419 | const EVP_MD *evp_md; |
| @@ -423,7 +503,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 423 | int max; | 503 | int max; |
| 424 | X509_OBJECT ret; | 504 | X509_OBJECT ret; |
| 425 | #endif | 505 | #endif |
| 426 | int jj; | 506 | unsigned char *ek = NULL; |
| 507 | int eklen; | ||
| 427 | 508 | ||
| 428 | if ((etmp=BIO_new(BIO_f_cipher())) == NULL) | 509 | if ((etmp=BIO_new(BIO_f_cipher())) == NULL) |
| 429 | { | 510 | { |
| @@ -438,26 +519,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 438 | * (if any) | 519 | * (if any) |
| 439 | */ | 520 | */ |
| 440 | 521 | ||
| 441 | if (pcert) { | 522 | if (pcert) |
| 442 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { | 523 | { |
| 524 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | ||
| 525 | { | ||
| 443 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 526 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 444 | if (!pkcs7_cmp_ri(ri, pcert)) | 527 | if (!pkcs7_cmp_ri(ri, pcert)) |
| 445 | break; | 528 | break; |
| 446 | ri=NULL; | 529 | ri=NULL; |
| 447 | } | 530 | } |
| 448 | if (ri == NULL) { | 531 | if (ri == NULL) |
| 532 | { | ||
| 449 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | 533 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, |
| 450 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); | 534 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); |
| 451 | goto err; | 535 | goto err; |
| 452 | } | 536 | } |
| 453 | } | ||
| 454 | |||
| 455 | jj=EVP_PKEY_size(pkey); | ||
| 456 | tmp=(unsigned char *)OPENSSL_malloc(jj+10); | ||
| 457 | if (tmp == NULL) | ||
| 458 | { | ||
| 459 | PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); | ||
| 460 | goto err; | ||
| 461 | } | 537 | } |
| 462 | 538 | ||
| 463 | /* If we haven't got a certificate try each ri in turn */ | 539 | /* If we haven't got a certificate try each ri in turn */ |
| @@ -467,11 +543,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 467 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | 543 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
| 468 | { | 544 | { |
| 469 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 545 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 470 | jj=EVP_PKEY_decrypt(tmp, | 546 | if (pkcs7_decrypt_rinfo(&ek, &eklen, |
| 471 | M_ASN1_STRING_data(ri->enc_key), | 547 | ri, pkey) > 0) |
| 472 | M_ASN1_STRING_length(ri->enc_key), | ||
| 473 | pkey); | ||
| 474 | if (jj > 0) | ||
| 475 | break; | 548 | break; |
| 476 | ERR_clear_error(); | 549 | ERR_clear_error(); |
| 477 | ri = NULL; | 550 | ri = NULL; |
| @@ -485,15 +558,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 485 | } | 558 | } |
| 486 | else | 559 | else |
| 487 | { | 560 | { |
| 488 | jj=EVP_PKEY_decrypt(tmp, | 561 | if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0) |
| 489 | M_ASN1_STRING_data(ri->enc_key), | ||
| 490 | M_ASN1_STRING_length(ri->enc_key), pkey); | ||
| 491 | if (jj <= 0) | ||
| 492 | { | ||
| 493 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | ||
| 494 | ERR_R_EVP_LIB); | ||
| 495 | goto err; | 562 | goto err; |
| 496 | } | ||
| 497 | } | 563 | } |
| 498 | 564 | ||
| 499 | evp_ctx=NULL; | 565 | evp_ctx=NULL; |
| @@ -503,22 +569,26 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 503 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) | 569 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) |
| 504 | goto err; | 570 | goto err; |
| 505 | 571 | ||
| 506 | if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { | 572 | if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { |
| 507 | /* Some S/MIME clients don't use the same key | 573 | /* Some S/MIME clients don't use the same key |
| 508 | * and effective key length. The key length is | 574 | * and effective key length. The key length is |
| 509 | * determined by the size of the decrypted RSA key. | 575 | * determined by the size of the decrypted RSA key. |
| 510 | */ | 576 | */ |
| 511 | if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) | 577 | if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) |
| 512 | { | 578 | { |
| 513 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | 579 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, |
| 514 | PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); | 580 | PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); |
| 515 | goto err; | 581 | goto err; |
| 516 | } | 582 | } |
| 517 | } | 583 | } |
| 518 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) | 584 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) |
| 519 | goto err; | 585 | goto err; |
| 520 | 586 | ||
| 521 | OPENSSL_cleanse(tmp,jj); | 587 | if (ek) |
| 588 | { | ||
| 589 | OPENSSL_cleanse(ek,eklen); | ||
| 590 | OPENSSL_free(ek); | ||
| 591 | } | ||
| 522 | 592 | ||
| 523 | if (out == NULL) | 593 | if (out == NULL) |
| 524 | out=etmp; | 594 | out=etmp; |
| @@ -566,8 +636,6 @@ err: | |||
| 566 | if (bio != NULL) BIO_free_all(bio); | 636 | if (bio != NULL) BIO_free_all(bio); |
| 567 | out=NULL; | 637 | out=NULL; |
| 568 | } | 638 | } |
| 569 | if (tmp != NULL) | ||
| 570 | OPENSSL_free(tmp); | ||
| 571 | return(out); | 639 | return(out); |
| 572 | } | 640 | } |
| 573 | 641 | ||
| @@ -594,13 +662,43 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) | |||
| 594 | return NULL; | 662 | return NULL; |
| 595 | } | 663 | } |
| 596 | 664 | ||
| 665 | static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) | ||
| 666 | { | ||
| 667 | unsigned char md_data[EVP_MAX_MD_SIZE]; | ||
| 668 | unsigned int md_len; | ||
| 669 | |||
| 670 | /* Add signing time if not already present */ | ||
| 671 | if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) | ||
| 672 | { | ||
| 673 | if (!PKCS7_add0_attrib_signing_time(si, NULL)) | ||
| 674 | { | ||
| 675 | PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, | ||
| 676 | ERR_R_MALLOC_FAILURE); | ||
| 677 | return 0; | ||
| 678 | } | ||
| 679 | } | ||
| 680 | |||
| 681 | /* Add digest */ | ||
| 682 | EVP_DigestFinal_ex(mctx, md_data,&md_len); | ||
| 683 | if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) | ||
| 684 | { | ||
| 685 | PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); | ||
| 686 | return 0; | ||
| 687 | } | ||
| 688 | |||
| 689 | /* Now sign the attributes */ | ||
| 690 | if (!PKCS7_SIGNER_INFO_sign(si)) | ||
| 691 | return 0; | ||
| 692 | |||
| 693 | return 1; | ||
| 694 | } | ||
| 695 | |||
| 696 | |||
| 597 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | 697 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) |
| 598 | { | 698 | { |
| 599 | int ret=0; | 699 | int ret=0; |
| 600 | int i,j; | 700 | int i,j; |
| 601 | BIO *btmp; | 701 | BIO *btmp; |
| 602 | BUF_MEM *buf_mem=NULL; | ||
| 603 | BUF_MEM *buf=NULL; | ||
| 604 | PKCS7_SIGNER_INFO *si; | 702 | PKCS7_SIGNER_INFO *si; |
| 605 | EVP_MD_CTX *mdc,ctx_tmp; | 703 | EVP_MD_CTX *mdc,ctx_tmp; |
| 606 | STACK_OF(X509_ATTRIBUTE) *sk; | 704 | STACK_OF(X509_ATTRIBUTE) *sk; |
| @@ -613,24 +711,37 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 613 | 711 | ||
| 614 | switch (i) | 712 | switch (i) |
| 615 | { | 713 | { |
| 714 | case NID_pkcs7_data: | ||
| 715 | os = p7->d.data; | ||
| 716 | break; | ||
| 616 | case NID_pkcs7_signedAndEnveloped: | 717 | case NID_pkcs7_signedAndEnveloped: |
| 617 | /* XXXXXXXXXXXXXXXX */ | 718 | /* XXXXXXXXXXXXXXXX */ |
| 618 | si_sk=p7->d.signed_and_enveloped->signer_info; | 719 | si_sk=p7->d.signed_and_enveloped->signer_info; |
| 619 | if (!(os=M_ASN1_OCTET_STRING_new())) | 720 | os = p7->d.signed_and_enveloped->enc_data->enc_data; |
| 721 | if (!os) | ||
| 620 | { | 722 | { |
| 621 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); | 723 | os=M_ASN1_OCTET_STRING_new(); |
| 622 | goto err; | 724 | if (!os) |
| 725 | { | ||
| 726 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); | ||
| 727 | goto err; | ||
| 728 | } | ||
| 729 | p7->d.signed_and_enveloped->enc_data->enc_data=os; | ||
| 623 | } | 730 | } |
| 624 | p7->d.signed_and_enveloped->enc_data->enc_data=os; | ||
| 625 | break; | 731 | break; |
| 626 | case NID_pkcs7_enveloped: | 732 | case NID_pkcs7_enveloped: |
| 627 | /* XXXXXXXXXXXXXXXX */ | 733 | /* XXXXXXXXXXXXXXXX */ |
| 628 | if (!(os=M_ASN1_OCTET_STRING_new())) | 734 | os = p7->d.enveloped->enc_data->enc_data; |
| 735 | if (!os) | ||
| 629 | { | 736 | { |
| 630 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); | 737 | os=M_ASN1_OCTET_STRING_new(); |
| 631 | goto err; | 738 | if (!os) |
| 739 | { | ||
| 740 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); | ||
| 741 | goto err; | ||
| 742 | } | ||
| 743 | p7->d.enveloped->enc_data->enc_data=os; | ||
| 632 | } | 744 | } |
| 633 | p7->d.enveloped->enc_data->enc_data=os; | ||
| 634 | break; | 745 | break; |
| 635 | case NID_pkcs7_signed: | 746 | case NID_pkcs7_signed: |
| 636 | si_sk=p7->d.sign->signer_info; | 747 | si_sk=p7->d.sign->signer_info; |
| @@ -652,21 +763,20 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 652 | } | 763 | } |
| 653 | break; | 764 | break; |
| 654 | 765 | ||
| 766 | default: | ||
| 767 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); | ||
| 768 | goto err; | ||
| 655 | } | 769 | } |
| 656 | 770 | ||
| 657 | if (si_sk != NULL) | 771 | if (si_sk != NULL) |
| 658 | { | 772 | { |
| 659 | if ((buf=BUF_MEM_new()) == NULL) | ||
| 660 | { | ||
| 661 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); | ||
| 662 | goto err; | ||
| 663 | } | ||
| 664 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) | 773 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) |
| 665 | { | 774 | { |
| 666 | si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); | 775 | si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); |
| 667 | if (si->pkey == NULL) continue; | 776 | if (si->pkey == NULL) |
| 777 | continue; | ||
| 668 | 778 | ||
| 669 | j=OBJ_obj2nid(si->digest_alg->algorithm); | 779 | j = OBJ_obj2nid(si->digest_alg->algorithm); |
| 670 | 780 | ||
| 671 | btmp=bio; | 781 | btmp=bio; |
| 672 | 782 | ||
| @@ -678,97 +788,33 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 678 | /* We now have the EVP_MD_CTX, lets do the | 788 | /* We now have the EVP_MD_CTX, lets do the |
| 679 | * signing. */ | 789 | * signing. */ |
| 680 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); | 790 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); |
| 681 | if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) | ||
| 682 | { | ||
| 683 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); | ||
| 684 | goto err; | ||
| 685 | } | ||
| 686 | 791 | ||
| 687 | sk=si->auth_attr; | 792 | sk=si->auth_attr; |
| 688 | 793 | ||
| 689 | /* If there are attributes, we add the digest | 794 | /* If there are attributes, we add the digest |
| 690 | * attribute and only sign the attributes */ | 795 | * attribute and only sign the attributes */ |
| 691 | if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) | 796 | if (sk_X509_ATTRIBUTE_num(sk) > 0) |
| 692 | { | 797 | { |
| 693 | unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; | 798 | if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) |
| 694 | unsigned int md_len, alen; | ||
| 695 | ASN1_OCTET_STRING *digest; | ||
| 696 | ASN1_UTCTIME *sign_time; | ||
| 697 | const EVP_MD *md_tmp; | ||
| 698 | |||
| 699 | /* Add signing time if not already present */ | ||
| 700 | if (!PKCS7_get_signed_attribute(si, | ||
| 701 | NID_pkcs9_signingTime)) | ||
| 702 | { | ||
| 703 | if (!(sign_time=X509_gmtime_adj(NULL,0))) | ||
| 704 | { | ||
| 705 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, | ||
| 706 | ERR_R_MALLOC_FAILURE); | ||
| 707 | goto err; | ||
| 708 | } | ||
| 709 | if (!PKCS7_add_signed_attribute(si, | ||
| 710 | NID_pkcs9_signingTime, | ||
| 711 | V_ASN1_UTCTIME,sign_time)) | ||
| 712 | { | ||
| 713 | M_ASN1_UTCTIME_free(sign_time); | ||
| 714 | goto err; | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | /* Add digest */ | ||
| 719 | md_tmp=EVP_MD_CTX_md(&ctx_tmp); | ||
| 720 | EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); | ||
| 721 | if (!(digest=M_ASN1_OCTET_STRING_new())) | ||
| 722 | { | ||
| 723 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, | ||
| 724 | ERR_R_MALLOC_FAILURE); | ||
| 725 | goto err; | 799 | goto err; |
| 726 | } | 800 | } |
| 727 | if (!M_ASN1_OCTET_STRING_set(digest,md_data, | 801 | else |
| 728 | md_len)) | 802 | { |
| 729 | { | 803 | unsigned char *abuf = NULL; |
| 730 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, | 804 | unsigned int abuflen; |
| 731 | ERR_R_MALLOC_FAILURE); | 805 | abuflen = EVP_PKEY_size(si->pkey); |
| 732 | M_ASN1_OCTET_STRING_free(digest); | 806 | abuf = OPENSSL_malloc(abuflen); |
| 807 | if (!abuf) | ||
| 733 | goto err; | 808 | goto err; |
| 734 | } | 809 | |
| 735 | if (!PKCS7_add_signed_attribute(si, | 810 | if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, |
| 736 | NID_pkcs9_messageDigest, | 811 | si->pkey)) |
| 737 | V_ASN1_OCTET_STRING,digest)) | ||
| 738 | { | 812 | { |
| 739 | M_ASN1_OCTET_STRING_free(digest); | 813 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
| 814 | ERR_R_EVP_LIB); | ||
| 740 | goto err; | 815 | goto err; |
| 741 | } | 816 | } |
| 742 | 817 | ASN1_STRING_set0(si->enc_digest, abuf, abuflen); | |
| 743 | /* Now sign the attributes */ | ||
| 744 | EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); | ||
| 745 | alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, | ||
| 746 | ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); | ||
| 747 | if(!abuf) goto err; | ||
| 748 | EVP_SignUpdate(&ctx_tmp,abuf,alen); | ||
| 749 | OPENSSL_free(abuf); | ||
| 750 | } | ||
| 751 | |||
| 752 | #ifndef OPENSSL_NO_DSA | ||
| 753 | if (si->pkey->type == EVP_PKEY_DSA) | ||
| 754 | ctx_tmp.digest=EVP_dss1(); | ||
| 755 | #endif | ||
| 756 | #ifndef OPENSSL_NO_ECDSA | ||
| 757 | if (si->pkey->type == EVP_PKEY_EC) | ||
| 758 | ctx_tmp.digest=EVP_ecdsa(); | ||
| 759 | #endif | ||
| 760 | |||
| 761 | if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, | ||
| 762 | (unsigned int *)&buf->length,si->pkey)) | ||
| 763 | { | ||
| 764 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); | ||
| 765 | goto err; | ||
| 766 | } | ||
| 767 | if (!ASN1_STRING_set(si->enc_digest, | ||
| 768 | (unsigned char *)buf->data,buf->length)) | ||
| 769 | { | ||
| 770 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); | ||
| 771 | goto err; | ||
| 772 | } | 818 | } |
| 773 | } | 819 | } |
| 774 | } | 820 | } |
| @@ -783,34 +829,90 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 783 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); | 829 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); |
| 784 | } | 830 | } |
| 785 | 831 | ||
| 786 | if (!PKCS7_is_detached(p7)) | 832 | if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) |
| 787 | { | 833 | { |
| 834 | char *cont; | ||
| 835 | long contlen; | ||
| 788 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); | 836 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); |
| 789 | if (btmp == NULL) | 837 | if (btmp == NULL) |
| 790 | { | 838 | { |
| 791 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); | 839 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); |
| 792 | goto err; | 840 | goto err; |
| 793 | } | 841 | } |
| 794 | BIO_get_mem_ptr(btmp,&buf_mem); | 842 | contlen = BIO_get_mem_data(btmp, &cont); |
| 795 | /* Mark the BIO read only then we can use its copy of the data | 843 | /* Mark the BIO read only then we can use its copy of the data |
| 796 | * instead of making an extra copy. | 844 | * instead of making an extra copy. |
| 797 | */ | 845 | */ |
| 798 | BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); | 846 | BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); |
| 799 | BIO_set_mem_eof_return(btmp, 0); | 847 | BIO_set_mem_eof_return(btmp, 0); |
| 800 | os->data = (unsigned char *)buf_mem->data; | 848 | ASN1_STRING_set0(os, (unsigned char *)cont, contlen); |
| 801 | os->length = buf_mem->length; | ||
| 802 | #if 0 | ||
| 803 | M_ASN1_OCTET_STRING_set(os, | ||
| 804 | (unsigned char *)buf_mem->data,buf_mem->length); | ||
| 805 | #endif | ||
| 806 | } | 849 | } |
| 807 | ret=1; | 850 | ret=1; |
| 808 | err: | 851 | err: |
| 809 | EVP_MD_CTX_cleanup(&ctx_tmp); | 852 | EVP_MD_CTX_cleanup(&ctx_tmp); |
| 810 | if (buf != NULL) BUF_MEM_free(buf); | ||
| 811 | return(ret); | 853 | return(ret); |
| 812 | } | 854 | } |
| 813 | 855 | ||
| 856 | int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) | ||
| 857 | { | ||
| 858 | EVP_MD_CTX mctx; | ||
| 859 | EVP_PKEY_CTX *pctx; | ||
| 860 | unsigned char *abuf = NULL; | ||
| 861 | int alen; | ||
| 862 | size_t siglen; | ||
| 863 | const EVP_MD *md = NULL; | ||
| 864 | |||
| 865 | md = EVP_get_digestbyobj(si->digest_alg->algorithm); | ||
| 866 | if (md == NULL) | ||
| 867 | return 0; | ||
| 868 | |||
| 869 | EVP_MD_CTX_init(&mctx); | ||
| 870 | if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0) | ||
| 871 | goto err; | ||
| 872 | |||
| 873 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | ||
| 874 | EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) | ||
| 875 | { | ||
| 876 | PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); | ||
| 877 | goto err; | ||
| 878 | } | ||
| 879 | |||
| 880 | alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf, | ||
| 881 | ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); | ||
| 882 | if(!abuf) | ||
| 883 | goto err; | ||
| 884 | if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0) | ||
| 885 | goto err; | ||
| 886 | OPENSSL_free(abuf); | ||
| 887 | if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) | ||
| 888 | goto err; | ||
| 889 | abuf = OPENSSL_malloc(siglen); | ||
| 890 | if(!abuf) | ||
| 891 | goto err; | ||
| 892 | if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) | ||
| 893 | goto err; | ||
| 894 | |||
| 895 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | ||
| 896 | EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) | ||
| 897 | { | ||
| 898 | PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); | ||
| 899 | goto err; | ||
| 900 | } | ||
| 901 | |||
| 902 | EVP_MD_CTX_cleanup(&mctx); | ||
| 903 | |||
| 904 | ASN1_STRING_set0(si->enc_digest, abuf, siglen); | ||
| 905 | |||
| 906 | return 1; | ||
| 907 | |||
| 908 | err: | ||
| 909 | if (abuf) | ||
| 910 | OPENSSL_free(abuf); | ||
| 911 | EVP_MD_CTX_cleanup(&mctx); | ||
| 912 | return 0; | ||
| 913 | |||
| 914 | } | ||
| 915 | |||
| 814 | int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, | 916 | int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, |
| 815 | PKCS7 *p7, PKCS7_SIGNER_INFO *si) | 917 | PKCS7 *p7, PKCS7_SIGNER_INFO *si) |
| 816 | { | 918 | { |
| @@ -922,7 +1024,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, | |||
| 922 | if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) | 1024 | if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) |
| 923 | { | 1025 | { |
| 924 | unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; | 1026 | unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; |
| 925 | unsigned int md_len, alen; | 1027 | unsigned int md_len; |
| 1028 | int alen; | ||
| 926 | ASN1_OCTET_STRING *message_digest; | 1029 | ASN1_OCTET_STRING *message_digest; |
| 927 | 1030 | ||
| 928 | EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); | 1031 | EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); |
| @@ -954,6 +1057,12 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
| 954 | 1057 | ||
| 955 | alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, | 1058 | alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, |
| 956 | ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); | 1059 | ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); |
| 1060 | if (alen <= 0) | ||
| 1061 | { | ||
| 1062 | PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB); | ||
| 1063 | ret = -1; | ||
| 1064 | goto err; | ||
| 1065 | } | ||
| 957 | EVP_VerifyUpdate(&mdc_tmp, abuf, alen); | 1066 | EVP_VerifyUpdate(&mdc_tmp, abuf, alen); |
| 958 | 1067 | ||
| 959 | OPENSSL_free(abuf); | 1068 | OPENSSL_free(abuf); |
| @@ -966,12 +1075,6 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
| 966 | ret = -1; | 1075 | ret = -1; |
| 967 | goto err; | 1076 | goto err; |
| 968 | } | 1077 | } |
| 969 | #ifndef OPENSSL_NO_DSA | ||
| 970 | if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); | ||
| 971 | #endif | ||
| 972 | #ifndef OPENSSL_NO_ECDSA | ||
| 973 | if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); | ||
| 974 | #endif | ||
| 975 | 1078 | ||
| 976 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); | 1079 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); |
| 977 | EVP_PKEY_free(pkey); | 1080 | EVP_PKEY_free(pkey); |
| @@ -1107,8 +1210,9 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | |||
| 1107 | 1210 | ||
| 1108 | if (*sk == NULL) | 1211 | if (*sk == NULL) |
| 1109 | { | 1212 | { |
| 1110 | if (!(*sk = sk_X509_ATTRIBUTE_new_null())) | 1213 | *sk = sk_X509_ATTRIBUTE_new_null(); |
| 1111 | return 0; | 1214 | if (*sk == NULL) |
| 1215 | return 0; | ||
| 1112 | new_attrib: | 1216 | new_attrib: |
| 1113 | if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) | 1217 | if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) |
| 1114 | return 0; | 1218 | return 0; |
