summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2010-02-07 13:41:23 +0000
committerDr. Stephen Henson <steve@openssl.org>2010-02-07 13:41:23 +0000
commit1700426256fcf906e730531791fc95fea3db139a (patch)
tree65ad51ff567be401248674a8c1e22790670dd04a /crypto/evp
parentaa7f5baad27729b819bced7040957dc401ed2b46 (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.c6
-rw-r--r--crypto/evp/evp.h5
-rw-r--r--crypto/evp/evp_enc.c35
-rw-r--r--crypto/evp/evp_err.c1
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"},