On Wed, Nov 30, 2016 at 08:01:02PM +0000, Mike Gabriel wrote:
> 
> Reopening, as the latest upload "-11" fixes the FTBFS by build-depending on
> libssl1.0-dev, but freerdp still does not build against libssl1.1-dev.
> Lowering severity though, to unblock the openssl transition.

At some point I started looking at this, and then got distracted
doing other things. I have a partial patch, and I guess I should
just post it here, so see attachment.

It seems to be importing structs from openssl and others into it's
own headers, and this is just a disastor waiting to happen. So I
rewrote the openssl part (partially?) to avoid it.


Kurt

diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c
index 85a28b8..8777ab8 100644
--- a/libfreerdp/crypto/crypto.c
+++ b/libfreerdp/crypto/crypto.c
@@ -98,7 +98,7 @@ static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, c
 	BYTE* input_reverse;
 	BYTE* modulus_reverse;
 	BYTE* exponent_reverse;
-	BIGNUM mod, exp, x, y;
+	BIGNUM *mod, *exp, *x, *y;
 
 	input_reverse = (BYTE*) malloc(2 * key_length + exponent_size);
 	if (!input_reverse)
@@ -114,31 +114,30 @@ static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, c
 	crypto_reverse(input_reverse, length);
 
 	ctx = BN_CTX_new();
-	if (!ctx)
-		goto out_free_input_reverse;
-	BN_init(&mod);
-	BN_init(&exp);
-	BN_init(&x);
-	BN_init(&y);
-
-	BN_bin2bn(modulus_reverse, key_length, &mod);
-	BN_bin2bn(exponent_reverse, exponent_size, &exp);
-	BN_bin2bn(input_reverse, length, &x);
-	BN_mod_exp(&y, &x, &exp, &mod, ctx);
-
-	output_length = BN_bn2bin(&y, output);
+	mod = BN_new();
+	exp = BN_new();
+	x = BN_new();
+	y = BN_new();
+	if (!ctx || !mod || !exp || !x || !y)
+		goto out;
+
+	BN_bin2bn(modulus_reverse, key_length, mod);
+	BN_bin2bn(exponent_reverse, exponent_size, exp);
+	BN_bin2bn(input_reverse, length, x);
+	BN_mod_exp(y, x, exp, mod, ctx);
+
+	output_length = BN_bn2bin(y, output);
 	crypto_reverse(output, output_length);
 
 	if (output_length < (int) key_length)
 		memset(output + output_length, 0, key_length - output_length);
 
-	BN_free(&y);
-	BN_clear_free(&x);
-	BN_free(&exp);
-	BN_free(&mod);
+out:
+	BN_free(y);
+	BN_clear_free(x);
+	BN_free(exp);
+	BN_free(mod);
 	BN_CTX_free(ctx);
-
-out_free_input_reverse:
 	free(input_reverse);
 
 	return output_length;
diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c
index db4b462..00166a0 100644
--- a/libfreerdp/crypto/tls.c
+++ b/libfreerdp/crypto/tls.c
@@ -62,7 +62,7 @@ static int bio_rdp_tls_write(BIO* bio, const char* buf, int size)
 {
 	int error;
 	int status;
-	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr;
+	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio);
 
 	if (!buf || !tls)
 		return 0;
@@ -91,12 +91,12 @@ static int bio_rdp_tls_write(BIO* bio, const char* buf, int size)
 
 			case SSL_ERROR_WANT_X509_LOOKUP:
 				BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL);
-				bio->retry_reason = BIO_RR_SSL_X509_LOOKUP;
+				BIO_set_retry_reason(bio, BIO_RR_SSL_X509_LOOKUP);
 				break;
 
 			case SSL_ERROR_WANT_CONNECT:
 				BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL);
-				bio->retry_reason = BIO_RR_CONNECT;
+				BIO_set_retry_reason(bio, BIO_RR_CONNECT);
 				break;
 
 			case SSL_ERROR_SYSCALL:
