X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_doit.c;h=5481036f35654f26c2a2354cfe552398c244f7af;hp=071ff099377c284454d99fbd3d6b1fead84cba3d;hb=8f0edcd1422e4cf5258f0af7be0d3435f37f8b22;hpb=06c684912465497b3feff3e2327680b46b552be7 diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 071ff09937..5481036f35 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -58,24 +58,23 @@ #include #include "cryptlib.h" -#include "rand.h" -#include "objects.h" -#include "x509.h" +#include +#include +#include -static int add_attribute(STACK **sk, int nid, int atrtype, char *value); -static ASN1_TYPE *get_attribute(STACK *sk, int nid); +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value); +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); -#if 1 -BIO *PKCS7_dataInit(p7,bio) -PKCS7 *p7; -BIO *bio; +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i,j; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa; - EVP_MD *evp_md; - EVP_CIPHER *evp_cipher=NULL; - STACK *md_sk=NULL,*rsk=NULL; + const EVP_MD *evp_md; + const EVP_CIPHER *evp_cipher=NULL; + STACK_OF(X509_ALGOR) *md_sk=NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; @@ -91,23 +90,25 @@ BIO *bio; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; - evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.signed_and_enveloped->enc_data->algorithm->algorithm))); + xalg=p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + PKCS7err(PKCS7_F_PKCS7_DATAINIT, + PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } - xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; - evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.enveloped->enc_data->algorithm->algorithm))); + xalg=p7->d.enveloped->enc_data->algorithm; + evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + PKCS7err(PKCS7_F_PKCS7_DATAINIT, + PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } - xalg=p7->d.enveloped->enc_data->algorithm; break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); @@ -116,9 +117,9 @@ BIO *bio; if (md_sk != NULL) { - for (i=0; i 0) - { - ASN1_OCTET_STRING *os; - - RAND_bytes(iv,ivlen); - os=ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(os,iv,ivlen); -/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX this needs to change */ - if (xalg->parameter == NULL) - xalg->parameter=ASN1_TYPE_new(); - ASN1_TYPE_set(xalg->parameter,V_ASN1_OCTET_STRING, - (char *)os); - } RAND_bytes(key,keylen); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + if (ivlen > 0) RAND_bytes(iv,ivlen); + EVP_CipherInit(ctx, evp_cipher, key, iv, 1); + + if (ivlen > 0) { + if (xalg->parameter == NULL) + xalg->parameter=ASN1_TYPE_new(); + if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + goto err; + } /* Lets do the pub key stuff :-) */ max=0; - for (i=0; icert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); @@ -185,6 +184,7 @@ BIO *bio; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); + EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)Malloc(max)) == NULL) @@ -192,11 +192,12 @@ BIO *bio; PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } - for (i=0; icert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); + EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); @@ -206,8 +207,7 @@ BIO *bio; ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } Free(tmp); - - BIO_set_cipher(btmp,evp_cipher,key,iv,1); + memset(key, 0, keylen); if (out == NULL) out=btmp; @@ -255,22 +255,19 @@ err: } /* int */ -BIO *PKCS7_dataDecode(p7,pkey,in_bio,xs) -PKCS7 *p7; -EVP_PKEY *pkey; -BIO *in_bio; -X509_STORE *xs; +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; - EVP_MD *evp_md; - EVP_CIPHER *evp_cipher=NULL; + const EVP_MD *evp_md; + const EVP_CIPHER *evp_cipher=NULL; EVP_CIPHER_CTX *evp_ctx=NULL; X509_ALGOR *enc_alg=NULL; - STACK *md_sk=NULL,*rsk=NULL; + STACK_OF(X509_ALGOR) *md_sk=NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; /* EVP_PKEY *pkey; */ @@ -295,7 +292,7 @@ X509_STORE *xs; evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; @@ -307,25 +304,25 @@ X509_STORE *xs; evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm))); if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.enveloped->enc_data->algorithm; break; default: - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { - for (i=0; iissuer_and_serial->issuer, - ri->issuer_and_serial->serial, - &ret)) - break; + for (i=0; iissuer_and_serial->issuer, + pcert->cert_info->issuer) && + !ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + ri->issuer_and_serial->serial)) break; ri=NULL; - } - if (ri == NULL) return(NULL); - pkey=ret.data.pkey; -#endif - if (pkey == NULL) - { + } + if (ri == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); return(NULL); - } + } jj=EVP_PKEY_size(pkey); tmp=Malloc(jj+10); if (tmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_MALLOC_FAILURE); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } @@ -408,7 +396,7 @@ X509_STORE *xs; pkey); if (jj <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_EVP_LIB); + PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); goto err; } @@ -420,7 +408,8 @@ X509_STORE *xs; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { - PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0); @@ -466,11 +455,8 @@ err: Free(tmp); return(out); } -#endif -int PKCS7_dataFinal(p7,bio) -PKCS7 *p7; -BIO *bio; +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) { int ret=0; int i,j; @@ -479,7 +465,8 @@ BIO *bio; BUF_MEM *buf=NULL; PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc,ctx_tmp; - STACK *sk,*si_sk=NULL; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; unsigned char *p,*pp=NULL; int x; ASN1_OCTET_STRING *os=NULL; @@ -503,6 +490,11 @@ BIO *bio; case NID_pkcs7_signed: si_sk=p7->d.sign->signer_info; os=p7->d.sign->contents->d.data; + /* If detached data then the content is excluded */ + if(p7->detached) { + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } break; } @@ -513,10 +505,9 @@ BIO *bio; PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); goto err; } - for (i=0; ipkey == NULL) continue; j=OBJ_obj2nid(si->digest_alg->algorithm); @@ -555,36 +546,39 @@ BIO *bio; /* If there are attributes, we add the digest * attribute and only sign the attributes */ - if ((sk != NULL) && (sk_num(sk) != 0)) + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_data[EVP_MAX_MD_SIZE]; unsigned int md_len; ASN1_OCTET_STRING *digest; ASN1_UTCTIME *sign_time; - EVP_MD *md_tmp; + const EVP_MD *md_tmp; /* Add signing time */ sign_time=X509_gmtime_adj(NULL,0); PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, - V_ASN1_UTCTIME,(char *)sign_time); + V_ASN1_UTCTIME,sign_time); /* Add digest */ md_tmp=EVP_MD_CTX_type(&ctx_tmp); EVP_DigestFinal(&ctx_tmp,md_data,&md_len); digest=ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(digest,md_data,md_len); - PKCS7_add_signed_attribute(si,NID_pkcs9_messageDigest, - V_ASN1_OCTET_STRING,(char *)digest); + PKCS7_add_signed_attribute(si, + NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING,digest); /* Now sign the mess */ EVP_SignInit(&ctx_tmp,md_tmp); - x=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE, - V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET); + x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL, + i2d_X509_ATTRIBUTE, + V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); pp=(unsigned char *)Malloc(x); p=pp; - i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE, - V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SET); + i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p, + i2d_X509_ATTRIBUTE, + V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); EVP_SignUpdate(&ctx_tmp,pp,x); Free(pp); pp=NULL; @@ -608,9 +602,7 @@ BIO *bio; } } - if (p7->detached) - ASN1_OCTET_STRING_set(os,(unsigned char *)"",0); - else + if (!p7->detached) { btmp=BIO_find_type(bio,BIO_TYPE_MEM); if (btmp == NULL) @@ -631,12 +623,8 @@ err: return(ret); } -int PKCS7_dataVerify(cert_store,ctx,bio,p7,si) -X509_STORE *cert_store; -X509_STORE_CTX *ctx; -BIO *bio; -PKCS7 *p7; -PKCS7_SIGNER_INFO *si; +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, + PKCS7 *p7, PKCS7_SIGNER_INFO *si) { /* PKCS7_SIGNED *s; */ ASN1_OCTET_STRING *os; @@ -645,9 +633,11 @@ PKCS7_SIGNER_INFO *si; PKCS7_ISSUER_AND_SERIAL *ias; int ret=0,i; int md_type; - STACK *sk,*cert; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(X509) *cert; BIO *btmp; X509 *x509; + EVP_PKEY *pkey; if (PKCS7_type_is_signed(p7)) { @@ -712,10 +702,10 @@ PKCS7_SIGNER_INFO *si; memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp)); sk=si->auth_attr; - if ((sk != NULL) && (sk_num(sk) != 0)) + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { unsigned char md_dat[EVP_MAX_MD_SIZE]; - int md_len; + unsigned int md_len; ASN1_OCTET_STRING *message_digest; EVP_DigestFinal(&mdc_tmp,md_dat,&md_len); @@ -725,7 +715,7 @@ PKCS7_SIGNER_INFO *si; PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } - if ((message_digest->length != md_len) || + if ((message_digest->length != (int)md_len) || (memcmp(message_digest->data,md_dat,md_len))) { #if 0 @@ -742,22 +732,27 @@ for (ii=0; iienc_digest; - if (X509_get_pubkey(x509)->type == EVP_PKEY_DSA) - mdc_tmp.digest=EVP_dss1(); + pkey = X509_get_pubkey(x509); + if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); - i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, - X509_get_pubkey(x509)); + i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); + EVP_PKEY_free(pkey); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE); @@ -770,54 +765,46 @@ err: return(ret); } -PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(p7,idx) -PKCS7 *p7; -int idx; +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) { - STACK *rsk; + STACK_OF(PKCS7_RECIP_INFO) *rsk; PKCS7_RECIP_INFO *ri; int i; i=OBJ_obj2nid(p7->type); if (i != NID_pkcs7_signedAndEnveloped) return(NULL); rsk=p7->d.signed_and_enveloped->recipientinfo; - ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0); - if (sk_num(rsk) <= idx) return(NULL); - ri=(PKCS7_RECIP_INFO *)sk_value(rsk,idx); + ri=sk_PKCS7_RECIP_INFO_value(rsk,0); + if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); + ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); return(ri->issuer_and_serial); } -ASN1_TYPE *PKCS7_get_signed_attribute(si,nid) -PKCS7_SIGNER_INFO *si; -int nid; +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) { return(get_attribute(si->auth_attr,nid)); } -ASN1_TYPE *PKCS7_get_attribute(si,nid) -PKCS7_SIGNER_INFO *si; -int nid; +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) { return(get_attribute(si->unauth_attr,nid)); } -static ASN1_TYPE *get_attribute(sk,nid) -STACK *sk; -int nid; +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) { int i; X509_ATTRIBUTE *xa; ASN1_OBJECT *o; o=OBJ_nid2obj(nid); - if (o == NULL) return(NULL); - for (i=0; iobject,o) == 0) { - if (xa->set && sk_num(xa->value.set)) - return((ASN1_TYPE *)sk_value(xa->value.set,0)); + if (xa->set && sk_ASN1_TYPE_num(xa->value.set)) + return(sk_ASN1_TYPE_value(xa->value.set,0)); else return(NULL); } @@ -825,110 +812,85 @@ int nid; return(NULL); } -ASN1_OCTET_STRING *PKCS7_digest_from_attributes(sk) -STACK *sk; - { - X509_ATTRIBUTE *attr; +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) +{ ASN1_TYPE *astype; - int i; - if (!sk || !sk_num(sk)) return NULL; - /* Search the attributes for a digest */ - for (i = 0; i < sk_num(sk); i++) - { - attr = (X509_ATTRIBUTE *) sk_value(sk, i); - if (OBJ_obj2nid(attr->object) == NID_pkcs9_messageDigest) - { - if (!attr->set) return NULL; - if (!attr->value.set || - !sk_num (attr->value.set) ) return NULL; - astype = (ASN1_TYPE *) sk_value(attr->value.set, 0); - return astype->value.octet_string; - } - } - return NULL; - } + if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL; + return astype->value.octet_string; +} -int PKCS7_set_signed_attributes(p7si,sk) -PKCS7_SIGNER_INFO *p7si; -STACK *sk; +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) { int i; if (p7si->auth_attr != NULL) - sk_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); - p7si->auth_attr=sk_dup(sk); - for (i=0; iauth_attr,X509_ATTRIBUTE_free); + p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); + for (i=0; iauth_attr,i)=(char *)X509_ATTRIBUTE_dup( - (X509_ATTRIBUTE *)sk_value(sk,i))) == NULL) + if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) + == NULL) return(0); } return(1); } -int PKCS7_set_attributes(p7si,sk) -PKCS7_SIGNER_INFO *p7si; -STACK *sk; +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) { int i; if (p7si->unauth_attr != NULL) - sk_pop_free(p7si->unauth_attr,X509_ATTRIBUTE_free); - p7si->unauth_attr=sk_dup(sk); - for (i=0; iunauth_attr, + X509_ATTRIBUTE_free); + p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); + for (i=0; iunauth_attr,i)=(char *)X509_ATTRIBUTE_dup( - (X509_ATTRIBUTE *)sk_value(sk,i))) == NULL) + if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) + == NULL) return(0); } return(1); } -int PKCS7_add_signed_attribute(p7si,nid,atrtype,value) -PKCS7_SIGNER_INFO *p7si; -int nid; -int atrtype; -char *value; +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) { return(add_attribute(&(p7si->auth_attr),nid,atrtype,value)); } -int PKCS7_add_attribute(p7si,nid,atrtype,value) -PKCS7_SIGNER_INFO *p7si; -int nid; -int atrtype; -char *value; +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) { return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value)); } -static int add_attribute(sk, nid, atrtype, value) -STACK **sk; -int nid; -int atrtype; -char *value; +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value) { X509_ATTRIBUTE *attr=NULL; if (*sk == NULL) { - *sk = sk_new(NULL); + *sk = sk_X509_ATTRIBUTE_new(NULL); new_attrib: attr=X509_ATTRIBUTE_create(nid,atrtype,value); - sk_push(*sk,(char *)attr); + sk_X509_ATTRIBUTE_push(*sk,attr); } else { int i; - for (i=0; iobject) == nid) { X509_ATTRIBUTE_free(attr); attr=X509_ATTRIBUTE_create(nid,atrtype,value); - sk_value(*sk,i)=(char *)attr; + sk_X509_ATTRIBUTE_set(*sk,i,attr); goto end; } }