#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)
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;
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;
/* 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;
ri->type = CMS_RECIPINFO_TRANS;
ktri = ri->d.ktri;
+ ktri->cms_ctx = ctx;
if (flags & CMS_USE_KEYID) {
ktri->version = 2;
* structure.
*/
- if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
+ if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
return 0;
X509_up_ref(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)
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;
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;
EVP_PKEY_CTX *pctx;
unsigned char *ek = NULL;
size_t eklen;
+ const CMS_CTX *ctx = cms_get0_cmsctx(cms);
int ret = 0;
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;
ktri->pctx = NULL;
OPENSSL_free(ek);
return ret;
-
}
/* Decrypt content key from KTRI */
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) {
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;
err:
M_ASN1_free_of(ri, CMS_RecipientInfo);
return NULL;
-
}
int CMS_RecipientInfo_kekri_get0_id(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);
}
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;
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;
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 */
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;
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;
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)
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)
/* 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)
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;
}