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>
... | ... |
@@ -919,6 +919,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then |
919 | 919 |
|
920 | 920 |
AC_CHECK_FUNCS( |
921 | 921 |
[ \ |
922 |
+ EVP_MD_CTX_new \ |
|
923 |
+ EVP_MD_CTX_free \ |
|
924 |
+ EVP_MD_CTX_reset \ |
|
922 | 925 |
SSL_CTX_get_default_passwd_cb \ |
923 | 926 |
SSL_CTX_get_default_passwd_cb_userdata \ |
924 | 927 |
X509_get0_pubkey \ |
... | ... |
@@ -507,6 +507,20 @@ int md_kt_size(const md_kt_t *kt); |
507 | 507 |
int md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst); |
508 | 508 |
|
509 | 509 |
/* |
510 |
+ * Allocate a new message digest context |
|
511 |
+ * |
|
512 |
+ * @return a new zeroed MD context |
|
513 |
+ */ |
|
514 |
+md_ctx_t *md_ctx_new(void); |
|
515 |
+ |
|
516 |
+/* |
|
517 |
+ * Free an existing, non-null message digest context |
|
518 |
+ * |
|
519 |
+ * @param ctx Message digest context |
|
520 |
+ */ |
|
521 |
+void md_ctx_free(md_ctx_t *ctx); |
|
522 |
+ |
|
523 |
+/* |
|
510 | 524 |
* Initialises the given message digest context. |
511 | 525 |
* |
512 | 526 |
* @param ctx Message digest context |
... | ... |
@@ -765,6 +765,18 @@ md_full(const md_kt_t *kt, const uint8_t *src, int src_len, uint8_t *dst) |
765 | 765 |
return 0 == mbedtls_md(kt, src, src_len, dst); |
766 | 766 |
} |
767 | 767 |
|
768 |
+mbedtls_md_context_t * |
|
769 |
+md_ctx_new(void) |
|
770 |
+{ |
|
771 |
+ mbedtls_md_context_t *ctx; |
|
772 |
+ ALLOC_OBJ_CLEAR(ctx, mbedtls_md_context_t); |
|
773 |
+ return ctx; |
|
774 |
+} |
|
775 |
+ |
|
776 |
+void md_ctx_free(mbedtls_md_context_t *ctx) |
|
777 |
+{ |
|
778 |
+ free(ctx); |
|
779 |
+} |
|
768 | 780 |
|
769 | 781 |
void |
770 | 782 |
md_ctx_init(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) |
... | ... |
@@ -41,6 +41,7 @@ |
41 | 41 |
#include "integer.h" |
42 | 42 |
#include "crypto.h" |
43 | 43 |
#include "crypto_backend.h" |
44 |
+#include "openssl_compat.h" |
|
44 | 45 |
|
45 | 46 |
#include <openssl/des.h> |
46 | 47 |
#include <openssl/err.h> |
... | ... |
@@ -843,13 +844,24 @@ md_full(const EVP_MD *kt, const uint8_t *src, int src_len, uint8_t *dst) |
843 | 843 |
return EVP_Digest(src, src_len, dst, &in_md_len, kt, NULL); |
844 | 844 |
} |
845 | 845 |
|
846 |
+EVP_MD_CTX * |
|
847 |
+md_ctx_new(void) |
|
848 |
+{ |
|
849 |
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new(); |
|
850 |
+ check_malloc_return(ctx); |
|
851 |
+ return ctx; |
|
852 |
+} |
|
853 |
+ |
|
854 |
+void md_ctx_free(EVP_MD_CTX *ctx) |
|
855 |
+{ |
|
856 |
+ EVP_MD_CTX_free(ctx); |
|
857 |
+} |
|
858 |
+ |
|
846 | 859 |
void |
847 | 860 |
md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt) |
848 | 861 |
{ |
849 | 862 |
ASSERT(NULL != ctx && NULL != kt); |
850 | 863 |
|
851 |
- CLEAR(*ctx); |
|
852 |
- |
|
853 | 864 |
EVP_MD_CTX_init(ctx); |
854 | 865 |
EVP_DigestInit(ctx, kt); |
855 | 866 |
} |
... | ... |
@@ -857,7 +869,7 @@ md_ctx_init(EVP_MD_CTX *ctx, const EVP_MD *kt) |
857 | 857 |
void |
858 | 858 |
md_ctx_cleanup(EVP_MD_CTX *ctx) |
859 | 859 |
{ |
860 |
- EVP_MD_CTX_cleanup(ctx); |
|
860 |
+ EVP_MD_CTX_reset(ctx); |
|
861 | 861 |
} |
862 | 862 |
|
863 | 863 |
int |
... | ... |
@@ -80,27 +80,28 @@ DigestCalcHA1( |
80 | 80 |
) |
81 | 81 |
{ |
82 | 82 |
HASH HA1; |
83 |
- md_ctx_t md5_ctx; |
|
83 |
+ md_ctx_t *md5_ctx = md_ctx_new(); |
|
84 | 84 |
const md_kt_t *md5_kt = md_kt_get("MD5"); |
85 | 85 |
|
86 |
- md_ctx_init(&md5_ctx, md5_kt); |
|
87 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName)); |
|
88 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
89 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm)); |
|
90 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
91 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword)); |
|
92 |
- md_ctx_final(&md5_ctx, HA1); |
|
86 |
+ md_ctx_init(md5_ctx, md5_kt); |
|
87 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszUserName, strlen(pszUserName)); |
|
88 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
89 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszRealm, strlen(pszRealm)); |
|
90 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
91 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszPassword, strlen(pszPassword)); |
|
92 |
+ md_ctx_final(md5_ctx, HA1); |
|
93 | 93 |
if (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0) |
94 | 94 |
{ |
95 |
- md_ctx_init(&md5_ctx, md5_kt); |
|
96 |
- md_ctx_update(&md5_ctx, HA1, HASHLEN); |
|
97 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
98 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); |
|
99 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
100 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); |
|
101 |
- md_ctx_final(&md5_ctx, HA1); |
|
95 |
+ md_ctx_init(md5_ctx, md5_kt); |
|
96 |
+ md_ctx_update(md5_ctx, HA1, HASHLEN); |
|
97 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
98 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); |
|
99 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
100 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); |
|
101 |
+ md_ctx_final(md5_ctx, HA1); |
|
102 | 102 |
} |
103 |
- md_ctx_cleanup(&md5_ctx); |
|
103 |
+ md_ctx_cleanup(md5_ctx); |
|
104 |
+ md_ctx_free(md5_ctx); |
|
104 | 105 |
CvtHex(HA1, SessionKey); |
105 | 106 |
} |
106 | 107 |
|
... | ... |
@@ -122,40 +123,41 @@ DigestCalcResponse( |
122 | 122 |
HASH RespHash; |
123 | 123 |
HASHHEX HA2Hex; |
124 | 124 |
|
125 |
- md_ctx_t md5_ctx; |
|
125 |
+ md_ctx_t *md5_ctx = md_ctx_new(); |
|
126 | 126 |
const md_kt_t *md5_kt = md_kt_get("MD5"); |
127 | 127 |
|
128 | 128 |
/* calculate H(A2) */ |
129 |
- md_ctx_init(&md5_ctx, md5_kt); |
|
130 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod)); |
|
131 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
132 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri)); |
|
129 |
+ md_ctx_init(md5_ctx, md5_kt); |
|
130 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszMethod, strlen(pszMethod)); |
|
131 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
132 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszDigestUri, strlen(pszDigestUri)); |
|
133 | 133 |
if (strcasecmp(pszQop, "auth-int") == 0) |
134 | 134 |
{ |
135 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
136 |
- md_ctx_update(&md5_ctx, HEntity, HASHHEXLEN); |
|
135 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
136 |
+ md_ctx_update(md5_ctx, HEntity, HASHHEXLEN); |
|
137 | 137 |
} |
138 |
- md_ctx_final(&md5_ctx, HA2); |
|
138 |
+ md_ctx_final(md5_ctx, HA2); |
|
139 | 139 |
CvtHex(HA2, HA2Hex); |
140 | 140 |
|
141 | 141 |
/* calculate response */ |
142 |
- md_ctx_init(&md5_ctx, md5_kt); |
|
143 |
- md_ctx_update(&md5_ctx, HA1, HASHHEXLEN); |
|
144 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
145 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); |
|
146 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
142 |
+ md_ctx_init(md5_ctx, md5_kt); |
|
143 |
+ md_ctx_update(md5_ctx, HA1, HASHHEXLEN); |
|
144 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
145 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszNonce, strlen(pszNonce)); |
|
146 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
147 | 147 |
if (*pszQop) |
148 | 148 |
{ |
149 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount)); |
|
150 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
151 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); |
|
152 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
153 |
- md_ctx_update(&md5_ctx, (const uint8_t *) pszQop, strlen(pszQop)); |
|
154 |
- md_ctx_update(&md5_ctx, (const uint8_t *) ":", 1); |
|
149 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszNonceCount, strlen(pszNonceCount)); |
|
150 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
151 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszCNonce, strlen(pszCNonce)); |
|
152 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
153 |
+ md_ctx_update(md5_ctx, (const uint8_t *) pszQop, strlen(pszQop)); |
|
154 |
+ md_ctx_update(md5_ctx, (const uint8_t *) ":", 1); |
|
155 | 155 |
} |
156 |
- md_ctx_update(&md5_ctx, HA2Hex, HASHHEXLEN); |
|
157 |
- md_ctx_final(&md5_ctx, RespHash); |
|
158 |
- md_ctx_cleanup(&md5_ctx); |
|
156 |
+ md_ctx_update(md5_ctx, HA2Hex, HASHHEXLEN); |
|
157 |
+ md_ctx_final(md5_ctx, RespHash); |
|
158 |
+ md_ctx_cleanup(md5_ctx); |
|
159 |
+ md_ctx_free(md5_ctx); |
|
159 | 160 |
CvtHex(RespHash, Response); |
160 | 161 |
} |
161 | 162 |
|
... | ... |
@@ -1387,7 +1387,7 @@ get_user_pass_auto_userid(struct user_pass *up, const char *tag) |
1387 | 1387 |
static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST"; |
1388 | 1388 |
|
1389 | 1389 |
const md_kt_t *md5_kt = md_kt_get("MD5"); |
1390 |
- md_ctx_t ctx; |
|
1390 |
+ md_ctx_t *ctx; |
|
1391 | 1391 |
|
1392 | 1392 |
CLEAR(*up); |
1393 | 1393 |
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) |
1395 | 1395 |
if (get_default_gateway_mac_addr(macaddr)) |
1396 | 1396 |
{ |
1397 | 1397 |
dmsg(D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex(macaddr, sizeof(macaddr), 0, 1, ":", &gc)); |
1398 |
- md_ctx_init(&ctx, md5_kt); |
|
1399 |
- md_ctx_update(&ctx, hashprefix, sizeof(hashprefix) - 1); |
|
1400 |
- md_ctx_update(&ctx, macaddr, sizeof(macaddr)); |
|
1401 |
- md_ctx_final(&ctx, digest); |
|
1402 |
- md_ctx_cleanup(&ctx) |
|
1398 |
+ ctx = md_ctx_new(); |
|
1399 |
+ md_ctx_init(ctx, md5_kt); |
|
1400 |
+ md_ctx_update(ctx, hashprefix, sizeof(hashprefix) - 1); |
|
1401 |
+ md_ctx_update(ctx, macaddr, sizeof(macaddr)); |
|
1402 |
+ md_ctx_final(ctx, digest); |
|
1403 |
+ md_ctx_cleanup(ctx); |
|
1404 |
+ md_ctx_free(ctx); |
|
1403 | 1405 |
buf_printf(&buf, "%s", format_hex_ex(digest, sizeof(digest), 0, 256, " ", &gc)); |
1404 | 1406 |
} |
1405 | 1407 |
else |
... | ... |
@@ -45,6 +45,49 @@ |
45 | 45 |
#include <openssl/ssl.h> |
46 | 46 |
#include <openssl/x509.h> |
47 | 47 |
|
48 |
+#if !defined(HAVE_EVP_MD_CTX_RESET) |
|
49 |
+/** |
|
50 |
+ * Reset a message digest context |
|
51 |
+ * |
|
52 |
+ * @param ctx The message digest context |
|
53 |
+ * @return 1 on success, 0 on error |
|
54 |
+ */ |
|
55 |
+static inline int |
|
56 |
+EVP_MD_CTX_reset(EVP_MD_CTX *ctx) |
|
57 |
+{ |
|
58 |
+ EVP_MD_CTX_cleanup(ctx); |
|
59 |
+ return 1; |
|
60 |
+} |
|
61 |
+#endif |
|
62 |
+ |
|
63 |
+#if !defined(HAVE_EVP_MD_CTX_FREE) |
|
64 |
+/** |
|
65 |
+ * Free an existing message digest context |
|
66 |
+ * |
|
67 |
+ * @param ctx The message digest context |
|
68 |
+ */ |
|
69 |
+static inline void |
|
70 |
+EVP_MD_CTX_free(EVP_MD_CTX *ctx) |
|
71 |
+{ |
|
72 |
+ free(ctx); |
|
73 |
+} |
|
74 |
+#endif |
|
75 |
+ |
|
76 |
+#if !defined(HAVE_EVP_MD_CTX_NEW) |
|
77 |
+/** |
|
78 |
+ * Allocate a new message digest object |
|
79 |
+ * |
|
80 |
+ * @return A zero'ed message digest object |
|
81 |
+ */ |
|
82 |
+static inline EVP_MD_CTX * |
|
83 |
+EVP_MD_CTX_new(void) |
|
84 |
+{ |
|
85 |
+ EVP_MD_CTX *ctx = NULL; |
|
86 |
+ ALLOC_OBJ_CLEAR(ctx, EVP_MD_CTX); |
|
87 |
+ return ctx; |
|
88 |
+} |
|
89 |
+#endif |
|
90 |
+ |
|
48 | 91 |
#if !defined(HAVE_SSL_CTX_GET_DEFAULT_PASSWD_CB_USERDATA) |
49 | 92 |
/** |
50 | 93 |
* Fetch the default password callback user data from the SSL context |
... | ... |
@@ -472,7 +472,7 @@ struct context_2 |
472 | 472 |
|
473 | 473 |
/* hash of pulled options, so we can compare when options change */ |
474 | 474 |
bool pulled_options_digest_init_done; |
475 |
- md_ctx_t pulled_options_state; |
|
475 |
+ md_ctx_t *pulled_options_state; |
|
476 | 476 |
struct sha256_digest pulled_options_digest; |
477 | 477 |
|
478 | 478 |
struct event_timeout scheduled_exit; |
... | ... |
@@ -723,7 +723,8 @@ process_incoming_push_msg(struct context *c, |
723 | 723 |
struct buffer buf_orig = buf; |
724 | 724 |
if (!c->c2.pulled_options_digest_init_done) |
725 | 725 |
{ |
726 |
- md_ctx_init(&c->c2.pulled_options_state, md_kt_get("SHA256")); |
|
726 |
+ c->c2.pulled_options_state = md_ctx_new(); |
|
727 |
+ md_ctx_init(c->c2.pulled_options_state, md_kt_get("SHA256")); |
|
727 | 728 |
c->c2.pulled_options_digest_init_done = true; |
728 | 729 |
} |
729 | 730 |
if (!c->c2.did_pre_pull_restore) |
... | ... |
@@ -737,14 +738,16 @@ process_incoming_push_msg(struct context *c, |
737 | 737 |
option_types_found, |
738 | 738 |
c->c2.es)) |
739 | 739 |
{ |
740 |
- push_update_digest(&c->c2.pulled_options_state, &buf_orig, |
|
740 |
+ push_update_digest(c->c2.pulled_options_state, &buf_orig, |
|
741 | 741 |
&c->options); |
742 | 742 |
switch (c->options.push_continuation) |
743 | 743 |
{ |
744 | 744 |
case 0: |
745 | 745 |
case 1: |
746 |
- md_ctx_final(&c->c2.pulled_options_state, c->c2.pulled_options_digest.digest); |
|
747 |
- md_ctx_cleanup(&c->c2.pulled_options_state); |
|
746 |
+ md_ctx_final(c->c2.pulled_options_state, c->c2.pulled_options_digest.digest); |
|
747 |
+ md_ctx_cleanup(c->c2.pulled_options_state); |
|
748 |
+ md_ctx_free(c->c2.pulled_options_state); |
|
749 |
+ c->c2.pulled_options_state = NULL; |
|
748 | 750 |
c->c2.pulled_options_digest_init_done = false; |
749 | 751 |
ret = PUSH_MSG_REPLY; |
750 | 752 |
break; |