diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_doit.c')
| -rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_doit.c | 354 |
1 files changed, 244 insertions, 110 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c index 4ac29ae14d..a03d7ebedf 100644 --- a/src/lib/libcrypto/pkcs7/pk7_doit.c +++ b/src/lib/libcrypto/pkcs7/pk7_doit.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <openssl/objects.h> | 62 | #include <openssl/objects.h> |
| 63 | #include <openssl/x509.h> | 63 | #include <openssl/x509.h> |
| 64 | #include <openssl/x509v3.h> | 64 | #include <openssl/x509v3.h> |
| 65 | #include <openssl/err.h> | ||
| 65 | 66 | ||
| 66 | static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | 67 | static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, |
| 67 | void *value); | 68 | void *value); |
| @@ -101,18 +102,54 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) | |||
| 101 | return NULL; | 102 | return NULL; |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 105 | static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) | ||
| 106 | { | ||
| 107 | BIO *btmp; | ||
| 108 | const EVP_MD *md; | ||
| 109 | if ((btmp=BIO_new(BIO_f_md())) == NULL) | ||
| 110 | { | ||
| 111 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); | ||
| 112 | goto err; | ||
| 113 | } | ||
| 114 | |||
| 115 | md=EVP_get_digestbyobj(alg->algorithm); | ||
| 116 | if (md == NULL) | ||
| 117 | { | ||
| 118 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE); | ||
| 119 | goto err; | ||
| 120 | } | ||
| 121 | |||
| 122 | BIO_set_md(btmp,md); | ||
| 123 | if (*pbio == NULL) | ||
| 124 | *pbio=btmp; | ||
| 125 | else if (!BIO_push(*pbio,btmp)) | ||
| 126 | { | ||
| 127 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); | ||
| 128 | goto err; | ||
| 129 | } | ||
| 130 | btmp=NULL; | ||
| 131 | |||
| 132 | return 1; | ||
| 133 | |||
| 134 | err: | ||
| 135 | if (btmp) | ||
| 136 | BIO_free(btmp); | ||
| 137 | return 0; | ||
| 138 | |||
| 139 | } | ||
| 140 | |||
| 104 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | 141 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) |
| 105 | { | 142 | { |
| 106 | int i; | 143 | int i; |
| 107 | BIO *out=NULL,*btmp=NULL; | 144 | BIO *out=NULL,*btmp=NULL; |
| 108 | X509_ALGOR *xa; | 145 | X509_ALGOR *xa = NULL; |
| 109 | const EVP_MD *evp_md; | ||
| 110 | const EVP_CIPHER *evp_cipher=NULL; | 146 | const EVP_CIPHER *evp_cipher=NULL; |
| 111 | STACK_OF(X509_ALGOR) *md_sk=NULL; | 147 | STACK_OF(X509_ALGOR) *md_sk=NULL; |
| 112 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; | 148 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; |
| 113 | X509_ALGOR *xalg=NULL; | 149 | X509_ALGOR *xalg=NULL; |
| 114 | PKCS7_RECIP_INFO *ri=NULL; | 150 | PKCS7_RECIP_INFO *ri=NULL; |
| 115 | EVP_PKEY *pkey; | 151 | EVP_PKEY *pkey; |
| 152 | ASN1_OCTET_STRING *os=NULL; | ||
| 116 | 153 | ||
| 117 | i=OBJ_obj2nid(p7->type); | 154 | i=OBJ_obj2nid(p7->type); |
| 118 | p7->state=PKCS7_S_HEADER; | 155 | p7->state=PKCS7_S_HEADER; |
| @@ -121,6 +158,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 121 | { | 158 | { |
| 122 | case NID_pkcs7_signed: | 159 | case NID_pkcs7_signed: |
| 123 | md_sk=p7->d.sign->md_algs; | 160 | md_sk=p7->d.sign->md_algs; |
| 161 | os = PKCS7_get_octet_string(p7->d.sign->contents); | ||
| 124 | break; | 162 | break; |
| 125 | case NID_pkcs7_signedAndEnveloped: | 163 | case NID_pkcs7_signedAndEnveloped: |
| 126 | rsk=p7->d.signed_and_enveloped->recipientinfo; | 164 | rsk=p7->d.signed_and_enveloped->recipientinfo; |
| @@ -145,37 +183,21 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 145 | goto err; | 183 | goto err; |
| 146 | } | 184 | } |
| 147 | break; | 185 | break; |
| 186 | case NID_pkcs7_digest: | ||
| 187 | xa = p7->d.digest->md; | ||
| 188 | os = PKCS7_get_octet_string(p7->d.digest->contents); | ||
| 189 | break; | ||
| 148 | default: | 190 | default: |
| 149 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); | 191 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
| 150 | goto err; | 192 | goto err; |
| 151 | } | 193 | } |
| 152 | 194 | ||
| 153 | if (md_sk != NULL) | 195 | for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) |
| 154 | { | 196 | if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) |
| 155 | for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) | 197 | goto err; |
| 156 | { | ||
| 157 | xa=sk_X509_ALGOR_value(md_sk,i); | ||
| 158 | if ((btmp=BIO_new(BIO_f_md())) == NULL) | ||
| 159 | { | ||
| 160 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); | ||
| 161 | goto err; | ||
| 162 | } | ||
| 163 | |||
| 164 | evp_md=EVP_get_digestbyobj(xa->algorithm); | ||
| 165 | if (evp_md == NULL) | ||
| 166 | { | ||
| 167 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE); | ||
| 168 | goto err; | ||
| 169 | } | ||
| 170 | 198 | ||
| 171 | BIO_set_md(btmp,evp_md); | 199 | if (xa && !PKCS7_bio_add_digest(&out, xa)) |
| 172 | if (out == NULL) | 200 | goto err; |
| 173 | out=btmp; | ||
| 174 | else | ||
| 175 | BIO_push(out,btmp); | ||
| 176 | btmp=NULL; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | 201 | ||
| 180 | if (evp_cipher != NULL) | 202 | if (evp_cipher != NULL) |
| 181 | { | 203 | { |
| @@ -194,17 +216,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 194 | BIO_get_cipher_ctx(btmp, &ctx); | 216 | BIO_get_cipher_ctx(btmp, &ctx); |
| 195 | keylen=EVP_CIPHER_key_length(evp_cipher); | 217 | keylen=EVP_CIPHER_key_length(evp_cipher); |
| 196 | ivlen=EVP_CIPHER_iv_length(evp_cipher); | 218 | ivlen=EVP_CIPHER_iv_length(evp_cipher); |
| 197 | if (RAND_bytes(key,keylen) <= 0) | ||
| 198 | goto err; | ||
| 199 | xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); | 219 | xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); |
| 200 | if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); | 220 | if (ivlen > 0) |
| 201 | EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); | 221 | if (RAND_pseudo_bytes(iv,ivlen) <= 0) |
| 222 | goto err; | ||
| 223 | if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) | ||
| 224 | goto err; | ||
| 225 | if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) | ||
| 226 | goto err; | ||
| 227 | if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) | ||
| 228 | goto err; | ||
| 202 | 229 | ||
| 203 | if (ivlen > 0) { | 230 | if (ivlen > 0) { |
| 204 | if (xalg->parameter == NULL) | 231 | if (xalg->parameter == NULL) { |
| 205 | xalg->parameter=ASN1_TYPE_new(); | 232 | xalg->parameter = ASN1_TYPE_new(); |
| 233 | if (xalg->parameter == NULL) | ||
| 234 | goto err; | ||
| 235 | } | ||
| 206 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) | 236 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) |
| 207 | goto err; | 237 | goto err; |
| 208 | } | 238 | } |
| 209 | 239 | ||
| 210 | /* Lets do the pub key stuff :-) */ | 240 | /* Lets do the pub key stuff :-) */ |
| @@ -217,7 +247,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 217 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); | 247 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); |
| 218 | goto err; | 248 | goto err; |
| 219 | } | 249 | } |
| 220 | pkey=X509_get_pubkey(ri->cert); | 250 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) |
| 251 | goto err; | ||
| 221 | jj=EVP_PKEY_size(pkey); | 252 | jj=EVP_PKEY_size(pkey); |
| 222 | EVP_PKEY_free(pkey); | 253 | EVP_PKEY_free(pkey); |
| 223 | if (max < jj) max=jj; | 254 | if (max < jj) max=jj; |
| @@ -230,7 +261,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 230 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | 261 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
| 231 | { | 262 | { |
| 232 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 263 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 233 | pkey=X509_get_pubkey(ri->cert); | 264 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) |
| 265 | goto err; | ||
| 234 | jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); | 266 | jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); |
| 235 | EVP_PKEY_free(pkey); | 267 | EVP_PKEY_free(pkey); |
| 236 | if (jj <= 0) | 268 | if (jj <= 0) |
| @@ -261,24 +293,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
| 261 | { | 293 | { |
| 262 | if (PKCS7_is_detached(p7)) | 294 | if (PKCS7_is_detached(p7)) |
| 263 | bio=BIO_new(BIO_s_null()); | 295 | bio=BIO_new(BIO_s_null()); |
| 264 | else | 296 | else if (os && os->length > 0) |
| 297 | bio = BIO_new_mem_buf(os->data, os->length); | ||
| 298 | if(bio == NULL) | ||
| 265 | { | 299 | { |
| 266 | if (PKCS7_type_is_signed(p7)) | 300 | bio=BIO_new(BIO_s_mem()); |
| 267 | { | 301 | if (bio == NULL) |
| 268 | ASN1_OCTET_STRING *os; | 302 | goto err; |
| 269 | os = PKCS7_get_octet_string( | 303 | BIO_set_mem_eof_return(bio,0); |
| 270 | p7->d.sign->contents); | ||
| 271 | if (os && os->length > 0) | ||
| 272 | bio = BIO_new_mem_buf(os->data, | ||
| 273 | os->length); | ||
| 274 | } | ||
| 275 | if(bio == NULL) | ||
| 276 | { | ||
| 277 | bio=BIO_new(BIO_s_mem()); | ||
| 278 | BIO_set_mem_eof_return(bio,0); | ||
| 279 | } | ||
| 280 | } | 304 | } |
| 281 | } | 305 | } |
| 282 | BIO_push(out,bio); | 306 | BIO_push(out,bio); |
| 283 | bio=NULL; | 307 | bio=NULL; |
| 284 | if (0) | 308 | if (0) |
| @@ -293,6 +317,17 @@ err: | |||
| 293 | return(out); | 317 | return(out); |
| 294 | } | 318 | } |
| 295 | 319 | ||
| 320 | static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) | ||
| 321 | { | ||
| 322 | int ret; | ||
| 323 | ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, | ||
| 324 | pcert->cert_info->issuer); | ||
| 325 | if (ret) | ||
| 326 | return ret; | ||
| 327 | return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, | ||
| 328 | ri->issuer_and_serial->serial); | ||
| 329 | } | ||
| 330 | |||
| 296 | /* int */ | 331 | /* int */ |
| 297 | BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | 332 | BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) |
| 298 | { | 333 | { |
| @@ -403,18 +438,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 403 | * (if any) | 438 | * (if any) |
| 404 | */ | 439 | */ |
| 405 | 440 | ||
| 406 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { | 441 | if (pcert) { |
| 407 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 442 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { |
| 408 | if(!X509_NAME_cmp(ri->issuer_and_serial->issuer, | 443 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 409 | pcert->cert_info->issuer) && | 444 | if (!pkcs7_cmp_ri(ri, pcert)) |
| 410 | !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, | 445 | break; |
| 411 | ri->issuer_and_serial->serial)) break; | 446 | ri=NULL; |
| 412 | ri=NULL; | 447 | } |
| 413 | } | 448 | if (ri == NULL) { |
| 414 | if (ri == NULL) { | 449 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, |
| 415 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | 450 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); |
| 416 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); | 451 | goto err; |
| 417 | goto err; | 452 | } |
| 418 | } | 453 | } |
| 419 | 454 | ||
| 420 | jj=EVP_PKEY_size(pkey); | 455 | jj=EVP_PKEY_size(pkey); |
| @@ -425,17 +460,46 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 425 | goto err; | 460 | goto err; |
| 426 | } | 461 | } |
| 427 | 462 | ||
| 428 | jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), | 463 | /* If we haven't got a certificate try each ri in turn */ |
| 429 | M_ASN1_STRING_length(ri->enc_key), pkey); | 464 | |
| 430 | if (jj <= 0) | 465 | if (pcert == NULL) |
| 431 | { | 466 | { |
| 432 | PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); | 467 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
| 433 | goto err; | 468 | { |
| 469 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | ||
| 470 | jj=EVP_PKEY_decrypt(tmp, | ||
| 471 | M_ASN1_STRING_data(ri->enc_key), | ||
| 472 | M_ASN1_STRING_length(ri->enc_key), | ||
| 473 | pkey); | ||
| 474 | if (jj > 0) | ||
| 475 | break; | ||
| 476 | ERR_clear_error(); | ||
| 477 | ri = NULL; | ||
| 478 | } | ||
| 479 | if (ri == NULL) | ||
| 480 | { | ||
| 481 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | ||
| 482 | PKCS7_R_NO_RECIPIENT_MATCHES_KEY); | ||
| 483 | goto err; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | else | ||
| 487 | { | ||
| 488 | jj=EVP_PKEY_decrypt(tmp, | ||
| 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; | ||
| 496 | } | ||
| 434 | } | 497 | } |
| 435 | 498 | ||
| 436 | evp_ctx=NULL; | 499 | evp_ctx=NULL; |
| 437 | BIO_get_cipher_ctx(etmp,&evp_ctx); | 500 | BIO_get_cipher_ctx(etmp,&evp_ctx); |
| 438 | EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0); | 501 | if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) |
| 502 | goto err; | ||
| 439 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) | 503 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) |
| 440 | goto err; | 504 | goto err; |
| 441 | 505 | ||
| @@ -451,7 +515,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 451 | goto err; | 515 | goto err; |
| 452 | } | 516 | } |
| 453 | } | 517 | } |
| 454 | EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); | 518 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) |
| 519 | goto err; | ||
| 455 | 520 | ||
| 456 | OPENSSL_cleanse(tmp,jj); | 521 | OPENSSL_cleanse(tmp,jj); |
| 457 | 522 | ||
| @@ -485,6 +550,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 485 | bio=BIO_new(BIO_s_mem()); | 550 | bio=BIO_new(BIO_s_mem()); |
| 486 | BIO_set_mem_eof_return(bio,0); | 551 | BIO_set_mem_eof_return(bio,0); |
| 487 | } | 552 | } |
| 553 | if (bio == NULL) | ||
| 554 | goto err; | ||
| 488 | #endif | 555 | #endif |
| 489 | } | 556 | } |
| 490 | BIO_push(out,bio); | 557 | BIO_push(out,bio); |
| @@ -504,6 +571,29 @@ err: | |||
| 504 | return(out); | 571 | return(out); |
| 505 | } | 572 | } |
| 506 | 573 | ||
| 574 | static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) | ||
| 575 | { | ||
| 576 | for (;;) | ||
| 577 | { | ||
| 578 | bio=BIO_find_type(bio,BIO_TYPE_MD); | ||
| 579 | if (bio == NULL) | ||
| 580 | { | ||
| 581 | PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); | ||
| 582 | return NULL; | ||
| 583 | } | ||
| 584 | BIO_get_md_ctx(bio,pmd); | ||
| 585 | if (*pmd == NULL) | ||
| 586 | { | ||
| 587 | PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); | ||
| 588 | return NULL; | ||
| 589 | } | ||
| 590 | if (EVP_MD_CTX_type(*pmd) == nid) | ||
| 591 | return bio; | ||
| 592 | bio=BIO_next(bio); | ||
| 593 | } | ||
| 594 | return NULL; | ||
| 595 | } | ||
| 596 | |||
| 507 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | 597 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) |
| 508 | { | 598 | { |
| 509 | int ret=0; | 599 | int ret=0; |
| @@ -528,7 +618,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 528 | si_sk=p7->d.signed_and_enveloped->signer_info; | 618 | si_sk=p7->d.signed_and_enveloped->signer_info; |
| 529 | if (!(os=M_ASN1_OCTET_STRING_new())) | 619 | if (!(os=M_ASN1_OCTET_STRING_new())) |
| 530 | { | 620 | { |
| 531 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE); | 621 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); |
| 532 | goto err; | 622 | goto err; |
| 533 | } | 623 | } |
| 534 | p7->d.signed_and_enveloped->enc_data->enc_data=os; | 624 | p7->d.signed_and_enveloped->enc_data->enc_data=os; |
| @@ -537,7 +627,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 537 | /* XXXXXXXXXXXXXXXX */ | 627 | /* XXXXXXXXXXXXXXXX */ |
| 538 | if (!(os=M_ASN1_OCTET_STRING_new())) | 628 | if (!(os=M_ASN1_OCTET_STRING_new())) |
| 539 | { | 629 | { |
| 540 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE); | 630 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); |
| 541 | goto err; | 631 | goto err; |
| 542 | } | 632 | } |
| 543 | p7->d.enveloped->enc_data->enc_data=os; | 633 | p7->d.enveloped->enc_data->enc_data=os; |
| @@ -551,13 +641,24 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 551 | p7->d.sign->contents->d.data = NULL; | 641 | p7->d.sign->contents->d.data = NULL; |
| 552 | } | 642 | } |
| 553 | break; | 643 | break; |
| 644 | |||
| 645 | case NID_pkcs7_digest: | ||
| 646 | os=PKCS7_get_octet_string(p7->d.digest->contents); | ||
| 647 | /* If detached data then the content is excluded */ | ||
| 648 | if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) | ||
| 649 | { | ||
| 650 | M_ASN1_OCTET_STRING_free(os); | ||
| 651 | p7->d.digest->contents->d.data = NULL; | ||
| 652 | } | ||
| 653 | break; | ||
| 654 | |||
| 554 | } | 655 | } |
| 555 | 656 | ||
| 556 | if (si_sk != NULL) | 657 | if (si_sk != NULL) |
| 557 | { | 658 | { |
| 558 | if ((buf=BUF_MEM_new()) == NULL) | 659 | if ((buf=BUF_MEM_new()) == NULL) |
| 559 | { | 660 | { |
| 560 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); | 661 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); |
| 561 | goto err; | 662 | goto err; |
| 562 | } | 663 | } |
| 563 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) | 664 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) |
| @@ -568,32 +669,18 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 568 | j=OBJ_obj2nid(si->digest_alg->algorithm); | 669 | j=OBJ_obj2nid(si->digest_alg->algorithm); |
| 569 | 670 | ||
| 570 | btmp=bio; | 671 | btmp=bio; |
| 571 | for (;;) | 672 | |
| 572 | { | 673 | btmp = PKCS7_find_digest(&mdc, btmp, j); |
| 573 | if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) | 674 | |
| 574 | == NULL) | 675 | if (btmp == NULL) |
| 575 | { | 676 | goto err; |
| 576 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); | 677 | |
| 577 | goto err; | ||
| 578 | } | ||
| 579 | BIO_get_md_ctx(btmp,&mdc); | ||
| 580 | if (mdc == NULL) | ||
| 581 | { | ||
| 582 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR); | ||
| 583 | goto err; | ||
| 584 | } | ||
| 585 | if (EVP_MD_CTX_type(mdc) == j) | ||
| 586 | break; | ||
| 587 | else | ||
| 588 | btmp=BIO_next(btmp); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* We now have the EVP_MD_CTX, lets do the | 678 | /* We now have the EVP_MD_CTX, lets do the |
| 592 | * signing. */ | 679 | * signing. */ |
| 593 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); | 680 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); |
| 594 | if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) | 681 | if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) |
| 595 | { | 682 | { |
| 596 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); | 683 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); |
| 597 | goto err; | 684 | goto err; |
| 598 | } | 685 | } |
| 599 | 686 | ||
| @@ -615,13 +702,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 615 | { | 702 | { |
| 616 | if (!(sign_time=X509_gmtime_adj(NULL,0))) | 703 | if (!(sign_time=X509_gmtime_adj(NULL,0))) |
| 617 | { | 704 | { |
| 618 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 705 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
| 619 | ERR_R_MALLOC_FAILURE); | 706 | ERR_R_MALLOC_FAILURE); |
| 620 | goto err; | 707 | goto err; |
| 621 | } | 708 | } |
| 622 | PKCS7_add_signed_attribute(si, | 709 | if (!PKCS7_add_signed_attribute(si, |
| 623 | NID_pkcs9_signingTime, | 710 | NID_pkcs9_signingTime, |
| 624 | V_ASN1_UTCTIME,sign_time); | 711 | V_ASN1_UTCTIME,sign_time)) |
| 712 | { | ||
| 713 | M_ASN1_UTCTIME_free(sign_time); | ||
| 714 | goto err; | ||
| 715 | } | ||
| 625 | } | 716 | } |
| 626 | 717 | ||
| 627 | /* Add digest */ | 718 | /* Add digest */ |
| @@ -629,20 +720,25 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 629 | EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); | 720 | EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); |
| 630 | if (!(digest=M_ASN1_OCTET_STRING_new())) | 721 | if (!(digest=M_ASN1_OCTET_STRING_new())) |
| 631 | { | 722 | { |
| 632 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 723 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
| 633 | ERR_R_MALLOC_FAILURE); | 724 | ERR_R_MALLOC_FAILURE); |
| 634 | goto err; | 725 | goto err; |
| 635 | } | 726 | } |
| 636 | if (!M_ASN1_OCTET_STRING_set(digest,md_data, | 727 | if (!M_ASN1_OCTET_STRING_set(digest,md_data, |
| 637 | md_len)) | 728 | md_len)) |
| 638 | { | 729 | { |
| 639 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 730 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
| 640 | ERR_R_MALLOC_FAILURE); | 731 | ERR_R_MALLOC_FAILURE); |
| 732 | M_ASN1_OCTET_STRING_free(digest); | ||
| 641 | goto err; | 733 | goto err; |
| 642 | } | 734 | } |
| 643 | PKCS7_add_signed_attribute(si, | 735 | if (!PKCS7_add_signed_attribute(si, |
| 644 | NID_pkcs9_messageDigest, | 736 | NID_pkcs9_messageDigest, |
| 645 | V_ASN1_OCTET_STRING,digest); | 737 | V_ASN1_OCTET_STRING,digest)) |
| 738 | { | ||
| 739 | M_ASN1_OCTET_STRING_free(digest); | ||
| 740 | goto err; | ||
| 741 | } | ||
| 646 | 742 | ||
| 647 | /* Now sign the attributes */ | 743 | /* Now sign the attributes */ |
| 648 | EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); | 744 | EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); |
| @@ -657,28 +753,42 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 657 | if (si->pkey->type == EVP_PKEY_DSA) | 753 | if (si->pkey->type == EVP_PKEY_DSA) |
| 658 | ctx_tmp.digest=EVP_dss1(); | 754 | ctx_tmp.digest=EVP_dss1(); |
| 659 | #endif | 755 | #endif |
| 756 | #ifndef OPENSSL_NO_ECDSA | ||
| 757 | if (si->pkey->type == EVP_PKEY_EC) | ||
| 758 | ctx_tmp.digest=EVP_ecdsa(); | ||
| 759 | #endif | ||
| 660 | 760 | ||
| 661 | if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, | 761 | if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, |
| 662 | (unsigned int *)&buf->length,si->pkey)) | 762 | (unsigned int *)&buf->length,si->pkey)) |
| 663 | { | 763 | { |
| 664 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB); | 764 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); |
| 665 | goto err; | 765 | goto err; |
| 666 | } | 766 | } |
| 667 | if (!ASN1_STRING_set(si->enc_digest, | 767 | if (!ASN1_STRING_set(si->enc_digest, |
| 668 | (unsigned char *)buf->data,buf->length)) | 768 | (unsigned char *)buf->data,buf->length)) |
| 669 | { | 769 | { |
| 670 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB); | 770 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); |
| 671 | goto err; | 771 | goto err; |
| 672 | } | 772 | } |
| 673 | } | 773 | } |
| 674 | } | 774 | } |
| 775 | else if (i == NID_pkcs7_digest) | ||
| 776 | { | ||
| 777 | unsigned char md_data[EVP_MAX_MD_SIZE]; | ||
| 778 | unsigned int md_len; | ||
| 779 | if (!PKCS7_find_digest(&mdc, bio, | ||
| 780 | OBJ_obj2nid(p7->d.digest->md->algorithm))) | ||
| 781 | goto err; | ||
| 782 | EVP_DigestFinal_ex(mdc,md_data,&md_len); | ||
| 783 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); | ||
| 784 | } | ||
| 675 | 785 | ||
| 676 | if (!PKCS7_is_detached(p7)) | 786 | if (!PKCS7_is_detached(p7)) |
| 677 | { | 787 | { |
| 678 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); | 788 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); |
| 679 | if (btmp == NULL) | 789 | if (btmp == NULL) |
| 680 | { | 790 | { |
| 681 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); | 791 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); |
| 682 | goto err; | 792 | goto err; |
| 683 | } | 793 | } |
| 684 | BIO_get_mem_ptr(btmp,&buf_mem); | 794 | BIO_get_mem_ptr(btmp,&buf_mem); |
| @@ -859,6 +969,9 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
| 859 | #ifndef OPENSSL_NO_DSA | 969 | #ifndef OPENSSL_NO_DSA |
| 860 | if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); | 970 | if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); |
| 861 | #endif | 971 | #endif |
| 972 | #ifndef OPENSSL_NO_ECDSA | ||
| 973 | if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); | ||
| 974 | #endif | ||
| 862 | 975 | ||
| 863 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); | 976 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); |
| 864 | EVP_PKEY_free(pkey); | 977 | EVP_PKEY_free(pkey); |
| @@ -883,8 +996,13 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) | |||
| 883 | int i; | 996 | int i; |
| 884 | 997 | ||
| 885 | i=OBJ_obj2nid(p7->type); | 998 | i=OBJ_obj2nid(p7->type); |
| 886 | if (i != NID_pkcs7_signedAndEnveloped) return(NULL); | 999 | if (i != NID_pkcs7_signedAndEnveloped) |
| 1000 | return NULL; | ||
| 1001 | if (p7->d.signed_and_enveloped == NULL) | ||
| 1002 | return NULL; | ||
| 887 | rsk=p7->d.signed_and_enveloped->recipientinfo; | 1003 | rsk=p7->d.signed_and_enveloped->recipientinfo; |
| 1004 | if (rsk == NULL) | ||
| 1005 | return NULL; | ||
| 888 | ri=sk_PKCS7_RECIP_INFO_value(rsk,0); | 1006 | ri=sk_PKCS7_RECIP_INFO_value(rsk,0); |
| 889 | if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); | 1007 | if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); |
| 890 | ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); | 1008 | ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); |
| @@ -938,6 +1056,8 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, | |||
| 938 | if (p7si->auth_attr != NULL) | 1056 | if (p7si->auth_attr != NULL) |
| 939 | sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); | 1057 | sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); |
| 940 | p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); | 1058 | p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); |
| 1059 | if (p7si->auth_attr == NULL) | ||
| 1060 | return 0; | ||
| 941 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) | 1061 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) |
| 942 | { | 1062 | { |
| 943 | if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, | 1063 | if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, |
| @@ -956,6 +1076,8 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) | |||
| 956 | sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, | 1076 | sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, |
| 957 | X509_ATTRIBUTE_free); | 1077 | X509_ATTRIBUTE_free); |
| 958 | p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); | 1078 | p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); |
| 1079 | if (p7si->unauth_attr == NULL) | ||
| 1080 | return 0; | ||
| 959 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) | 1081 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) |
| 960 | { | 1082 | { |
| 961 | if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, | 1083 | if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, |
| @@ -985,10 +1107,16 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | |||
| 985 | 1107 | ||
| 986 | if (*sk == NULL) | 1108 | if (*sk == NULL) |
| 987 | { | 1109 | { |
| 988 | *sk = sk_X509_ATTRIBUTE_new_null(); | 1110 | if (!(*sk = sk_X509_ATTRIBUTE_new_null())) |
| 1111 | return 0; | ||
| 989 | new_attrib: | 1112 | new_attrib: |
| 990 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); | 1113 | if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) |
| 991 | sk_X509_ATTRIBUTE_push(*sk,attr); | 1114 | return 0; |
| 1115 | if (!sk_X509_ATTRIBUTE_push(*sk,attr)) | ||
| 1116 | { | ||
| 1117 | X509_ATTRIBUTE_free(attr); | ||
| 1118 | return 0; | ||
| 1119 | } | ||
| 992 | } | 1120 | } |
| 993 | else | 1121 | else |
| 994 | { | 1122 | { |
| @@ -1001,7 +1129,13 @@ new_attrib: | |||
| 1001 | { | 1129 | { |
| 1002 | X509_ATTRIBUTE_free(attr); | 1130 | X509_ATTRIBUTE_free(attr); |
| 1003 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); | 1131 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); |
| 1004 | sk_X509_ATTRIBUTE_set(*sk,i,attr); | 1132 | if (attr == NULL) |
| 1133 | return 0; | ||
| 1134 | if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) | ||
| 1135 | { | ||
| 1136 | X509_ATTRIBUTE_free(attr); | ||
| 1137 | return 0; | ||
| 1138 | } | ||
| 1005 | goto end; | 1139 | goto end; |
| 1006 | } | 1140 | } |
| 1007 | } | 1141 | } |
