From: Dr. Stephen Henson Date: Fri, 14 Mar 2008 00:58:43 +0000 (+0000) Subject: New utility functions for encryptedData content type which will also be used X-Git-Tag: OpenSSL_0_9_8k^2~534 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=5c4436c97759a98794cd84dc37c937fa637aad61 New utility functions for encryptedData content type which will also be used by envelopedData. Use PRE and not POST when freeing up RecipientInfo. --- diff --git a/crypto/cms/Makefile b/crypto/cms/Makefile index fdca7fe6e3..abb8d83f76 100644 --- a/crypto/cms/Makefile +++ b/crypto/cms/Makefile @@ -18,9 +18,9 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \ - cms_sd.c cms_dd.c cms_cd.c cms_env.c + cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \ - cms_sd.o cms_dd.o cms_cd.o cms_env.o + cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o SRC= $(LIBSRC) diff --git a/crypto/cms/cms.h b/crypto/cms/cms.h index 2f45f57df2..0df4b0f4cf 100644 --- a/crypto/cms/cms.h +++ b/crypto/cms/cms.h @@ -241,6 +241,7 @@ void ERR_load_CMS_strings(void); #define CMS_F_CMS_ADD1_RECIPIENT_CERT 99 #define CMS_F_CMS_ADD1_SIGNER 100 #define CMS_F_CMS_ADD1_SIGNINGTIME 101 +#define CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT 137 #define CMS_F_CMS_COMPRESS 102 #define CMS_F_CMS_COMPRESSEDDATA_CREATE 103 #define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 104 @@ -253,6 +254,7 @@ void ERR_load_CMS_strings(void); #define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 111 #define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 112 #define CMS_F_CMS_DIGEST_VERIFY 113 +#define CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO 138 #define CMS_F_CMS_ENVELOPED_DATA_INIT 114 #define CMS_F_CMS_FINAL 115 #define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 116 @@ -280,6 +282,8 @@ void ERR_load_CMS_strings(void); /* Reason codes. */ #define CMS_R_ADD_SIGNER_ERROR 99 #define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +#define CMS_R_CIPHER_INITIALISATION_ERROR 138 +#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 139 #define CMS_R_CMS_DATAFINAL_ERROR 101 #define CMS_R_CONTENT_NOT_FOUND 102 #define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 103 @@ -290,6 +294,7 @@ void ERR_load_CMS_strings(void); #define CMS_R_CTRL_FAILURE 108 #define CMS_R_ERROR_GETTING_PUBLIC_KEY 109 #define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 110 +#define CMS_R_INVALID_KEY_LENGTH 140 #define CMS_R_MD_BIO_INIT_ERROR 111 #define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 112 #define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 113 @@ -311,6 +316,7 @@ void ERR_load_CMS_strings(void); #define CMS_R_TYPE_NOT_DATA 129 #define CMS_R_TYPE_NOT_DIGESTED_DATA 130 #define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 131 +#define CMS_R_UNKNOWN_CIPHER 141 #define CMS_R_UNKNOWN_DIGEST_ALGORIHM 132 #define CMS_R_UNKNOWN_ID 133 #define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 134 diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c index 918dd0f30c..b9521c9a5a 100644 --- a/crypto/cms/cms_asn1.c +++ b/crypto/cms/cms_asn1.c @@ -216,7 +216,7 @@ ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) { - if(operation == ASN1_OP_FREE_POST) + if(operation == ASN1_OP_FREE_PRE) { CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; if (ri->type == CMS_RECIPINFO_TRANS) diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c new file mode 100644 index 0000000000..084bc12466 --- /dev/null +++ b/crypto/cms/cms_enc.c @@ -0,0 +1,196 @@ +/* crypto/cms/cms_enc.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 +#include +#include +#include +#include +#include +#include "cms_lcl.h" +#include "asn1_locl.h" + +/* CMS EncryptedData Utilities */ + +/* Set up EncryptedContentInfo based on supplied cipher bio */ + +int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec, + const unsigned char *key, int keylen, + BIO *b) + { + EVP_CIPHER_CTX *ctx = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv; + int ivlen; + + BIO_get_cipher_ctx(b, &ctx); + + /* If necessary set key length */ + + if (keylen != EVP_CIPHER_CTX_key_length(ctx)) + { + if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) + { + CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, + CMS_R_INVALID_KEY_LENGTH); + return 0; + } + } + + /* 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) + return 0; + piv = iv; + } + 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; + } + + 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) + { + CMSerr(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + return 0; + } + } + + return 1; + } + +/* Return BIO based on EncryptedContentInfo and key */ + +BIO *cms_EncryptedContent_to_bio(CMS_EncryptedContentInfo *ec, + const unsigned char *key, int keylen) + { + BIO *b; + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *ciph; + b = BIO_new(BIO_f_cipher()); + if (!b) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + BIO_get_cipher_ctx(b, &ctx); + + ciph = EVP_get_cipherbyobj(ec->contentEncryptionAlgorithm->algorithm); + + if (!ciph) + { + 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, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + /* If necessary set key length */ + + if (keylen != EVP_CIPHER_CTX_key_length(ctx)) + { + if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMS_R_INVALID_KEY_LENGTH); + goto err; + } + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 0) <= 0) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + if (EVP_CIPHER_asn1_to_param(ctx, + ec->contentEncryptionAlgorithm->parameter) <= 0) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + return b; + + err: + BIO_free(b); + return NULL; + } + diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index 238198543d..3a5991e016 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "cms_lcl.h" #include "asn1_locl.h" @@ -66,12 +67,6 @@ DECLARE_ASN1_ITEM(CMS_EnvelopedData) DECLARE_ASN1_ITEM(CMS_RecipientInfo) DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) -#if 0 -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_EnvelopedData) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_RecipientInfo) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_KeyTransRecipientInfo) -#endif - DECLARE_STACK_OF(CMS_RecipientInfo) static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index a2c7c1b216..8a45c059a8 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -73,6 +73,7 @@ static ERR_STRING_DATA CMS_str_functs[]= {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_ADD1_RECIPIENT_CERT"}, {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"}, {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"}, +{ERR_FUNC(CMS_F_CMS_BIO_TO_ENCRYPTEDCONTENT), "CMS_BIO_TO_ENCRYPTEDCONTENT"}, {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"}, {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "CMS_COMPRESSEDDATA_CREATE"}, {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), "CMS_COMPRESSEDDATA_INIT_BIO"}, @@ -85,6 +86,7 @@ static ERR_STRING_DATA CMS_str_functs[]= {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), "CMS_DIGESTALGORITHM_INIT_BIO"}, {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"}, {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"}, +{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO), "CMS_ENCRYPTEDCONTENT_TO_BIO"}, {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"}, {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"}, {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"}, @@ -115,6 +117,8 @@ static ERR_STRING_DATA CMS_str_reasons[]= { {ERR_REASON(CMS_R_ADD_SIGNER_ERROR) ,"add signer error"}, {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"}, +{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"}, +{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"}, {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"}, {ERR_REASON(CMS_R_CONTENT_NOT_FOUND) ,"content not found"}, {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"}, @@ -125,6 +129,7 @@ static ERR_STRING_DATA CMS_str_reasons[]= {ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"}, {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"}, {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"}, +{ERR_REASON(CMS_R_INVALID_KEY_LENGTH) ,"invalid key length"}, {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR) ,"md bio init error"}, {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"}, {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"}, @@ -146,6 +151,7 @@ static ERR_STRING_DATA CMS_str_reasons[]= {ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"}, {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"}, {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"}, +{ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"}, {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"}, {ERR_REASON(CMS_R_UNKNOWN_ID) ,"unknown id"}, {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, diff --git a/test/runex.pl b/test/runex.pl index 1d77c88d12..1c7431b865 100644 --- a/test/runex.pl +++ b/test/runex.pl @@ -56,8 +56,8 @@ my $badttest = 0; my $verbose = 1; -my $cmscmd = "../apps/openssl cms"; -my $convcmd = "../apps/openssl x509 -inform DER"; +my $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms"; +my $convcmd = "../util/shlib_wrap.sh ../apps/openssl x509 -inform DER"; my $exdir = "examples"; my @test_list = (