Add support for digested data PKCS#7 type.

This commit is contained in:
Dr. Stephen Henson 2003-10-11 22:11:45 +00:00
parent 77fe058c10
commit c5a5546389
5 changed files with 144 additions and 62 deletions

11
CHANGES
View file

@ -4,11 +4,16 @@
Changes between 0.9.7c and 0.9.8 [xx XXX xxxx]
*) New function PKCS7_set0_type_other() this initializes a PKCS7
structure of type "other".
*) Reorganise PKCS#7 code to separate the digest location functionality
into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest().
New function PKCS7_set_digest() to set the digest type for PKCS#7
digestedData type. Add additional code to correctly generate the
digestedData type and add support for this type in PKCS7 initialization
functions.
[Steve Henson]
*) Correctly initialize digested data content type in PKCS7_set_type().
*) New function PKCS7_set0_type_other() this initializes a PKCS7
structure of type "other".
[Steve Henson]
*) Fix prime generation loop in crypto/bn/bn_prime.pl by making

View file

@ -101,18 +101,54 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
return NULL;
}
static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
{
BIO *btmp;
const EVP_MD *md;
if ((btmp=BIO_new(BIO_f_md())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
goto err;
}
md=EVP_get_digestbyobj(alg->algorithm);
if (md == NULL)
{
PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE);
goto err;
}
BIO_set_md(btmp,md);
if (*pbio == NULL)
*pbio=btmp;
else if (!BIO_push(*pbio,btmp))
{
PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
goto err;
}
btmp=NULL;
return 1;
err:
if (btmp)
BIO_free(btmp);
return 0;
}
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
int i;
BIO *out=NULL,*btmp=NULL;
X509_ALGOR *xa;
const EVP_MD *evp_md;
X509_ALGOR *xa = NULL;
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;
ASN1_OCTET_STRING *os=NULL;
i=OBJ_obj2nid(p7->type);
p7->state=PKCS7_S_HEADER;
@ -121,6 +157,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
case NID_pkcs7_signed:
md_sk=p7->d.sign->md_algs;
os = PKCS7_get_octet_string(p7->d.sign->contents);
break;
case NID_pkcs7_signedAndEnveloped:
rsk=p7->d.signed_and_enveloped->recipientinfo;
@ -145,37 +182,21 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
goto err;
}
break;
case NID_pkcs7_digest:
xa = p7->d.digest->md;
os = PKCS7_get_octet_string(p7->d.digest->contents);
break;
default:
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
goto err;
}
if (md_sk != NULL)
{
for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
{
xa=sk_X509_ALGOR_value(md_sk,i);
if ((btmp=BIO_new(BIO_f_md())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
goto err;
}
for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
goto err;
evp_md=EVP_get_digestbyobj(xa->algorithm);
if (evp_md == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
goto err;
}
BIO_set_md(btmp,evp_md);
if (out == NULL)
out=btmp;
else
BIO_push(out,btmp);
btmp=NULL;
}
}
if (xa && !PKCS7_bio_add_digest(&out, xa))
goto err;
if (evp_cipher != NULL)
{
@ -255,19 +276,14 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{
if (PKCS7_is_detached(p7))
bio=BIO_new(BIO_s_null());
else
else if (os && os->length > 0)
bio = BIO_new_mem_buf(os->data, os->length);
if(bio == NULL)
{
ASN1_OCTET_STRING *os;
os = PKCS7_get_octet_string(p7->d.sign->contents);
if (os && 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=BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(bio,0);
}
}
}
BIO_push(out,bio);
bio=NULL;
if (0)
@ -493,6 +509,29 @@ err:
return(out);
}
static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
{
for (;;)
{
bio=BIO_find_type(bio,BIO_TYPE_MD);
if (bio == NULL)
{
PKCS7err(PKCS7_F_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
return NULL;
}
BIO_get_md_ctx(bio,pmd);
if (*pmd == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
return NULL;
}
if (EVP_MD_CTX_type(*pmd) == nid)
return bio;
bio=BIO_next(bio);
}
return NULL;
}
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
{
int ret=0;
@ -532,6 +571,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
p7->d.sign->contents->d.data = NULL;
}
break;
case NID_pkcs7_digest:
os=PKCS7_get_octet_string(p7->d.digest->contents);
/* If detached data then the content is excluded */
if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
{
M_ASN1_OCTET_STRING_free(os);
p7->d.digest->contents->d.data = NULL;
}
break;
}
if (si_sk != NULL)
@ -549,26 +599,12 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
j=OBJ_obj2nid(si->digest_alg->algorithm);
btmp=bio;
for (;;)
{
if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD))
== NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
goto err;
}
BIO_get_md_ctx(btmp,&mdc);
if (mdc == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
goto err;
}
if (EVP_MD_CTX_type(mdc) == j)
break;
else
btmp=BIO_next(btmp);
}
btmp = PKCS7_find_digest(&mdc, btmp, j);
if (btmp == NULL)
goto err;
/* We now have the EVP_MD_CTX, lets do the
* signing. */
EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
@ -641,6 +677,16 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
}
}
}
else if (i == NID_pkcs7_digest)
{
unsigned char md_data[EVP_MAX_MD_SIZE];
unsigned int md_len;
if (!PKCS7_find_digest(&mdc, bio,
OBJ_obj2nid(p7->d.digest->md->algorithm)))
goto err;
EVP_DigestFinal_ex(mdc,md_data,&md_len);
M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
}
if (!PKCS7_is_detached(p7))
{

View file

@ -138,6 +138,10 @@ int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
p7->d.sign->contents=p7_data;
break;
case NID_pkcs7_digest:
if (p7->d.digest->contents != NULL)
PKCS7_free(p7->d.digest->contents);
p7->d.digest->contents=p7_data;
break;
case NID_pkcs7_data:
case NID_pkcs7_enveloped:
case NID_pkcs7_signedAndEnveloped:
@ -410,6 +414,24 @@ err:
return(NULL);
}
int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
{
if (PKCS7_type_is_digest(p7))
{
if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
{
PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
return 0;
}
p7->d.digest->md->parameter->type = V_ASN1_NULL;
p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
return 1;
}
PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
return 1;
}
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
{
if (PKCS7_type_is_signed(p7))

View file

@ -233,6 +233,8 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
#define PKCS7_set_detached(p,v) \
PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
#define PKCS7_get_detached(p) \
@ -329,6 +331,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
EVP_PKEY *pkey, const EVP_MD *dgst);
X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
@ -379,11 +382,13 @@ void ERR_load_PKCS7_strings(void);
/* Function codes. */
#define PKCS7_F_B64_READ_PKCS7 120
#define PKCS7_F_B64_WRITE_PKCS7 121
#define PKCS7_F_FIND_DIGEST 127
#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
#define PKCS7_F_PKCS7_ADD_CRL 101
#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
#define PKCS7_F_PKCS7_ADD_SIGNER 103
#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125
#define PKCS7_F_PKCS7_CTRL 104
#define PKCS7_F_PKCS7_DATADECODE 112
#define PKCS7_F_PKCS7_DATAINIT 105
@ -394,6 +399,7 @@ void ERR_load_PKCS7_strings(void);
#define PKCS7_F_PKCS7_GET0_SIGNERS 124
#define PKCS7_F_PKCS7_SET_CIPHER 108
#define PKCS7_F_PKCS7_SET_CONTENT 109
#define PKCS7_F_PKCS7_SET_DIGEST 126
#define PKCS7_F_PKCS7_SET_TYPE 110
#define PKCS7_F_PKCS7_SIGN 116
#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113

