Browse code

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>

Emmanuel Deloget authored on 2017/06/12 22:43:27
Showing 9 changed files
... ...
@@ -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;