diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_doit.c')
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_doit.c | 486 |
1 files changed, 295 insertions, 191 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c index a03d7ebedf..451de84489 100644 --- a/src/lib/libcrypto/pkcs7/pk7_doit.c +++ b/src/lib/libcrypto/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; |