Support for verification of signed receipts.
This commit is contained in:
parent
f7ccba3edf
commit
eb9d8d8cd4
5
CHANGES
5
CHANGES
@ -59,8 +59,9 @@
|
||||
*) Initial support for Cryptographic Message Syntax (aka CMS) based
|
||||
on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
|
||||
support for data, signedData, compressedData, digestedData and
|
||||
encryptedData types currently included, more to come. Scripts to
|
||||
check against RFC4134 examples draft.
|
||||
encryptedData, envelopedData types included. Scripts to check against
|
||||
RFC4134 examples draft and interop and consistency checks of many
|
||||
content types and variants.
|
||||
[Steve Henson]
|
||||
|
||||
*) Zlib compression BIO. This is a filter BIO which compressed and
|
||||
|
67
apps/cms.c
67
apps/cms.c
@ -91,6 +91,8 @@ 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_VERIFY_RECEIPT (16 | SMIME_IP)
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
@ -101,17 +103,17 @@ int MAIN(int argc, char **argv)
|
||||
int ret = 0;
|
||||
char **args;
|
||||
const char *inmode = "r", *outmode = "w";
|
||||
char *infile = NULL, *outfile = NULL;
|
||||
char *infile = NULL, *outfile = NULL, *rctfile = NULL;
|
||||
char *signerfile = NULL, *recipfile = NULL;
|
||||
STACK *sksigners = NULL, *skkeys = NULL;
|
||||
char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
CMS_ContentInfo *cms = NULL, *rcms = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
X509 *cert = NULL, *recip = NULL, *signer = NULL;
|
||||
EVP_PKEY *key = NULL;
|
||||
STACK_OF(X509) *encerts = NULL, *other = NULL;
|
||||
BIO *in = NULL, *out = NULL, *indata = NULL;
|
||||
BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
|
||||
int badarg = 0;
|
||||
int flags = CMS_DETACHED, noout = 0, print = 0;
|
||||
int rr_print = 0, rr_allorfirst = -1;
|
||||
@ -124,7 +126,7 @@ int MAIN(int argc, char **argv)
|
||||
int need_rand = 0;
|
||||
const EVP_MD *sign_md = NULL;
|
||||
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
|
||||
int keyform = FORMAT_PEM;
|
||||
int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *engine=NULL;
|
||||
#endif
|
||||
@ -161,6 +163,14 @@ int MAIN(int argc, char **argv)
|
||||
operation = SMIME_RESIGN;
|
||||
else if (!strcmp (*args, "-verify"))
|
||||
operation = SMIME_VERIFY;
|
||||
else if (!strcmp(*args,"-verify_receipt"))
|
||||
{
|
||||
operation = SMIME_VERIFY_RECEIPT;
|
||||
if (!args[1])
|
||||
goto argerr;
|
||||
args++;
|
||||
rctfile = *args;
|
||||
}
|
||||
else if (!strcmp (*args, "-cmsout"))
|
||||
operation = SMIME_CMSOUT;
|
||||
else if (!strcmp (*args, "-data_out"))
|
||||
@ -425,6 +435,12 @@ int MAIN(int argc, char **argv)
|
||||
goto argerr;
|
||||
keyform = str2fmt(*++args);
|
||||
}
|
||||
else if (!strcmp (*args, "-rctform"))
|
||||
{
|
||||
if (!args[1])
|
||||
goto argerr;
|
||||
rctformat = str2fmt(*++args);
|
||||
}
|
||||
else if (!strcmp (*args, "-certfile"))
|
||||
{
|
||||
if (!args[1])
|
||||
@ -770,6 +786,35 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (rctfile)
|
||||
{
|
||||
char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
|
||||
if (!(rctin = BIO_new_file(rctfile, rctmode)))
|
||||
{
|
||||
BIO_printf (bio_err,
|
||||
"Can't open receipt file %s\n", rctfile);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rctformat == FORMAT_SMIME)
|
||||
rcms = SMIME_read_CMS(rctin, NULL);
|
||||
else if (rctformat == FORMAT_PEM)
|
||||
rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
|
||||
else if (rctformat == FORMAT_ASN1)
|
||||
rcms = d2i_CMS_bio(rctin, NULL);
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err, "Bad input format for receipt\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!rcms)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading receipt\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (outfile)
|
||||
{
|
||||
if (!(out = BIO_new_file(outfile, outmode)))
|
||||
@ -790,7 +835,7 @@ int MAIN(int argc, char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (operation == SMIME_VERIFY)
|
||||
if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
|
||||
{
|
||||
if (!(store = setup_verify(bio_err, CAfile, CApath)))
|
||||
goto end;
|
||||
@ -1001,6 +1046,16 @@ int MAIN(int argc, char **argv)
|
||||
receipt_request_print(bio_err, cms);
|
||||
|
||||
}
|
||||
else if (operation == SMIME_VERIFY_RECEIPT)
|
||||
{
|
||||
if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
|
||||
BIO_printf(bio_err, "Verification successful\n");
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_err, "Verification failure\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (noout)
|
||||
@ -1068,6 +1123,8 @@ end:
|
||||
X509_free(signer);
|
||||
EVP_PKEY_free(key);
|
||||
CMS_ContentInfo_free(cms);
|
||||
CMS_ContentInfo_free(rcms);
|
||||
BIO_free(rctin);
|
||||
BIO_free(in);
|
||||
BIO_free(indata);
|
||||
BIO_free_all(out);
|
||||
|
@ -162,6 +162,10 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
|
||||
|
||||
int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||
STACK_OF(X509) *certs,
|
||||
X509_STORE *store, unsigned int flags);
|
||||
|
||||
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
|
||||
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
||||
@ -354,6 +358,7 @@ void ERR_load_CMS_strings(void);
|
||||
#define CMS_F_CMS_GET0_REVOCATION_CHOICES 132
|
||||
#define CMS_F_CMS_GET0_SIGNED 133
|
||||
#define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159
|
||||
#define CMS_F_CMS_RECEIPT_VERIFY 160
|
||||
#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135
|
||||
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136
|
||||
@ -387,7 +392,9 @@ void ERR_load_CMS_strings(void);
|
||||
#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102
|
||||
#define CMS_R_CMS_DATAFINAL_ERROR 103
|
||||
#define CMS_R_CMS_LIB 104
|
||||
#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170
|
||||
#define CMS_R_CONTENT_NOT_FOUND 105
|
||||
#define CMS_R_CONTENT_TYPE_MISMATCH 171
|
||||
#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106
|
||||
#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107
|
||||
#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108
|
||||
@ -395,6 +402,7 @@ void ERR_load_CMS_strings(void);
|
||||
#define CMS_R_CTRL_ERROR 110
|
||||
#define CMS_R_CTRL_FAILURE 111
|
||||
#define CMS_R_DECRYPT_ERROR 112
|
||||
#define CMS_R_DIGEST_ERROR 161
|
||||
#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113
|
||||
#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
|
||||
#define CMS_R_ERROR_SETTING_KEY 115
|
||||
@ -404,21 +412,31 @@ void ERR_load_CMS_strings(void);
|
||||
#define CMS_R_MD_BIO_INIT_ERROR 119
|
||||
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
|
||||
#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121
|
||||
#define CMS_R_MSGSIGDIGEST_ERROR 172
|
||||
#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162
|
||||
#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163
|
||||
#define CMS_R_NEED_ONE_SIGNER 164
|
||||
#define CMS_R_NOT_A_SIGNED_RECEIPT 165
|
||||
#define CMS_R_NOT_ENCRYPTED_DATA 122
|
||||
#define CMS_R_NOT_KEK 123
|
||||
#define CMS_R_NOT_KEY_TRANSPORT 124
|
||||
#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125
|
||||
#define CMS_R_NO_CIPHER 126
|
||||
#define CMS_R_NO_CONTENT 127
|
||||
#define CMS_R_NO_CONTENT_TYPE 173
|
||||
#define CMS_R_NO_DEFAULT_DIGEST 128
|
||||
#define CMS_R_NO_DIGEST_SET 129
|
||||
#define CMS_R_NO_KEY 130
|
||||
#define CMS_R_NO_MATCHING_DIGEST 131
|
||||
#define CMS_R_NO_MATCHING_RECIPIENT 132
|
||||
#define CMS_R_NO_MATCHING_SIGNATURE 166
|
||||
#define CMS_R_NO_MSGSIGDIGEST 167
|
||||
#define CMS_R_NO_PRIVATE_KEY 133
|
||||
#define CMS_R_NO_PUBLIC_KEY 134
|
||||
#define CMS_R_NO_RECEIPT_REQUEST 168
|
||||
#define CMS_R_NO_SIGNERS 135
|
||||
#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136
|
||||
#define CMS_R_RECEIPT_DECODE_ERROR 169
|
||||
#define CMS_R_RECIPIENT_ERROR 137
|
||||
#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138
|
||||
#define CMS_R_SIGNFINAL_ERROR 139
|
||||
|
@ -371,3 +371,10 @@ ASN1_SEQUENCE(CMS_ReceiptRequest) = {
|
||||
ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
|
||||
} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
|
||||
|
||||
ASN1_SEQUENCE(CMS_Receipt) = {
|
||||
ASN1_SIMPLE(CMS_Receipt, version, LONG),
|
||||
ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(CMS_Receipt)
|
||||
|
||||
|
@ -107,10 +107,11 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
||||
{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_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"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), "CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), "CMS_RECIPIENTINFO_KEKRI_GET0_ID"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), "CMS_RecipientInfo_kekri_get0_id"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), "CMS_RecipientInfo_kekri_id_cmp"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"},
|
||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), "CMS_RECIPIENTINFO_KTRI_DECRYPT"},
|
||||
@ -143,7 +144,9 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
||||
{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
|
||||
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"},
|
||||
{ERR_REASON(CMS_R_CMS_LIB) ,"cms lib"},
|
||||
{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
|
||||
{ERR_REASON(CMS_R_CONTENT_NOT_FOUND) ,"content not found"},
|
||||
{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
|
||||
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
|
||||
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
|
||||
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
|
||||
@ -151,6 +154,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
||||
{ERR_REASON(CMS_R_CTRL_ERROR) ,"ctrl error"},
|
||||
{ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"},
|
||||
{ERR_REASON(CMS_R_DECRYPT_ERROR) ,"decrypt error"},
|
||||
{ERR_REASON(CMS_R_DIGEST_ERROR) ,"digest error"},
|
||||
{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
|
||||
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
|
||||
{ERR_REASON(CMS_R_ERROR_SETTING_KEY) ,"error setting key"},
|
||||
@ -160,21 +164,31 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
||||
{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR) ,"md bio init error"},
|
||||
{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
|
||||
{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
|
||||
{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR) ,"msgsigdigest error"},
|
||||
{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
|
||||
{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
|
||||
{ERR_REASON(CMS_R_NEED_ONE_SIGNER) ,"need one signer"},
|
||||
{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT) ,"not a signed receipt"},
|
||||
{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA) ,"not encrypted data"},
|
||||
{ERR_REASON(CMS_R_NOT_KEK) ,"not kek"},
|
||||
{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT) ,"not key transport"},
|
||||
{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
|
||||
{ERR_REASON(CMS_R_NO_CIPHER) ,"no cipher"},
|
||||
{ERR_REASON(CMS_R_NO_CONTENT) ,"no content"},
|
||||
{ERR_REASON(CMS_R_NO_CONTENT_TYPE) ,"no content type"},
|
||||
{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_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"},
|
||||
{ERR_REASON(CMS_R_NO_MSGSIGDIGEST) ,"no msgsigdigest"},
|
||||
{ERR_REASON(CMS_R_NO_PRIVATE_KEY) ,"no private key"},
|
||||
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"},
|
||||
{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST) ,"no receipt request"},
|
||||
{ERR_REASON(CMS_R_NO_SIGNERS) ,"no signers"},
|
||||
{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
|
||||
{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR) ,"receipt decode error"},
|
||||
{ERR_REASON(CMS_R_RECIPIENT_ERROR) ,"recipient error"},
|
||||
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
||||
{ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"},
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "asn1_locl.h"
|
||||
|
||||
DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
|
||||
DECLARE_ASN1_ITEM(CMS_Receipt)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
|
||||
@ -189,5 +190,161 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||
*prto = rr->receiptsTo;
|
||||
}
|
||||
|
||||
static int cms_msgSigDigest(CMS_SignerInfo *si,
|
||||
unsigned char *dig, unsigned int *diglen)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
|
||||
si->signedAttrs, dig, diglen))
|
||||
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)
|
||||
{
|
||||
int r = 0, i;
|
||||
CMS_ReceiptRequest *rr = NULL;
|
||||
CMS_Receipt *rct = NULL;
|
||||
STACK_OF(CMS_SignerInfo) *sis, *osis;
|
||||
CMS_SignerInfo *si, *osi;
|
||||
ASN1_OCTET_STRING *msig, **pcont;
|
||||
ASN1_OBJECT *octype;
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
|
||||
/* Get SignerInfos, also checks SignedData content type */
|
||||
osis = CMS_get0_SignerInfos(req_cms);
|
||||
sis = CMS_get0_SignerInfos(cms);
|
||||
if (!osis || !sis)
|
||||
goto err;
|
||||
|
||||
if (sk_CMS_SignerInfo_num(sis) != 1)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Check receipt content type */
|
||||
if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Extract and decode receipt content */
|
||||
pcont = CMS_get0_content(cms);
|
||||
if (!pcont || !*pcont)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
|
||||
|
||||
if (!rct)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Locate original request */
|
||||
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
|
||||
{
|
||||
osi = sk_CMS_SignerInfo_value(osis, i);
|
||||
if (!ASN1_STRING_cmp(osi->signature,
|
||||
rct->originatorSignatureValue))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == sk_CMS_SignerInfo_num(osis))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
si = sk_CMS_SignerInfo_value(sis, 0);
|
||||
|
||||
/* Get msgSigDigest value and compare */
|
||||
|
||||
msig = CMS_signed_get0_data_by_OBJ(si,
|
||||
OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
|
||||
-3, V_ASN1_OCTET_STRING);
|
||||
|
||||
if (!msig)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!cms_msgSigDigest(osi, dig, &diglen))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (diglen != (unsigned int)msig->length)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||
CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (memcmp(dig, msig->data, diglen))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||
CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Compare content types */
|
||||
|
||||
octype = CMS_signed_get0_data_by_OBJ(osi,
|
||||
OBJ_nid2obj(NID_pkcs9_contentType),
|
||||
-3, V_ASN1_OBJECT);
|
||||
if (!octype)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Compare details in receipt request */
|
||||
|
||||
if (OBJ_cmp(octype, rct->contentType))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Get original receipt request details */
|
||||
|
||||
if (!CMS_get1_ReceiptRequest(osi, &rr))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ASN1_STRING_cmp(rr->signedContentIdentifier,
|
||||
rct->signedContentIdentifier))
|
||||
{
|
||||
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||
CMS_R_CONTENTIDENTIFIER_MISMATCH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
|
||||
err:
|
||||
if (rr)
|
||||
CMS_ReceiptRequest_free(rr);
|
||||
if (rct)
|
||||
M_ASN1_free_of(rct, CMS_Receipt);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
@ -449,6 +449,8 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, size_t keylen);
|
||||
|
||||
int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
|
||||
|
||||
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -65,17 +65,18 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
|
||||
int r = 0, i;
|
||||
BIO *tmpout = NULL;
|
||||
|
||||
if(flags & CMS_TEXT)
|
||||
{
|
||||
if (out == NULL)
|
||||
tmpout = BIO_new(BIO_s_null());
|
||||
else if (flags & CMS_TEXT)
|
||||
tmpout = BIO_new(BIO_s_mem());
|
||||
else
|
||||
tmpout = out;
|
||||
|
||||
if(!tmpout)
|
||||
{
|
||||
CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpout = out;
|
||||
|
||||
/* Read all content through chain to process digest, decrypt etc */
|
||||
for (;;)
|
||||
@ -419,6 +420,17 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||
STACK_OF(X509) *certs,
|
||||
X509_STORE *store, unsigned int flags)
|
||||
{
|
||||
int r;
|
||||
r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
return cms_Receipt_verify(rcms, ocms);
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||
BIO *data, unsigned int flags)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user