diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2008-03-14 19:37:56 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2008-03-14 19:37:56 +0000 |
commit | 320bfc1be79513f2a782f9ee8894cf7a7b9ffe2d (patch) | |
tree | 88b544dce8cf3d100cee2b1f4f286eefbf106270 /crypto/cms/cms_enc.c | |
parent | b820455c6e0aa38e7bdf121ec971f72e0eb097d0 (diff) |
Reorganise encrypted content info code to avoid duplication and be more
consistent with other content types.
Diffstat (limited to 'crypto/cms/cms_enc.c')
-rw-r--r-- | crypto/cms/cms_enc.c | 195 |
1 files changed, 112 insertions, 83 deletions
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index b395bc499b..ccb436f098 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -63,135 +63,164 @@ /* CMS EncryptedData Utilities */ -/* Set up EncryptedContentInfo based on supplied cipher bio */ +DECLARE_ASN1_ITEM(CMS_EncryptedData) -int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec, - const unsigned char *key, int keylen, - BIO *b) +/* Return BIO based on EncryptedContentInfo and key */ + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) { - EVP_CIPHER_CTX *ctx = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH], *piv; - int ivlen; + BIO *b; + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *ciph; + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; - BIO_get_cipher_ctx(b, &ctx); + int enc; - /* If necessary set key length */ + enc = ec->cipher ? 1 : 0; - if (keylen != EVP_CIPHER_CTX_key_length(ctx)) + b = BIO_new(BIO_f_cipher()); + if (!b) { - if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) - { - CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, - CMS_R_INVALID_KEY_LENGTH); - return 0; - } + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + ERR_R_MALLOC_FAILURE); + return NULL; } - /* Generate a random IV if we need one */ + BIO_get_cipher_ctx(b, &ctx); - ivlen = EVP_CIPHER_CTX_iv_length(ctx); - if (ivlen > 0) - { - if (RAND_pseudo_bytes(iv, ivlen) <= 0) - return 0; - piv = iv; - } + if (enc) + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); else - piv = NULL; - - if (EVP_CipherInit_ex(ctx, NULL, NULL, key, piv, 1) <= 0) { - CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, - CMS_R_CIPHER_INITIALISATION_ERROR); - return 0; - } + ciph = EVP_get_cipherbyobj(calg->algorithm); - ec->contentEncryptionAlgorithm->algorithm = - OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); - - if (piv) - { - ec->contentEncryptionAlgorithm->parameter = ASN1_TYPE_new(); - if (!ec->contentEncryptionAlgorithm->parameter) - { - CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, - ERR_R_MALLOC_FAILURE); - return 0; - } - if (EVP_CIPHER_param_to_asn1(ctx, - ec->contentEncryptionAlgorithm->parameter) <= 0) + if (!ciph) { - CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - return 0; + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_UNKNOWN_CIPHER); + goto err; } } - return 1; - } - -/* Return BIO based on EncryptedContentInfo and key */ - -int cms_EncryptedContent_to_bio(BIO *b, CMS_EncryptedContentInfo *ec, - const unsigned char *key, int keylen) - { - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *ciph; - BIO_get_cipher_ctx(b, &ctx); - - ciph = EVP_get_cipherbyobj(ec->contentEncryptionAlgorithm->algorithm); - - if (!ciph) + if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, CMS_R_UNKNOWN_CIPHER); - goto err; - } - - if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, 0) <= 0) - { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } /* If necessary set key length */ - if (keylen != EVP_CIPHER_CTX_key_length(ctx)) + if (ec->keylen != EVP_CIPHER_CTX_key_length(ctx)) { - if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) + if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_INVALID_KEY_LENGTH); goto err; } } - if (EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 0) <= 0) + if (enc) + { + int ivlen; + /* Generate a random IV if we need one */ + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivlen > 0) + { + if (RAND_pseudo_bytes(iv, ivlen) <= 0) + goto err; + piv = iv; + } + } + else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } - if (EVP_CIPHER_asn1_to_param(ctx, - ec->contentEncryptionAlgorithm->parameter) <= 0) + if (piv) + { + calg->parameter = ASN1_TYPE_new(); + if (!calg->parameter) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } - return 1; + } + return b; err: - return 0; + BIO_free(b); + return NULL; } -int CMS_EncryptedData_set1_key(BIO *b, CMS_ContentInfo *cms, +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen) + { + ec->cipher = cipher; + ec->key = OPENSSL_malloc(keylen); + if (!ec->key) + return 0; + if (cipher) + ec->contentType = OBJ_nid2obj(NID_pkcs7_data); + memcpy(ec->key, key, keylen); + ec->keylen = keylen; + return 1; + } + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, const unsigned char *key, size_t keylen) { CMS_EncryptedContentInfo *ec; - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) + if (ciph) + { + cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); + if (!cms->d.encryptedData) + { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, + ERR_R_MALLOC_FAILURE); + return 0; + } + cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); + cms->d.encryptedData->version = 0; + } + else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) + { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, + CMS_R_NOT_ENCRYPTED_DATA); return 0; + } + ec = cms->d.encryptedData->encryptedContentInfo; + return cms_EncryptedContent_init(ec, ciph, key, keylen); + } + +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) + { + CMS_EncryptedContentInfo *ec; + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) + { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO, + CMS_R_NOT_ENCRYPTED_DATA); + return NULL; + } ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_to_bio(b, ec, key, keylen); + return cms_EncryptedContent_init_bio(ec); } |