@@ -116,7 +116,7 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size)
 {
 	int error;
 	int status;
-	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr;
+	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio);
 
 	if (!buf || !tls)
 		return 0;
@@ -145,17 +145,17 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size)
 
 			case SSL_ERROR_WANT_X509_LOOKUP:
 				BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL);
-				bio->retry_reason = BIO_RR_SSL_X509_LOOKUP;
+				BIO_set_retry_reason(bio, BIO_RR_SSL_X509_LOOKUP);
 				break;
 
 			case SSL_ERROR_WANT_ACCEPT:
 				BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL);
-				bio->retry_reason = BIO_RR_ACCEPT;
+				BIO_set_retry_reason(bio, BIO_RR_ACCEPT);
 				break;
 
 			case SSL_ERROR_WANT_CONNECT:
 				BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL);
-				bio->retry_reason = BIO_RR_CONNECT;
+				BIO_set_retry_reason(bio, BIO_RR_CONNECT);
 				break;
 
 			case SSL_ERROR_SSL:
@@ -205,7 +205,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr)
 {
 	BIO* rbio;
 	int status = -1;
-	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) bio->ptr;
+	BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio);
 
 	if (!tls)
 		return 0;
diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h
index 7e05124..57ee285 100644
--- a/winpr/include/winpr/crypto.h
+++ b/winpr/include/winpr/crypto.h
@@ -610,6 +610,8 @@ BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, L
 #define CALG_ECDSA			(ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
 #endif
 
+typedef struct evp_md_ctx_st EVP_MD_CTX;
+
 /**
  * Custom Crypto API Abstraction Layer
  */
@@ -618,15 +620,6 @@ BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, L
  * MD5 hashing
  */
 
