提交 36309aa2 编写于 作者: D Dr. Stephen Henson

Signed receipt generation code.

上级 eb9d8d8c
......@@ -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)
{
......
......@@ -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
......
......@@ -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"},
......
......@@ -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;
}
......@@ -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);
......
......@@ -471,6 +471,78 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
return NULL;
}
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
X509 *signcert, EVP_PKEY *pkey,
STACK_OF(X509) *certs,
unsigned int flags)
{
CMS_SignerInfo *rct_si;
CMS_ContentInfo *cms = NULL;
ASN1_OCTET_STRING **pos, *os;
BIO *rct_cont = NULL;
int r = 0;
flags &= ~CMS_STREAM;
/* Not really detached but avoids content being allocated */
flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
if (!pkey || !signcert)
{
CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
return NULL;
}
/* Initialize signed data */
cms = CMS_sign(NULL, NULL, certs, NULL, flags);
if (!cms)
goto err;
/* Set inner content type to signed receipt */
if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
goto err;
rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
if (!rct_si)
{
CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
goto err;
}
os = cms_encode_Receipt(si);
if (!os)
goto err;
/* Set content to digest */
rct_cont = BIO_new_mem_buf(os->data, os->length);
if (!rct_cont)
goto err;
/* Add msgSigDigest attribute */
if (!cms_msgSigDigest_add1(rct_si, si))
goto err;
/* Finalize structure */
if (!CMS_final(cms, rct_cont, flags))
goto err;
/* Set embedded content */
pos = CMS_get0_content(cms);
*pos = os;
r = 1;
err:
if (rct_cont)
BIO_free(rct_cont);
if (r)
return cms;
CMS_ContentInfo_free(cms);
return NULL;
}
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
const EVP_CIPHER *cipher, unsigned int flags)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册