mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-28 02:34:40 +00:00
Add libctx support to CMS.
-Public CMS methods that create a CMS_ContentInfo object now have variants that also add a libctx and propq. This includes CMS_ContentInfo_new_with_libctx(), CMS_sign_with_libctx(), CMS_data_create_with_libctx(), CMS_digest_create_with_libctx(), CMS_EncryptedData_encrypt_with_libctx(), CMS_EnvelopedData_create_with_libctx(). -Added CMS_ReceiptRequest_create0_with_libctx(). -Added SMIME_read_CMS_ex() so that a new CMS_ContentInfo object (created using CMS_ContentInfo_new_with_libctx()) can be passed to the read. -d2i_CMS_bio() has been modified so that after it loads the CMS_ContentInfo() it then resolves any subobjects that require the libctx/propq (such as objects containing X509 certificates). Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11884)
This commit is contained in:
parent
82a7b2fb00
commit
c1669f41ea
123
apps/cms.c
123
apps/cms.c
@ -32,9 +32,9 @@ DEFINE_STACK_OF_STRING()
|
||||
static int save_certs(char *signerfile, STACK_OF(X509) *signers);
|
||||
static int cms_cb(int ok, X509_STORE_CTX *ctx);
|
||||
static void receipt_request_print(CMS_ContentInfo *cms);
|
||||
static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
|
||||
*rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
|
||||
*rr_from);
|
||||
static CMS_ReceiptRequest *make_receipt_request(
|
||||
STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
|
||||
STACK_OF(OPENSSL_STRING) *rr_from, OPENSSL_CTX *libctx, const char *propq);
|
||||
static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
|
||||
STACK_OF(OPENSSL_STRING) *param);
|
||||
|
||||
@ -89,7 +89,7 @@ typedef enum OPTION_choice {
|
||||
OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
|
||||
OPT_3DES_WRAP, OPT_WRAP, OPT_ENGINE,
|
||||
OPT_R_ENUM,
|
||||
OPT_PROV_ENUM,
|
||||
OPT_PROV_ENUM, OPT_CONFIG,
|
||||
OPT_V_ENUM,
|
||||
OPT_CIPHER,
|
||||
OPT_ORIGINATOR
|
||||
@ -124,6 +124,7 @@ const OPTIONS cms_options[] = {
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
|
||||
# endif
|
||||
OPT_CONFIG_OPTION,
|
||||
|
||||
OPT_SECTION("Action"),
|
||||
{"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
|
||||
@ -236,8 +237,44 @@ const OPTIONS cms_options[] = {
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static CMS_ContentInfo *load_content_info(int informat, BIO *in, BIO **indata,
|
||||
const char *name,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *ret, *ci;
|
||||
|
||||
ret = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (ret == NULL) {
|
||||
BIO_printf(bio_err, "Error allocating CMS_contentinfo\n");
|
||||
return NULL;
|
||||
}
|
||||
switch (informat) {
|
||||
case FORMAT_SMIME:
|
||||
ci = SMIME_read_CMS_ex(in, indata, &ret);
|
||||
break;
|
||||
case FORMAT_PEM:
|
||||
ci = PEM_read_bio_CMS(in, &ret, NULL, NULL);
|
||||
break;
|
||||
case FORMAT_ASN1:
|
||||
ci = d2i_CMS_bio(in, &ret);
|
||||
break;
|
||||
default:
|
||||
BIO_printf(bio_err, "Bad input format for %s\n", name);
|
||||
goto err;
|
||||
}
|
||||
if (ci == NULL) {
|
||||
BIO_printf(bio_err, "Error reading %s Content Info\n", name);
|
||||
goto err;
|
||||
}
|
||||
return ret;
|
||||
err:
|
||||
CMS_ContentInfo_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cms_main(int argc, char **argv)
|
||||
{
|
||||
CONF *conf = NULL;
|
||||
ASN1_OBJECT *econtent_type = NULL;
|
||||
BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
|
||||
CMS_ContentInfo *cms = NULL, *rcms = NULL;
|
||||
@ -270,6 +307,8 @@ int cms_main(int argc, char **argv)
|
||||
long ltmp;
|
||||
const char *mime_eol = "\n";
|
||||
OPTION_CHOICE o;
|
||||
OPENSSL_CTX *libctx = app_get0_libctx();
|
||||
const char *propq = app_get0_propq();
|
||||
|
||||
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
|
||||
return 1;
|
||||
@ -417,14 +456,14 @@ int cms_main(int argc, char **argv)
|
||||
rr_allorfirst = 1;
|
||||
break;
|
||||
case OPT_RCTFORM:
|
||||
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)
|
||||
if (rctformat == FORMAT_ASN1) {
|
||||
if (!opt_format(opt_arg(),
|
||||
OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
|
||||
goto opthelp;
|
||||
} else {
|
||||
rcms = load_content_info(rctformat, rctin, NULL, "recipient",
|
||||
libctx, propq);
|
||||
}
|
||||
break;
|
||||
case OPT_CERTFILE:
|
||||
certfile = opt_arg();
|
||||
@ -639,6 +678,11 @@ int cms_main(int argc, char **argv)
|
||||
if (!opt_provider(o))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_CONFIG:
|
||||
conf = app_load_config_modules(opt_arg());
|
||||
if (conf == NULL)
|
||||
goto end;
|
||||
break;
|
||||
case OPT_3DES_WRAP:
|
||||
# ifndef OPENSSL_NO_DES
|
||||
wrap_cipher = EVP_des_ede3_wrap();
|
||||
@ -830,21 +874,9 @@ int cms_main(int argc, char **argv)
|
||||
goto end;
|
||||
|
||||
if (operation & SMIME_IP) {
|
||||
if (informat == FORMAT_SMIME) {
|
||||
cms = SMIME_read_CMS(in, &indata);
|
||||
} else if (informat == FORMAT_PEM) {
|
||||
cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
|
||||
} else if (informat == FORMAT_ASN1) {
|
||||
cms = d2i_CMS_bio(in, NULL);
|
||||
} else {
|
||||
BIO_printf(bio_err, "Bad input format for CMS file\n");
|
||||
cms = load_content_info(informat, in, &indata, "SMIME", libctx, propq);
|
||||
if (cms == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cms == NULL) {
|
||||
BIO_printf(bio_err, "Error reading S/MIME message\n");
|
||||
goto end;
|
||||
}
|
||||
if (contfile != NULL) {
|
||||
BIO_free(indata);
|
||||
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
|
||||
@ -872,21 +904,10 @@ int cms_main(int argc, char **argv)
|
||||
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");
|
||||
rcms = load_content_info(rctformat, rctin, NULL, "recipient", libctx,
|
||||
propq);
|
||||
if (rcms == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rcms == NULL) {
|
||||
BIO_printf(bio_err, "Error reading receipt\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
out = bio_open_default(outfile, 'w', outformat);
|
||||
@ -905,15 +926,15 @@ int cms_main(int argc, char **argv)
|
||||
ret = 3;
|
||||
|
||||
if (operation == SMIME_DATA_CREATE) {
|
||||
cms = CMS_data_create(in, flags);
|
||||
cms = CMS_data_create_with_libctx(in, flags, libctx, propq);
|
||||
} else if (operation == SMIME_DIGEST_CREATE) {
|
||||
cms = CMS_digest_create(in, sign_md, flags);
|
||||
cms = CMS_digest_create_with_libctx(in, sign_md, flags, libctx, propq);
|
||||
} else if (operation == SMIME_COMPRESS) {
|
||||
cms = CMS_compress(in, -1, flags);
|
||||
} else if (operation == SMIME_ENCRYPT) {
|
||||
int i;
|
||||
flags |= CMS_PARTIAL;
|
||||
cms = CMS_encrypt(NULL, in, cipher, flags);
|
||||
cms = CMS_encrypt_with_libctx(NULL, in, cipher, flags, libctx, propq);
|
||||
if (cms == NULL)
|
||||
goto end;
|
||||
for (i = 0; i < sk_X509_num(encerts); i++) {
|
||||
@ -978,8 +999,9 @@ int cms_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
} else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
|
||||
cms = CMS_EncryptedData_encrypt(in, cipher,
|
||||
secret_key, secret_keylen, flags);
|
||||
cms = CMS_EncryptedData_encrypt_with_libctx(in, cipher, secret_key,
|
||||
secret_keylen, flags,
|
||||
libctx, propq);
|
||||
|
||||
} else if (operation == SMIME_SIGN_RECEIPT) {
|
||||
CMS_ContentInfo *srcms = NULL;
|
||||
@ -1007,14 +1029,15 @@ int cms_main(int argc, char **argv)
|
||||
flags |= CMS_STREAM;
|
||||
}
|
||||
flags |= CMS_PARTIAL;
|
||||
cms = CMS_sign(NULL, NULL, other, in, flags);
|
||||
cms = CMS_sign_with_libctx(NULL, NULL, other, in, flags, libctx, propq);
|
||||
if (cms == NULL)
|
||||
goto end;
|
||||
if (econtent_type != NULL)
|
||||
CMS_set1_eContentType(cms, econtent_type);
|
||||
|
||||
if (rr_to != NULL) {
|
||||
rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
|
||||
rr = make_receipt_request(rr_to, rr_allorfirst, rr_from, libctx,
|
||||
propq);
|
||||
if (rr == NULL) {
|
||||
BIO_puts(bio_err,
|
||||
"Signed Receipt Request Creation Error\n");
|
||||
@ -1231,6 +1254,7 @@ int cms_main(int argc, char **argv)
|
||||
BIO_free(indata);
|
||||
BIO_free_all(out);
|
||||
OPENSSL_free(passin);
|
||||
NCONF_free(conf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1367,9 +1391,10 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
|
||||
*rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
|
||||
*rr_from)
|
||||
static CMS_ReceiptRequest *make_receipt_request(
|
||||
STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
|
||||
STACK_OF(OPENSSL_STRING) *rr_from,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
|
||||
CMS_ReceiptRequest *rr;
|
||||
@ -1383,8 +1408,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
|
||||
} else {
|
||||
rct_from = NULL;
|
||||
}
|
||||
rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
|
||||
rct_to);
|
||||
rr = CMS_ReceiptRequest_create0_with_libctx(NULL, -1, rr_allorfirst,
|
||||
rct_from, rct_to, libctx, propq);
|
||||
return rr;
|
||||
err:
|
||||
sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
|
||||
|
@ -21,10 +21,12 @@
|
||||
|
||||
/* CMS CompressedData Utilities */
|
||||
|
||||
CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
|
||||
CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
CMS_CompressedData *cd;
|
||||
|
||||
/*
|
||||
* Will need something cleverer if there is ever more than one
|
||||
* compression algorithm or parameters have some meaning...
|
||||
@ -34,7 +36,7 @@ CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
|
||||
CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
cms = CMS_ContentInfo_new();
|
||||
cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -64,6 +66,7 @@ BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_CompressedData *cd;
|
||||
const ASN1_OBJECT *compoid;
|
||||
|
||||
if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
|
||||
CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
|
||||
CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
|
||||
|
@ -17,11 +17,13 @@
|
||||
|
||||
/* CMS DigestedData Utilities */
|
||||
|
||||
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
|
||||
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
CMS_DigestedData *dd;
|
||||
cms = CMS_ContentInfo_new();
|
||||
|
||||
cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -47,9 +49,9 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
|
||||
|
||||
BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_DigestedData *dd;
|
||||
dd = cms->d.digestedData;
|
||||
return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
|
||||
CMS_DigestedData *dd = cms->d.digestedData;
|
||||
|
||||
return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm, cms_get0_cmsctx(cms));
|
||||
}
|
||||
|
||||
int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify)
|
||||
|
@ -20,19 +20,19 @@
|
||||
|
||||
/* Return BIO based on EncryptedContentInfo and key */
|
||||
|
||||
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
||||
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
|
||||
const CMS_CTX *cms_ctx)
|
||||
{
|
||||
BIO *b;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
const EVP_CIPHER *ciph;
|
||||
EVP_CIPHER *fetched_ciph = NULL;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
|
||||
unsigned char *tkey = NULL;
|
||||
int len;
|
||||
size_t tkeylen = 0;
|
||||
|
||||
int ok = 0;
|
||||
|
||||
int enc, keep_key = 0;
|
||||
|
||||
enc = ec->cipher ? 1 : 0;
|
||||
@ -46,26 +46,29 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
||||
BIO_get_cipher_ctx(b, &ctx);
|
||||
|
||||
if (enc) {
|
||||
ciph = ec->cipher;
|
||||
cipher = ec->cipher;
|
||||
/*
|
||||
* If not keeping key set cipher to NULL so subsequent calls decrypt.
|
||||
*/
|
||||
if (ec->key)
|
||||
if (ec->key != NULL)
|
||||
ec->cipher = NULL;
|
||||
} else {
|
||||
ciph = EVP_get_cipherbyobj(calg->algorithm);
|
||||
|
||||
if (!ciph) {
|
||||
cipher = EVP_get_cipherbyobj(calg->algorithm);
|
||||
}
|
||||
if (cipher != NULL) {
|
||||
fetched_ciph = EVP_CIPHER_fetch(cms_ctx->libctx, EVP_CIPHER_name(cipher),
|
||||
cms_ctx->propq);
|
||||
if (fetched_ciph == NULL) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
|
||||
if (EVP_CipherInit_ex(ctx, fetched_ciph, NULL, NULL, NULL, enc) <= 0) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||
CMS_R_CIPHER_INITIALISATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
EVP_CIPHER_free(fetched_ciph);
|
||||
|
||||
if (enc) {
|
||||
int ivlen;
|
||||
@ -73,7 +76,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
||||
/* Generate a random IV if we need one */
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||
if (ivlen > 0) {
|
||||
if (RAND_bytes(iv, ivlen) <= 0)
|
||||
if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0)
|
||||
goto err;
|
||||
piv = iv;
|
||||
}
|
||||
@ -169,7 +172,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
||||
|
||||
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, size_t keylen)
|
||||
const unsigned char *key, size_t keylen,
|
||||
const CMS_CTX *cms_ctx)
|
||||
{
|
||||
ec->cipher = cipher;
|
||||
if (key) {
|
||||
@ -180,7 +184,7 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
memcpy(ec->key, key, keylen);
|
||||
}
|
||||
ec->keylen = keylen;
|
||||
if (cipher)
|
||||
if (cipher != NULL)
|
||||
ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||
return 1;
|
||||
}
|
||||
@ -189,6 +193,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
|
||||
if (!key || !keylen) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
|
||||
return 0;
|
||||
@ -206,7 +211,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||
return 0;
|
||||
}
|
||||
ec = cms->d.encryptedData->encryptedContentInfo;
|
||||
return cms_EncryptedContent_init(ec, ciph, key, keylen);
|
||||
return cms_EncryptedContent_init(ec, ciph, key, keylen, cms_get0_cmsctx(cms));
|
||||
}
|
||||
|
||||
BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms)
|
||||
@ -214,5 +219,6 @@ BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms)
|
||||
CMS_EncryptedData *enc = cms->d.encryptedData;
|
||||
if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
|
||||
enc->version = 2;
|
||||
return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
|
||||
return cms_EncryptedContent_init_bio(enc->encryptedContentInfo,
|
||||
cms_get0_cmsctx(cms));
|
||||
}
|
||||
|
@ -14,9 +14,10 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "cms_local.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/x509.h"
|
||||
#include "cms_local.h"
|
||||
|
||||
DEFINE_STACK_OF(CMS_RecipientInfo)
|
||||
DEFINE_STACK_OF(CMS_RevocationInfoChoice)
|
||||
@ -94,6 +95,37 @@ STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
|
||||
return env->recipientInfos;
|
||||
}
|
||||
|
||||
void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms)
|
||||
{
|
||||
int i;
|
||||
CMS_RecipientInfo *ri;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms);
|
||||
|
||||
for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
|
||||
ri = sk_CMS_RecipientInfo_value(rinfos, i);
|
||||
if (ri != NULL) {
|
||||
switch (ri->type) {
|
||||
case CMS_RECIPINFO_AGREE:
|
||||
ri->d.kari->cms_ctx = ctx;
|
||||
break;
|
||||
case CMS_RECIPINFO_TRANS:
|
||||
ri->d.ktri->cms_ctx = ctx;
|
||||
x509_set0_libctx(ri->d.ktri->recip, ctx->libctx, ctx->propq);
|
||||
break;
|
||||
case CMS_RECIPINFO_KEK:
|
||||
ri->d.kekri->cms_ctx = ctx;
|
||||
break;
|
||||
case CMS_RECIPINFO_PASS:
|
||||
ri->d.pwri->cms_ctx = ctx;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
|
||||
{
|
||||
return ri->type;
|
||||
@ -108,26 +140,35 @@ EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
|
||||
OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
CMS_EnvelopedData *env;
|
||||
cms = CMS_ContentInfo_new();
|
||||
|
||||
cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (cms == NULL)
|
||||
goto merr;
|
||||
env = cms_enveloped_data_init(cms);
|
||||
if (env == NULL)
|
||||
goto merr;
|
||||
if (!cms_EncryptedContent_init(env->encryptedContentInfo,
|
||||
cipher, NULL, 0))
|
||||
|
||||
if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, 0,
|
||||
cms_get0_cmsctx(cms)))
|
||||
goto merr;
|
||||
return cms;
|
||||
merr:
|
||||
CMS_ContentInfo_free(cms);
|
||||
CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
|
||||
CMSerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
|
||||
{
|
||||
return CMS_EnvelopedData_create_with_libctx(cipher, NULL, NULL);
|
||||
}
|
||||
|
||||
int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
|
||||
{
|
||||
CMS_EnvelopedData *env = NULL;
|
||||
@ -174,7 +215,8 @@ int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
|
||||
/* Initialise a ktri based on passed certificate and key */
|
||||
|
||||
static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
EVP_PKEY *pk, unsigned int flags)
|
||||
EVP_PKEY *pk, unsigned int flags,
|
||||
const CMS_CTX *ctx)
|
||||
{
|
||||
CMS_KeyTransRecipientInfo *ktri;
|
||||
int idtype;
|
||||
@ -185,6 +227,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
ri->type = CMS_RECIPINFO_TRANS;
|
||||
|
||||
ktri = ri->d.ktri;
|
||||
ktri->cms_ctx = ctx;
|
||||
|
||||
if (flags & CMS_USE_KEYID) {
|
||||
ktri->version = 2;
|
||||
@ -199,7 +242,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
* structure.
|
||||
*/
|
||||
|
||||
if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
|
||||
if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
|
||||
return 0;
|
||||
|
||||
X509_up_ref(recip);
|
||||
@ -209,7 +252,8 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
ktri->recip = recip;
|
||||
|
||||
if (flags & CMS_KEY_PARAM) {
|
||||
ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey,
|
||||
ctx->propq);
|
||||
if (ktri->pctx == NULL)
|
||||
return 0;
|
||||
if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
|
||||
@ -230,6 +274,8 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
|
||||
CMS_RecipientInfo *ri = NULL;
|
||||
CMS_EnvelopedData *env;
|
||||
EVP_PKEY *pk = NULL;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
env = cms_get0_enveloped(cms);
|
||||
if (!env)
|
||||
goto err;
|
||||
@ -248,12 +294,13 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
|
||||
switch (cms_pkey_get_ri_type(pk)) {
|
||||
|
||||
case CMS_RECIPINFO_TRANS:
|
||||
if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
|
||||
if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx))
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case CMS_RECIPINFO_AGREE:
|
||||
if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originatorPrivKey, flags))
|
||||
if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator,
|
||||
originatorPrivKey, flags, ctx))
|
||||
goto err;
|
||||
break;
|
||||
|
||||
@ -352,6 +399,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
|
||||
EVP_PKEY_CTX *pctx;
|
||||
unsigned char *ek = NULL;
|
||||
size_t eklen;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
@ -368,7 +416,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
|
||||
if (!cms_env_asn1_ctrl(ri, 0))
|
||||
goto err;
|
||||
} else {
|
||||
pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
|
||||
pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey, ctx->propq);
|
||||
if (pctx == NULL)
|
||||
return 0;
|
||||
|
||||
@ -405,7 +453,6 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
|
||||
ktri->pctx = NULL;
|
||||
OPENSSL_free(ek);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* Decrypt content key from KTRI */
|
||||
@ -419,7 +466,10 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
||||
size_t eklen;
|
||||
int ret = 0;
|
||||
size_t fixlen = 0;
|
||||
EVP_CIPHER *ciph = NULL;
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
if (ktri->pkey == NULL) {
|
||||
@ -430,19 +480,21 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
||||
if (cms->d.envelopedData->encryptedContentInfo->havenocert
|
||||
&& !cms->d.envelopedData->encryptedContentInfo->debug) {
|
||||
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
|
||||
const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
|
||||
const char *name = OBJ_nid2sn(OBJ_obj2nid(calg->algorithm));
|
||||
|
||||
ciph = EVP_CIPHER_fetch(ctx->libctx, name, ctx->propq);
|
||||
if (ciph == NULL) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fixlen = EVP_CIPHER_key_length(ciph);
|
||||
EVP_CIPHER_free(ciph);
|
||||
}
|
||||
|
||||
ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
|
||||
if (ktri->pctx == NULL)
|
||||
return 0;
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
|
||||
goto err;
|
||||
@ -627,7 +679,6 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
|
||||
err:
|
||||
M_ASN1_free_of(ri, CMS_RecipientInfo);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
|
||||
@ -679,20 +730,24 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen)
|
||||
static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx)
|
||||
{
|
||||
const char *alg = NULL;
|
||||
|
||||
switch(keylen) {
|
||||
case 16:
|
||||
return EVP_aes_128_wrap();
|
||||
|
||||
alg = "AES-128-WRAP";
|
||||
break;
|
||||
case 24:
|
||||
return EVP_aes_192_wrap();
|
||||
|
||||
alg = "AES-192-WRAP";
|
||||
break;
|
||||
case 32:
|
||||
return EVP_aes_256_wrap();
|
||||
alg = "AES-256-WRAP";
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return EVP_CIPHER_fetch(ctx->libctx, alg, ctx->propq);
|
||||
}
|
||||
|
||||
|
||||
@ -706,9 +761,10 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
|
||||
unsigned char *wkey = NULL;
|
||||
int wkeylen;
|
||||
int r = 0;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
int outlen = 0;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
@ -719,7 +775,7 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
|
||||
return 0;
|
||||
}
|
||||
|
||||
cipher = cms_get_key_wrap_cipher(kekri->keylen);
|
||||
cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
|
||||
if (cipher == NULL) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH);
|
||||
goto err;
|
||||
@ -756,12 +812,12 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
|
||||
r = 1;
|
||||
|
||||
err:
|
||||
EVP_CIPHER_free(cipher);
|
||||
if (!r)
|
||||
OPENSSL_free(wkey);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
/* Decrypt content key in KEK recipient info */
|
||||
@ -774,9 +830,10 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
|
||||
unsigned char *ukey = NULL;
|
||||
int ukeylen;
|
||||
int r = 0, wrap_nid;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
int outlen = 0;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
@ -802,7 +859,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
|
||||
goto err;
|
||||
}
|
||||
|
||||
cipher = cms_get_key_wrap_cipher(kekri->keylen);
|
||||
cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
|
||||
if (cipher == NULL) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH);
|
||||
goto err;
|
||||
@ -836,12 +893,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
|
||||
r = 1;
|
||||
|
||||
err:
|
||||
EVP_CIPHER_free(cipher);
|
||||
if (!r)
|
||||
OPENSSL_free(ukey);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
|
||||
@ -951,7 +1008,7 @@ static void cms_env_set_version(CMS_EnvelopedData *env)
|
||||
static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
BIO *contentBio = cms_EncryptedContent_init_bio(ec);
|
||||
BIO *contentBio = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
|
||||
if (contentBio == NULL)
|
||||
@ -986,7 +1043,7 @@ static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms)
|
||||
/* Get BIO first to set up key */
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
ret = cms_EncryptedContent_init_bio(ec);
|
||||
ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
|
||||
|
||||
/* If error end of processing */
|
||||
if (!ret)
|
||||
@ -1051,7 +1108,8 @@ int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
|
||||
if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
|
||||
int i, r;
|
||||
|
||||
i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r);
|
||||
i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED,
|
||||
ri_type, &r);
|
||||
if (i > 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -15,9 +15,10 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/ess.h>
|
||||
#include "cms_local.h"
|
||||
#include "crypto/ess.h"
|
||||
#include "crypto/cms.h"
|
||||
#include "crypto/x509.h"
|
||||
#include "cms_local.h"
|
||||
|
||||
DEFINE_STACK_OF(GENERAL_NAMES)
|
||||
DEFINE_STACK_OF(CMS_SignerInfo)
|
||||
@ -119,11 +120,10 @@ int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain)
|
||||
return ret;
|
||||
}
|
||||
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES)
|
||||
*receiptList, STACK_OF(GENERAL_NAMES)
|
||||
*receiptsTo)
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0_with_libctx(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ReceiptRequest *rr;
|
||||
|
||||
@ -135,14 +135,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
else {
|
||||
if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
|
||||
goto merr;
|
||||
if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
|
||||
if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
|
||||
rr->receiptsTo = receiptsTo;
|
||||
|
||||
if (receiptList) {
|
||||
if (receiptList != NULL) {
|
||||
rr->receiptsFrom->type = 1;
|
||||
rr->receiptsFrom->d.receiptList = receiptList;
|
||||
} else {
|
||||
@ -153,7 +153,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
return rr;
|
||||
|
||||
merr:
|
||||
CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
|
||||
CMSerr(0, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
CMS_ReceiptRequest_free(rr);
|
||||
@ -161,6 +161,15 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
|
||||
}
|
||||
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo)
|
||||
{
|
||||
return CMS_ReceiptRequest_create0_with_libctx(id, idlen, allorfirst,
|
||||
receiptList, receiptsTo,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
|
||||
{
|
||||
unsigned char *rrder = NULL;
|
||||
@ -192,20 +201,20 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||
STACK_OF(GENERAL_NAMES) **plist,
|
||||
STACK_OF(GENERAL_NAMES) **prto)
|
||||
{
|
||||
if (pcid)
|
||||
if (pcid != NULL)
|
||||
*pcid = rr->signedContentIdentifier;
|
||||
if (rr->receiptsFrom->type == 0) {
|
||||
if (pallorfirst)
|
||||
if (pallorfirst != NULL)
|
||||
*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
|
||||
if (plist)
|
||||
if (plist != NULL)
|
||||
*plist = NULL;
|
||||
} else {
|
||||
if (pallorfirst)
|
||||
if (pallorfirst != NULL)
|
||||
*pallorfirst = -1;
|
||||
if (plist)
|
||||
if (plist != NULL)
|
||||
*plist = rr->receiptsFrom->d.receiptList;
|
||||
}
|
||||
if (prto)
|
||||
if (prto != NULL)
|
||||
*prto = rr->receiptsTo;
|
||||
}
|
||||
|
||||
@ -214,13 +223,13 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||
static int cms_msgSigDigest(CMS_SignerInfo *si,
|
||||
unsigned char *dig, unsigned int *diglen)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
|
||||
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))
|
||||
if (!asn1_item_digest_with_libctx(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
|
||||
si->signedAttrs, dig, diglen,
|
||||
si->cms_ctx->libctx, si->cms_ctx->propq))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -35,7 +35,12 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
|
||||
|
||||
CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
|
||||
{
|
||||
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
|
||||
CMS_ContentInfo *ci;
|
||||
|
||||
ci = ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
|
||||
if (ci != NULL && cms != NULL)
|
||||
cms_resolve_libctx(ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
|
||||
@ -71,19 +76,33 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
|
||||
STACK_OF(X509_ALGOR) *mdalgs;
|
||||
int ctype_nid = OBJ_obj2nid(cms->contentType);
|
||||
int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
if (ctype_nid == NID_pkcs7_signed)
|
||||
mdalgs = cms->d.signedData->digestAlgorithms;
|
||||
else
|
||||
mdalgs = NULL;
|
||||
|
||||
return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
|
||||
ctype_nid, econt_nid, mdalgs,
|
||||
ASN1_ITEM_rptr(CMS_ContentInfo));
|
||||
return SMIME_write_ASN1_with_libctx(bio, (ASN1_VALUE *)cms, data, flags,
|
||||
ctype_nid, econt_nid, mdalgs,
|
||||
ASN1_ITEM_rptr(CMS_ContentInfo),
|
||||
cms_ctx_get0_libctx(ctx),
|
||||
cms_ctx_get0_propq(ctx));
|
||||
}
|
||||
|
||||
CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **cms)
|
||||
{
|
||||
CMS_ContentInfo *ci;
|
||||
|
||||
ci = (CMS_ContentInfo *)SMIME_read_ASN1_ex(bio, bcont,
|
||||
ASN1_ITEM_rptr(CMS_ContentInfo),
|
||||
(ASN1_VALUE **)cms);
|
||||
if (ci != NULL && cms != NULL)
|
||||
cms_resolve_libctx(ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
|
||||
{
|
||||
return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
|
||||
ASN1_ITEM_rptr
|
||||
(CMS_ContentInfo));
|
||||
return SMIME_read_CMS_ex(bio, bcont, NULL);
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
|
||||
ASN1_INTEGER **sno)
|
||||
{
|
||||
CMS_OriginatorIdentifierOrKey *oik;
|
||||
|
||||
if (ri->type != CMS_RECIPINFO_AGREE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
|
||||
CMS_R_NOT_KEY_AGREEMENT);
|
||||
@ -101,6 +102,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
|
||||
int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
|
||||
{
|
||||
CMS_OriginatorIdentifierOrKey *oik;
|
||||
|
||||
if (ri->type != CMS_RECIPINFO_AGREE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
|
||||
CMS_R_NOT_KEY_AGREEMENT);
|
||||
@ -121,6 +123,7 @@ int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
|
||||
X509_NAME **issuer, ASN1_INTEGER **sno)
|
||||
{
|
||||
CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
|
||||
|
||||
if (rid->type == CMS_REK_ISSUER_SERIAL) {
|
||||
if (issuer)
|
||||
*issuer = rid->d.issuerAndSerialNumber->issuer;
|
||||
@ -152,6 +155,7 @@ int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
|
||||
X509 *cert)
|
||||
{
|
||||
CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
|
||||
|
||||
if (rid->type == CMS_REK_ISSUER_SERIAL)
|
||||
return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
|
||||
else if (rid->type == CMS_REK_KEYIDENTIFIER)
|
||||
@ -170,7 +174,8 @@ int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, EVP_PKEY *p
|
||||
if (pk == NULL)
|
||||
return 1;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(pk, NULL);
|
||||
pctx = EVP_PKEY_CTX_new_from_pkey(kari->cms_ctx->libctx, pk,
|
||||
kari->cms_ctx->propq);
|
||||
if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
|
||||
goto err;
|
||||
|
||||
@ -215,6 +220,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
|
||||
int rv = 0;
|
||||
unsigned char *out = NULL;
|
||||
int outlen;
|
||||
|
||||
keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
|
||||
if (keklen > EVP_MAX_KEY_LENGTH)
|
||||
return 0;
|
||||
@ -303,8 +309,9 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *ekey = NULL;
|
||||
int rv = 0;
|
||||
const CMS_CTX *ctx = kari->cms_ctx;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(pk, NULL);
|
||||
pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pk, ctx->propq);
|
||||
if (pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_keygen_init(pctx) <= 0)
|
||||
@ -312,7 +319,7 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
|
||||
if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
|
||||
goto err;
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
pctx = EVP_PKEY_CTX_new(ekey, NULL);
|
||||
pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ekey, ctx->propq);
|
||||
if (pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_derive_init(pctx) <= 0)
|
||||
@ -327,12 +334,14 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
|
||||
}
|
||||
|
||||
/* Set originator private key and initialise context based on it */
|
||||
static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *originatorPrivKey )
|
||||
static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
|
||||
EVP_PKEY *originatorPrivKey )
|
||||
{
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
int rv = 0;
|
||||
const CMS_CTX *ctx = kari->cms_ctx;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new(originatorPrivKey, NULL);
|
||||
pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, originatorPrivKey, ctx->propq);
|
||||
if (pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_derive_init(pctx) <= 0)
|
||||
@ -348,18 +357,22 @@ static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
|
||||
|
||||
/* Initialise a kari based on passed certificate and key */
|
||||
|
||||
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 * originator, EVP_PKEY *originatorPrivKey, unsigned int flags)
|
||||
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
EVP_PKEY *recipPubKey, X509 *originator,
|
||||
EVP_PKEY *originatorPrivKey, unsigned int flags,
|
||||
const CMS_CTX *ctx)
|
||||
{
|
||||
CMS_KeyAgreeRecipientInfo *kari;
|
||||
CMS_RecipientEncryptedKey *rek = NULL;
|
||||
|
||||
ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
|
||||
if (!ri->d.kari)
|
||||
if (ri->d.kari == NULL)
|
||||
return 0;
|
||||
ri->type = CMS_RECIPINFO_AGREE;
|
||||
|
||||
kari = ri->d.kari;
|
||||
kari->version = 3;
|
||||
kari->cms_ctx = ctx;
|
||||
|
||||
rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
|
||||
if (rek == NULL)
|
||||
@ -419,8 +432,11 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *r
|
||||
static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
|
||||
const EVP_CIPHER *cipher)
|
||||
{
|
||||
const CMS_CTX *cms_ctx = kari->cms_ctx;
|
||||
EVP_CIPHER_CTX *ctx = kari->ctx;
|
||||
const EVP_CIPHER *kekcipher;
|
||||
EVP_CIPHER *fetched_kekcipher;
|
||||
const char *kekcipher_name;
|
||||
int keylen;
|
||||
int ret;
|
||||
|
||||
@ -444,8 +460,8 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
|
||||
if (kekcipher != NULL) {
|
||||
if (EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
|
||||
return 0;
|
||||
|
||||
return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
|
||||
kekcipher_name = EVP_CIPHER_name(kekcipher);
|
||||
goto enc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,16 +471,23 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
|
||||
*/
|
||||
#ifndef OPENSSL_NO_DES
|
||||
if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
|
||||
kekcipher = EVP_des_ede3_wrap();
|
||||
kekcipher_name = SN_id_smime_alg_CMS3DESwrap;
|
||||
else
|
||||
#endif
|
||||
if (keylen <= 16)
|
||||
kekcipher = EVP_aes_128_wrap();
|
||||
kekcipher_name = SN_id_aes128_wrap;
|
||||
else if (keylen <= 24)
|
||||
kekcipher = EVP_aes_192_wrap();
|
||||
kekcipher_name = SN_id_aes192_wrap;
|
||||
else
|
||||
kekcipher = EVP_aes_256_wrap();
|
||||
return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
|
||||
kekcipher_name = SN_id_aes256_wrap;
|
||||
enc:
|
||||
fetched_kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, kekcipher_name,
|
||||
cms_ctx->propq);
|
||||
if (fetched_kekcipher == NULL)
|
||||
return 0;
|
||||
ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL);
|
||||
EVP_CIPHER_free(fetched_kekcipher);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Encrypt content key in key agreement recipient info */
|
||||
@ -542,5 +565,4 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
@ -14,24 +14,118 @@
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/cms.h>
|
||||
#include "crypto/x509.h"
|
||||
#include "cms_local.h"
|
||||
|
||||
static STACK_OF(CMS_CertificateChoices)
|
||||
**cms_get0_certificate_choices(CMS_ContentInfo *cms);
|
||||
|
||||
DEFINE_STACK_OF(CMS_RevocationInfoChoice)
|
||||
DEFINE_STACK_OF(X509)
|
||||
DEFINE_STACK_OF(X509_CRL)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
|
||||
IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
|
||||
|
||||
CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a,
|
||||
const unsigned char **in, long len)
|
||||
{
|
||||
CMS_ContentInfo *ci;
|
||||
|
||||
ci = (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
|
||||
(CMS_ContentInfo_it()));
|
||||
if (ci != NULL && a != NULL)
|
||||
cms_resolve_libctx(ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out)
|
||||
{
|
||||
return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it()));
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_ContentInfo_new_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *ci;
|
||||
|
||||
ci = (CMS_ContentInfo *)ASN1_item_new(ASN1_ITEM_rptr(CMS_ContentInfo));
|
||||
if (ci != NULL) {
|
||||
ci->ctx.libctx = libctx;
|
||||
ci->ctx.propq = NULL;
|
||||
if (propq != NULL) {
|
||||
ci->ctx.propq = OPENSSL_strdup(propq);
|
||||
if (ci->ctx.propq == NULL) {
|
||||
CMS_ContentInfo_free(ci);
|
||||
ci = NULL;
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ci;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_ContentInfo_new(void)
|
||||
{
|
||||
return CMS_ContentInfo_new_with_libctx(NULL, NULL);
|
||||
}
|
||||
|
||||
void CMS_ContentInfo_free(CMS_ContentInfo *cms)
|
||||
{
|
||||
if (cms != NULL) {
|
||||
OPENSSL_free(cms->ctx.propq);
|
||||
ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo));
|
||||
}
|
||||
}
|
||||
|
||||
const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms)
|
||||
{
|
||||
return cms != NULL ? &cms->ctx : NULL;
|
||||
}
|
||||
|
||||
OPENSSL_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx)
|
||||
{
|
||||
return ctx->libctx;
|
||||
}
|
||||
|
||||
const char *cms_ctx_get0_propq(const CMS_CTX *ctx)
|
||||
{
|
||||
return ctx->propq;
|
||||
}
|
||||
|
||||
void cms_resolve_libctx(CMS_ContentInfo *ci)
|
||||
{
|
||||
int i;
|
||||
CMS_CertificateChoices *cch;
|
||||
STACK_OF(CMS_CertificateChoices) **pcerts;
|
||||
const CMS_CTX *ctx;
|
||||
|
||||
if (ci == NULL)
|
||||
return;
|
||||
|
||||
ctx = cms_get0_cmsctx(ci);
|
||||
cms_SignerInfos_set_cmsctx(ci);
|
||||
cms_RecipientInfos_set_cmsctx(ci);
|
||||
|
||||
pcerts = cms_get0_certificate_choices(ci);
|
||||
if (pcerts != NULL) {
|
||||
for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
|
||||
cch = sk_CMS_CertificateChoices_value(*pcerts, i);
|
||||
if (cch->type == CMS_CERTCHOICE_CERT)
|
||||
x509_set0_libctx(cch->d.certificate, ctx->libctx, ctx->propq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
|
||||
{
|
||||
return cms->contentType;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *cms_Data_create(void)
|
||||
CMS_ContentInfo *cms_Data_create(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
cms = CMS_ContentInfo_new();
|
||||
CMS_ContentInfo *cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
|
||||
if (cms != NULL) {
|
||||
cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||
/* Never detached */
|
||||
@ -295,14 +389,18 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached)
|
||||
|
||||
/* Create a digest BIO from an X509_ALGOR structure */
|
||||
|
||||
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
|
||||
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
|
||||
const CMS_CTX *ctx)
|
||||
{
|
||||
BIO *mdbio = NULL;
|
||||
const ASN1_OBJECT *digestoid;
|
||||
const EVP_MD *digest;
|
||||
EVP_MD *digest = NULL;
|
||||
const char *alg;
|
||||
|
||||
X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
|
||||
digest = EVP_get_digestbyobj(digestoid);
|
||||
if (!digest) {
|
||||
alg = OBJ_nid2sn(OBJ_obj2nid(digestoid));
|
||||
digest = EVP_MD_fetch(ctx->libctx, alg, ctx->propq);
|
||||
if (digest == NULL) {
|
||||
CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
|
||||
CMS_R_UNKNOWN_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
@ -312,8 +410,10 @@ BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
|
||||
CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
|
||||
goto err;
|
||||
}
|
||||
EVP_MD_free(digest);
|
||||
return mdbio;
|
||||
err:
|
||||
EVP_MD_free(digest);
|
||||
BIO_free(mdbio);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -43,6 +43,12 @@ typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
|
||||
typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
|
||||
typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
|
||||
typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
|
||||
typedef struct CMS_CTX_st CMS_CTX;
|
||||
|
||||
struct CMS_CTX_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
};
|
||||
|
||||
struct CMS_ContentInfo_st {
|
||||
ASN1_OBJECT *contentType;
|
||||
@ -58,6 +64,7 @@ struct CMS_ContentInfo_st {
|
||||
/* Other types ... */
|
||||
void *otherData;
|
||||
} d;
|
||||
CMS_CTX ctx;
|
||||
};
|
||||
|
||||
DEFINE_STACK_OF(CMS_CertificateChoices)
|
||||
@ -92,6 +99,7 @@ struct CMS_SignerInfo_st {
|
||||
/* Digest and public key context for alternative parameters */
|
||||
EVP_MD_CTX *mctx;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
const CMS_CTX *cms_ctx;
|
||||
};
|
||||
|
||||
struct CMS_SignerIdentifier_st {
|
||||
@ -152,6 +160,7 @@ struct CMS_KeyTransRecipientInfo_st {
|
||||
EVP_PKEY *pkey;
|
||||
/* Public key context for this operation */
|
||||
EVP_PKEY_CTX *pctx;
|
||||
const CMS_CTX *cms_ctx;
|
||||
};
|
||||
|
||||
struct CMS_KeyAgreeRecipientInfo_st {
|
||||
@ -164,6 +173,7 @@ struct CMS_KeyAgreeRecipientInfo_st {
|
||||
EVP_PKEY_CTX *pctx;
|
||||
/* Cipher context for CEK wrapping */
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
const CMS_CTX *cms_ctx;
|
||||
};
|
||||
|
||||
struct CMS_OriginatorIdentifierOrKey_st {
|
||||
@ -209,6 +219,7 @@ struct CMS_KEKRecipientInfo_st {
|
||||
/* Extra info: symmetric key to use */
|
||||
unsigned char *key;
|
||||
size_t keylen;
|
||||
const CMS_CTX *cms_ctx;
|
||||
};
|
||||
|
||||
struct CMS_KEKIdentifier_st {
|
||||
@ -225,6 +236,7 @@ struct CMS_PasswordRecipientInfo_st {
|
||||
/* Extra info: password to use */
|
||||
unsigned char *pass;
|
||||
size_t passlen;
|
||||
const CMS_CTX *cms_ctx;
|
||||
};
|
||||
|
||||
struct CMS_OtherRecipientInfo_st {
|
||||
@ -363,27 +375,34 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
|
||||
# define CMS_OIK_PUBKEY 2
|
||||
|
||||
BIO *cms_content_bio(CMS_ContentInfo *cms);
|
||||
const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms);
|
||||
OPENSSL_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx);
|
||||
const char *cms_ctx_get0_propq(const CMS_CTX *ctx);
|
||||
void cms_resolve_libctx(CMS_ContentInfo *ci);
|
||||
|
||||
CMS_ContentInfo *cms_Data_create(void);
|
||||
CMS_ContentInfo *cms_Data_create(OPENSSL_CTX *ctx, const char *propq);
|
||||
|
||||
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
|
||||
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md,
|
||||
OPENSSL_CTX *libctx, const char *propq);
|
||||
BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms);
|
||||
int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify);
|
||||
|
||||
BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
|
||||
int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
|
||||
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
|
||||
int type);
|
||||
int type, const CMS_CTX *ctx);
|
||||
int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
|
||||
ASN1_OCTET_STRING **keyid,
|
||||
X509_NAME **issuer,
|
||||
ASN1_INTEGER **sno);
|
||||
int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
|
||||
|
||||
CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
|
||||
CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OPENSSL_CTX *libctx,
|
||||
const char *propq);
|
||||
BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms);
|
||||
|
||||
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
|
||||
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
|
||||
const CMS_CTX *ctx);
|
||||
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
||||
X509_ALGOR *mdalg);
|
||||
|
||||
@ -392,11 +411,13 @@ int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
|
||||
int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
|
||||
int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
|
||||
|
||||
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
|
||||
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
|
||||
const CMS_CTX *ctx);
|
||||
BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms);
|
||||
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, size_t keylen);
|
||||
const unsigned char *key, size_t keylen,
|
||||
const CMS_CTX *ctx);
|
||||
|
||||
int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
|
||||
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
|
||||
@ -405,21 +426,29 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
|
||||
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
|
||||
int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
|
||||
CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
|
||||
|
||||
/* RecipientInfo routines */
|
||||
int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
|
||||
int cms_pkey_get_ri_type(EVP_PKEY *pk);
|
||||
int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type);
|
||||
|
||||
void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms);
|
||||
|
||||
/* KARI routines */
|
||||
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||
EVP_PKEY *recipPubKey, X509 *originator,
|
||||
EVP_PKEY *originatorPrivKey, unsigned int flags);
|
||||
EVP_PKEY *originatorPrivKey, unsigned int flags,
|
||||
const CMS_CTX *ctx);
|
||||
int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
|
||||
CMS_RecipientInfo *ri);
|
||||
|
||||
/* PWRI routines */
|
||||
int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
|
||||
int en_de);
|
||||
int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
|
||||
CMS_RecipientInfo *ri, int en_de);
|
||||
/* SignerInfo routines */
|
||||
int CMS_si_check_attributes(const CMS_SignerInfo *si);
|
||||
void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms);
|
||||
|
||||
|
||||
/* ESS routines */
|
||||
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
|
||||
|
@ -51,6 +51,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
|
||||
X509_ALGOR *encalg = NULL;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
int ivlen;
|
||||
const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
env = cms_get0_enveloped(cms);
|
||||
if (!env)
|
||||
@ -91,7 +92,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||
|
||||
if (ivlen > 0) {
|
||||
if (RAND_bytes(iv, ivlen) <= 0)
|
||||
if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0)
|
||||
goto err;
|
||||
if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
|
||||
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
|
||||
@ -125,6 +126,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
|
||||
ri->type = CMS_RECIPINFO_PASS;
|
||||
|
||||
pwri = ri->d.pwri;
|
||||
pwri->cms_ctx = cms_ctx;
|
||||
/* Since this is overwritten, free up empty structure already there */
|
||||
X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
|
||||
pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
|
||||
@ -232,7 +234,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
|
||||
|
||||
static int kek_wrap_key(unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen,
|
||||
EVP_CIPHER_CTX *ctx)
|
||||
EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx)
|
||||
{
|
||||
size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
|
||||
size_t olen;
|
||||
@ -260,7 +262,8 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
|
||||
memcpy(out + 4, in, inlen);
|
||||
/* Add random padding to end */
|
||||
if (olen > inlen + 4
|
||||
&& RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
|
||||
&& RAND_bytes_ex(cms_ctx->libctx, out + 4 + inlen,
|
||||
olen - 4 - inlen) <= 0)
|
||||
return 0;
|
||||
/* Encrypt twice */
|
||||
if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
|
||||
@ -275,17 +278,19 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
|
||||
|
||||
/* Encrypt/Decrypt content key in PWRI recipient info */
|
||||
|
||||
int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
|
||||
int en_de)
|
||||
int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
|
||||
CMS_RecipientInfo *ri, int en_de)
|
||||
{
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
CMS_PasswordRecipientInfo *pwri;
|
||||
int r = 0;
|
||||
X509_ALGOR *algtmp, *kekalg = NULL;
|
||||
EVP_CIPHER_CTX *kekctx = NULL;
|
||||
const EVP_CIPHER *kekcipher;
|
||||
const char *name;
|
||||
EVP_CIPHER *kekcipher;
|
||||
unsigned char *key = NULL;
|
||||
size_t keylen;
|
||||
const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||
|
||||
@ -312,17 +317,18 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
return 0;
|
||||
}
|
||||
|
||||
kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
|
||||
name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm));
|
||||
kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, name, cms_ctx->propq);
|
||||
|
||||
if (!kekcipher) {
|
||||
if (kekcipher == NULL) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
kekctx = EVP_CIPHER_CTX_new();
|
||||
if (kekctx == NULL) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
/* Fixup cipher based on AlgorithmIdentifier to set IV etc */
|
||||
if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
|
||||
@ -349,7 +355,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
|
||||
if (en_de) {
|
||||
|
||||
if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
|
||||
if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
|
||||
goto err;
|
||||
|
||||
key = OPENSSL_malloc(keylen);
|
||||
@ -357,7 +363,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
if (key == NULL)
|
||||
goto err;
|
||||
|
||||
if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
|
||||
if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
|
||||
goto err;
|
||||
pwri->encryptedKey->data = key;
|
||||
pwri->encryptedKey->length = keylen;
|
||||
@ -384,7 +390,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
r = 1;
|
||||
|
||||
err:
|
||||
|
||||
EVP_CIPHER_free(kekcipher);
|
||||
EVP_CIPHER_CTX_free(kekctx);
|
||||
|
||||
if (!r)
|
||||
|
@ -67,6 +67,7 @@ int CMS_SignedData_init(CMS_ContentInfo *cms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check structures and fixup version numbers (if necessary) */
|
||||
|
||||
static void cms_sd_set_version(CMS_SignedData *sd)
|
||||
@ -146,9 +147,11 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
|
||||
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||
CMS_SignerInfo *sitmp;
|
||||
int i;
|
||||
|
||||
sinfos = CMS_get0_SignerInfos(cms);
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
ASN1_OCTET_STRING *messageDigest;
|
||||
|
||||
sitmp = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (sitmp == si)
|
||||
continue;
|
||||
@ -178,7 +181,8 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
|
||||
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type,
|
||||
const CMS_CTX *ctx)
|
||||
{
|
||||
switch (type) {
|
||||
case CMS_SIGNERINFO_ISSUER_SERIAL:
|
||||
@ -233,6 +237,7 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
|
||||
{
|
||||
EVP_PKEY *pkey = si->pkey;
|
||||
int i;
|
||||
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
|
||||
return 1;
|
||||
i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
|
||||
@ -255,6 +260,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
CMS_SignerInfo *si = NULL;
|
||||
X509_ALGOR *alg;
|
||||
int i, type;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
if (!X509_check_private_key(signer, pk)) {
|
||||
CMSerr(CMS_F_CMS_ADD1_SIGNER,
|
||||
CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
|
||||
@ -272,6 +279,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
X509_up_ref(signer);
|
||||
EVP_PKEY_up_ref(pk);
|
||||
|
||||
si->cms_ctx = ctx;
|
||||
si->pkey = pk;
|
||||
si->signer = signer;
|
||||
si->mctx = EVP_MD_CTX_new();
|
||||
@ -292,7 +300,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
si->version = 1;
|
||||
}
|
||||
|
||||
if (!cms_set1_SignerIdentifier(si->sid, signer, type))
|
||||
if (!cms_set1_SignerIdentifier(si->sid, signer, type, ctx))
|
||||
goto err;
|
||||
|
||||
if (md == NULL) {
|
||||
@ -311,6 +319,11 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (md == NULL) {
|
||||
CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
|
||||
goto err;
|
||||
}
|
||||
|
||||
X509_ALGOR_set_md(si->digestAlgorithm, md);
|
||||
|
||||
/* See if digest is present in digestAlgorithms */
|
||||
@ -395,15 +408,20 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
|
||||
if (flags & CMS_KEY_PARAM) {
|
||||
if (flags & CMS_NOATTR) {
|
||||
si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
|
||||
si->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey,
|
||||
ctx->propq);
|
||||
if (si->pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_sign_init(si->pctx) <= 0)
|
||||
goto err;
|
||||
if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
|
||||
goto err;
|
||||
} else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0)
|
||||
} else if (EVP_DigestSignInit_with_libctx(si->mctx, &si->pctx,
|
||||
EVP_MD_name(md),
|
||||
ctx->libctx, ctx->propq,
|
||||
pk) <= 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sd->signerInfos)
|
||||
@ -421,16 +439,31 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||
|
||||
}
|
||||
|
||||
void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms)
|
||||
{
|
||||
int i;
|
||||
CMS_SignerInfo *si;
|
||||
STACK_OF(CMS_SignerInfo) *sinfos = CMS_get0_SignerInfos(cms);
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (si != NULL)
|
||||
si->cms_ctx = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
|
||||
{
|
||||
ASN1_TIME *tt;
|
||||
int r = 0;
|
||||
if (t)
|
||||
|
||||
if (t != NULL)
|
||||
tt = t;
|
||||
else
|
||||
tt = X509_gmtime_adj(NULL, 0);
|
||||
|
||||
if (!tt)
|
||||
if (tt == NULL)
|
||||
goto merr;
|
||||
|
||||
if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
|
||||
@ -438,10 +471,8 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
|
||||
goto merr;
|
||||
|
||||
r = 1;
|
||||
|
||||
merr:
|
||||
|
||||
if (!t)
|
||||
if (t == NULL)
|
||||
ASN1_TIME_free(tt);
|
||||
|
||||
if (!r)
|
||||
@ -463,11 +494,9 @@ EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
|
||||
|
||||
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
|
||||
{
|
||||
CMS_SignedData *sd;
|
||||
sd = cms_get0_signed(cms);
|
||||
if (!sd)
|
||||
return NULL;
|
||||
return sd->signerInfos;
|
||||
CMS_SignedData *sd = cms_get0_signed(cms);
|
||||
|
||||
return sd != NULL ? sd->signerInfos : NULL;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
|
||||
@ -476,13 +505,14 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
|
||||
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||
CMS_SignerInfo *si;
|
||||
int i;
|
||||
|
||||
sinfos = CMS_get0_SignerInfos(cms);
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (si->signer) {
|
||||
if (!signers) {
|
||||
if (si->signer != NULL) {
|
||||
if (signers == NULL) {
|
||||
signers = sk_X509_new_null();
|
||||
if (!signers)
|
||||
if (signers == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (!sk_X509_push(signers, si->signer)) {
|
||||
@ -496,7 +526,7 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
|
||||
|
||||
void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
|
||||
{
|
||||
if (signer) {
|
||||
if (signer != NULL) {
|
||||
X509_up_ref(signer);
|
||||
EVP_PKEY_free(si->pkey);
|
||||
si->pkey = X509_get_pubkey(signer);
|
||||
@ -527,13 +557,14 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
|
||||
X509 *x;
|
||||
int i, j;
|
||||
int ret = 0;
|
||||
|
||||
sd = cms_get0_signed(cms);
|
||||
if (!sd)
|
||||
if (sd == NULL)
|
||||
return -1;
|
||||
certs = sd->certificates;
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
|
||||
si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
|
||||
if (si->signer)
|
||||
if (si->signer != NULL)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < sk_X509_num(scerts); j++) {
|
||||
@ -545,7 +576,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
|
||||
}
|
||||
}
|
||||
|
||||
if (si->signer || (flags & CMS_NOINTERN))
|
||||
if (si->signer != NULL || (flags & CMS_NOINTERN))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
|
||||
@ -567,13 +598,13 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
|
||||
X509 **signer, X509_ALGOR **pdig,
|
||||
X509_ALGOR **psig)
|
||||
{
|
||||
if (pk)
|
||||
if (pk != NULL)
|
||||
*pk = si->pkey;
|
||||
if (signer)
|
||||
if (signer != NULL)
|
||||
*signer = si->signer;
|
||||
if (pdig)
|
||||
if (pdig != NULL)
|
||||
*pdig = si->digestAlgorithm;
|
||||
if (psig)
|
||||
if (psig != NULL)
|
||||
*psig = si->signatureAlgorithm;
|
||||
}
|
||||
|
||||
@ -588,13 +619,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
int r = 0;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
if (mctx == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!si->pkey) {
|
||||
if (si->pkey == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
@ -612,6 +644,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
||||
if (CMS_signed_get_attr_count(si) >= 0) {
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int mdlen;
|
||||
|
||||
if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
|
||||
goto err;
|
||||
if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
|
||||
@ -628,6 +661,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
||||
size_t siglen;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int mdlen;
|
||||
|
||||
pctx = si->pctx;
|
||||
if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
|
||||
goto err;
|
||||
@ -645,12 +679,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
||||
} else {
|
||||
unsigned char *sig;
|
||||
unsigned int siglen;
|
||||
|
||||
sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
|
||||
if (sig == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
|
||||
if (!EVP_SignFinal_with_libctx(mctx, sig, &siglen, si->pkey,
|
||||
ctx->libctx, ctx->propq)) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
|
||||
OPENSSL_free(sig);
|
||||
goto err;
|
||||
@ -672,6 +708,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
|
||||
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||
CMS_SignerInfo *si;
|
||||
int i;
|
||||
|
||||
sinfos = CMS_get0_SignerInfos(cms);
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
@ -689,10 +726,10 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
||||
unsigned char *abuf = NULL;
|
||||
int alen;
|
||||
size_t siglen;
|
||||
const EVP_MD *md = NULL;
|
||||
const CMS_CTX *ctx = si->cms_ctx;
|
||||
const char *md_name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm));
|
||||
|
||||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
if (md == NULL)
|
||||
if (md_name == NULL)
|
||||
return 0;
|
||||
|
||||
if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
|
||||
@ -707,7 +744,9 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
||||
pctx = si->pctx;
|
||||
else {
|
||||
EVP_MD_CTX_reset(mctx);
|
||||
if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
|
||||
if (EVP_DigestSignInit_with_libctx(mctx, &pctx,
|
||||
md_name, ctx->libctx, ctx->propq,
|
||||
si->pkey) <= 0)
|
||||
goto err;
|
||||
si->pctx = pctx;
|
||||
}
|
||||
@ -780,9 +819,11 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
unsigned char *abuf = NULL;
|
||||
int alen, r = -1;
|
||||
const EVP_MD *md = NULL;
|
||||
const char *name;
|
||||
EVP_MD *md = NULL;
|
||||
const CMS_CTX *ctx = si->cms_ctx;
|
||||
|
||||
if (!si->pkey) {
|
||||
if (si->pkey == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
|
||||
return -1;
|
||||
}
|
||||
@ -790,15 +831,18 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
||||
if (!CMS_si_check_attributes(si))
|
||||
return -1;
|
||||
|
||||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm));
|
||||
md = EVP_MD_fetch(ctx->libctx, name, ctx->propq);
|
||||
if (md == NULL)
|
||||
return -1;
|
||||
if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
mctx = si->mctx;
|
||||
if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
|
||||
if (EVP_DigestVerifyInit_with_libctx(mctx, &si->pctx,
|
||||
EVP_MD_name(md), ctx->libctx, NULL,
|
||||
si->pkey) <= 0)
|
||||
goto err;
|
||||
|
||||
if (!cms_sd_asn1_ctrl(si, 1))
|
||||
@ -819,6 +863,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
||||
if (r <= 0)
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
|
||||
err:
|
||||
EVP_MD_free(md);
|
||||
EVP_MD_CTX_reset(mctx);
|
||||
return r;
|
||||
}
|
||||
@ -830,19 +875,21 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
|
||||
int i;
|
||||
CMS_SignedData *sd;
|
||||
BIO *chain = NULL;
|
||||
|
||||
sd = cms_get0_signed(cms);
|
||||
if (!sd)
|
||||
if (sd == NULL)
|
||||
return NULL;
|
||||
if (cms->d.signedData->encapContentInfo->partial)
|
||||
cms_sd_set_version(sd);
|
||||
for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
|
||||
X509_ALGOR *digestAlgorithm;
|
||||
BIO *mdbio;
|
||||
|
||||
digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
|
||||
mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
|
||||
if (!mdbio)
|
||||
mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm, cms_get0_cmsctx(cms));
|
||||
if (mdbio == NULL)
|
||||
goto err;
|
||||
if (chain)
|
||||
if (chain != NULL)
|
||||
BIO_push(chain, mdbio);
|
||||
else
|
||||
chain = mdbio;
|
||||
@ -871,7 +918,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
||||
os = CMS_signed_get0_data_by_OBJ(si,
|
||||
OBJ_nid2obj(NID_pkcs9_messageDigest),
|
||||
-3, V_ASN1_OCTET_STRING);
|
||||
if (!os) {
|
||||
if (os == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
|
||||
goto err;
|
||||
@ -889,7 +936,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
||||
|
||||
/* If messageDigest found compare it */
|
||||
|
||||
if (os) {
|
||||
if (os != NULL) {
|
||||
if (mlen != (unsigned int)os->length) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
|
||||
CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
|
||||
@ -904,7 +951,9 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
||||
r = 1;
|
||||
} else {
|
||||
const EVP_MD *md = EVP_MD_CTX_md(mctx);
|
||||
pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
|
||||
const CMS_CTX *ctx = si->cms_ctx;
|
||||
|
||||
pkctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey, ctx->propq);
|
||||
if (pkctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_verify_init(pkctx) <= 0)
|
||||
@ -934,6 +983,7 @@ int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
|
||||
{
|
||||
unsigned char *smder = NULL;
|
||||
int smderlen, r;
|
||||
|
||||
smderlen = i2d_X509_ALGORS(algs, &smder);
|
||||
if (smderlen <= 0)
|
||||
return 0;
|
||||
@ -948,6 +998,7 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
|
||||
{
|
||||
X509_ALGOR *alg;
|
||||
ASN1_INTEGER *key = NULL;
|
||||
|
||||
if (keysize > 0) {
|
||||
key = ASN1_INTEGER_new();
|
||||
if (key == NULL || !ASN1_INTEGER_set(key, keysize)) {
|
||||
|
@ -25,6 +25,7 @@ DEFINE_STACK_OF(CMS_RecipientInfo)
|
||||
static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
|
||||
{
|
||||
BIO *rbio;
|
||||
|
||||
if (out == NULL)
|
||||
rbio = BIO_new(BIO_s_null());
|
||||
else if (flags & CMS_TEXT) {
|
||||
@ -61,7 +62,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmpout && (BIO_write(tmpout, buf, i) != i))
|
||||
if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -73,7 +74,6 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
|
||||
}
|
||||
|
||||
r = 1;
|
||||
|
||||
err:
|
||||
if (tmpout != out)
|
||||
BIO_free(tmpout);
|
||||
@ -96,62 +96,73 @@ static void do_free_upto(BIO *f, BIO *upto)
|
||||
{
|
||||
if (upto != NULL) {
|
||||
BIO *tbio;
|
||||
|
||||
do {
|
||||
tbio = BIO_pop(f);
|
||||
BIO_free(f);
|
||||
f = tbio;
|
||||
} while (f != NULL && f != upto);
|
||||
} else
|
||||
} else {
|
||||
BIO_free_all(f);
|
||||
}
|
||||
}
|
||||
|
||||
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
|
||||
{
|
||||
BIO *cont;
|
||||
int r;
|
||||
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
|
||||
CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
|
||||
return 0;
|
||||
}
|
||||
cont = CMS_dataInit(cms, NULL);
|
||||
if (!cont)
|
||||
if (cont == NULL)
|
||||
return 0;
|
||||
r = cms_copy_content(out, cont, flags);
|
||||
BIO_free_all(cont);
|
||||
return r;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
|
||||
CMS_ContentInfo *CMS_data_create_with_libctx(BIO *in, unsigned int flags,
|
||||
OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
cms = cms_Data_create();
|
||||
if (!cms)
|
||||
CMS_ContentInfo *cms = cms_Data_create(libctx, propq);
|
||||
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
|
||||
return cms;
|
||||
|
||||
CMS_ContentInfo_free(cms);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
|
||||
{
|
||||
return CMS_data_create_with_libctx(in, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||
unsigned int flags)
|
||||
{
|
||||
BIO *cont;
|
||||
int r;
|
||||
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
|
||||
CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
if (dcont == NULL && !check_content(cms))
|
||||
return 0;
|
||||
|
||||
cont = CMS_dataInit(cms, dcont);
|
||||
if (!cont)
|
||||
if (cont == NULL)
|
||||
return 0;
|
||||
|
||||
r = cms_copy_content(out, cont, flags);
|
||||
if (r)
|
||||
r = cms_DigestedData_do_final(cms, cont, 1);
|
||||
@ -159,14 +170,18 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||
return r;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||
unsigned int flags)
|
||||
CMS_ContentInfo *CMS_digest_create_with_libctx(BIO *in,
|
||||
const EVP_MD *md,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
if (!md)
|
||||
|
||||
if (md == NULL)
|
||||
md = EVP_sha1();
|
||||
cms = cms_DigestedData_create(md);
|
||||
if (!cms)
|
||||
cms = cms_DigestedData_create(md, ctx, propq);
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!(flags & CMS_DETACHED))
|
||||
@ -179,41 +194,53 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||
unsigned int flags)
|
||||
{
|
||||
return CMS_digest_create_with_libctx(in, md, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||
const unsigned char *key, size_t keylen,
|
||||
BIO *dcont, BIO *out, unsigned int flags)
|
||||
{
|
||||
BIO *cont;
|
||||
int r;
|
||||
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
|
||||
CMS_R_TYPE_NOT_ENCRYPTED_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
if (dcont == NULL && !check_content(cms))
|
||||
return 0;
|
||||
|
||||
if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
|
||||
return 0;
|
||||
cont = CMS_dataInit(cms, dcont);
|
||||
if (!cont)
|
||||
if (cont == NULL)
|
||||
return 0;
|
||||
r = cms_copy_content(out, cont, flags);
|
||||
do_free_upto(cont, dcont);
|
||||
return r;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
size_t keylen, unsigned int flags)
|
||||
CMS_ContentInfo *CMS_EncryptedData_encrypt_with_libctx(BIO *in,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
size_t keylen,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
if (!cipher) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
|
||||
|
||||
if (cipher == NULL) {
|
||||
CMSerr(0, CMS_R_NO_CIPHER);
|
||||
return NULL;
|
||||
}
|
||||
cms = CMS_ContentInfo_new();
|
||||
cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
|
||||
@ -230,16 +257,26 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
size_t keylen, unsigned int flags)
|
||||
{
|
||||
return CMS_EncryptedData_encrypt_with_libctx(in, cipher, key, keylen, flags,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
X509_STORE *store,
|
||||
STACK_OF(X509) *certs,
|
||||
STACK_OF(X509_CRL) *crls,
|
||||
STACK_OF(X509) **chain)
|
||||
STACK_OF(X509) **chain,
|
||||
const CMS_CTX *cms_ctx)
|
||||
{
|
||||
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
|
||||
X509_STORE_CTX *ctx;
|
||||
X509 *signer;
|
||||
int i, j, r = 0;
|
||||
|
||||
ctx = X509_STORE_CTX_new_with_libctx(cms_ctx->libctx, cms_ctx->propq);
|
||||
if (ctx == NULL) {
|
||||
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
@ -250,7 +287,7 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
goto err;
|
||||
}
|
||||
X509_STORE_CTX_set_default(ctx, "smime_sign");
|
||||
if (crls)
|
||||
if (crls != NULL)
|
||||
X509_STORE_CTX_set0_crls(ctx, crls);
|
||||
|
||||
i = X509_verify_cert(ctx);
|
||||
@ -285,11 +322,13 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
int i, scount = 0, ret = 0;
|
||||
BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
|
||||
int cadesVerify = (flags & CMS_CADES) != 0;
|
||||
const CMS_CTX *ctx = cms_get0_cmsctx(cms);
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
if (dcont == NULL && !check_content(cms))
|
||||
return 0;
|
||||
if (dcont && !(flags & CMS_BINARY)) {
|
||||
if (dcont != NULL && !(flags & CMS_BINARY)) {
|
||||
const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
|
||||
|
||||
if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
|
||||
flags |= CMS_ASCIICRLF;
|
||||
}
|
||||
@ -337,7 +376,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
|
||||
if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls,
|
||||
si_chains ? &si_chains[i] : NULL))
|
||||
si_chains ? &si_chains[i] : NULL,
|
||||
ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -367,17 +407,19 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
* reading from a read write memory BIO when signatures are calculated.
|
||||
*/
|
||||
|
||||
if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
|
||||
if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
|
||||
char *ptr;
|
||||
long len;
|
||||
|
||||
len = BIO_get_mem_data(dcont, &ptr);
|
||||
tmpin = BIO_new_mem_buf(ptr, len);
|
||||
if (tmpin == NULL) {
|
||||
CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err2;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
tmpin = dcont;
|
||||
}
|
||||
/*
|
||||
* If not binary mode and detached generate digests by *writing* through
|
||||
* the BIO. That makes it possible to canonicalise the input.
|
||||
@ -388,12 +430,12 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
* included content doesn't override detached content.
|
||||
*/
|
||||
tmpout = cms_get_text_bio(out, flags);
|
||||
if (!tmpout) {
|
||||
if (tmpout == NULL) {
|
||||
CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
cmsbio = CMS_dataInit(cms, tmpout);
|
||||
if (!cmsbio)
|
||||
if (cmsbio == NULL)
|
||||
goto err;
|
||||
/*
|
||||
* Don't use SMIME_TEXT for verify: it adds headers and we want to
|
||||
@ -409,7 +451,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
}
|
||||
} else {
|
||||
cmsbio = CMS_dataInit(cms, tmpin);
|
||||
if (!cmsbio)
|
||||
if (cmsbio == NULL)
|
||||
goto err;
|
||||
|
||||
if (!cms_copy_content(out, cmsbio, flags))
|
||||
@ -427,7 +469,6 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (!(flags & SMIME_BINARY) && dcont) {
|
||||
do_free_upto(cmsbio, tmpout);
|
||||
@ -460,6 +501,7 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||
X509_STORE *store, unsigned int flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
flags &= ~(CMS_DETACHED | CMS_TEXT);
|
||||
r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
|
||||
if (r <= 0)
|
||||
@ -467,14 +509,15 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||
return cms_Receipt_verify(rcms, ocms);
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, BIO *data,
|
||||
unsigned int flags)
|
||||
CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, BIO *data,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
int i;
|
||||
|
||||
cms = CMS_ContentInfo_new();
|
||||
cms = CMS_ContentInfo_new_with_libctx(libctx, propq);
|
||||
if (cms == NULL || !CMS_SignedData_init(cms))
|
||||
goto merr;
|
||||
if (flags & CMS_ASCIICRLF
|
||||
@ -482,13 +525,14 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
|
||||
OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
|
||||
goto err;
|
||||
|
||||
if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
|
||||
CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
|
||||
if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
|
||||
CMSerr(0, CMS_R_ADD_SIGNER_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++) {
|
||||
X509 *x = sk_X509_value(certs, i);
|
||||
|
||||
if (!CMS_add1_cert(cms, x))
|
||||
goto merr;
|
||||
}
|
||||
@ -503,13 +547,19 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
|
||||
goto err;
|
||||
|
||||
merr:
|
||||
CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
|
||||
CMSerr(0, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
CMS_ContentInfo_free(cms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||
BIO *data, unsigned int flags)
|
||||
{
|
||||
return CMS_sign_with_libctx(signcert, pkey, certs, data, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, unsigned int flags)
|
||||
@ -519,6 +569,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
ASN1_OCTET_STRING **pos, *os;
|
||||
BIO *rct_cont = NULL;
|
||||
int r = 0;
|
||||
const CMS_CTX *ctx = si->cms_ctx;
|
||||
|
||||
flags &= ~(CMS_STREAM | CMS_TEXT);
|
||||
/* Not really detached but avoids content being allocated */
|
||||
@ -530,8 +581,9 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
|
||||
/* Initialize signed data */
|
||||
|
||||
cms = CMS_sign(NULL, NULL, certs, NULL, flags);
|
||||
if (!cms)
|
||||
cms = CMS_sign_with_libctx(NULL, NULL, certs, NULL, flags,
|
||||
ctx->libctx, ctx->propq);
|
||||
if (cms == NULL)
|
||||
goto err;
|
||||
|
||||
/* Set inner content type to signed receipt */
|
||||
@ -545,13 +597,12 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
}
|
||||
|
||||
os = cms_encode_Receipt(si);
|
||||
|
||||
if (!os)
|
||||
if (os == NULL)
|
||||
goto err;
|
||||
|
||||
/* Set content to digest */
|
||||
rct_cont = BIO_new_mem_buf(os->data, os->length);
|
||||
if (!rct_cont)
|
||||
if (rct_cont == NULL)
|
||||
goto err;
|
||||
|
||||
/* Add msgSigDigest attribute */
|
||||
@ -578,19 +629,22 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
|
||||
}
|
||||
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
|
||||
const EVP_CIPHER *cipher, unsigned int flags)
|
||||
CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
|
||||
BIO *data, const EVP_CIPHER *cipher,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
int i;
|
||||
X509 *recip;
|
||||
cms = CMS_EnvelopedData_create(cipher);
|
||||
if (!cms)
|
||||
|
||||
cms = CMS_EnvelopedData_create_with_libctx(cipher, libctx, propq);
|
||||
if (cms == NULL)
|
||||
goto merr;
|
||||
for (i = 0; i < sk_X509_num(certs); i++) {
|
||||
recip = sk_X509_value(certs, i);
|
||||
if (!CMS_add1_recipient_cert(cms, recip, flags)) {
|
||||
CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
|
||||
CMSerr(0, CMS_R_RECIPIENT_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -605,13 +659,20 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
|
||||
goto err;
|
||||
|
||||
merr:
|
||||
CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
||||
CMSerr(0, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
CMS_ContentInfo_free(cms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
|
||||
const EVP_CIPHER *cipher, unsigned int flags)
|
||||
{
|
||||
return CMS_encrypt_with_libctx(certs, data, cipher, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms,
|
||||
CMS_RecipientInfo *ri,
|
||||
EVP_PKEY *pk, X509 *cert, X509 *peer)
|
||||
{
|
||||
int i;
|
||||
@ -621,6 +682,7 @@ static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
reks = CMS_RecipientInfo_kari_get0_reks(ri);
|
||||
for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
|
||||
int rv;
|
||||
|
||||
rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
|
||||
if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
|
||||
continue;
|
||||
@ -639,14 +701,16 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
|
||||
return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL);
|
||||
}
|
||||
|
||||
int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer)
|
||||
int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
|
||||
X509 *cert, X509 *peer)
|
||||
{
|
||||
STACK_OF(CMS_RecipientInfo) *ris;
|
||||
CMS_RecipientInfo *ri;
|
||||
int i, r, cms_pkey_ri_type;
|
||||
int debug = 0, match_ri = 0;
|
||||
|
||||
ris = CMS_get0_RecipientInfos(cms);
|
||||
if (ris)
|
||||
if (ris != NULL)
|
||||
debug = cms->d.envelopedData->encryptedContentInfo->debug;
|
||||
|
||||
cms_pkey_ri_type = cms_pkey_get_ri_type(pk);
|
||||
@ -675,12 +739,12 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer
|
||||
* If we have a cert try matching RecipientInfo otherwise try them
|
||||
* all.
|
||||
*/
|
||||
else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
|
||||
else if (cert == NULL|| !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
|
||||
EVP_PKEY_up_ref(pk);
|
||||
CMS_RecipientInfo_set0_pkey(ri, pk);
|
||||
r = CMS_RecipientInfo_decrypt(cms, ri);
|
||||
CMS_RecipientInfo_set0_pkey(ri, NULL);
|
||||
if (cert) {
|
||||
if (cert != NULL) {
|
||||
/*
|
||||
* If not debugging clear any error and return success to
|
||||
* avoid leaking of information useful to MMA
|
||||
@ -704,7 +768,10 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer
|
||||
}
|
||||
}
|
||||
/* If no cert, key transport and not debugging always return success */
|
||||
if (cert == NULL && cms_pkey_ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
|
||||
if (cert == NULL
|
||||
&& cms_pkey_ri_type == CMS_RECIPINFO_TRANS
|
||||
&& match_ri
|
||||
&& !debug) {
|
||||
ERR_clear_error();
|
||||
return 1;
|
||||
}
|
||||
@ -721,6 +788,7 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
|
||||
STACK_OF(CMS_RecipientInfo) *ris;
|
||||
CMS_RecipientInfo *ri;
|
||||
int i, r;
|
||||
|
||||
ris = CMS_get0_RecipientInfos(cms);
|
||||
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
|
||||
ri = sk_CMS_RecipientInfo_value(ris, i);
|
||||
@ -731,13 +799,13 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
|
||||
* If we have an id try matching RecipientInfo otherwise try them
|
||||
* all.
|
||||
*/
|
||||
if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
|
||||
if (id == NULL || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
|
||||
CMS_RecipientInfo_set0_key(ri, key, keylen);
|
||||
r = CMS_RecipientInfo_decrypt(cms, ri);
|
||||
CMS_RecipientInfo_set0_key(ri, NULL, 0);
|
||||
if (r > 0)
|
||||
return 1;
|
||||
if (id) {
|
||||
if (id != NULL) {
|
||||
CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
@ -756,6 +824,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
|
||||
STACK_OF(CMS_RecipientInfo) *ris;
|
||||
CMS_RecipientInfo *ri;
|
||||
int i, r;
|
||||
|
||||
ris = CMS_get0_RecipientInfos(cms);
|
||||
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
|
||||
ri = sk_CMS_RecipientInfo_value(ris, i);
|
||||
@ -783,13 +852,13 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
|
||||
CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
|
||||
return 0;
|
||||
}
|
||||
if (!dcont && !check_content(cms))
|
||||
if (dcont == NULL && !check_content(cms))
|
||||
return 0;
|
||||
if (flags & CMS_DEBUG_DECRYPT)
|
||||
cms->d.envelopedData->encryptedContentInfo->debug = 1;
|
||||
else
|
||||
cms->d.envelopedData->encryptedContentInfo->debug = 0;
|
||||
if (!cert)
|
||||
if (cert == NULL)
|
||||
cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
|
||||
else
|
||||
cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
|
||||
@ -815,7 +884,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SMIME_crlf_copy(data, cmsbio, flags);
|
||||
ret = SMIME_crlf_copy(data, cmsbio, flags);
|
||||
|
||||
(void)BIO_flush(cmsbio);
|
||||
|
||||
@ -823,10 +892,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
|
||||
CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
err:
|
||||
do_free_upto(cmsbio, dcont);
|
||||
|
||||
return ret;
|
||||
@ -840,16 +906,17 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||
{
|
||||
BIO *cont;
|
||||
int r;
|
||||
|
||||
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
|
||||
CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
if (dcont == NULL && !check_content(cms))
|
||||
return 0;
|
||||
|
||||
cont = CMS_dataInit(cms, dcont);
|
||||
if (!cont)
|
||||
if (cont == NULL)
|
||||
return 0;
|
||||
r = cms_copy_content(out, cont, flags);
|
||||
do_free_upto(cont, dcont);
|
||||
@ -859,10 +926,11 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
|
||||
{
|
||||
CMS_ContentInfo *cms;
|
||||
|
||||
if (comp_nid <= 0)
|
||||
comp_nid = NID_zlib_compression;
|
||||
cms = cms_CompressedData_create(comp_nid);
|
||||
if (!cms)
|
||||
cms = cms_CompressedData_create(comp_nid, NULL, NULL);
|
||||
if (cms == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!(flags & CMS_DETACHED))
|
||||
|
@ -83,6 +83,7 @@ B<openssl> B<cms>
|
||||
{- $OpenSSL::safe::opt_r_synopsis -}
|
||||
{- $OpenSSL::safe::opt_engine_synopsis -}
|
||||
{- $OpenSSL::safe::opt_provider_synopsis -}
|
||||
{- $OpenSSL::safe::opt_config_synopsis -}
|
||||
[I<recipient-cert> ...]
|
||||
|
||||
=for openssl ifdef des-wrap engine
|
||||
@ -501,6 +502,8 @@ Any verification errors cause the command to exit.
|
||||
|
||||
{- $OpenSSL::safe::opt_provider_item -}
|
||||
|
||||
{- $OpenSSL::safe::opt_config_item -}
|
||||
|
||||
=item I<recipient-cert> ...
|
||||
|
||||
One or more certificates of message recipients: used when encrypting
|
||||
|
@ -2,20 +2,26 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_EnvelopedData_create - Create CMS envelope
|
||||
CMS_EnvelopedData_create_with_libctx, CMS_EnvelopedData_create
|
||||
- Create CMS envelope
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
|
||||
OPENSSL_CTX *libctx,
|
||||
const char *propq);
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CMS_EnvelopedData_create() creates a B<CMS_ContentInfo> structure with
|
||||
a type B<NID_pkcs7_enveloped>. B<cipher> is the symmetric cipher to use.
|
||||
CMS_EnvelopedData_create_with_libctx() creates a B<CMS_ContentInfo> structure with
|
||||
a type B<NID_pkcs7_enveloped>. I<cipher> is the symmetric cipher to use. The
|
||||
library context I<libctx> and the property query I<propq> are used when
|
||||
retrieving algorithms from providers.
|
||||
|
||||
The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
|
||||
The algorithm passed in the I<cipher> parameter must support ASN1 encoding of
|
||||
its parameters.
|
||||
|
||||
The recipients can be added later using L<CMS_add1_recipient_cert(3)> or
|
||||
@ -24,6 +30,10 @@ L<CMS_add0_recipient_key(3)>.
|
||||
The B<CMS_ContentInfo> structure needs to be finalized using L<CMS_final(3)>
|
||||
and then freed using L<CMS_ContentInfo_free(3)>.
|
||||
|
||||
CMS_EnvelopedData_create() is similar to CMS_EnvelopedData_create_with_libctx()
|
||||
but uses default values of NULL for the library context I<libctx> and the
|
||||
property query I<propq>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
Although CMS_EnvelopedData_create() allocates a new B<CMS_ContentInfo>
|
||||
@ -40,6 +50,10 @@ Otherwise it returns a pointer to the newly allocated structure.
|
||||
|
||||
L<ERR_get_error(3)>, L<CMS_encrypt(3)>, L<CMS_decrypt(3)>, L<CMS_final(3)>
|
||||
|
||||
head1 HISTORY
|
||||
|
||||
The CMS_EnvelopedData_create_with_libctx() method was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -2,20 +2,26 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_encrypt - create a CMS envelopedData structure
|
||||
CMS_encrypt_with_libctx, CMS_encrypt - create a CMS envelopedData structure
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
|
||||
BIO *in, const EVP_CIPHER *cipher,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *libctx, const char *propq);
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
||||
const EVP_CIPHER *cipher, unsigned int flags);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CMS_encrypt() creates and returns a CMS EnvelopedData structure. B<certs>
|
||||
is a list of recipient certificates. B<in> is the content to be encrypted.
|
||||
B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
|
||||
CMS_encrypt_with_libctx() creates and returns a CMS EnvelopedData structure.
|
||||
I<certs> is a list of recipient certificates. I<in> is the content to be
|
||||
encrypted. I<cipher> is the symmetric cipher to use. I<flags> is an optional set
|
||||
of flags. The library context I<libctx> and the property query I<propq> are used
|
||||
internally when retrieving algorithms from providers.
|
||||
|
||||
Only certificates carrying RSA, Diffie-Hellman or EC keys are supported by this
|
||||
function.
|
||||
@ -75,10 +81,14 @@ and CMS_add0_recipient_key().
|
||||
The parameter B<certs> may be NULL if B<CMS_PARTIAL> is set and recipients
|
||||
added later using CMS_add1_recipient_cert() or CMS_add0_recipient_key().
|
||||
|
||||
CMS_encrypt() is similar to CMS_encrypt_with_libctx() but uses default values of
|
||||
NULL for the library context I<libctx> and the property query I<propq>.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
CMS_encrypt() returns either a CMS_ContentInfo structure or NULL if an error
|
||||
occurred. The error can be obtained from ERR_get_error(3).
|
||||
CMS_encrypt_with_libctx() and CMS_encrypt() return either a CMS_ContentInfo
|
||||
structure or NULL if an error occurred. The error can be obtained from
|
||||
ERR_get_error(3).
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
@ -86,11 +96,13 @@ L<ERR_get_error(3)>, L<CMS_decrypt(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The function CMS_encrypt_with_libctx() was added in OpenSSL 3.0.
|
||||
|
||||
The B<CMS_STREAM> flag was first supported in OpenSSL 1.0.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -2,16 +2,21 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values - CMS signed receipt request functions
|
||||
CMS_ReceiptRequest_create0_with_libctx, CMS_ReceiptRequest_create0,
|
||||
CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CMS_ReceiptRequest_get0_values
|
||||
- CMS signed receipt request functions
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList,
|
||||
STACK_OF(GENERAL_NAMES) *receiptsTo);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0_with_libctx(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo,
|
||||
OPENSSL_CTX *libctx, const char *propq);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo);
|
||||
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
|
||||
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
|
||||
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid,
|
||||
@ -21,13 +26,18 @@ CMS_ReceiptRequest_create0, CMS_add1_ReceiptRequest, CMS_get1_ReceiptRequest, CM
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CMS_ReceiptRequest_create0() creates a signed receipt request structure. The
|
||||
B<signedContentIdentifier> field is set using B<id> and B<idlen>, or it is set
|
||||
to 32 bytes of pseudo random data if B<id> is NULL. If B<receiptList> is NULL
|
||||
the allOrFirstTier option in B<receiptsFrom> is used and set to the value of
|
||||
the B<allorfirst> parameter. If B<receiptList> is not NULL the B<receiptList>
|
||||
option in B<receiptsFrom> is used. The B<receiptsTo> parameter specifies the
|
||||
B<receiptsTo> field value.
|
||||
CMS_ReceiptRequest_create0_with_libctx() creates a signed receipt request
|
||||
structure. The B<signedContentIdentifier> field is set using I<id> and I<idlen>,
|
||||
or it is set to 32 bytes of pseudo random data if I<id> is NULL.
|
||||
If I<receiptList> is NULL the allOrFirstTier option in I<receiptsFrom> is used
|
||||
and set to the value of the I<allorfirst> parameter. If I<receiptList> is not
|
||||
NULL the I<receiptList> option in I<receiptsFrom> is used. The I<receiptsTo>
|
||||
parameter specifies the I<receiptsTo> field value. The library context I<libctx>
|
||||
and the property query I<propq> are used when retrieving algorithms from providers.
|
||||
|
||||
CMS_ReceiptRequest_create0() is similar to
|
||||
CMS_ReceiptRequest_create0_with_libctx() but uses default values of NULL for the
|
||||
library context I<libctx> and the property query I<propq>.
|
||||
|
||||
The CMS_add1_ReceiptRequest() function adds a signed receipt request B<rr>
|
||||
to SignerInfo structure B<si>.
|
||||
@ -51,8 +61,8 @@ CMS_verify().
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
CMS_ReceiptRequest_create0() returns a signed receipt request structure or
|
||||
NULL if an error occurred.
|
||||
CMS_ReceiptRequest_create0_with_libctx() and CMS_ReceiptRequest_create0() return
|
||||
a signed receipt request structure or NULL if an error occurred.
|
||||
|
||||
CMS_add1_ReceiptRequest() returns 1 for success or 0 if an error occurred.
|
||||
|
||||
@ -66,9 +76,13 @@ L<ERR_get_error(3)>, L<CMS_sign(3)>,
|
||||
L<CMS_sign_receipt(3)>, L<CMS_verify(3)>
|
||||
L<CMS_verify_receipt(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The function CMS_ReceiptRequest_create0_with_libctx() was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -2,27 +2,36 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_sign - create a CMS SignedData structure
|
||||
CMS_sign, CMS_sign_with_libctx - create a CMS SignedData structure
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, BIO *data,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx, const char *propq);
|
||||
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||
BIO *data, unsigned int flags);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
CMS_sign() creates and returns a CMS SignedData structure. B<signcert> is
|
||||
the certificate to sign with, B<pkey> is the corresponding private key.
|
||||
B<certs> is an optional additional set of certificates to include in the CMS
|
||||
structure (for example any intermediate CAs in the chain). Any or all of
|
||||
these parameters can be B<NULL>, see B<NOTES> below.
|
||||
CMS_sign_with_libctx() creates and returns a CMS SignedData structure.
|
||||
I<signcert> is the certificate to sign with, I<pkey> is the corresponding
|
||||
private key. I<certs> is an optional additional set of certificates to include
|
||||
in the CMS structure (for example any intermediate CAs in the chain). The
|
||||
library context I<libctx> and the property query I<propq> are used when
|
||||
retrieving algorithms from providers. Any or all of these parameters can be
|
||||
B<NULL>, see B<NOTES> below.
|
||||
|
||||
The data to be signed is read from BIO B<data>.
|
||||
|
||||
B<flags> is an optional set of flags.
|
||||
|
||||
CMS_sign() is similar to CMS_sign_with_libctx() but uses default values of NULL
|
||||
for the library context I<libctx> and the property query I<propq>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
Any of the following flags (ored together) can be passed in the B<flags>
|
||||
@ -57,7 +66,8 @@ omitted.
|
||||
If present the SMIMECapabilities attribute indicates support for the following
|
||||
algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
|
||||
bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
|
||||
If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
|
||||
If any of these algorithms is not available then it will not be included:
|
||||
for example the GOST algorithms will not be included if the GOST ENGINE is
|
||||
not loaded.
|
||||
|
||||
OpenSSL will by default identify signing certificates using issuer name
|
||||
@ -105,8 +115,9 @@ Some attributes such as counter signatures are not supported.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
CMS_sign() returns either a valid CMS_ContentInfo structure or NULL if an error
|
||||
occurred. The error can be obtained from ERR_get_error(3).
|
||||
CMS_sign_with_libctx() and CMS_sign() return either a valid CMS_ContentInfo
|
||||
structure or NULL if an error occurred. The error can be obtained from
|
||||
ERR_get_error(3).
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
@ -117,6 +128,8 @@ L<ERR_get_error(3)>, L<CMS_verify(3)>
|
||||
The B<CMS_STREAM> flag is only supported for detached data in OpenSSL 0.9.8,
|
||||
it is supported for embedded data in OpenSSL 1.0.0 and later.
|
||||
|
||||
The CMS_sign_with_libctx() method was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SMIME_read_CMS - parse S/MIME message
|
||||
SMIME_read_CMS_ex, SMIME_read_CMS - parse S/MIME message
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cms.h>
|
||||
|
||||
CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont,
|
||||
CMS_ContentInfo **cms);
|
||||
CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -22,6 +24,11 @@ written to B<*bcont>, otherwise B<*bcont> is set to NULL.
|
||||
The parsed CMS_ContentInfo structure is returned or NULL if an
|
||||
error occurred.
|
||||
|
||||
SMIME_read_CMS_ex() is similar to SMIME_read_CMS() but can optionally supply a
|
||||
previously created I<cms> CMS_ContentInfo object. If I<cms> is NULL then it is
|
||||
identical to SMIME_read_CMS().
|
||||
To create a I<cms> object use L<CMS_ContentInfo_new_with_libctx(3)>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can
|
||||
@ -53,16 +60,22 @@ should be available.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL>
|
||||
if an error occurred. The error can be obtained from ERR_get_error(3).
|
||||
SMIME_read_CMS_ex() and SMIME_read_CMS() return a valid B<CMS_ContentInfo>
|
||||
structure or B<NULL> if an error occurred. The error can be obtained from
|
||||
ERR_get_error(3).
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ERR_get_error(3)>,
|
||||
L<SMIME_read_CMS(3)>, L<CMS_sign(3)>,
|
||||
L<CMS_verify(3)>, L<CMS_encrypt(3)>,
|
||||
L<CMS_sign(3)>,
|
||||
L<CMS_verify(3)>,
|
||||
L<CMS_encrypt(3)>,
|
||||
L<CMS_decrypt(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The function SMIME_read_CMS_ex() was added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
@ -45,6 +45,9 @@ DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
|
||||
DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
|
||||
|
||||
CMS_ContentInfo *CMS_ContentInfo_new_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *propq);
|
||||
|
||||
# define CMS_SIGNERINFO_ISSUER_SERIAL 0
|
||||
# define CMS_SIGNERINFO_KEYIDENTIFIER 1
|
||||
|
||||
@ -104,6 +107,7 @@ int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
|
||||
int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
|
||||
int flags);
|
||||
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
|
||||
CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **ci);
|
||||
int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
|
||||
|
||||
int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
|
||||
@ -112,6 +116,10 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
|
||||
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, BIO *data,
|
||||
unsigned int flags);
|
||||
CMS_ContentInfo *CMS_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
|
||||
STACK_OF(X509) *certs, BIO *data,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx, const char *propq);
|
||||
|
||||
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
X509 *signcert, EVP_PKEY *pkey,
|
||||
@ -119,11 +127,18 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||
|
||||
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
|
||||
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
|
||||
CMS_ContentInfo *CMS_data_create_with_libctx(BIO *in, unsigned int flags,
|
||||
OPENSSL_CTX *ctx,
|
||||
const char *propq);
|
||||
|
||||
int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||
unsigned int flags);
|
||||
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||
unsigned int flags);
|
||||
CMS_ContentInfo *CMS_digest_create_with_libctx(BIO *in, const EVP_MD *md,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx,
|
||||
const char *propq);
|
||||
|
||||
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||
const unsigned char *key, size_t keylen,
|
||||
@ -132,6 +147,13 @@ int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
size_t keylen, unsigned int flags);
|
||||
CMS_ContentInfo *CMS_EncryptedData_encrypt_with_libctx(BIO *in,
|
||||
const EVP_CIPHER *cipher,
|
||||
const unsigned char *key,
|
||||
size_t keylen,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx,
|
||||
const char *propq);
|
||||
|
||||
int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||
const unsigned char *key, size_t keylen);
|
||||
@ -147,12 +169,17 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
|
||||
|
||||
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
||||
const EVP_CIPHER *cipher, unsigned int flags);
|
||||
CMS_ContentInfo *CMS_encrypt_with_libctx(STACK_OF(X509) *certs,
|
||||
BIO *in, const EVP_CIPHER *cipher,
|
||||
unsigned int flags,
|
||||
OPENSSL_CTX *ctx, const char *propq);
|
||||
|
||||
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
|
||||
BIO *dcont, BIO *out, unsigned int flags);
|
||||
|
||||
int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
|
||||
int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer);
|
||||
int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
|
||||
X509 *cert, X509 *peer);
|
||||
int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
|
||||
unsigned char *key, size_t keylen,
|
||||
const unsigned char *id, size_t idlen);
|
||||
@ -163,6 +190,10 @@ STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
|
||||
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
|
||||
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
|
||||
CMS_ContentInfo *CMS_EnvelopedData_create_with_libctx(const EVP_CIPHER *cipher,
|
||||
OPENSSL_CTX *ctx,
|
||||
const char *propq);
|
||||
|
||||
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||
X509 *recip, unsigned int flags);
|
||||
CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
|
||||
@ -297,11 +328,16 @@ void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||
int lastpos, int type);
|
||||
|
||||
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES)
|
||||
*receiptList, STACK_OF(GENERAL_NAMES)
|
||||
*receiptsTo);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList,
|
||||
STACK_OF(GENERAL_NAMES) *receiptsTo);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0_with_libctx(
|
||||
unsigned char *id, int idlen, int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES) *receiptList,
|
||||
STACK_OF(GENERAL_NAMES) *receiptsTo,
|
||||
OPENSSL_CTX *ctx, const char *propq);
|
||||
|
||||
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
|
||||
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||
ASN1_STRING **pcid,
|
||||
|
Loading…
x
Reference in New Issue
Block a user