Commit c5a55463 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add support for digested data PKCS#7 type.

parent 77fe058c
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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
+104 −58
Original line number Diff line number Diff line
@@ -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);
		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);
	if (xa && !PKCS7_bio_add_digest(&out, xa))
			goto err;
				}

			BIO_set_md(btmp,evp_md);
			if (out == NULL)
				out=btmp;
			else
				BIO_push(out,btmp);
			btmp=NULL;
			}
		}

	if (evp_cipher != NULL)
		{
@@ -255,11 +276,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
		{
		if (PKCS7_is_detached(p7))
			bio=BIO_new(BIO_s_null());
		else
			{
			ASN1_OCTET_STRING *os;
			os = PKCS7_get_octet_string(p7->d.sign->contents);
			if (os && os->length > 0)
		else if (os && os->length > 0)
			bio = BIO_new_mem_buf(os->data, os->length);
		if(bio == NULL)
			{
@@ -267,7 +284,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
			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,25 +599,11 @@ 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);

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;
					}
				if (EVP_MD_CTX_type(mdc) == j)
					break;
				else
					btmp=BIO_next(btmp);
				}

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
@@ -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))
		{
+22 −0
Original line number Diff line number Diff line
@@ -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))
+6 −0
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
/* 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"},