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
|
*) Initial support for Cryptographic Message Syntax (aka CMS) based
|
||||||
on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
|
on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
|
||||||
support for data, signedData, compressedData, digestedData and
|
support for data, signedData, compressedData, digestedData and
|
||||||
encryptedData types currently included, more to come. Scripts to
|
encryptedData, envelopedData types included. Scripts to check against
|
||||||
check against RFC4134 examples draft.
|
RFC4134 examples draft and interop and consistency checks of many
|
||||||
|
content types and variants.
|
||||||
[Steve Henson]
|
[Steve Henson]
|
||||||
|
|
||||||
*) Zlib compression BIO. This is a filter BIO which compressed and
|
*) 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_COMPRESS (12 | SMIME_OP)
|
||||||
#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
|
#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
|
||||||
#define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
|
#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 **);
|
int MAIN(int, char **);
|
||||||
|
|
||||||
@ -101,17 +103,17 @@ int MAIN(int argc, char **argv)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
char **args;
|
char **args;
|
||||||
const char *inmode = "r", *outmode = "w";
|
const char *inmode = "r", *outmode = "w";
|
||||||
char *infile = NULL, *outfile = NULL;
|
char *infile = NULL, *outfile = NULL, *rctfile = NULL;
|
||||||
char *signerfile = NULL, *recipfile = NULL;
|
char *signerfile = NULL, *recipfile = NULL;
|
||||||
STACK *sksigners = NULL, *skkeys = NULL;
|
STACK *sksigners = NULL, *skkeys = NULL;
|
||||||
char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
|
char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
|
||||||
const EVP_CIPHER *cipher = NULL;
|
const EVP_CIPHER *cipher = NULL;
|
||||||
CMS_ContentInfo *cms = NULL;
|
CMS_ContentInfo *cms = NULL, *rcms = NULL;
|
||||||
X509_STORE *store = NULL;
|
X509_STORE *store = NULL;
|
||||||
X509 *cert = NULL, *recip = NULL, *signer = NULL;
|
X509 *cert = NULL, *recip = NULL, *signer = NULL;
|
||||||
EVP_PKEY *key = NULL;
|
EVP_PKEY *key = NULL;
|
||||||
STACK_OF(X509) *encerts = NULL, *other = 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 badarg = 0;
|
||||||
int flags = CMS_DETACHED, noout = 0, print = 0;
|
int flags = CMS_DETACHED, noout = 0, print = 0;
|
||||||
int rr_print = 0, rr_allorfirst = -1;
|
int rr_print = 0, rr_allorfirst = -1;
|
||||||
@ -124,7 +126,7 @@ int MAIN(int argc, char **argv)
|
|||||||
int need_rand = 0;
|
int need_rand = 0;
|
||||||
const EVP_MD *sign_md = NULL;
|
const EVP_MD *sign_md = NULL;
|
||||||
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
|
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
|
||||||
int keyform = FORMAT_PEM;
|
int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
char *engine=NULL;
|
char *engine=NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -161,6 +163,14 @@ int MAIN(int argc, char **argv)
|
|||||||
operation = SMIME_RESIGN;
|
operation = SMIME_RESIGN;
|
||||||
else if (!strcmp (*args, "-verify"))
|
else if (!strcmp (*args, "-verify"))
|
||||||
operation = SMIME_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"))
|
else if (!strcmp (*args, "-cmsout"))
|
||||||
operation = SMIME_CMSOUT;
|
operation = SMIME_CMSOUT;
|
||||||
else if (!strcmp (*args, "-data_out"))
|
else if (!strcmp (*args, "-data_out"))
|
||||||
@ -425,6 +435,12 @@ int MAIN(int argc, char **argv)
|
|||||||
goto argerr;
|
goto argerr;
|
||||||
keyform = str2fmt(*++args);
|
keyform = str2fmt(*++args);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (*args, "-rctform"))
|
||||||
|
{
|
||||||
|
if (!args[1])
|
||||||
|
goto argerr;
|
||||||
|
rctformat = str2fmt(*++args);
|
||||||
|
}
|
||||||
else if (!strcmp (*args, "-certfile"))
|
else if (!strcmp (*args, "-certfile"))
|
||||||
{
|
{
|
||||||
if (!args[1])
|
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 (outfile)
|
||||||
{
|
{
|
||||||
if (!(out = BIO_new_file(outfile, outmode)))
|
if (!(out = BIO_new_file(outfile, outmode)))
|
||||||
@ -790,7 +835,7 @@ int MAIN(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operation == SMIME_VERIFY)
|
if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
|
||||||
{
|
{
|
||||||
if (!(store = setup_verify(bio_err, CAfile, CApath)))
|
if (!(store = setup_verify(bio_err, CAfile, CApath)))
|
||||||
goto end;
|
goto end;
|
||||||
@ -1001,6 +1046,16 @@ int MAIN(int argc, char **argv)
|
|||||||
receipt_request_print(bio_err, cms);
|
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
|
else
|
||||||
{
|
{
|
||||||
if (noout)
|
if (noout)
|
||||||
@ -1068,6 +1123,8 @@ end:
|
|||||||
X509_free(signer);
|
X509_free(signer);
|
||||||
EVP_PKEY_free(key);
|
EVP_PKEY_free(key);
|
||||||
CMS_ContentInfo_free(cms);
|
CMS_ContentInfo_free(cms);
|
||||||
|
CMS_ContentInfo_free(rcms);
|
||||||
|
BIO_free(rctin);
|
||||||
BIO_free(in);
|
BIO_free(in);
|
||||||
BIO_free(indata);
|
BIO_free(indata);
|
||||||
BIO_free_all(out);
|
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,
|
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||||
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
|
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);
|
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
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_REVOCATION_CHOICES 132
|
||||||
#define CMS_F_CMS_GET0_SIGNED 133
|
#define CMS_F_CMS_GET0_SIGNED 133
|
||||||
#define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159
|
#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_DECRYPT 134
|
||||||
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135
|
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135
|
||||||
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136
|
#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_CIPHER_PARAMETER_INITIALISATION_ERROR 102
|
||||||
#define CMS_R_CMS_DATAFINAL_ERROR 103
|
#define CMS_R_CMS_DATAFINAL_ERROR 103
|
||||||
#define CMS_R_CMS_LIB 104
|
#define CMS_R_CMS_LIB 104
|
||||||
|
#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170
|
||||||
#define CMS_R_CONTENT_NOT_FOUND 105
|
#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_COMPRESSED_DATA 106
|
||||||
#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107
|
#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107
|
||||||
#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108
|
#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_ERROR 110
|
||||||
#define CMS_R_CTRL_FAILURE 111
|
#define CMS_R_CTRL_FAILURE 111
|
||||||
#define CMS_R_DECRYPT_ERROR 112
|
#define CMS_R_DECRYPT_ERROR 112
|
||||||
|
#define CMS_R_DIGEST_ERROR 161
|
||||||
#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113
|
#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113
|
||||||
#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
|
#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
|
||||||
#define CMS_R_ERROR_SETTING_KEY 115
|
#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_MD_BIO_INIT_ERROR 119
|
||||||
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
|
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
|
||||||
#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121
|
#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_ENCRYPTED_DATA 122
|
||||||
#define CMS_R_NOT_KEK 123
|
#define CMS_R_NOT_KEK 123
|
||||||
#define CMS_R_NOT_KEY_TRANSPORT 124
|
#define CMS_R_NOT_KEY_TRANSPORT 124
|
||||||
#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125
|
#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125
|
||||||
#define CMS_R_NO_CIPHER 126
|
#define CMS_R_NO_CIPHER 126
|
||||||
#define CMS_R_NO_CONTENT 127
|
#define CMS_R_NO_CONTENT 127
|
||||||
|
#define CMS_R_NO_CONTENT_TYPE 173
|
||||||
#define CMS_R_NO_DEFAULT_DIGEST 128
|
#define CMS_R_NO_DEFAULT_DIGEST 128
|
||||||
#define CMS_R_NO_DIGEST_SET 129
|
#define CMS_R_NO_DIGEST_SET 129
|
||||||
#define CMS_R_NO_KEY 130
|
#define CMS_R_NO_KEY 130
|
||||||
#define CMS_R_NO_MATCHING_DIGEST 131
|
#define CMS_R_NO_MATCHING_DIGEST 131
|
||||||
#define CMS_R_NO_MATCHING_RECIPIENT 132
|
#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_PRIVATE_KEY 133
|
||||||
#define CMS_R_NO_PUBLIC_KEY 134
|
#define CMS_R_NO_PUBLIC_KEY 134
|
||||||
|
#define CMS_R_NO_RECEIPT_REQUEST 168
|
||||||
#define CMS_R_NO_SIGNERS 135
|
#define CMS_R_NO_SIGNERS 135
|
||||||
#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136
|
#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_RECIPIENT_ERROR 137
|
||||||
#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138
|
#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138
|
||||||
#define CMS_R_SIGNFINAL_ERROR 139
|
#define CMS_R_SIGNFINAL_ERROR 139
|
||||||
|
@ -371,3 +371,10 @@ ASN1_SEQUENCE(CMS_ReceiptRequest) = {
|
|||||||
ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
|
ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
|
||||||
} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
|
} 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_REVOCATION_CHOICES), "CMS_GET0_REVOCATION_CHOICES"},
|
||||||
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
|
{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_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_DECRYPT), "CMS_RecipientInfo_decrypt"},
|
||||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), "CMS_RECIPIENTINFO_KEKRI_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_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_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_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"},
|
||||||
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), "CMS_RECIPIENTINFO_KTRI_DECRYPT"},
|
{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_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
|
||||||
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"},
|
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"},
|
||||||
{ERR_REASON(CMS_R_CMS_LIB) ,"cms lib"},
|
{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_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_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_ENVELOPED_DATA),"content type not enveloped data"},
|
||||||
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed 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_ERROR) ,"ctrl error"},
|
||||||
{ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"},
|
{ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"},
|
||||||
{ERR_REASON(CMS_R_DECRYPT_ERROR) ,"decrypt error"},
|
{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_GETTING_PUBLIC_KEY),"error getting public key"},
|
||||||
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
|
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
|
||||||
{ERR_REASON(CMS_R_ERROR_SETTING_KEY) ,"error setting key"},
|
{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_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_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
|
||||||
{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest 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_ENCRYPTED_DATA) ,"not encrypted data"},
|
||||||
{ERR_REASON(CMS_R_NOT_KEK) ,"not kek"},
|
{ERR_REASON(CMS_R_NOT_KEK) ,"not kek"},
|
||||||
{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT) ,"not key transport"},
|
{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_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_CIPHER) ,"no cipher"},
|
||||||
{ERR_REASON(CMS_R_NO_CONTENT) ,"no content"},
|
{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_DEFAULT_DIGEST) ,"no default digest"},
|
||||||
{ERR_REASON(CMS_R_NO_DIGEST_SET) ,"no digest set"},
|
{ERR_REASON(CMS_R_NO_DIGEST_SET) ,"no digest set"},
|
||||||
{ERR_REASON(CMS_R_NO_KEY) ,"no key"},
|
{ERR_REASON(CMS_R_NO_KEY) ,"no key"},
|
||||||
{ERR_REASON(CMS_R_NO_MATCHING_DIGEST) ,"no matching digest"},
|
{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_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_PRIVATE_KEY) ,"no private key"},
|
||||||
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public 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_NO_SIGNERS) ,"no signers"},
|
||||||
{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
|
{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_RECIPIENT_ERROR) ,"recipient error"},
|
||||||
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
||||||
{ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"},
|
{ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"},
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
|
DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_Receipt)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||||
|
|
||||||
@ -189,5 +190,161 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
|||||||
*prto = rr->receiptsTo;
|
*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 EVP_CIPHER *cipher,
|
||||||
const unsigned char *key, size_t keylen);
|
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);
|
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -65,18 +65,19 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
|
|||||||
int r = 0, i;
|
int r = 0, i;
|
||||||
BIO *tmpout = NULL;
|
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());
|
tmpout = BIO_new(BIO_s_mem());
|
||||||
if(!tmpout)
|
|
||||||
{
|
|
||||||
CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
tmpout = out;
|
tmpout = out;
|
||||||
|
|
||||||
|
if(!tmpout)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read all content through chain to process digest, decrypt etc */
|
/* Read all content through chain to process digest, decrypt etc */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -419,6 +420,17 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
|||||||
return ret;
|
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,
|
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||||
BIO *data, unsigned int flags)
|
BIO *data, unsigned int flags)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user