OpenSSL: don't use direct access to the internal of EVP_MD_CTX

OpenSSL 1.1 does not allow us to directly access the internal of
any data type, including EVP_MD_CTX. We have to use the defined
functions to do so.

Compatibility with OpenSSL 1.0 is kept by defining the corresponding
functions when they are not found in the library.

Signed-off-by: Emmanuel Deloget <logout@free.fr>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <20170612134330.20971-6-logout@free.fr>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14793.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Emmanuel Deloget 2017-06-12 15:43:27 +02:00 committed by Gert Doering
parent 21a540f92b
commit c481ef0028
9 changed files with 143 additions and 52 deletions

View File

@ -919,6 +919,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
AC_CHECK_FUNCS(
[ \
EVP_MD_CTX_new \
EVP_MD_CTX_free \
EVP_MD_CTX_reset \
SSL_CTX_get_default_passwd_cb \
SSL_CTX_get_default_passwd_cb_userdata \
X509_get0_pubkey \

View File

@ -506,6 +506,20 @@ int md_kt_size(const md_kt_t *kt);
*/
int md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst);
/*
* Allocate a new message digest context
*
* @return a new zeroed MD context
*/
md_ctx_t *md_ctx_new(void);
/*
* Free an existing, non-null message digest context
*
* @param ctx Message digest context
*/
void md_ctx_free(md_ctx_t *ctx);
/*
* Initialises the given message digest context.
*

View File

@ -765,6 +765,18 @@ md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst)
return 0 == mbedtls_md(kt, src, src_len, dst);
}
mbedtls_md_context_t *
md_ctx_new(void)
{
mbedtls_md_context_t *ctx;
ALLOC_OBJ_CLEAR(ctx, mbedtls_md_context_t);
return ctx;
}
void md_ctx_free(mbedtls_md_context_t *ctx)
{
free(ctx);
}
void
md_ctx_init(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt)

View File

@ -41,6 +41,7 @@
#include "integer.h"
#include "crypto.h"
#include "crypto_backend.h"
#include "openssl_compat.h"
#include <openssl/des.h>
#include <openssl/err.h>
@ -843,13 +844,24 @@ md_full(const EVP_MD *kt, const uint8_t *src, int src_len, uint8_t *dst)
return EVP_Digest(src, src_len, dst, &in_md_len, kt, NULL);
}
EVP_MD_CTX *
md_ctx_new(void)
{
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
check_malloc_return(ctx);
return ctx;
}
void md_ctx_free(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_free(ctx);
}
void
md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt)
{
ASSERT(NULL != ctx && NULL != kt);
CLEAR(*ctx);
EVP_MD_CTX_init(ctx);
EVP_DigestInit(ctx, kt);
}
@ -857,7 +869,7 @@ md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt)
void
md_ctx_cleanup(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_cleanup(ctx);
EVP_MD_CTX_reset(ctx);
}
int

View File

@ -80,27 +80,28 @@ DigestCalcHA1(
)
{
HASH HA1;
md_ctx_t md5_ctx;
md_ctx_t *md5_ctx = md_ctx_new();
const md_kt_t *md5_kt = md_kt_get("MD5");
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword));
md_ctx_final(&md5_ctx, HA1);
md_ctx_init(md5_ctx, md5_kt);
md_ctx_update(md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword));
md_ctx_final(md5_ctx, HA1);
if (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0)
{
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, HA1, HASHLEN);
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce));
md_ctx_final(&md5_ctx, HA1);
md_ctx_init(md5_ctx, md5_kt);
md_ctx_update(md5_ctx, HA1, HASHLEN);
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce));
md_ctx_final(md5_ctx, HA1);
}
md_ctx_cleanup(&md5_ctx);
md_ctx_cleanup(md5_ctx);
md_ctx_free(md5_ctx);
CvtHex(HA1, SessionKey);
}
@ -122,40 +123,41 @@ DigestCalcResponse(
HASH RespHash;
HASHHEX HA2Hex;
md_ctx_t md5_ctx;
md_ctx_t *md5_ctx = md_ctx_new();
const md_kt_t *md5_kt = md_kt_get("MD5");
/* calculate H(A2) */
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri));
md_ctx_init(md5_ctx, md5_kt);
md_ctx_update(md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri));
if (strcasecmp(pszQop, "auth-int") == 0)
{
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, HEntity, HASHHEXLEN);
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, HEntity, HASHHEXLEN);
}
md_ctx_final(&md5_ctx, HA2);
md_ctx_final(md5_ctx, HA2);
CvtHex(HA2, HA2Hex);
/* calculate response */
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, HA1, HASHHEXLEN);
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_init(md5_ctx, md5_kt);
md_ctx_update(md5_ctx, HA1, HASHHEXLEN);
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
if (*pszQop)
{
md_ctx_update(&md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(&md5_ctx, (const uint8_t *) pszQop, strlen(pszQop));
md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
md_ctx_update(md5_ctx, (const uint8_t *) pszQop, strlen(pszQop));
md_ctx_update(md5_ctx, (const uint8_t *) ":", 1);
}
md_ctx_update(&md5_ctx, HA2Hex, HASHHEXLEN);
md_ctx_final(&md5_ctx, RespHash);
md_ctx_cleanup(&md5_ctx);
md_ctx_update(md5_ctx, HA2Hex, HASHHEXLEN);
md_ctx_final(md5_ctx, RespHash);
md_ctx_cleanup(md5_ctx);
md_ctx_free(md5_ctx);
CvtHex(RespHash, Response);
}

