diff options
author | Parménides GV <parmegv@sdf.org> | 2015-06-04 19:20:15 +0200 |
---|---|---|
committer | Parménides GV <parmegv@sdf.org> | 2015-06-04 19:20:15 +0200 |
commit | 27594eeae6f40a402bc3110f06d57975168e74e3 (patch) | |
tree | cdabf6571e6f4ff07205fd6921d8095539a1fcdc /app/openssl/crypto/cms/cms_env.c | |
parent | 8dc4f58d96892fbfd83094fb85b1d17656035290 (diff) |
ics-openvpn as a submodule! beautiful
ics-openvpn is now officially on GitHub, and they track openssl and
openvpn as submodules, so it's easier to update everything. Just a git
submodule update --recursive.
I've also set up soft links to native modules from ics-openvpn in app,
so that we don't copy files in Gradle (which was causing problems with
the submodules .git* files, not being copied). That makes the repo
cleaner.
Diffstat (limited to 'app/openssl/crypto/cms/cms_env.c')
-rw-r--r-- | app/openssl/crypto/cms/cms_env.c | 878 |
1 files changed, 0 insertions, 878 deletions
diff --git a/app/openssl/crypto/cms/cms_env.c b/app/openssl/crypto/cms/cms_env.c deleted file mode 100644 index add00bf9..00000000 --- a/app/openssl/crypto/cms/cms_env.c +++ /dev/null @@ -1,878 +0,0 @@ -/* crypto/cms/cms_env.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "cryptlib.h" -#include <openssl/asn1t.h> -#include <openssl/pem.h> -#include <openssl/x509v3.h> -#include <openssl/err.h> -#include <openssl/cms.h> -#include <openssl/rand.h> -#include <openssl/aes.h> -#include "cms_lcl.h" -#include "asn1_locl.h" - -/* CMS EnvelopedData Utilities */ - -DECLARE_ASN1_ITEM(CMS_EnvelopedData) -DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) -DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) -DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) - -DECLARE_STACK_OF(CMS_RecipientInfo) - -CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) - { - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) - { - CMSerr(CMS_F_CMS_GET0_ENVELOPED, - CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); - return NULL; - } - return cms->d.envelopedData; - } - -static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) - { - if (cms->d.other == NULL) - { - cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); - if (!cms->d.envelopedData) - { - CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, - ERR_R_MALLOC_FAILURE); - return NULL; - } - cms->d.envelopedData->version = 0; - cms->d.envelopedData->encryptedContentInfo->contentType = - OBJ_nid2obj(NID_pkcs7_data); - ASN1_OBJECT_free(cms->contentType); - cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); - return cms->d.envelopedData; - } - return cms_get0_enveloped(cms); - } - -STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) - { - CMS_EnvelopedData *env; - env = cms_get0_enveloped(cms); - if (!env) - return NULL; - return env->recipientInfos; - } - -int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) - { - return ri->type; - } - -CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) - { - CMS_ContentInfo *cms; - CMS_EnvelopedData *env; - cms = CMS_ContentInfo_new(); - if (!cms) - goto merr; - env = cms_enveloped_data_init(cms); - if (!env) - goto merr; - if (!cms_EncryptedContent_init(env->encryptedContentInfo, - cipher, NULL, 0)) - goto merr; - return cms; - merr: - if (cms) - CMS_ContentInfo_free(cms); - CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); - return NULL; - } - -/* Key Transport Recipient Info (KTRI) routines */ - -/* Add a recipient certificate. For now only handle key transport. - * If we ever handle key agreement will need updating. - */ - -CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags) - { - CMS_RecipientInfo *ri = NULL; - CMS_KeyTransRecipientInfo *ktri; - CMS_EnvelopedData *env; - EVP_PKEY *pk = NULL; - int i, type; - env = cms_get0_enveloped(cms); - if (!env) - goto err; - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - /* Initialize and add key transport recipient info */ - - ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); - if (!ri->d.ktri) - goto merr; - ri->type = CMS_RECIPINFO_TRANS; - - ktri = ri->d.ktri; - - X509_check_purpose(recip, -1, -1); - pk = X509_get_pubkey(recip); - if (!pk) - { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_ERROR_GETTING_PUBLIC_KEY); - goto err; - } - CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); - ktri->pkey = pk; - ktri->recip = recip; - - if (flags & CMS_USE_KEYID) - { - ktri->version = 2; - if (env->version < 2) - env->version = 2; - type = CMS_RECIPINFO_KEYIDENTIFIER; - } - else - { - ktri->version = 0; - type = CMS_RECIPINFO_ISSUER_SERIAL; - } - - /* Not a typo: RecipientIdentifier and SignerIdentifier are the - * same structure. - */ - - if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) - goto err; - - if (pk->ameth && pk->ameth->pkey_ctrl) - { - i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, - 0, ri); - if (i == -2) - { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - } - if (i <= 0) - { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_CTRL_FAILURE); - goto err; - } - } - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); - err: - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - return NULL; - - } - -int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, - EVP_PKEY **pk, X509 **recip, - X509_ALGOR **palg) - { - CMS_KeyTransRecipientInfo *ktri; - if (ri->type != CMS_RECIPINFO_TRANS) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - - ktri = ri->d.ktri; - - if (pk) - *pk = ktri->pkey; - if (recip) - *recip = ktri->recip; - if (palg) - *palg = ktri->keyEncryptionAlgorithm; - return 1; - } - -int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, ASN1_INTEGER **sno) - { - CMS_KeyTransRecipientInfo *ktri; - if (ri->type != CMS_RECIPINFO_TRANS) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ktri = ri->d.ktri; - - return cms_SignerIdentifier_get0_signer_id(ktri->rid, - keyid, issuer, sno); - } - -int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) - { - if (ri->type != CMS_RECIPINFO_TRANS) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, - CMS_R_NOT_KEY_TRANSPORT); - return -2; - } - return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); - } - -int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) - { - if (ri->type != CMS_RECIPINFO_TRANS) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ri->d.ktri->pkey = pkey; - return 1; - } - -/* Encrypt content key in key transport recipient info */ - -static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) - { - CMS_KeyTransRecipientInfo *ktri; - CMS_EncryptedContentInfo *ec; - EVP_PKEY_CTX *pctx = NULL; - unsigned char *ek = NULL; - size_t eklen; - - int ret = 0; - - if (ri->type != CMS_RECIPINFO_TRANS) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ktri = ri->d.ktri; - ec = cms->d.envelopedData->encryptedContentInfo; - - pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); - if (!pctx) - return 0; - - if (EVP_PKEY_encrypt_init(pctx) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) - goto err; - - ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); - ek = NULL; - - ret = 1; - - err: - if (pctx) - EVP_PKEY_CTX_free(pctx); - if (ek) - OPENSSL_free(ek); - return ret; - - } - -/* Decrypt content key from KTRI */ - -static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) - { - CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; - EVP_PKEY_CTX *pctx = NULL; - unsigned char *ek = NULL; - size_t eklen; - int ret = 0; - CMS_EncryptedContentInfo *ec; - ec = cms->d.envelopedData->encryptedContentInfo; - - if (ktri->pkey == NULL) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, - CMS_R_NO_PRIVATE_KEY); - return 0; - } - - pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); - if (!pctx) - return 0; - - if (EVP_PKEY_decrypt_init(pctx) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); - goto err; - } - - ret = 1; - - if (ec->key) - { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - } - - ec->key = ek; - ec->keylen = eklen; - - err: - if (pctx) - EVP_PKEY_CTX_free(pctx); - if (!ret && ek) - OPENSSL_free(ek); - - return ret; - } - -/* Key Encrypted Key (KEK) RecipientInfo routines */ - -int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, - const unsigned char *id, size_t idlen) - { - ASN1_OCTET_STRING tmp_os; - CMS_KEKRecipientInfo *kekri; - if (ri->type != CMS_RECIPINFO_KEK) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); - return -2; - } - kekri = ri->d.kekri; - tmp_os.type = V_ASN1_OCTET_STRING; - tmp_os.flags = 0; - tmp_os.data = (unsigned char *)id; - tmp_os.length = (int)idlen; - return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); - } - -/* For now hard code AES key wrap info */ - -static size_t aes_wrap_keylen(int nid) - { - switch (nid) - { - case NID_id_aes128_wrap: - return 16; - - case NID_id_aes192_wrap: - return 24; - - case NID_id_aes256_wrap: - return 32; - - default: - return 0; - } - } - -CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, - unsigned char *key, size_t keylen, - unsigned char *id, size_t idlen, - ASN1_GENERALIZEDTIME *date, - ASN1_OBJECT *otherTypeId, - ASN1_TYPE *otherType) - { - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; - CMS_KEKRecipientInfo *kekri; - env = cms_get0_enveloped(cms); - if (!env) - goto err; - - if (nid == NID_undef) - { - switch (keylen) - { - case 16: - nid = NID_id_aes128_wrap; - break; - - case 24: - nid = NID_id_aes192_wrap; - break; - - case 32: - nid = NID_id_aes256_wrap; - break; - - default: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, - CMS_R_INVALID_KEY_LENGTH); - goto err; - } - - } - else - { - - size_t exp_keylen = aes_wrap_keylen(nid); - - if (!exp_keylen) - { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, - CMS_R_UNSUPPORTED_KEK_ALGORITHM); - goto err; - } - - if (keylen != exp_keylen) - { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, - CMS_R_INVALID_KEY_LENGTH); - goto err; - } - - } - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); - if (!ri->d.kekri) - goto merr; - ri->type = CMS_RECIPINFO_KEK; - - kekri = ri->d.kekri; - - if (otherTypeId) - { - kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); - if (kekri->kekid->other == NULL) - goto merr; - } - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - - /* After this point no calls can fail */ - - kekri->version = 4; - - kekri->key = key; - kekri->keylen = keylen; - - ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); - - kekri->kekid->date = date; - - if (kekri->kekid->other) - { - kekri->kekid->other->keyAttrId = otherTypeId; - kekri->kekid->other->keyAttr = otherType; - } - - X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, - OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); - err: - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - return NULL; - - } - -int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, - X509_ALGOR **palg, - ASN1_OCTET_STRING **pid, - ASN1_GENERALIZEDTIME **pdate, - ASN1_OBJECT **potherid, - ASN1_TYPE **pothertype) - { - CMS_KEKIdentifier *rkid; - if (ri->type != CMS_RECIPINFO_KEK) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); - return 0; - } - rkid = ri->d.kekri->kekid; - if (palg) - *palg = ri->d.kekri->keyEncryptionAlgorithm; - if (pid) - *pid = rkid->keyIdentifier; - if (pdate) - *pdate = rkid->date; - if (potherid) - { - if (rkid->other) - *potherid = rkid->other->keyAttrId; - else - *potherid = NULL; - } - if (pothertype) - { - if (rkid->other) - *pothertype = rkid->other->keyAttr; - else - *pothertype = NULL; - } - return 1; - } - -int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, - unsigned char *key, size_t keylen) - { - CMS_KEKRecipientInfo *kekri; - if (ri->type != CMS_RECIPINFO_KEK) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); - return 0; - } - - kekri = ri->d.kekri; - kekri->key = key; - kekri->keylen = keylen; - return 1; - } - - -/* Encrypt content key in KEK recipient info */ - -static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) - { - CMS_EncryptedContentInfo *ec; - CMS_KEKRecipientInfo *kekri; - AES_KEY actx; - unsigned char *wkey = NULL; - int wkeylen; - int r = 0; - - ec = cms->d.envelopedData->encryptedContentInfo; - - kekri = ri->d.kekri; - - if (!kekri->key) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); - return 0; - } - - if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - CMS_R_ERROR_SETTING_KEY); - goto err; - } - - wkey = OPENSSL_malloc(ec->keylen + 8); - - if (!wkey) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - ERR_R_MALLOC_FAILURE); - goto err; - } - - wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); - - if (wkeylen <= 0) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); - goto err; - } - - ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); - - r = 1; - - err: - - if (!r && wkey) - OPENSSL_free(wkey); - OPENSSL_cleanse(&actx, sizeof(actx)); - - return r; - - } - -/* Decrypt content key in KEK recipient info */ - -static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) - { - CMS_EncryptedContentInfo *ec; - CMS_KEKRecipientInfo *kekri; - AES_KEY actx; - unsigned char *ukey = NULL; - int ukeylen; - int r = 0, wrap_nid; - - ec = cms->d.envelopedData->encryptedContentInfo; - - kekri = ri->d.kekri; - - if (!kekri->key) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); - return 0; - } - - wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); - if (aes_wrap_keylen(wrap_nid) != kekri->keylen) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_KEY_LENGTH); - return 0; - } - - /* If encrypted key length is invalid don't bother */ - - if (kekri->encryptedKey->length < 16) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); - goto err; - } - - if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_ERROR_SETTING_KEY); - goto err; - } - - ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - - if (!ukey) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - ERR_R_MALLOC_FAILURE); - goto err; - } - - ukeylen = AES_unwrap_key(&actx, NULL, ukey, - kekri->encryptedKey->data, - kekri->encryptedKey->length); - - if (ukeylen <= 0) - { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_UNWRAP_ERROR); - goto err; - } - - ec->key = ukey; - ec->keylen = ukeylen; - - r = 1; - - err: - - if (!r && ukey) - OPENSSL_free(ukey); - OPENSSL_cleanse(&actx, sizeof(actx)); - - return r; - - } - -int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) - { - switch(ri->type) - { - case CMS_RECIPINFO_TRANS: - return cms_RecipientInfo_ktri_decrypt(cms, ri); - - case CMS_RECIPINFO_KEK: - return cms_RecipientInfo_kekri_decrypt(cms, ri); - - case CMS_RECIPINFO_PASS: - return cms_RecipientInfo_pwri_crypt(cms, ri, 0); - - default: - CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, - CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); - return 0; - } - } - -BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) - { - CMS_EncryptedContentInfo *ec; - STACK_OF(CMS_RecipientInfo) *rinfos; - CMS_RecipientInfo *ri; - int i, r, ok = 0; - BIO *ret; - - /* Get BIO first to set up key */ - - ec = cms->d.envelopedData->encryptedContentInfo; - ret = cms_EncryptedContent_init_bio(ec); - - /* If error or no cipher end of processing */ - - if (!ret || !ec->cipher) - return ret; - - /* Now encrypt content key according to each RecipientInfo type */ - - rinfos = cms->d.envelopedData->recipientInfos; - - for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) - { - ri = sk_CMS_RecipientInfo_value(rinfos, i); - - switch (ri->type) - { - case CMS_RECIPINFO_TRANS: - r = cms_RecipientInfo_ktri_encrypt(cms, ri); - break; - - case CMS_RECIPINFO_KEK: - r = cms_RecipientInfo_kekri_encrypt(cms, ri); - break; - - case CMS_RECIPINFO_PASS: - r = cms_RecipientInfo_pwri_crypt(cms, ri, 1); - break; - - default: - CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, - CMS_R_UNSUPPORTED_RECIPIENT_TYPE); - goto err; - } - - if (r <= 0) - { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, - CMS_R_ERROR_SETTING_RECIPIENTINFO); - goto err; - } - } - - ok = 1; - - err: - ec->cipher = NULL; - if (ec->key) - { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - ec->key = NULL; - ec->keylen = 0; - } - if (ok) - return ret; - BIO_free(ret); - return NULL; - - } |