-struct _OPENSSL_MD5_CTX
-{
-	UINT32 A, B, C, D;
-	UINT32 Nl, Nh;
-	UINT32 data[16];
-	UINT32 num;
-};
-typedef struct _OPENSSL_MD5_CTX OPENSSL_MD5_CTX;
-
 struct _MBEDTLS_MD5_CTX
 {
 	UINT32 total[2];
@@ -637,7 +630,7 @@ typedef struct _MBEDTLS_MD5_CTX MBEDTLS_MD5_CTX;
 
 union _WINPR_MD5_CTX
 {
-	OPENSSL_MD5_CTX openssl;
+	EVP_MD_CTX *openssl;
 	MBEDTLS_MD5_CTX mbedtls;
 };
 typedef union _WINPR_MD5_CTX WINPR_MD5_CTX;
@@ -661,14 +654,7 @@ WINPR_API BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t ol
  * MD4 hashing
  */
 
-struct _OPENSSL_MD4_CTX
-{
-	UINT32 A, B, C, D;
-	UINT32 Nl, Nh;
-	UINT32 data[16];
-	UINT32 num;
-};
-typedef struct _OPENSSL_MD4_CTX OPENSSL_MD4_CTX;
+typedef struct MD4state_st MD4_CTX;
 
 struct _MBEDTLS_MD4_CTX
 {
@@ -680,7 +666,7 @@ typedef struct _MBEDTLS_MD4_CTX MBEDTLS_MD4_CTX;
 
 union _WINPR_MD4_CTX
 {
-	OPENSSL_MD4_CTX openssl;
+	EVP_MD_CTX *openssl;
 	MBEDTLS_MD4_CTX mbedtls;
 };
 typedef union _WINPR_MD4_CTX WINPR_MD4_CTX;
@@ -706,14 +692,7 @@ WINPR_API BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t ol
 
 #define WINPR_SHA1_DIGEST_LENGTH	20
 
-struct _OPENSSL_SHA1_CTX
-{
-	UINT32 h0, h1, h2, h3, h4;
-	UINT32 Nl, Nh;
-	UINT32 data[16];
-	UINT32 num;
-};
-typedef struct _OPENSSL_SHA1_CTX OPENSSL_SHA1_CTX;
+typedef struct SHAstate_st SHA_CTX;
 
 struct _MBEDTLS_SHA1_CTX
 {
@@ -725,7 +704,7 @@ typedef struct _MBEDTLS_SHA1_CTX MBEDTLS_SHA1_CTX;
 
 union _WINPR_SHA1_CTX
 {
-	OPENSSL_SHA1_CTX openssl;
+	EVP_MD_CTX *openssl;
 	MBEDTLS_SHA1_CTX mbedtls;
 };
 typedef union _WINPR_SHA1_CTX WINPR_SHA1_CTX;
@@ -760,27 +739,7 @@ typedef enum
     WINPR_MD_RIPEMD160	= 9
 } WINPR_MD_TYPE;
 
-struct _OPENSSL_EVP_MD_CTX
-{
-	const void* digest;
-	void* engine;
-	unsigned long flags;
-	void* md_data;
-	void* pctx;
-	void* update;
-};
-typedef struct _OPENSSL_EVP_MD_CTX OPENSSL_EVP_MD_CTX;
-
-struct _OPENSSL_HMAC_CTX
-{
-	const void* md;
-	OPENSSL_EVP_MD_CTX md_ctx;
-	OPENSSL_EVP_MD_CTX i_ctx;
-	OPENSSL_EVP_MD_CTX o_ctx;
-	unsigned int key_length;
-	unsigned char key[128];
-};
-typedef struct _OPENSSL_HMAC_CTX OPENSSL_HMAC_CTX;
+typedef struct hmac_ctx_st HMAC_CTX;
 
 struct _MBEDTLS_HMAC_CTX
 {
@@ -792,7 +751,7 @@ typedef struct _MBEDTLS_HMAC_CTX MBEDTLS_HMAC_CTX;
 
 union _WINPR_HMAC_CTX
 {
-	OPENSSL_HMAC_CTX openssl;
+	HMAC_CTX *openssl;
 	MBEDTLS_HMAC_CTX mbedtls;
 };
 typedef union _WINPR_HMAC_CTX WINPR_HMAC_CTX;
@@ -815,18 +774,6 @@ WINPR_API BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen,
  * Generic Digest API
  */
 
-struct _OPENSSL_DIGEST_CTX
-{
-	const void* digest;
-	void* engine;
-	unsigned long flags;
-	void* md_data;
-	void* pctx;
-	void* update;
-	BYTE winpr_pad[8];
-};
-typedef struct _OPENSSL_DIGEST_CTX OPENSSL_DIGEST_CTX;
-
 struct _MBEDTLS_DIGEST_CTX
 {
 	const void* md_info;
@@ -838,7 +785,7 @@ typedef struct _MBEDTLS_DIGEST_CTX MBEDTLS_DIGEST_CTX;
 
 union _WINPR_DIGEST_CTX
 {
-	OPENSSL_DIGEST_CTX openssl;
+	EVP_MD_CTX *openssl;
 	MBEDTLS_DIGEST_CTX mbedtls;
 };
 typedef union _WINPR_DIGEST_CTX WINPR_DIGEST_CTX;
@@ -970,26 +917,7 @@ WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx);
 #define WINPR_CIPHER_CAMELLIA_192_CCM		47
 #define WINPR_CIPHER_CAMELLIA_256_CCM		48
 
-struct _OPENSSL_CIPHER_CTX
-{
-	const void* cipher;
-	void* engine;
-	int encrypt;
-	int buf_len;
-	BYTE oiv[16];
-	BYTE iv[16];
-	BYTE buf[32];
-	int num;
-	void* app_data;
-	int key_len;
-	unsigned long flags;
-	void* cipher_data;
-	int final_used;
-	int block_mask;
-	BYTE final[32];
-	BYTE winpr_pad[32];
-};
-typedef struct _OPENSSL_CIPHER_CTX OPENSSL_CIPHER_CTX;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
 
 struct _MBEDTLS_CIPHER_CTX
 {
@@ -1009,7 +937,7 @@ typedef struct _MBEDTLS_CIPHER_CTX MBEDTLS_CIPHER_CTX;
 
 union _WINPR_CIPHER_CTX
 {
-	OPENSSL_CIPHER_CTX openssl;
+	EVP_CIPHER_CTX *openssl;
 	MBEDTLS_CIPHER_CTX mbedtls;
 };
 typedef union _WINPR_CIPHER_CTX WINPR_CIPHER_CTX;
diff --git a/winpr/libwinpr/crypto/hash.c b/winpr/libwinpr/crypto/hash.c
index 70c4392..86e4a8f 100644
--- a/winpr/libwinpr/crypto/hash.c
+++ b/winpr/libwinpr/crypto/hash.c
@@ -46,8 +46,14 @@
 BOOL winpr_MD5_Init(WINPR_MD5_CTX* ctx)
 {
 #if defined(WITH_OPENSSL)
-	if (MD5_Init((MD5_CTX*) ctx) != 1)
+	ctx->openssl = EVP_MD_CTX_new();
+	if (ctx->openssl == NULL ||
+		EVP_DigestInit_ex(ctx->openssl, EVP_md5(), NULL) == 0)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
 	mbedtls_md5_init((mbedtls_md5_context*) ctx);
 	mbedtls_md5_starts((mbedtls_md5_context*) ctx);
@@ -59,8 +65,12 @@ BOOL winpr_MD5_Init(WINPR_MD5_CTX* ctx)
 BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen)
 {
 #if defined(WITH_OPENSSL)
-	if (MD5_Update((MD5_CTX*) ctx, input, ilen) != 1)
+	if (EVP_DigestUpdate(ctx->openssl, input, ilen) != 1)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
 	mbedtls_md5_update((mbedtls_md5_context*) ctx, input, ilen);
 #endif
@@ -70,18 +80,21 @@ BOOL winpr_MD5_Update(WINPR_MD5_CTX* ctx, const BYTE* input, size_t ilen)
 
 BOOL winpr_MD5_Final(WINPR_MD5_CTX* ctx, BYTE* output, size_t ilen)
 {
+	BOOL ret = TRUE;
 	if (ilen < WINPR_MD5_DIGEST_LENGTH)
 		return FALSE;
 
 #if defined(WITH_OPENSSL)
-	if (MD5_Final(output, (MD5_CTX*) ctx) != 1)
-		return FALSE;
+	if (EVP_DigestFinal_ex(ctx->openssl, output, NULL) != 1)
+		ret = FALSE;
+	EVP_MD_CTX_free(ctx->openssl);
+	ctx->openssl = NULL;
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD5_C)
 	mbedtls_md5_finish((mbedtls_md5_context*) ctx, output);
 	mbedtls_md5_free((mbedtls_md5_context*) ctx);
 #endif
 
-	return TRUE;
+	return ret;
 }
 
 BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen)
@@ -102,8 +115,14 @@ BOOL winpr_MD5(const BYTE* input, size_t ilen, BYTE* output, size_t olen)
 BOOL winpr_MD4_Init(WINPR_MD4_CTX* ctx)
 {
 #if defined(WITH_OPENSSL)
-	if (MD4_Init((MD4_CTX*) ctx) != 1)
+	ctx->openssl = EVP_MD_CTX_new();
+	if (ctx->openssl == NULL ||
+		EVP_DigestInit_ex(ctx->openssl, EVP_md4(), NULL) == 0)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
 	mbedtls_md4_init((mbedtls_md4_context*) ctx);
 	mbedtls_md4_starts((mbedtls_md4_context*) ctx);
@@ -114,8 +133,12 @@ BOOL winpr_MD4_Init(WINPR_MD4_CTX* ctx)
 BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen)
 {
 #if defined(WITH_OPENSSL)
-	if (MD4_Update((MD4_CTX*) ctx, input, ilen) != 1)
+	if (EVP_DigestUpdate(ctx->openssl, input, ilen) != 1)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
 	mbedtls_md4_update((mbedtls_md4_context*) ctx, input, ilen);
 #endif
@@ -125,18 +148,21 @@ BOOL winpr_MD4_Update(WINPR_MD4_CTX* ctx, const BYTE* input, size_t ilen)
 
 BOOL winpr_MD4_Final(WINPR_MD4_CTX* ctx, BYTE* output, size_t olen)
 {
+	BOOL ret = TRUE;
 	if (olen < WINPR_MD4_DIGEST_LENGTH)
 		return FALSE;
 
 #if defined(WITH_OPENSSL)
-	if (MD4_Final(output, (MD4_CTX*) ctx) != 1)
-		return FALSE;
+	if (EVP_DigestFinal_ex(ctx->openssl, output, NULL) != 1)
+		ret = FALSE;
+	EVP_MD_CTX_free(ctx->openssl);
+	ctx->openssl = NULL;
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_MD4_C)
 	mbedtls_md4_finish((mbedtls_md4_context*) ctx, output);
 	mbedtls_md4_free((mbedtls_md4_context*) ctx);
 #endif
 
-	return TRUE;
+	return ret;
 }
 
 BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen)
@@ -157,8 +183,14 @@ BOOL winpr_MD4(const BYTE* input, size_t ilen, BYTE* output, size_t olen)
 BOOL winpr_SHA1_Init(WINPR_SHA1_CTX* ctx)
 {
 #if defined(WITH_OPENSSL)
-	if (SHA1_Init((SHA_CTX*) ctx) != 1)
+	ctx->openssl = EVP_MD_CTX_new();
+	if (ctx->openssl == NULL ||
+		EVP_DigestInit_ex(ctx->openssl, EVP_sha1(), NULL) == 0)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
 	mbedtls_sha1_init((mbedtls_sha1_context*) ctx);
 	mbedtls_sha1_starts((mbedtls_sha1_context*) ctx);
@@ -170,8 +202,12 @@ BOOL winpr_SHA1_Init(WINPR_SHA1_CTX* ctx)
 BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen)
 {
 #if defined(WITH_OPENSSL)
-	if (SHA1_Update((SHA_CTX*) ctx, input, ilen) != 1)
+	if (EVP_DigestUpdate(ctx->openssl, input, ilen) != 1)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
 	mbedtls_sha1_update((mbedtls_sha1_context*) ctx, input, ilen);
 #endif
@@ -181,18 +217,21 @@ BOOL winpr_SHA1_Update(WINPR_SHA1_CTX* ctx, const BYTE* input, size_t ilen)
 
 BOOL winpr_SHA1_Final(WINPR_SHA1_CTX* ctx, BYTE* output, size_t olen)
 {
+	BOOL ret = TRUE;
 	if (olen < WINPR_SHA1_DIGEST_LENGTH)
 		return FALSE;
 
 #if defined(WITH_OPENSSL)
-	if (SHA1_Final(output, (SHA_CTX*) ctx) != 1)
-		return FALSE;
+	if (EVP_DigestFinal_ex(ctx->openssl, output, NULL) != 1)
+		ret = FALSE;
+	EVP_MD_CTX_free(ctx->openssl);
+	ctx->openssl = NULL;
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_SHA1_C)
 	mbedtls_sha1_finish((mbedtls_sha1_context*) ctx, output);
 	mbedtls_sha1_free((mbedtls_sha1_context*) ctx);
 #endif
 
-	return TRUE;
+	return ret;
 }
 
 BOOL winpr_SHA1(const BYTE* input, size_t ilen, BYTE* output, size_t olen)
@@ -316,13 +355,19 @@ BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, siz
 	if (!evp)
 		return FALSE;
 
-	HMAC_CTX_init((HMAC_CTX*) ctx);
+	ctx->openssl = HMAC_CTX_new();
+	if (!ctx->openssl)
+		return FALSE;
 
 #if (OPENSSL_VERSION_NUMBER < 0x10000000L)
-	HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL);
+	HMAC_Init_ex(ctx->openssl, key, keylen, evp, NULL);
 #else
-	if (HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL) != 1)
+	if (HMAC_Init_ex(ctx->openssl, key, keylen, evp, NULL) != 1)
+	{
+		HMAC_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #endif
 
 #elif defined(WITH_MBEDTLS)
@@ -351,7 +396,11 @@ BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
 	HMAC_Update((HMAC_CTX*) ctx, input, ilen);
 #else
 	if (HMAC_Update((HMAC_CTX*) ctx, input, ilen) != 1)
+	{
+		HMAC_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #endif
 #elif defined(WITH_MBEDTLS)
 	if (mbedtls_md_hmac_update((mbedtls_md_context_t*) ctx, input, ilen) != 0)
@@ -362,6 +411,7 @@ BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
 
 BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
 {
+	BOOL ret = TRUE;
 	/* TODO
 	if (olen < ctx->digestLength)
 		return FALSE;
@@ -372,16 +422,17 @@ BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
 	HMAC_Final((HMAC_CTX*) ctx, output, NULL);
 #else
 	if (HMAC_Final((HMAC_CTX*) ctx, output, NULL) != 1)
-		return FALSE;
+		ret = FALSE;
 #endif
-	HMAC_CTX_cleanup((HMAC_CTX*) ctx);
+	HMAC_CTX_free(ctx->openssl);
+	ctx->openssl = NULL;
 #elif defined(WITH_MBEDTLS)
 	if (mbedtls_md_hmac_finish((mbedtls_md_context_t*) ctx, output) != 0)
-		return FALSE;
+		ret = FALSE;
 
 	mbedtls_md_free((mbedtls_md_context_t*) ctx);
 #endif
-	return TRUE;
+	return ret;
 }
 
 BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen,
@@ -413,10 +464,14 @@ BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
 	if (!evp)
 		return FALSE;
 
-	EVP_MD_CTX_init((EVP_MD_CTX*) ctx);
-
-	if (EVP_DigestInit_ex((EVP_MD_CTX*) ctx, evp, NULL) != 1)
+	ctx->openssl = EVP_MD_CTX_new();
+	if (ctx->openssl == NULL ||
+		EVP_DigestInit_ex(ctx->openssl, evp, NULL) == 0)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS)
 	const mbedtls_md_info_t* md_info;
 	mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
@@ -439,8 +494,12 @@ BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
 BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
 {
 #if defined(WITH_OPENSSL)
-	if (EVP_DigestUpdate((EVP_MD_CTX*) ctx, input, ilen) != 1)
+	if (EVP_DigestUpdate(ctx->openssl, input, ilen) != 1)
+	{
+		EVP_MD_CTX_free(ctx->openssl);
+		ctx->openssl = NULL;
 		return FALSE;
+	}
 #elif defined(WITH_MBEDTLS)
 	if (mbedtls_md_update((mbedtls_md_context_t*) ctx, input, ilen) != 0)
 		return FALSE;
@@ -451,16 +510,19 @@ BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
 BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
 {
 	// TODO: output length check
+	BOOL ret = TRUE;
 #if defined(WITH_OPENSSL)
-	if (EVP_DigestFinal_ex((EVP_MD_CTX*) ctx, output, NULL) != 1)
-		return FALSE;
+	if (EVP_DigestFinal_ex(ctx->openssl, output, NULL) != 1)
+		ret = FALSE;
+	EVP_MD_CTX_free(ctx->openssl);
+	ctx->openssl = NULL;
 #elif defined(WITH_MBEDTLS)
 	if (mbedtls_md_finish((mbedtls_md_context_t*) ctx, output) != 0)
 		return FALSE;
 
 	mbedtls_md_free((mbedtls_md_context_t*) ctx);
 #endif
-	return TRUE;
+	return ret;
 }
 
 BOOL winpr_Digest(int md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)

Reply via email to