X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_lib.c;h=e8c279dc93b82801f04778894d3f1b0a64a0b26d;hp=aac133e639fe0eb93fb7140b43c9ad29bfc3a1eb;hb=ec577822f95a8bca0023c5c77cef1a4916822d4a;hpb=d02b48c63a58ea4367a0e905979f140b7d090f86 diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index aac133e639..e8c279dc93 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -1,5 +1,5 @@ /* crypto/pkcs7/pk7_lib.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -58,14 +58,10 @@ #include #include "cryptlib.h" -#include "objects.h" -#include "x509.h" - -long PKCS7_ctrl(p7,cmd,larg,parg) -PKCS7 *p7; -int cmd; -long larg; -char *parg; +#include +#include + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) { int nid; long ret; @@ -98,14 +94,13 @@ char *parg; break; default: - abort(); + PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION); + ret=0; } return(ret); } -int PKCS7_content_new(p7,type) -PKCS7 *p7; -int type; +int PKCS7_content_new(PKCS7 *p7, int type) { PKCS7 *ret=NULL; @@ -119,9 +114,7 @@ err: return(0); } -int PKCS7_set_content(p7,p7_data) -PKCS7 *p7; -PKCS7 *p7_data; +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) { int i; @@ -147,9 +140,7 @@ err: return(0); } -int PKCS7_set_type(p7,type) -PKCS7 *p7; -int type; +int PKCS7_set_type(PKCS7 *p7, int type) { ASN1_OBJECT *obj; @@ -169,9 +160,22 @@ int type; if ((p7->d.data=ASN1_OCTET_STRING_new()) == NULL) goto err; break; - case NID_pkcs7_digest: - case NID_pkcs7_enveloped: case NID_pkcs7_signedAndEnveloped: + p7->type=obj; + if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new()) + == NULL) goto err; + ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1); +/* p7->d.signed_and_enveloped->enc_data->content_type= + OBJ_nid2obj(NID_pkcs7_encrypted);*/ + + break; + case NID_pkcs7_enveloped: + p7->type=obj; + if ((p7->d.enveloped=PKCS7_ENVELOPE_new()) + == NULL) goto err; + ASN1_INTEGER_set(p7->d.enveloped->version,0); + break; + case NID_pkcs7_digest: case NID_pkcs7_encrypted: default: PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); @@ -182,30 +186,36 @@ err: return(0); } -int PKCS7_add_signer(p7,psi) -PKCS7 *p7; -PKCS7_SIGNER_INFO *psi; +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) { int i,j,nid; X509_ALGOR *alg; - PKCS7_SIGNED *p7s; + STACK *signer_sk; + STACK *md_sk; i=OBJ_obj2nid(p7->type); - if (i != NID_pkcs7_signed) + switch (i) { + case NID_pkcs7_signed: + signer_sk= p7->d.sign->signer_info; + md_sk= p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + signer_sk= p7->d.signed_and_enveloped->signer_info; + md_sk= p7->d.signed_and_enveloped->md_algs; + break; + default: PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE); return(0); } - p7s=p7->d.sign; - nid=OBJ_obj2nid(psi->digest_alg->algorithm); /* If the digest is not currently listed, add it */ j=0; - for (i=0; imd_algs); i++) + for (i=0; imd_algs,i); + alg=(X509_ALGOR *)sk_value(md_sk,i); if (OBJ_obj2nid(alg->algorithm) == nid) { j=1; @@ -216,58 +226,68 @@ PKCS7_SIGNER_INFO *psi; { alg=X509_ALGOR_new(); alg->algorithm=OBJ_nid2obj(nid); - sk_push(p7s->md_algs,(char *)alg); + sk_push(md_sk,(char *)alg); } - sk_push(p7s->signer_info,(char *)psi); + sk_push(signer_sk,(char *)psi); return(1); } -int PKCS7_add_certificate(p7,x509) -PKCS7 *p7; -X509 *x509; +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) { int i; + STACK_OF(X509) **sk; i=OBJ_obj2nid(p7->type); - if (i != NID_pkcs7_signed) + switch (i) { - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE); + case NID_pkcs7_signed: + sk= &(p7->d.sign->cert); + break; + case NID_pkcs7_signedAndEnveloped: + sk= &(p7->d.signed_and_enveloped->cert); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE); return(0); } - if (p7->d.sign->cert == NULL) - p7->d.sign->cert=sk_new_null(); + if (*sk == NULL) + *sk=sk_X509_new_null(); CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); - sk_push(p7->d.sign->cert,(char *)x509); + sk_X509_push(*sk,x509); return(1); } -int PKCS7_add_crl(p7,crl) -PKCS7 *p7; -X509_CRL *crl; +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) { int i; + STACK **sk; + i=OBJ_obj2nid(p7->type); - if (i != NID_pkcs7_signed) + switch (i) { - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE); + case NID_pkcs7_signed: + sk= &(p7->d.sign->crl); + break; + case NID_pkcs7_signedAndEnveloped: + sk= &(p7->d.signed_and_enveloped->crl); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE); return(0); } - if (p7->d.sign->crl == NULL) - p7->d.sign->crl=sk_new_null(); + if (*sk == NULL) + *sk=sk_new_null(); CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL); - sk_push(p7->d.sign->crl,(char *)crl); + sk_push(*sk,(char *)crl); return(1); } -int PKCS7_SIGNER_INFO_set(p7i,x509,pkey,dgst) -PKCS7_SIGNER_INFO *p7i; -X509 *x509; -EVP_PKEY *pkey; -EVP_MD *dgst; +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + EVP_MD *dgst) { /* We now need to add another PKCS7_SIGNER_INFO entry */ ASN1_INTEGER_set(p7i->version,1); @@ -285,7 +305,10 @@ EVP_MD *dgst; p7i->pkey=pkey; /* Set the algorithms */ - p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); + if (pkey->type == EVP_PKEY_DSA) + p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1); + else + p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_MD_pkey_type(dgst)); #if 1 @@ -296,17 +319,13 @@ EVP_MD *dgst; p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; #endif - return(1); err: return(0); } -PKCS7_SIGNER_INFO *PKCS7_add_signature(p7,x509,pkey,dgst) -PKCS7 *p7; -X509 *x509; -EVP_PKEY *pkey; -EVP_MD *dgst; +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, + EVP_MD *dgst) { PKCS7_SIGNER_INFO *si; @@ -318,20 +337,77 @@ err: return(NULL); } -STACK *PKCS7_get_signer_info(p7) -PKCS7 *p7; +STACK *PKCS7_get_signer_info(PKCS7 *p7) { if (PKCS7_type_is_signed(p7)) { return(p7->d.sign->signer_info); } + else if (PKCS7_type_is_signedAndEnveloped(p7)) + { + return(p7->d.signed_and_enveloped->signer_info); + } else return(NULL); } -X509 *PKCS7_cert_from_signer_info(p7,si) -PKCS7 *p7; -PKCS7_SIGNER_INFO *si; +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) + { + PKCS7_RECIP_INFO *ri; + + if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; + if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; + if (!PKCS7_add_recipient_info(p7,ri)) goto err; + return(ri); +err: + return(NULL); + } + +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) + { + int i; + STACK *sk; + + i=OBJ_obj2nid(p7->type); + switch (i) + { + case NID_pkcs7_signedAndEnveloped: + sk= p7->d.signed_and_enveloped->recipientinfo; + break; + case NID_pkcs7_enveloped: + sk= p7->d.enveloped->recipientinfo; + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE); + return(0); + } + + sk_push(sk,(char *)ri); + return(1); + } + +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) + { + ASN1_INTEGER_set(p7i->version,0); + X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509)); + + ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + p7i->issuer_and_serial->serial= + ASN1_INTEGER_dup(X509_get_serialNumber(x509)); + + X509_ALGOR_free(p7i->key_enc_algor); + p7i->key_enc_algor=(X509_ALGOR *)ASN1_dup(i2d_X509_ALGOR, + (char *(*)())d2i_X509_ALGOR, + (char *)x509->cert_info->key->algor); + + CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); + p7i->cert=x509; + + return(1); + } + +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) { if (PKCS7_type_is_signed(p7)) return(X509_find_by_issuer_and_serial(p7->d.sign->cert, @@ -341,3 +417,26 @@ PKCS7_SIGNER_INFO *si; return(NULL); } +int PKCS7_set_cipher(PKCS7 *p7, EVP_CIPHER *cipher) + { + int i; + PKCS7_ENC_CONTENT *ec; + + i=OBJ_obj2nid(p7->type); + switch (i) + { + case NID_pkcs7_signedAndEnveloped: + ec=p7->d.signed_and_enveloped->enc_data; + break; + case NID_pkcs7_enveloped: + ec=p7->d.enveloped->enc_data; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE); + return(0); + } + + ec->algorithm->algorithm=OBJ_nid2obj(EVP_CIPHER_nid(cipher)); + return(ec->algorithm->algorithm != NULL); + } +