diff options
author | Matt Caswell <matt@openssl.org> | 2015-01-22 03:40:55 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2015-01-22 09:20:09 +0000 |
commit | 0f113f3ee4d629ef9a4a30911b22b224772085e5 (patch) | |
tree | e014603da5aed1d0751f587a66d6e270b6bda3de /crypto/cms/cms_env.c | |
parent | 22b52164aaed31d6e93dbd2d397ace041360e6aa (diff) |
Run util/openssl-format-source -v -c .
Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'crypto/cms/cms_env.c')
-rw-r--r-- | crypto/cms/cms_env.c | 1699 |
1 files changed, 810 insertions, 889 deletions
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index b6b6ca1696..93c06cb00a 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -1,5 +1,6 @@ /* crypto/cms/cms_env.c */ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== @@ -10,7 +11,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -72,982 +73,902 @@ 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; - } +{ + 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); - } +{ + 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); +} int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) - { - EVP_PKEY *pkey; - int i; - if (ri->type == CMS_RECIPINFO_TRANS) - pkey = ri->d.ktri->pkey; - else if (ri->type == CMS_RECIPINFO_AGREE) - { - EVP_PKEY_CTX *pctx = ri->d.kari->pctx; - if (!pctx) - return 0; - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pkey) - return 0; - } - else - return 0; - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) - return 1; - i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); - if (i == -2) - { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; - } - if (i <= 0) - { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE); - return 0; - } - return 1; - } +{ + EVP_PKEY *pkey; + int i; + if (ri->type == CMS_RECIPINFO_TRANS) + pkey = ri->d.ktri->pkey; + else if (ri->type == CMS_RECIPINFO_AGREE) { + EVP_PKEY_CTX *pctx = ri->d.kari->pctx; + if (!pctx) + return 0; + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pkey) + return 0; + } else + return 0; + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return 1; + i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); + if (i == -2) { + CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + if (i <= 0) { + CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE); + return 0; + } + return 1; +} 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; - } +{ + 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; - } +{ + return ri->type; +} EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) - { - if (ri->type == CMS_RECIPINFO_TRANS) - return ri->d.ktri->pctx; - else if (ri->type == CMS_RECIPINFO_AGREE) - return ri->d.kari->pctx; - return NULL; - } +{ + if (ri->type == CMS_RECIPINFO_TRANS) + return ri->d.ktri->pctx; + else if (ri->type == CMS_RECIPINFO_AGREE) + return ri->d.kari->pctx; + return NULL; +} 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; - } +{ + 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 */ /* 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) - { - CMS_KeyTransRecipientInfo *ktri; - int idtype; - - ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); - if (!ri->d.ktri) - return 0; - ri->type = CMS_RECIPINFO_TRANS; - - ktri = ri->d.ktri; - - if (flags & CMS_USE_KEYID) - { - ktri->version = 2; - idtype = CMS_RECIPINFO_KEYIDENTIFIER; - } - else - { - ktri->version = 0; - idtype = CMS_RECIPINFO_ISSUER_SERIAL; - } - - /* Not a typo: RecipientIdentifier and SignerIdentifier are the - * same structure. - */ - - if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) - return 0; - - CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); - CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); - ktri->pkey = pk; - ktri->recip = recip; - - if (flags & CMS_KEY_PARAM) - { - ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); - if (!ktri->pctx) - return 0; - if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) - return 0; - } - else if (!cms_env_asn1_ctrl(ri, 0)) - return 0; - return 1; - } - -/* Add a recipient certificate using appropriate type of RecipientInfo + EVP_PKEY *pk, unsigned int flags) +{ + CMS_KeyTransRecipientInfo *ktri; + int idtype; + + ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); + if (!ri->d.ktri) + return 0; + ri->type = CMS_RECIPINFO_TRANS; + + ktri = ri->d.ktri; + + if (flags & CMS_USE_KEYID) { + ktri->version = 2; + idtype = CMS_RECIPINFO_KEYIDENTIFIER; + } else { + ktri->version = 0; + idtype = CMS_RECIPINFO_ISSUER_SERIAL; + } + + /* + * Not a typo: RecipientIdentifier and SignerIdentifier are the same + * structure. + */ + + if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) + return 0; + + CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); + CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); + ktri->pkey = pk; + ktri->recip = recip; + + if (flags & CMS_KEY_PARAM) { + ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!ktri->pctx) + return 0; + if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) + return 0; + } else if (!cms_env_asn1_ctrl(ri, 0)) + return 0; + return 1; +} + +/* + * Add a recipient certificate using appropriate type of RecipientInfo */ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags) - { - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; - EVP_PKEY *pk = NULL; - env = cms_get0_enveloped(cms); - if (!env) - goto err; - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - pk = X509_get_pubkey(recip); - if (!pk) - { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_ERROR_GETTING_PUBLIC_KEY); - goto err; - } - - switch (cms_pkey_get_ri_type(pk)) - { - - case CMS_RECIPINFO_TRANS: - if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) - goto err; - break; - - case CMS_RECIPINFO_AGREE: - if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) - goto err; - break; - - default: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - - } - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - EVP_PKEY_free(pk); - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); - err: - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - if (pk) - EVP_PKEY_free(pk); - return NULL; - - } + X509 *recip, unsigned int flags) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + EVP_PKEY *pk = NULL; + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + pk = X509_get_pubkey(recip); + if (!pk) { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); + goto err; + } + + switch (cms_pkey_get_ri_type(pk)) { + + case CMS_RECIPINFO_TRANS: + if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) + goto err; + break; + + case CMS_RECIPINFO_AGREE: + if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) + goto err; + break; + + default: + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + EVP_PKEY_free(pk); + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); + err: + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + if (pk) + EVP_PKEY_free(pk); + 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; - } + 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); - } + 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); - } +{ + 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; - } +{ + 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; - 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 = ktri->pctx; - - if (pctx) - { - if (!cms_env_asn1_ctrl(ri, 0)) - goto err; - } - else - { - 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); - ktri->pctx = NULL; - } - if (ek) - OPENSSL_free(ek); - return ret; - - } + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri; + CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx; + 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 = ktri->pctx; + + if (pctx) { + if (!cms_env_asn1_ctrl(ri, 0)) + goto err; + } else { + 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); + ktri->pctx = NULL; + } + 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 *pkey = ktri->pkey; - 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; - } - - ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ktri->pctx) - return 0; - - if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) - goto err; - - if (!cms_env_asn1_ctrl(ri, 1)) - goto err; - - if (EVP_PKEY_CTX_ctrl(ktri->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(ktri->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(ktri->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 (ktri->pctx) - { - EVP_PKEY_CTX_free(ktri->pctx); - ktri->pctx = NULL; - } - if (!ret && ek) - OPENSSL_free(ek); - - return ret; - } + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY *pkey = ktri->pkey; + 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; + } + + ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ktri->pctx) + return 0; + + if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) + goto err; + + if (!cms_env_asn1_ctrl(ri, 1)) + goto err; + + if (EVP_PKEY_CTX_ctrl(ktri->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(ktri->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(ktri->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 (ktri->pctx) { + EVP_PKEY_CTX_free(ktri->pctx); + ktri->pctx = NULL; + } + 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); - } +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; +{ + switch (nid) { + case NID_id_aes128_wrap: + return 16; - case NID_id_aes192_wrap: - return 24; + case NID_id_aes192_wrap: + return 24; - case NID_id_aes256_wrap: - return 32; + case NID_id_aes256_wrap: + return 32; - default: - return 0; - } - } + 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; + 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; -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; - } + 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-& |