summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7/pk7_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_lib.c')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c192
1 files changed, 135 insertions, 57 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
index f2490941a3..3ca0952792 100644
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/src/lib/libcrypto/pkcs7/pk7_lib.c
@@ -60,6 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/objects.h> 61#include <openssl/objects.h>
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include "asn1_locl.h"
63 64
64long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 65long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
65 { 66 {
@@ -314,7 +315,7 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
314 *sk=sk_X509_new_null(); 315 *sk=sk_X509_new_null();
315 if (*sk == NULL) 316 if (*sk == NULL)
316 { 317 {
317 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE); 318 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
318 return 0; 319 return 0;
319 } 320 }
320 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 321 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
@@ -365,13 +366,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
365int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 366int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
366 const EVP_MD *dgst) 367 const EVP_MD *dgst)
367 { 368 {
368 int nid; 369 int ret;
369 char is_dsa;
370 370
371 if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
372 is_dsa = 1;
373 else
374 is_dsa = 0;
375 /* We now need to add another PKCS7_SIGNER_INFO entry */ 371 /* We now need to add another PKCS7_SIGNER_INFO entry */
376 if (!ASN1_INTEGER_set(p7i->version,1)) 372 if (!ASN1_INTEGER_set(p7i->version,1))
377 goto err; 373 goto err;
@@ -391,65 +387,55 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
391 p7i->pkey=pkey; 387 p7i->pkey=pkey;
392 388
393 /* Set the algorithms */ 389 /* Set the algorithms */
394 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
395 else
396 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
397 390
398 if (p7i->digest_alg->parameter != NULL) 391 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
399 ASN1_TYPE_free(p7i->digest_alg->parameter); 392 V_ASN1_NULL, NULL);
400 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
401 goto err;
402 p7i->digest_alg->parameter->type=V_ASN1_NULL;
403 393
404 if (p7i->digest_enc_alg->parameter != NULL) 394 if (pkey->ameth && pkey->ameth->pkey_ctrl)
405 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
406 nid = EVP_PKEY_type(pkey->type);
407 if (nid == EVP_PKEY_RSA)
408 { 395 {
409 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); 396 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
410 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) 397 0, p7i);
411 goto err; 398 if (ret > 0)
412 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; 399 return 1;
413 } 400 if (ret != -2)
414 else if (nid == EVP_PKEY_DSA) 401 {
415 { 402 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
416#if 1 403 PKCS7_R_SIGNING_CTRL_FAILURE);
417 /* use 'dsaEncryption' OID for compatibility with other software 404 return 0;
418 * (PKCS #7 v1.5 does specify how to handle DSA) ... */ 405 }
419 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
420#else
421 /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
422 * would make more sense. */
423 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
424#endif
425 p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
426 }
427 else if (nid == EVP_PKEY_EC)
428 {
429 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
430 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
431 goto err;
432 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
433 } 406 }
434 else 407 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
435 return(0); 408 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
436
437 return(1);
438err: 409err:
439 return(0); 410 return 0;
440 } 411 }
441 412
442PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, 413PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
443 const EVP_MD *dgst) 414 const EVP_MD *dgst)
444 { 415 {
445 PKCS7_SIGNER_INFO *si; 416 PKCS7_SIGNER_INFO *si = NULL;
417
418 if (dgst == NULL)
419 {
420 int def_nid;
421 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
422 goto err;
423 dgst = EVP_get_digestbynid(def_nid);
424 if (dgst == NULL)
425 {
426 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
427 PKCS7_R_NO_DEFAULT_DIGEST);
428 goto err;
429 }
430 }
446 431
447 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; 432 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
448 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; 433 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
449 if (!PKCS7_add_signer(p7,si)) goto err; 434 if (!PKCS7_add_signer(p7,si)) goto err;
450 return(si); 435 return(si);
451err: 436err:
452 PKCS7_SIGNER_INFO_free(si); 437 if (si)
438 PKCS7_SIGNER_INFO_free(si);
453 return(NULL); 439 return(NULL);
454 } 440 }
455 441
@@ -485,6 +471,23 @@ STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
485 return(NULL); 471 return(NULL);
486 } 472 }
487 473
474void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
475 X509_ALGOR **pdig, X509_ALGOR **psig)
476 {
477 if (pk)
478 *pk = si->pkey;
479 if (pdig)
480 *pdig = si->digest_alg;
481 if (psig)
482 *psig = si->digest_enc_alg;
483 }
484
485void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
486 {
487 if (penc)
488 *penc = ri->key_enc_algor;
489 }
490
488PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 491PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
489 { 492 {
490 PKCS7_RECIP_INFO *ri; 493 PKCS7_RECIP_INFO *ri;
@@ -492,10 +495,11 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
492 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; 495 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
493 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; 496 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
494 if (!PKCS7_add_recipient_info(p7,ri)) goto err; 497 if (!PKCS7_add_recipient_info(p7,ri)) goto err;
495 return(ri); 498 return ri;
496err: 499err:
497 PKCS7_RECIP_INFO_free(ri); 500 if (ri)
498 return(NULL); 501 PKCS7_RECIP_INFO_free(ri);
502 return NULL;
499 } 503 }
500 504
501int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 505int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
@@ -524,6 +528,8 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
524 528
525int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 529int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
526 { 530 {
531 int ret;
532 EVP_PKEY *pkey = NULL;
527 if (!ASN1_INTEGER_set(p7i->version,0)) 533 if (!ASN1_INTEGER_set(p7i->version,0))
528 return 0; 534 return 0;
529 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 535 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
@@ -535,14 +541,41 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
535 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 541 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
536 return 0; 542 return 0;
537 543
538 X509_ALGOR_free(p7i->key_enc_algor); 544 pkey = X509_get_pubkey(x509);
539 if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor))) 545
540 return 0; 546 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
547 {
548 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
549 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
550 goto err;
551 }
552
553 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
554 0, p7i);
555 if (ret == -2)
556 {
557 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
558 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
559 goto err;
560 }
561 if (ret <= 0)
562 {
563 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
564 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
565 goto err;
566 }
567
568 EVP_PKEY_free(pkey);
541 569
542 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 570 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
543 p7i->cert=x509; 571 p7i->cert=x509;
544 572
545 return(1); 573 return 1;
574
575 err:
576 if (pkey)
577 EVP_PKEY_free(pkey);
578 return 0;
546 } 579 }
547 580
548X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 581X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
@@ -587,3 +620,48 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
587 return 1; 620 return 1;
588 } 621 }
589 622
623int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
624 {
625 ASN1_OCTET_STRING *os = NULL;
626
627 switch (OBJ_obj2nid(p7->type))
628 {
629 case NID_pkcs7_data:
630 os = p7->d.data;
631 break;
632
633 case NID_pkcs7_signedAndEnveloped:
634 os = p7->d.signed_and_enveloped->enc_data->enc_data;
635 if (os == NULL)
636 {
637 os=M_ASN1_OCTET_STRING_new();
638 p7->d.signed_and_enveloped->enc_data->enc_data=os;
639 }
640 break;
641
642 case NID_pkcs7_enveloped:
643 os = p7->d.enveloped->enc_data->enc_data;
644 if (os == NULL)
645 {
646 os=M_ASN1_OCTET_STRING_new();
647 p7->d.enveloped->enc_data->enc_data=os;
648 }
649 break;
650
651 case NID_pkcs7_signed:
652 os=p7->d.sign->contents->d.data;
653 break;
654
655 default:
656 os = NULL;
657 break;
658 }
659
660 if (os == NULL)
661 return 0;
662
663 os->flags |= ASN1_STRING_FLAG_NDEF;
664 *boundary = &os->data;
665
666 return 1;
667 }