X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_doit.c;h=f016fdb2e255969c2e4bc7fba813e250c6cb3efc;hp=d93b27e7376e6de61e1ae656e96b240f597e66fc;hb=67fec850e1ccbbe921648b7f0b7ebeb4f1c084f6;hpb=7f0606016cbbec917b1fe094b84b062e87abe7da diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index d93b27e737..f016fdb2e2 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -67,6 +67,38 @@ 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); +static int PKCS7_type_is_other(PKCS7* p7) + { + int isOther=1; + + int nid=OBJ_obj2nid(p7->type); + + switch( nid ) + { + case NID_pkcs7_data: + case NID_pkcs7_signed: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_digest: + case NID_pkcs7_encrypted: + isOther=0; + break; + default: + isOther=1; + } + + return isOther; + + } + +static int PKCS7_type_is_octet_string(PKCS7* p7) + { + if ( 0==PKCS7_type_is_other(p7) ) + return 0; + + return (V_ASN1_OCTET_STRING==p7->d.other->type) ? 1 : 0; + } + BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i,j; @@ -165,7 +197,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) goto err; xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); - EVP_CipherInit(ctx, evp_cipher, key, iv, 1); + EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); if (ivlen > 0) { if (xalg->parameter == NULL) @@ -189,7 +221,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) EVP_PKEY_free(pkey); if (max < jj) max=jj; } - if ((tmp=(unsigned char *)Malloc(max)) == NULL) + if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; @@ -203,12 +235,12 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); - Free(tmp); + OPENSSL_free(tmp); goto err; } M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } - Free(tmp); + OPENSSL_free(tmp); memset(key, 0, keylen); if (out == NULL) @@ -219,16 +251,23 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) } if (bio == NULL) { - if (p7->detached) + if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else { - if (PKCS7_type_is_signed(p7) && - PKCS7_type_is_data(p7->d.sign->contents)) { - ASN1_OCTET_STRING *os; - os=p7->d.sign->contents->d.data; - if (os->length > 0) bio = - BIO_new_mem_buf(os->data, os->length); - } + if (PKCS7_type_is_signed(p7) ) { + if ( PKCS7_type_is_data(p7->d.sign->contents)) { + ASN1_OCTET_STRING *os; + os=p7->d.sign->contents->d.data; + if (os->length > 0) + bio = BIO_new_mem_buf(os->data, os->length); + } + else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) { + ASN1_OCTET_STRING *os; + os=p7->d.sign->contents->d.other->value.octet_string; + if (os->length > 0) + bio = BIO_new_mem_buf(os->data, os->length); + } + } if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); @@ -370,11 +409,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); - return(NULL); + goto err; } jj=EVP_PKEY_size(pkey); - tmp=(unsigned char *)Malloc(jj+10); + tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); @@ -391,9 +430,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) evp_ctx=NULL; BIO_get_cipher_ctx(etmp,&evp_ctx); - EVP_CipherInit(evp_ctx,evp_cipher,NULL,NULL,0); + EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0); if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) - return(NULL); + goto err; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key @@ -407,7 +446,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) goto err; } } - EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0); + EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); memset(tmp,0,jj); @@ -419,7 +458,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } #if 1 - if (p7->detached || (in_bio != NULL)) + if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio=in_bio; } @@ -456,7 +495,7 @@ err: out=NULL; } if (tmp != NULL) - Free(tmp); + OPENSSL_free(tmp); return(out); } @@ -471,8 +510,6 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) EVP_MD_CTX *mdc,ctx_tmp; 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; i=OBJ_obj2nid(p7->type); @@ -528,18 +565,19 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) BIO_get_md_ctx(btmp,&mdc); if (mdc == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR); + PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR); goto err; } if (EVP_MD_CTX_type(mdc) == j) break; else - btmp=btmp->next_bio; + btmp=BIO_next(btmp); } /* We now have the EVP_MD_CTX, lets do the * signing. */ - memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp)); + EVP_MD_CTX_init(&ctx_tmp); + EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey))) { PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); @@ -552,44 +590,44 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) * attribute and only sign the attributes */ if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { - unsigned char md_data[EVP_MAX_MD_SIZE]; - unsigned int md_len; + unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; + unsigned int md_len, alen; ASN1_OCTET_STRING *digest; ASN1_UTCTIME *sign_time; 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,sign_time); + /* Add signing time if not already present */ + if (!PKCS7_get_signed_attribute(si, + NID_pkcs9_signingTime)) + { + sign_time=X509_gmtime_adj(NULL,0); + PKCS7_add_signed_attribute(si, + NID_pkcs9_signingTime, + V_ASN1_UTCTIME,sign_time); + } /* Add digest */ md_tmp=EVP_MD_CTX_md(&ctx_tmp); - EVP_DigestFinal(&ctx_tmp,md_data,&md_len); + EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); digest=M_ASN1_OCTET_STRING_new(); M_ASN1_OCTET_STRING_set(digest,md_data,md_len); 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_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_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; + /* Now sign the attributes */ + EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); + alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); + if(!abuf) goto err; + EVP_SignUpdate(&ctx_tmp,abuf,alen); + OPENSSL_free(abuf); } +#ifndef OPENSSL_NO_DSA if (si->pkey->type == EVP_PKEY_DSA) ctx_tmp.digest=EVP_dss1(); +#endif if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, (unsigned int *)&buf->length,si->pkey)) @@ -606,7 +644,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) } } - if (!p7->detached) + if (!PKCS7_is_detached(p7)) { btmp=BIO_find_type(bio,BIO_TYPE_MEM); if (btmp == NULL) @@ -627,11 +665,9 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) (unsigned char *)buf_mem->data,buf_mem->length); #endif } - if (pp != NULL) Free(pp); - pp=NULL; - ret=1; err: + EVP_MD_CTX_cleanup(&ctx_tmp); if (buf != NULL) BUF_MEM_free(buf); return(ret); } @@ -670,7 +706,11 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, } /* Lets verify */ - X509_STORE_CTX_init(ctx,cert_store,x509,cert); + if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert)) + { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); + goto err; + } X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); i=X509_verify_cert(ctx); if (i <= 0) @@ -691,13 +731,14 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, { ASN1_OCTET_STRING *os; EVP_MD_CTX mdc_tmp,*mdc; - unsigned char *pp,*p; int ret=0,i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; BIO *btmp; EVP_PKEY *pkey; + EVP_MD_CTX_init(&mdc_tmp); + if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, @@ -721,26 +762,26 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, if (mdc == NULL) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_INTERNAL_ERROR); + ERR_R_INTERNAL_ERROR); goto err; } if (EVP_MD_CTX_type(mdc) == md_type) break; - btmp=btmp->next_bio; + btmp=BIO_next(btmp); } /* mdc is the digest ctx that we want, unless there are attributes, * in which case the digest is the signed attributes */ - memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp)); + EVP_MD_CTX_copy_ex(&mdc_tmp,mdc); sk=si->auth_attr; if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { - unsigned char md_dat[EVP_MAX_MD_SIZE]; - unsigned int md_len; + unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; + unsigned int md_len, alen; ASN1_OCTET_STRING *message_digest; - EVP_DigestFinal(&mdc_tmp,md_dat,&md_len); + EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); message_digest=PKCS7_digest_from_attributes(sk); if (!message_digest) { @@ -765,25 +806,25 @@ for (ii=0; iienc_digest; pkey = X509_get_pubkey(x509); + if (!pkey) + { + ret = -1; + goto err; + } +#ifndef OPENSSL_NO_DSA if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); +#endif i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); EVP_PKEY_free(pkey); @@ -797,6 +838,7 @@ for (ii=0; iiobject,o) == 0) { - if (xa->set && sk_ASN1_TYPE_num(xa->value.set)) + if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) return(sk_ASN1_TYPE_value(xa->value.set,0)); else return(NULL); @@ -909,7 +951,7 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, if (*sk == NULL) { - *sk = sk_X509_ATTRIBUTE_new(NULL); + *sk = sk_X509_ATTRIBUTE_new_null(); new_attrib: attr=X509_ATTRIBUTE_create(nid,atrtype,value); sk_X509_ATTRIBUTE_push(*sk,attr);