View file

@ -1,6 +1,6 @@
/* crypto/pkcs7/pkcs7err.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -68,11 +68,13 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
{
{ERR_PACK(0,PKCS7_F_B64_READ_PKCS7,0), "B64_READ_PKCS7"},
{ERR_PACK(0,PKCS7_F_B64_WRITE_PKCS7,0), "B64_WRITE_PKCS7"},
{ERR_PACK(0,PKCS7_F_FIND_DIGEST,0), "FIND_DIGEST"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,0), "PKCS7_add_attrib_smimecap"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CERTIFICATE,0), "PKCS7_add_certificate"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CRL,0), "PKCS7_add_crl"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0), "PKCS7_add_recipient_info"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_SIGNER,0), "PKCS7_add_signer"},
{ERR_PACK(0,PKCS7_F_PKCS7_BIO_ADD_DIGEST,0), "PKCS7_BIO_ADD_DIGEST"},
{ERR_PACK(0,PKCS7_F_PKCS7_CTRL,0), "PKCS7_ctrl"},
{ERR_PACK(0,PKCS7_F_PKCS7_DATADECODE,0), "PKCS7_dataDecode"},
{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
@ -83,6 +85,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
{ERR_PACK(0,PKCS7_F_PKCS7_GET0_SIGNERS,0), "PKCS7_get0_signers"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_DIGEST,0), "PKCS7_set_digest"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
{ERR_PACK(0,PKCS7_F_PKCS7_SIGN,0), "PKCS7_sign"},
{ERR_PACK(0,PKCS7_F_PKCS7_SIGNATUREVERIFY,0), "PKCS7_signatureVerify"},