X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_doit.c;h=7acd11e057d78399fe5ff18740eb83a04b4aa6f9;hb=1c4f90a05dffca6663f1392ed74fe51a13cc46f1;hp=4222173e36b9360bbc4092c4c55896faad60b963;hpb=b6436ff2c2d640e2e71ef1d5a902a4be9713640f;p=oweals%2Fopenssl.git diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 4222173e36..7acd11e057 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -61,6 +61,7 @@ #include #include #include +#include static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value); @@ -73,7 +74,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) X509_ALGOR *xa; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=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; @@ -116,9 +118,9 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (md_sk != NULL) { - for (i=0; ialgorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); - if (ivlen > 0) RAND_bytes(iv,ivlen); + if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); EVP_CipherInit(ctx, evp_cipher, key, iv, 1); if (ivlen > 0) { @@ -173,9 +176,9 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) /* Lets do the pub key stuff :-) */ max=0; - for (i=0; icert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); @@ -186,26 +189,26 @@ 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; } - 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); - Free(tmp); + OPENSSL_free(tmp); goto err; } - ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); + M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } - Free(tmp); + OPENSSL_free(tmp); memset(key, 0, keylen); if (out == NULL) @@ -215,30 +218,23 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) btmp=NULL; } - if (bio == NULL) /* ??????????? */ - { + if (bio == NULL) { if (p7->detached) bio=BIO_new(BIO_s_null()); - else - { - bio=BIO_new(BIO_s_mem()); - /* We need to set this so that when we have read all - * the data, the encrypt BIO, if present, will read - * EOF and encode the last few bytes */ - BIO_set_mem_eof_return(bio,0); - + else { if (PKCS7_type_is_signed(p7) && - PKCS7_type_is_data(p7->d.sign->contents)) - { + PKCS7_type_is_data(p7->d.sign->contents)) { ASN1_OCTET_STRING *os; - os=p7->d.sign->contents->d.data; - if (os->length > 0) - BIO_write(bio,(char *)os->data, - os->length); - } + 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); } } + } BIO_push(out,bio); bio=NULL; if (0) @@ -258,20 +254,17 @@ 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; + unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=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; */ -#if 0 - X509_STORE_CTX s_ctx; -#endif i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; @@ -315,9 +308,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) /* We will be checking the signature */ if (md_sk != NULL) { - for (i=0; iissuer_and_serial->issuer, pcert->cert_info->issuer) && - !ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, ri->issuer_and_serial->serial)) break; ri=NULL; } @@ -381,17 +374,15 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } jj=EVP_PKEY_size(pkey); - tmp=Malloc(jj+10); + tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } - jj=EVP_PKEY_decrypt((unsigned char *)tmp, - ASN1_STRING_data(ri->enc_key), - ASN1_STRING_length(ri->enc_key), - pkey); + jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), + M_ASN1_STRING_length(ri->enc_key), pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); @@ -404,13 +395,19 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) return(NULL); - if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) - { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, + if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { + /* Some S/MIME clients don't use the same key + * and effective key length. The key length is + * determined by the size of the decrypted RSA key. + */ + if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) + { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); - goto err; - } - EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0); + goto err; + } + } + EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0); memset(tmp,0,jj); @@ -428,6 +425,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } else { +#if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read @@ -436,6 +434,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); +#else + if (data_body->length > 0) + bio = BIO_new_mem_buf(data_body->data,data_body->length); + else { + bio=BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(bio,0); + } +#endif } BIO_push(out,bio); bio=NULL; @@ -450,7 +456,7 @@ err: out=NULL; } if (tmp != NULL) - Free(tmp); + OPENSSL_free(tmp); return(out); } @@ -464,7 +470,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) PKCS7_SIGNER_INFO *si; EVP_MD_CTX *mdc,ctx_tmp; STACK_OF(X509_ATTRIBUTE) *sk; - STACK *si_sk=NULL; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; unsigned char *p,*pp=NULL; int x; ASN1_OCTET_STRING *os=NULL; @@ -477,12 +483,12 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) case NID_pkcs7_signedAndEnveloped: /* XXXXXXXXXXXXXXXX */ si_sk=p7->d.signed_and_enveloped->signer_info; - os=ASN1_OCTET_STRING_new(); + os=M_ASN1_OCTET_STRING_new(); p7->d.signed_and_enveloped->enc_data->enc_data=os; break; case NID_pkcs7_enveloped: /* XXXXXXXXXXXXXXXX */ - os=ASN1_OCTET_STRING_new(); + os=M_ASN1_OCTET_STRING_new(); p7->d.enveloped->enc_data->enc_data=os; break; case NID_pkcs7_signed: @@ -490,7 +496,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) os=p7->d.sign->contents->d.data; /* If detached data then the content is excluded */ if(p7->detached) { - ASN1_OCTET_STRING_free(os); + M_ASN1_OCTET_STRING_free(os); p7->d.sign->contents->d.data = NULL; } break; @@ -503,10 +509,9 @@ int PKCS7_dataFinal(PKCS7 *p7, 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); @@ -526,7 +531,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR); goto err; } - if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == j) + if (EVP_MD_CTX_type(mdc) == j) break; else btmp=btmp->next_bio; @@ -560,10 +565,10 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) V_ASN1_UTCTIME,sign_time); /* Add digest */ - md_tmp=EVP_MD_CTX_type(&ctx_tmp); + md_tmp=EVP_MD_CTX_md(&ctx_tmp); EVP_DigestFinal(&ctx_tmp,md_data,&md_len); - digest=ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(digest,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); @@ -573,13 +578,13 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 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); + pp=(unsigned char *)OPENSSL_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); + OPENSSL_free(pp); pp=NULL; } @@ -610,10 +615,19 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; } BIO_get_mem_ptr(btmp,&buf_mem); - ASN1_OCTET_STRING_set(os, + /* Mark the BIO read only then we can use its copy of the data + * instead of making an extra copy. + */ + BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(btmp, 0); + os->data = (unsigned char *)buf_mem->data; + os->length = buf_mem->length; +#if 0 + M_ASN1_OCTET_STRING_set(os, (unsigned char *)buf_mem->data,buf_mem->length); +#endif } - if (pp != NULL) Free(pp); + if (pp != NULL) OPENSSL_free(pp); pp=NULL; ret=1; @@ -625,18 +639,10 @@ err: 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; - EVP_MD_CTX mdc_tmp,*mdc; - unsigned char *pp,*p; PKCS7_ISSUER_AND_SERIAL *ias; int ret=0,i; - int md_type; - STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(X509) *cert; - BIO *btmp; X509 *x509; - EVP_PKEY *pkey; if (PKCS7_type_is_signed(p7)) { @@ -665,15 +671,40 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, /* Lets verify */ X509_STORE_CTX_init(ctx,cert_store,x509,cert); + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); i=X509_verify_cert(ctx); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); + X509_STORE_CTX_cleanup(ctx); goto err; } X509_STORE_CTX_cleanup(ctx); - /* So we like 'x509', lets check the signature. */ + return PKCS7_signatureVerify(bio, p7, si, x509); + err: + return ret; + } + +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509) + { + 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; + + if (!PKCS7_type_is_signed(p7) && + !PKCS7_type_is_signedAndEnveloped(p7)) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + md_type=OBJ_obj2nid(si->digest_alg->algorithm); btmp=bio; @@ -682,16 +713,18 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, if ((btmp == NULL) || ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } BIO_get_md_ctx(btmp,&mdc); if (mdc == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_INTERNAL_ERROR); + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_INTERNAL_ERROR); goto err; } - if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type) + if (EVP_MD_CTX_type(mdc) == md_type) break; btmp=btmp->next_bio; } @@ -711,7 +744,8 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, message_digest=PKCS7_digest_from_attributes(sk); if (!message_digest) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } if ((message_digest->length != (int)md_len) || @@ -725,7 +759,8 @@ for (ii=0; iilength; ii++) for (ii=0; iienc_digest; @@ -754,7 +789,8 @@ for (ii=0; iitype); 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); }