View File

@ -1387,7 +1387,7 @@ get_user_pass_auto_userid(struct user_pass *up, const char *tag)
static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST";
const md_kt_t *md5_kt = md_kt_get("MD5");
md_ctx_t ctx;
md_ctx_t *ctx;
CLEAR(*up);
buf_set_write(&buf, (uint8_t *)up->username, USER_PASS_LEN);
@ -1395,11 +1395,13 @@ get_user_pass_auto_userid(struct user_pass *up, const char *tag)
if (get_default_gateway_mac_addr(macaddr))
{
dmsg(D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex(macaddr, sizeof(macaddr), 0, 1, ":", &gc));
md_ctx_init(&ctx, md5_kt);
md_ctx_update(&ctx, hashprefix, sizeof(hashprefix) - 1);
md_ctx_update(&ctx, macaddr, sizeof(macaddr));
md_ctx_final(&ctx, digest);
md_ctx_cleanup(&ctx)
ctx = md_ctx_new();
md_ctx_init(ctx, md5_kt);
md_ctx_update(ctx, hashprefix, sizeof(hashprefix) - 1);
md_ctx_update(ctx, macaddr, sizeof(macaddr));
md_ctx_final(ctx, digest);
md_ctx_cleanup(ctx);
md_ctx_free(ctx);
buf_printf(&buf, "%s", format_hex_ex(digest, sizeof(digest), 0, 256, " ", &gc));
}
else

View File

@ -45,6 +45,49 @@
#include <openssl/ssl.h>
#include <openssl/x509.h>
#if !defined(HAVE_EVP_MD_CTX_RESET)
/**
* Reset a message digest context
*
* @param ctx The message digest context
* @return 1 on success, 0 on error
*/
static inline int
EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_cleanup(ctx);
return 1;
}
#endif
#if !defined(HAVE_EVP_MD_CTX_FREE)
/**
* Free an existing message digest context
*
* @param ctx The message digest context
*/
static inline void
EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
free(ctx);
}
#endif
#if !defined(HAVE_EVP_MD_CTX_NEW)
/**
* Allocate a new message digest object
*
* @return A zero'ed message digest object
*/
static inline EVP_MD_CTX *
EVP_MD_CTX_new(void)
{
EVP_MD_CTX *ctx = NULL;
ALLOC_OBJ_CLEAR(ctx, EVP_MD_CTX);
return ctx;
}
#endif
#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA)
/**
* Fetch the default password callback user data from the SSL context

View File

@ -472,7 +472,7 @@ struct context_2
/* hash of pulled options, so we can compare when options change */
bool pulled_options_digest_init_done;
md_ctx_t pulled_options_state;
md_ctx_t *pulled_options_state;
struct sha256_digest pulled_options_digest;
struct event_timeout scheduled_exit;

View File

@ -723,7 +723,8 @@ process_incoming_push_msg(struct context *c,
struct buffer buf_orig = buf;
if (!c->c2.pulled_options_digest_init_done)
{
md_ctx_init(&c->c2.pulled_options_state, md_kt_get("SHA256"));
c->c2.pulled_options_state = md_ctx_new();
md_ctx_init(c->c2.pulled_options_state, md_kt_get("SHA256"));
c->c2.pulled_options_digest_init_done = true;
}
if (!c->c2.did_pre_pull_restore)
@ -737,14 +738,16 @@ process_incoming_push_msg(struct context *c,
option_types_found,
c->c2.es))
{
push_update_digest(&c->c2.pulled_options_state, &buf_orig,
push_update_digest(c->c2.pulled_options_state, &buf_orig,
&c->options);
switch (c->options.push_continuation)
{
case 0:
case 1:
md_ctx_final(&c->c2.pulled_options_state, c->c2.pulled_options_digest.digest);
md_ctx_cleanup(&c->c2.pulled_options_state);
md_ctx_final(c->c2.pulled_options_state, c->c2.pulled_options_digest.digest);
md_ctx_cleanup(c->c2.pulled_options_state);
md_ctx_free(c->c2.pulled_options_state);
c->c2.pulled_options_state = NULL;
c->c2.pulled_options_digest_init_done = false;
ret = PUSH_MSG_REPLY;
break;