Commit 17004262 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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.
parent aa7f5baa
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@

 Changes between 0.9.8m (?) and 1.0.0  [xx XXX xxxx]

  *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
     context. The operation can be customised via the ctrl mechanism in
     case ENGINEs want to include additional functionality.
     [Steve Henson]

  *) Tolerate yet another broken PKCS#8 key format: private key value negative.
     [Steve Henson]

+4 −2
Original line number Diff line number Diff line
@@ -361,7 +361,9 @@ again:
	case BIO_CTRL_DUP:
		dbio=(BIO *)ptr;
		dctx=(BIO_ENC_CTX *)dbio->ptr;
		memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
		EVP_CIPHER_CTX_init(&dctx->cipher);
		ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
		if (ret)
			dbio->init=1;
		break;
	default:
+5 −0
Original line number Diff line number Diff line
@@ -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
+35 −0
Original line number Diff line number Diff line
@@ -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;
	}
+1 −0
Original line number Diff line number Diff line
@@ -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"},