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

Signed receipt generation code.

parent eb9d8d8c
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst,
#define SMIME_COMPRESS		(12 | SMIME_OP)
#define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP)
#define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP)
#define SMIME_SIGN_RECEIPT	(15 | SMIME_OP | SMIME_IP)
#define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
#define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)

int MAIN(int, char **);
@@ -159,6 +159,8 @@ int MAIN(int argc, char **argv)
			operation = SMIME_DECRYPT;
		else if (!strcmp (*args, "-sign"))
			operation = SMIME_SIGN;
		else if (!strcmp (*args, "-sign_receipt"))
			operation = SMIME_SIGN_RECEIPT;
		else if (!strcmp (*args, "-resign"))
			operation = SMIME_RESIGN;
		else if (!strcmp (*args, "-verify"))
@@ -541,6 +543,7 @@ int MAIN(int argc, char **argv)
		keyfile = NULL;
		need_rand = 1;
		}

	else if (operation == SMIME_DECRYPT)
		{
		if (!recipfile && !keyfile && !secret_key)
@@ -724,12 +727,22 @@ int MAIN(int argc, char **argv)
			}
		}

	if (operation == SMIME_SIGN_RECEIPT)
		{
		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
			e, "receipt signer certificate file")))
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}

	if (operation == SMIME_DECRYPT)
		{
		if (!keyfile)
			keyfile = recipfile;
		}
	else if (operation == SMIME_SIGN)
	else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
		{
		if (!keyfile)
			keyfile = signerfile;
@@ -888,6 +901,21 @@ int MAIN(int argc, char **argv)
						secret_key, secret_keylen,
						flags);

		}
	else if (operation == SMIME_SIGN_RECEIPT)
		{
		CMS_ContentInfo *srcms = NULL;
		STACK_OF(CMS_SignerInfo) *sis;
		CMS_SignerInfo *si;
		sis = CMS_get0_SignerInfos(cms);
		if (!sis)
			goto end;
		si = sk_CMS_SignerInfo_value(sis, 0);
		srcms = CMS_sign_receipt(si, signer, key, other, flags);
		if (!srcms)
			goto end;
		CMS_ContentInfo_free(cms);
		cms = srcms;
		}
	else if (operation & SMIME_SIGNERS)
		{
+9 −0
Original line number Diff line number Diff line
@@ -140,6 +140,11 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags);
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
						BIO *data, unsigned int flags);

CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
					X509 *signcert, EVP_PKEY *pkey,
					STACK_OF(X509) *certs,
					unsigned int flags);

int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);

@@ -342,6 +347,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL			 117
#define CMS_F_CMS_DIGEST_VERIFY				 118
#define CMS_F_CMS_ENCODE_RECEIPT			 161
#define CMS_F_CMS_ENCRYPT				 119
#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO		 120
#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT			 121
@@ -357,6 +363,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_GET0_ENVELOPED			 131
#define CMS_F_CMS_GET0_REVOCATION_CHOICES		 132
#define CMS_F_CMS_GET0_SIGNED				 133
#define CMS_F_CMS_MSGSIGDIGEST_ADD1			 162
#define CMS_F_CMS_RECEIPTREQUEST_CREATE0		 159
#define CMS_F_CMS_RECEIPT_VERIFY			 160
#define CMS_F_CMS_RECIPIENTINFO_DECRYPT			 134
@@ -380,6 +387,7 @@ void ERR_load_CMS_strings(void);
#define CMS_F_CMS_SIGNERINFO_VERIFY			 152
#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT		 153
#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT		 154
#define CMS_F_CMS_SIGN_RECEIPT				 163
#define CMS_F_CMS_STREAM				 155
#define CMS_F_CMS_UNCOMPRESS				 156
#define CMS_F_CMS_VERIFY				 157
@@ -427,6 +435,7 @@ void ERR_load_CMS_strings(void);
#define CMS_R_NO_DEFAULT_DIGEST				 128
#define CMS_R_NO_DIGEST_SET				 129
#define CMS_R_NO_KEY					 130
#define CMS_R_NO_KEY_OR_CERT				 174
#define CMS_R_NO_MATCHING_DIGEST			 131
#define CMS_R_NO_MATCHING_RECIPIENT			 132
#define CMS_R_NO_MATCHING_SIGNATURE			 166
+4 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"CMS_DIGESTALGORITHM_INIT_BIO"},
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL),	"CMS_DIGESTEDDATA_DO_FINAL"},
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY),	"CMS_digest_verify"},
{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT),	"CMS_ENCODE_RECEIPT"},
{ERR_FUNC(CMS_F_CMS_ENCRYPT),	"CMS_encrypt"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),	"CMS_ENCRYPTEDCONTENT_INIT_BIO"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT),	"CMS_EncryptedData_decrypt"},
@@ -106,6 +107,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"CMS_GET0_ENVELOPED"},
{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"},
{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"CMS_MSGSIGDIGEST_ADD1"},
{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),	"CMS_ReceiptRequest_create0"},
{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),	"CMS_RECEIPT_VERIFY"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),	"CMS_RecipientInfo_decrypt"},
@@ -129,6 +131,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY),	"CMS_SignerInfo_verify"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),	"CMS_SIGNERINFO_VERIFY_CERT"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),	"CMS_SignerInfo_verify_content"},
{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT),	"CMS_SIGN_RECEIPT"},
{ERR_FUNC(CMS_F_CMS_STREAM),	"CMS_stream"},
{ERR_FUNC(CMS_F_CMS_UNCOMPRESS),	"CMS_uncompress"},
{ERR_FUNC(CMS_F_CMS_VERIFY),	"CMS_verify"},
@@ -179,6 +182,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
{ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
{ERR_REASON(CMS_R_NO_KEY_OR_CERT)        ,"no key or cert"},
{ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
+71 −0
Original line number Diff line number Diff line
@@ -190,6 +190,8 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
		*prto = rr->receiptsTo;
	}

/* Digest a SignerInfo structure for msgSigDigest attribute processing */

static int cms_msgSigDigest(CMS_SignerInfo *si,
				unsigned char *dig, unsigned int *diglen)
	{
@@ -203,6 +205,26 @@ static int cms_msgSigDigest(CMS_SignerInfo *si,
	return 1;
	}

/* Add a msgSigDigest attribute to a SignerInfo */

int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
	{
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int diglen;
	if (!cms_msgSigDigest(src, dig, &diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
		return 0;
		}
	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
					V_ASN1_OCTET_STRING, dig, diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	return 1;
	}

/* Verify signed receipt after it has already passed normal CMS verify */

int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
@@ -348,3 +370,52 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
	return r;

	}

/* Encode a Receipt into an OCTET STRING read for including into content of
 * a SignedData ContentInfo.
 */

ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
	{
	CMS_Receipt rct;
	CMS_ReceiptRequest *rr = NULL;
	ASN1_OBJECT *ctype;
	ASN1_OCTET_STRING *os = NULL;

	/* Get original receipt request */

	/* Get original receipt request details */

	if (!CMS_get1_ReceiptRequest(si, &rr))
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
		goto err;
		}

	/* Get original content type */

	ctype = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_pkcs9_contentType),
					-3, V_ASN1_OBJECT);
	if (!ctype)
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
		goto err;
		}

	rct.version = 1;
	rct.contentType = ctype;
	rct.signedContentIdentifier = rr->signedContentIdentifier;
	rct.originatorSignatureValue = si->signature;

	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);

	return os;

	}

+2 −0
Original line number Diff line number Diff line
@@ -450,6 +450,8 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
				const unsigned char *key, size_t keylen);

int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);

BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
	
Loading