Add support for digested data PKCS#7 type.
This commit is contained in:
parent
77fe058c10
commit
c5a5546389
5 changed files with 144 additions and 62 deletions
11
CHANGES
11
CHANGES
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"},
|
||||
|
|
Loading…
Reference in a new issue