diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2010-02-07 13:41:23 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2010-02-07 13:41:23 +0000 |
commit | 1700426256fcf906e730531791fc95fea3db139a (patch) | |
tree | 65ad51ff567be401248674a8c1e22790670dd04a /crypto/evp | |
parent | aa7f5baad27729b819bced7040957dc401ed2b46 (diff) |
Add missing function EVP_CIPHER_CTX_copy(). Current code uses memcpy() to copy
an EVP_CIPHER_CTX structure which may have problems with external ENGINEs
who need to duplicate internal handles etc.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/bio_enc.c | 6 | ||||
-rw-r--r-- | crypto/evp/evp.h | 5 | ||||
-rw-r--r-- | crypto/evp/evp_enc.c | 35 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 1 |
4 files changed, 45 insertions, 2 deletions
diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c index f6ac94c6e1..b6efb5fbc4 100644 --- a/crypto/evp/bio_enc.c +++ b/crypto/evp/bio_enc.c @@ -361,8 +361,10 @@ again: case BIO_CTRL_DUP: dbio=(BIO *)ptr; dctx=(BIO_ENC_CTX *)dbio->ptr; - memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher)); - dbio->init=1; + EVP_CIPHER_CTX_init(&dctx->cipher); + ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher); + if (ret) + dbio->init=1; break; default: ret=BIO_ctrl(b->next_bio,cmd,num,ptr); diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 35e7847342..26acd646ca 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -340,6 +340,8 @@ struct evp_cipher_st #define EVP_CIPH_NO_PADDING 0x100 /* cipher handles random key generation */ #define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x200 /* ctrl() values */ @@ -351,6 +353,7 @@ struct evp_cipher_st #define EVP_CTRL_SET_RC5_ROUNDS 0x5 #define EVP_CTRL_RAND_KEY 0x6 #define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 typedef struct evp_cipher_info_st { @@ -449,6 +452,7 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) @@ -1190,6 +1194,7 @@ void ERR_load_EVP_strings(void); #define EVP_F_ECDSA_PKEY2PKCS8 129 #define EVP_F_ECKEY_PKEY2PKCS8 132 #define EVP_F_EVP_CIPHERINIT_EX 123 +#define EVP_F_EVP_CIPHER_CTX_COPY 163 #define EVP_F_EVP_CIPHER_CTX_CTRL 124 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 #define EVP_F_EVP_DECRYPTFINAL_EX 101 diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 6e582c458d..fa786406ee 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -566,3 +566,38 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) return 1; } +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) + { + if ((in == NULL) || (in->cipher == NULL)) + { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a digest context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) + { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB); + return 0; + } +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out,in,sizeof *out); + + if (in->cipher_data && in->cipher->ctx_size) + { + out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) + { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size); + } + + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) + return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); + return 1; + } + diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index d4bdf51384..d8bfec0959 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -79,6 +79,7 @@ static ERR_STRING_DATA EVP_str_functs[]= {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, +{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"}, {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, |