diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-10 10:14:04 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-10 13:45:35 +0300 |
commit | b84dc1b220b3716e329745218cdc0925b8bc8519 (patch) | |
tree | d5223703ca910958371e88c39c620fccbed85b54 | |
parent | 749a8b434cdad1af2ff0aa1236cab59bbbac3642 (diff) | |
download | libmicrohttpd-b84dc1b220b3716e329745218cdc0925b8bc8519.tar.gz libmicrohttpd-b84dc1b220b3716e329745218cdc0925b8bc8519.zip |
test_tls_options: re-implemented, removed hardcoded TLS versions
The test now tries several TLS versions. If no TLS versions are
supported, then the test is considered SKIPPED.
This way test is forward compatible with future GnuTLS and libcurl
versions.
-rw-r--r-- | src/testcurl/https/test_tls_options.c | 493 | ||||
-rw-r--r-- | src/testcurl/https/tls_test_common.c | 48 | ||||
-rw-r--r-- | src/testcurl/https/tls_test_common.h | 33 |
3 files changed, 467 insertions, 107 deletions
diff --git a/src/testcurl/https/test_tls_options.c b/src/testcurl/https/test_tls_options.c index f6fa477a..196aebf5 100644 --- a/src/testcurl/https/test_tls_options.c +++ b/src/testcurl/https/test_tls_options.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libmicrohttpd | 2 | This file is part of libmicrohttpd |
3 | Copyright (C) 2007, 2010, 2016 Christian Grothoff | 3 | Copyright (C) 2007, 2016 Christian Grothoff |
4 | Copyright (C) 2016-2022 Evgeny Grin (Karlson2k) | ||
4 | 5 | ||
5 | libmicrohttpd is free software; you can redistribute it and/or modify | 6 | libmicrohttpd is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 7 | it under the terms of the GNU General Public License as published |
@@ -16,87 +17,419 @@ | |||
16 | along with libmicrohttpd; see the file COPYING. If not, write to the | 17 | along with libmicrohttpd; see the file COPYING. If not, write to the |
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 19 | Boston, MA 02110-1301, USA. |
19 | */ | 20 | */ |
20 | 21 | ||
21 | /** | 22 | /** |
22 | * @file tls_daemon_options_test.c | 23 | * @file test_tls_options.c |
23 | * @brief Testcase for libmicrohttpd HTTPS GET operations | 24 | * @brief Testcase for libmicrohttpd HTTPS TLS version match/mismatch |
24 | * @author Sagie Amir | 25 | * @author Sagie Amir |
26 | * @author Karlson2k (Evgeny Grin) | ||
25 | */ | 27 | */ |
26 | 28 | ||
27 | #include "platform.h" | 29 | #include "platform.h" |
28 | #include "microhttpd.h" | 30 | #include "microhttpd.h" |
29 | #include <sys/stat.h> | 31 | #include <curl/curl.h> |
30 | #include <limits.h> | ||
31 | #ifdef MHD_HTTPS_REQUIRE_GCRYPT | 32 | #ifdef MHD_HTTPS_REQUIRE_GCRYPT |
32 | #include <gcrypt.h> | 33 | #include <gcrypt.h> |
33 | #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ | 34 | #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ |
34 | #include "tls_test_common.h" | 35 | #include "tls_test_common.h" |
35 | #include "tls_test_keys.h" | 36 | #include "tls_test_keys.h" |
36 | 37 | ||
37 | /** | 38 | /* |
38 | * test server refuses to negotiate connections with unsupported protocol versions | 39 | * HTTP access handler call back |
39 | * | 40 | * used to query negotiated security parameters |
40 | */ | 41 | */ |
41 | static unsigned int | 42 | static enum MHD_Result |
42 | test_unmatching_ssl_version (void *cls, uint16_t port, const char *cipher_suite, | 43 | simple_ahc (void *cls, struct MHD_Connection *connection, |
43 | int curl_req_ssl_version) | 44 | const char *url, const char *method, |
45 | const char *version, const char *upload_data, | ||
46 | size_t *upload_data_size, void **req_cls) | ||
44 | { | 47 | { |
45 | struct CBC cbc; | 48 | struct MHD_Response *response; |
46 | char url[255]; | 49 | enum MHD_Result ret; |
47 | (void) cls; /* Unused. Silent compiler warning. */ | 50 | (void) cls; (void) url; (void) method; (void) version; /* Unused. Silent compiler warning. */ |
48 | if (NULL == (cbc.buf = malloc (sizeof (char) * 256))) | 51 | (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */ |
52 | |||
53 | if (NULL == *req_cls) | ||
49 | { | 54 | { |
50 | fprintf (stderr, "Error: failed to allocate: %s\n", | 55 | *req_cls = (void *) &simple_ahc; |
51 | strerror (errno)); | 56 | return MHD_YES; |
52 | return 1; | ||
53 | } | 57 | } |
54 | cbc.size = 256; | ||
55 | cbc.pos = 0; | ||
56 | 58 | ||
57 | if (gen_test_uri (url, | 59 | response = |
58 | sizeof (url), | 60 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (EMPTY_PAGE), |
59 | port)) | 61 | EMPTY_PAGE); |
62 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | ||
63 | MHD_destroy_response (response); | ||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | |||
68 | enum check_result | ||
69 | { | ||
70 | CHECK_RES_OK = 0, | ||
71 | CHECK_RES_ERR = 1, | ||
72 | |||
73 | CHECK_RES_MHD_START_FAILED = 17, | ||
74 | CHECK_RES_CURL_TLS_INIT_FAIL = 18, | ||
75 | CHECK_RES_CURL_TLS_CONN_FAIL = 19, | ||
76 | |||
77 | CHECK_RES_HARD_ERROR = 99 | ||
78 | }; | ||
79 | |||
80 | static enum check_result | ||
81 | check_tls_match_inner (enum know_gnutls_tls_id tls_ver_mhd, | ||
82 | enum know_gnutls_tls_id tls_ver_libcurl, | ||
83 | uint16_t *pport, | ||
84 | struct MHD_Daemon **d_ptr, | ||
85 | struct CBC *pcbc, | ||
86 | CURL **c_ptr) | ||
87 | { | ||
88 | CURLcode errornum; | ||
89 | char url[256]; | ||
90 | int libcurl_tls_set; | ||
91 | CURL *c; | ||
92 | struct MHD_Daemon *d; | ||
93 | |||
94 | /* setup test */ | ||
95 | d = | ||
96 | MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | ||
97 | | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS | ||
98 | | MHD_USE_ERROR_LOG, *pport, | ||
99 | NULL, NULL, | ||
100 | &simple_ahc, NULL, | ||
101 | MHD_OPTION_HTTPS_PRIORITIES, priorities_map[tls_ver_mhd], | ||
102 | MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, | ||
103 | MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, | ||
104 | MHD_OPTION_END); | ||
105 | fflush (stderr); | ||
106 | fflush (stdout); | ||
107 | *d_ptr = d; | ||
108 | |||
109 | if (d == NULL) | ||
110 | { | ||
111 | fprintf (stderr, "MHD_start_daemon() with %s failed.\n", | ||
112 | tls_names[tls_ver_mhd]); | ||
113 | return CHECK_RES_MHD_START_FAILED; | ||
114 | } | ||
115 | if (0 == *pport) | ||
60 | { | 116 | { |
61 | free (cbc.buf); | 117 | const union MHD_DaemonInfo *dinfo; |
62 | fprintf (stderr, | 118 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); |
63 | "Internal error in gen_test_file_url\n"); | 119 | if ((NULL == dinfo) || (0 == dinfo->port) ) |
64 | return 1; | 120 | { |
121 | fprintf (stderr, "MHD_get_daemon_info() failed.\n"); | ||
122 | return CHECK_RES_ERR; | ||
123 | } | ||
124 | *pport = dinfo->port; /* Use the same port for rest of the checks */ | ||
65 | } | 125 | } |
66 | 126 | ||
67 | /* assert daemon *rejected* request */ | 127 | if (0 != gen_test_uri (url, |
68 | if (CURLE_OK == | 128 | sizeof (url), |
69 | send_curl_req (url, &cbc, cipher_suite, curl_req_ssl_version)) | 129 | *pport)) |
130 | { | ||
131 | fprintf (stderr, "failed to generate URI.\n"); | ||
132 | return CHECK_RES_CURL_TLS_INIT_FAIL; | ||
133 | } | ||
134 | c = curl_easy_init (); | ||
135 | fflush (stderr); | ||
136 | fflush (stdout); | ||
137 | *c_ptr = c; | ||
138 | if (NULL == c) | ||
70 | { | 139 | { |
71 | free (cbc.buf); | 140 | fprintf (stderr, "curl_easy_init() failed.\n"); |
72 | fprintf (stderr, | 141 | return CHECK_RES_HARD_ERROR; |
73 | "cURL failed to reject request despite SSL version mismatch!\n"); | ||
74 | return 1; | ||
75 | } | 142 | } |
143 | #ifdef _DEBUG | ||
144 | curl_easy_setopt (c, CURLOPT_VERBOSE, 1L); | ||
145 | #endif | ||
76 | 146 | ||
147 | if ((CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_URL, url))) || | ||
148 | (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_HTTP_VERSION, | ||
149 | CURL_HTTP_VERSION_1_1))) || | ||
150 | (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L))) || | ||
151 | (CURLE_OK != | ||
152 | (errornum = curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L))) || | ||
153 | (CURLE_OK != | ||
154 | (errornum = curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer))) || | ||
155 | (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_WRITEDATA, | ||
156 | pcbc))) || | ||
157 | /* TLS options */ | ||
158 | /* currently skip any peer authentication */ | ||
159 | (CURLE_OK != | ||
160 | (errornum = curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L))) || | ||
161 | (CURLE_OK != | ||
162 | (errornum = curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0L))) || | ||
163 | (CURLE_OK != | ||
164 | (errornum = curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L))) || | ||
165 | (CURLE_OK != (errornum = curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)))) | ||
166 | { | ||
167 | fflush (stderr); | ||
168 | fflush (stdout); | ||
169 | fprintf (stderr, "Error setting libcurl option: %s.\n", | ||
170 | curl_easy_strerror (errornum)); | ||
171 | return CHECK_RES_HARD_ERROR; | ||
172 | } | ||
173 | libcurl_tls_set = 0; | ||
174 | #if CURL_AT_LEAST_VERSION (7,54,0) | ||
175 | if (CURL_SSLVERSION_MAX_DEFAULT != | ||
176 | libcurl_tls_max_vers_map[tls_ver_libcurl]) | ||
177 | { | ||
178 | errornum = curl_easy_setopt (c, CURLOPT_SSLVERSION, | ||
179 | libcurl_tls_vers_map[tls_ver_libcurl] | ||
180 | | libcurl_tls_max_vers_map[tls_ver_libcurl]); | ||
181 | if (CURLE_OK == errornum) | ||
182 | libcurl_tls_set = 1; | ||
183 | else | ||
184 | { | ||
185 | fprintf (stderr, "Error setting libcurl TLS version range: " | ||
186 | "%s.\nRetrying with minimum TLS version only.\n", | ||
187 | curl_easy_strerror (errornum)); | ||
188 | } | ||
189 | } | ||
190 | #endif /* CURL_AT_LEAST_VERSION(7,54,0) */ | ||
191 | if (! libcurl_tls_set && | ||
192 | (CURLE_OK != | ||
193 | (errornum = curl_easy_setopt (c, CURLOPT_SSLVERSION, | ||
194 | libcurl_tls_vers_map[tls_ver_libcurl])))) | ||
195 | { | ||
196 | fprintf (stderr, "Error setting libcurl minimum TLS version: %s.\n", | ||
197 | curl_easy_strerror (errornum)); | ||
198 | return CHECK_RES_CURL_TLS_INIT_FAIL; | ||
199 | } | ||
200 | |||
201 | errornum = curl_easy_perform (c); | ||
202 | fflush (stderr); | ||
203 | fflush (stdout); | ||
204 | if (CURLE_OK != errornum) | ||
205 | { | ||
206 | if ((CURLE_SSL_CONNECT_ERROR == errornum) || | ||
207 | (CURLE_SSL_CIPHER == errornum)) | ||
208 | { | ||
209 | fprintf (stderr, "libcurl request failed due to TLS error: '%s'\n", | ||
210 | curl_easy_strerror (errornum)); | ||
211 | return CHECK_RES_CURL_TLS_CONN_FAIL; | ||
212 | |||
213 | } | ||
214 | else | ||
215 | { | ||
216 | fprintf (stderr, "curl_easy_perform failed: '%s'\n", | ||
217 | curl_easy_strerror (errornum)); | ||
218 | return CHECK_RES_ERR; | ||
219 | } | ||
220 | } | ||
221 | return CHECK_RES_OK; | ||
222 | } | ||
223 | |||
224 | |||
225 | /** | ||
226 | * negotiate a secure connection with server with specific TLS versions | ||
227 | * set for MHD and for libcurl | ||
228 | */ | ||
229 | static enum check_result | ||
230 | check_tls_match (enum know_gnutls_tls_id tls_ver_mhd, | ||
231 | enum know_gnutls_tls_id tls_ver_libcurl, | ||
232 | uint16_t *pport) | ||
233 | { | ||
234 | CURL *c; | ||
235 | struct CBC cbc; | ||
236 | enum check_result ret; | ||
237 | struct MHD_Daemon *d; | ||
238 | |||
239 | if (NULL == (cbc.buf = malloc (sizeof (char) * 255))) | ||
240 | return CHECK_RES_HARD_ERROR; | ||
241 | cbc.size = 255; | ||
242 | cbc.pos = 0; | ||
243 | |||
244 | d = NULL; | ||
245 | c = NULL; | ||
246 | ret = check_tls_match_inner (tls_ver_mhd, tls_ver_libcurl, pport, | ||
247 | &d, &cbc, &c); | ||
248 | fflush (stderr); | ||
249 | fflush (stdout); | ||
250 | if (NULL != d) | ||
251 | MHD_stop_daemon (d); | ||
252 | if (NULL != c) | ||
253 | curl_easy_cleanup (c); | ||
77 | free (cbc.buf); | 254 | free (cbc.buf); |
78 | return 0; | 255 | |
256 | return ret; | ||
79 | } | 257 | } |
80 | 258 | ||
81 | 259 | ||
82 | int | 260 | static unsigned int |
83 | main (int argc, char *const *argv) | 261 | test_first_supported_versions (void) |
84 | { | 262 | { |
85 | unsigned int errorCount = 0; | 263 | enum know_gnutls_tls_id ver_for_check; /**< TLS version used for test */ |
86 | const char *ssl_version; | 264 | const gnutls_protocol_t *vers_list; /**< The list of GnuTLS supported TLS versions */ |
87 | unsigned int daemon_flags = | ||
88 | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | ||
89 | | MHD_USE_TLS | MHD_USE_ERROR_LOG; | ||
90 | uint16_t port; | 265 | uint16_t port; |
91 | (void) argc; (void) argv; /* Unused. Silent compiler warning. */ | ||
92 | 266 | ||
93 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) | 267 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) |
94 | port = 0; | 268 | port = 0; /* Use system automatic assignment */ |
95 | else | 269 | else |
96 | port = 3010; | 270 | port = 3060; /* Use predefined port, may break parallel testing of another MHD build */ |
271 | |||
272 | vers_list = gnutls_protocol_list (); | ||
273 | if (NULL == vers_list) | ||
274 | { | ||
275 | fprintf (stderr, "Error getting GnuTLS supported TLS versions"); | ||
276 | return 99; | ||
277 | } | ||
278 | |||
279 | for (ver_for_check = KNOWN_TLS_MIN; KNOWN_TLS_MAX >= ver_for_check; | ||
280 | ++ver_for_check) | ||
281 | { | ||
282 | const gnutls_protocol_t *ver_ptr; /**< The pointer to the position on the @a vers_list */ | ||
283 | enum check_result res; | ||
284 | for (ver_ptr = vers_list; 0 != *ver_ptr; ++ver_ptr) | ||
285 | { | ||
286 | if (ver_for_check == (enum know_gnutls_tls_id) *ver_ptr) | ||
287 | break; | ||
288 | } | ||
289 | if (0 == *ver_ptr) | ||
290 | { | ||
291 | printf ("%s is not supported by GnuTLS, skipping.\n\n", | ||
292 | tls_names[ver_for_check]); | ||
293 | fflush (stdout); | ||
294 | continue; | ||
295 | } | ||
296 | if (CURL_SSLVERSION_LAST == libcurl_tls_vers_map[ver_for_check]) | ||
297 | { | ||
298 | printf ("%s is not supported by libcurl, skipping.\n\n", | ||
299 | tls_names[ver_for_check]); | ||
300 | fflush (stdout); | ||
301 | continue; | ||
302 | } | ||
303 | /* Found some TLS version that supported by GnuTLS and should be supported | ||
304 | by libcurl (but in practice support depends on used TLS library) */ | ||
305 | |||
306 | if (KNOWN_TLS_MIN != ver_for_check) | ||
307 | printf ("\n"); | ||
308 | printf ("Starting check with MHD set to '%s' and " | ||
309 | "libcurl set to '%s' (successful connection is expected)...\n", | ||
310 | tls_names[ver_for_check], tls_names[ver_for_check]); | ||
311 | fflush (stdout); | ||
312 | |||
313 | /* Check with MHD and libcurl set to the same TLS version */ | ||
314 | res = check_tls_match (ver_for_check, ver_for_check, &port); | ||
315 | if (CHECK_RES_HARD_ERROR == res) | ||
316 | { | ||
317 | fprintf (stderr, "Hard error. Test stopped.\n"); | ||
318 | fflush (stderr); | ||
319 | return 99; | ||
320 | } | ||
321 | else if (CHECK_RES_ERR == res) | ||
322 | { | ||
323 | printf ("Test failed.\n"); | ||
324 | fflush (stdout); | ||
325 | return 2; | ||
326 | } | ||
327 | else if (CHECK_RES_MHD_START_FAILED == res) | ||
328 | { | ||
329 | printf ("Skipping '%s' as MHD cannot be started with this setting.\n", | ||
330 | tls_names[ver_for_check]); | ||
331 | fflush (stdout); | ||
332 | continue; | ||
333 | } | ||
334 | else if (CHECK_RES_CURL_TLS_INIT_FAIL == res) | ||
335 | { | ||
336 | printf ("Skipping '%s' as libcurl rejected this setting.\n", | ||
337 | tls_names[ver_for_check]); | ||
338 | fflush (stdout); | ||
339 | continue; | ||
340 | } | ||
341 | else if (CHECK_RES_CURL_TLS_CONN_FAIL == res) | ||
342 | { | ||
343 | printf ("Skipping '%s' as it is not supported by current libcurl " | ||
344 | "and GnuTLS combination.\n", | ||
345 | tls_names[ver_for_check]); | ||
346 | fflush (stdout); | ||
347 | continue; | ||
348 | } | ||
349 | printf ("Connection succeeded for MHD set to '%s' and " | ||
350 | "libcurl set to '%s'.\n\n", | ||
351 | tls_names[ver_for_check], tls_names[ver_for_check]); | ||
352 | |||
353 | /* Check with libcurl set to the next TLS version relative to MHD setting */ | ||
354 | if (KNOWN_TLS_MAX == ver_for_check) | ||
355 | { | ||
356 | printf ("Test is incomplete as the latest known TLS version ('%s') " | ||
357 | "was found as minimum working version.\nThere is no space to " | ||
358 | "advance to the next version.\nAssuming that test is fine.\n", | ||
359 | tls_names[ver_for_check]); | ||
360 | fflush (stdout); | ||
361 | return 0; | ||
362 | } | ||
363 | if (CURL_SSLVERSION_LAST == libcurl_tls_vers_map[ver_for_check + 1]) | ||
364 | { | ||
365 | printf ("Test is incomplete as '%s' is the latest version supported " | ||
366 | "by libcurl.\nThere is no space to " | ||
367 | "advance to the next version.\nAssuming that test is fine.\n", | ||
368 | tls_names[ver_for_check]); | ||
369 | fflush (stdout); | ||
370 | return 0; | ||
371 | } | ||
372 | printf ("Starting check with MHD set to '%s' and " | ||
373 | "minimum libcurl TLS version set to '%s' " | ||
374 | "(failed connection is expected)...\n", | ||
375 | tls_names[ver_for_check], tls_names[ver_for_check + 1]); | ||
376 | fflush (stdout); | ||
377 | res = check_tls_match (ver_for_check, ver_for_check + 1, | ||
378 | &port); | ||
379 | if (CHECK_RES_HARD_ERROR == res) | ||
380 | { | ||
381 | fprintf (stderr, "Hard error. Test stopped.\n"); | ||
382 | fflush (stderr); | ||
383 | return 99; | ||
384 | } | ||
385 | else if (CHECK_RES_ERR == res) | ||
386 | { | ||
387 | printf ("Test failed.\n"); | ||
388 | fflush (stdout); | ||
389 | return 2; | ||
390 | } | ||
391 | else if (CHECK_RES_MHD_START_FAILED == res) | ||
392 | { | ||
393 | printf ("MHD cannot be started for the second time with " | ||
394 | "the same setting.\n"); | ||
395 | fflush (stdout); | ||
396 | return 4; | ||
397 | } | ||
398 | else if (CHECK_RES_CURL_TLS_INIT_FAIL == res) | ||
399 | { | ||
400 | printf ("'%s' has been rejected by libcurl.\n" | ||
401 | "Assuming that test is fine.\n", | ||
402 | tls_names[ver_for_check + 1]); | ||
403 | fflush (stdout); | ||
404 | return 0; | ||
405 | } | ||
406 | else if (CHECK_RES_CURL_TLS_CONN_FAIL == res) | ||
407 | { | ||
408 | printf ("As expected, libcurl cannot connect to MHD when libcurl " | ||
409 | "minimum TLS version is set to '%s' while MHD TLS version set " | ||
410 | "to '%s'.\n" | ||
411 | "Test succeeded.\n", | ||
412 | tls_names[ver_for_check + 1], tls_names[ver_for_check]); | ||
413 | fflush (stdout); | ||
414 | return 0; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | fprintf (stderr, "The test skipped: No know TLS version is supported by " | ||
419 | "both MHD and libcurl.\n"); | ||
420 | fflush (stderr); | ||
421 | return 77; | ||
422 | } | ||
423 | |||
424 | |||
425 | int | ||
426 | main (int argc, char *const *argv) | ||
427 | { | ||
428 | unsigned int errorCount = 0; | ||
429 | const char *ssl_version; | ||
430 | (void) argc; /* Unused. Silent compiler warning. */ | ||
97 | 431 | ||
98 | #ifdef MHD_HTTPS_REQUIRE_GCRYPT | 432 | #ifdef MHD_HTTPS_REQUIRE_GCRYPT |
99 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); | ||
100 | gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); | 433 | gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); |
101 | #ifdef GCRYCTL_INITIALIZATION_FINISHED | 434 | #ifdef GCRYCTL_INITIALIZATION_FINISHED |
102 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); | 435 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); |
@@ -106,66 +439,20 @@ main (int argc, char *const *argv) | |||
106 | return 99; | 439 | return 99; |
107 | 440 | ||
108 | ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version; | 441 | ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version; |
109 | if (0 == strncmp (ssl_version, "OpenSSL/", 8)) | 442 | if (NULL == ssl_version) |
110 | { | ||
111 | if (0 == strncmp (ssl_version, "OpenSSL/0.", 10)) | ||
112 | { | ||
113 | fprintf (stderr, "Curl uses too old library: %s\n", ssl_version); | ||
114 | curl_global_cleanup (); | ||
115 | return 77; | ||
116 | } | ||
117 | } | ||
118 | else if ((0 == strncmp (ssl_version, "GnuTLS/", 7))) | ||
119 | { | 443 | { |
120 | #if GNUTLS_VERSION_NUMBER <= 0x020806 | 444 | fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n"); |
121 | fprintf (stderr, "Curl uses too old library: %s\n", ssl_version); | ||
122 | curl_global_cleanup (); | ||
123 | return 77; | ||
124 | #else | ||
125 | (void) 0; | ||
126 | #endif | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | if (NULL == ssl_version) | ||
131 | fprintf (stderr, "Curl does not support TLS.\n"); | ||
132 | else | ||
133 | fprintf (stderr, "Curl uses too old library: %s\n", ssl_version); | ||
134 | curl_global_cleanup (); | 445 | curl_global_cleanup (); |
135 | return 77; | 446 | return 77; |
136 | } | 447 | } |
137 | 448 | errorCount = test_first_supported_versions (); | |
138 | if (0 != | 449 | fflush (stderr); |
139 | test_wrap ("TLS1.0", | 450 | fflush (stdout); |
140 | &test_https_transfer, NULL, port, daemon_flags, | ||
141 | NULL, | ||
142 | CURL_SSLVERSION_TLSv1, | ||
143 | MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, | ||
144 | MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, | ||
145 | MHD_OPTION_HTTPS_PRIORITIES, | ||
146 | "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+RSA:+COMP-NULL", | ||
147 | MHD_OPTION_END)) | ||
148 | { | ||
149 | fprintf (stderr, "TLS1.0 test failed\n"); | ||
150 | errorCount++; | ||
151 | } | ||
152 | fprintf (stderr, | ||
153 | "The following handshake should fail (and print an error message)...\n"); | ||
154 | if (0 != | ||
155 | test_wrap ("TLS1.1 vs TLS1.0", | ||
156 | &test_unmatching_ssl_version, NULL, port, daemon_flags, | ||
157 | NULL, | ||
158 | CURL_SSLVERSION_TLSv1_1, | ||
159 | MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, | ||
160 | MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, | ||
161 | MHD_OPTION_HTTPS_PRIORITIES, | ||
162 | "NONE:+VERS-TLS1.0:+AES-256-CBC:+SHA1:+RSA:+COMP-NULL", | ||
163 | MHD_OPTION_END)) | ||
164 | { | ||
165 | fprintf (stderr, "TLS1.1 vs TLS1.0 test failed\n"); | ||
166 | errorCount++; | ||
167 | } | ||
168 | curl_global_cleanup (); | 451 | curl_global_cleanup (); |
169 | 452 | if (77 == errorCount) | |
453 | return 77; | ||
454 | else if (99 == errorCount) | ||
455 | return 99; | ||
456 | print_test_result (errorCount, argv[0]); | ||
170 | return errorCount != 0 ? 1 : 0; | 457 | return errorCount != 0 ? 1 : 0; |
171 | } | 458 | } |
diff --git a/src/testcurl/https/tls_test_common.c b/src/testcurl/https/tls_test_common.c index d2c7b14e..6d7daa02 100644 --- a/src/testcurl/https/tls_test_common.c +++ b/src/testcurl/https/tls_test_common.c | |||
@@ -29,7 +29,7 @@ | |||
29 | /** | 29 | /** |
30 | * Map @a know_gnutls_tls_ids values to printable names. | 30 | * Map @a know_gnutls_tls_ids values to printable names. |
31 | */ | 31 | */ |
32 | const char *tls_names[6] = { | 32 | const char *tls_names[KNOW_TLS_IDS_COUNT] = { |
33 | "Bad value", | 33 | "Bad value", |
34 | "SSL version 3", | 34 | "SSL version 3", |
35 | "TLS version 1.0", | 35 | "TLS version 1.0", |
@@ -41,7 +41,7 @@ const char *tls_names[6] = { | |||
41 | /** | 41 | /** |
42 | * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings. | 42 | * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings. |
43 | */ | 43 | */ |
44 | const char *priorities_map[6] = { | 44 | const char *priorities_map[KNOW_TLS_IDS_COUNT] = { |
45 | "NONE", | 45 | "NONE", |
46 | "NORMAL:!VERS-ALL:+VERS-SSL3.0", | 46 | "NORMAL:!VERS-ALL:+VERS-SSL3.0", |
47 | "NORMAL:!VERS-ALL:+VERS-TLS1.0", | 47 | "NORMAL:!VERS-ALL:+VERS-TLS1.0", |
@@ -50,6 +50,50 @@ const char *priorities_map[6] = { | |||
50 | "NORMAL:!VERS-ALL:+VERS-TLS1.3" | 50 | "NORMAL:!VERS-ALL:+VERS-TLS1.3" |
51 | }; | 51 | }; |
52 | 52 | ||
53 | |||
54 | /** | ||
55 | * Map @a know_gnutls_tls_ids values to libcurl @a CURLOPT_SSLVERSION value. | ||
56 | */ | ||
57 | const long libcurl_tls_vers_map[KNOW_TLS_IDS_COUNT] = { | ||
58 | CURL_SSLVERSION_LAST, /* bad value */ | ||
59 | CURL_SSLVERSION_SSLv3, | ||
60 | #if CURL_AT_LEAST_VERSION (7,34,0) | ||
61 | CURL_SSLVERSION_TLSv1_0, | ||
62 | #else /* CURL VER < 7.34.0 */ | ||
63 | CURL_SSLVERSION_TLSv1, /* TLS 1.0 or later */ | ||
64 | #endif /* CURL VER < 7.34.0 */ | ||
65 | #if CURL_AT_LEAST_VERSION (7,34,0) | ||
66 | CURL_SSLVERSION_TLSv1_1, | ||
67 | #else /* CURL VER < 7.34.0 */ | ||
68 | CURL_SSLVERSION_LAST, /* bad value, not supported by this libcurl version */ | ||
69 | #endif /* CURL VER < 7.34.0 */ | ||
70 | #if CURL_AT_LEAST_VERSION (7,34,0) | ||
71 | CURL_SSLVERSION_TLSv1_2, | ||
72 | #else /* CURL VER < 7.34.0 */ | ||
73 | CURL_SSLVERSION_LAST, /* bad value, not supported by this libcurl version */ | ||
74 | #endif /* CURL VER < 7.34.0 */ | ||
75 | #if CURL_AT_LEAST_VERSION (7,52,0) | ||
76 | CURL_SSLVERSION_TLSv1_3 | ||
77 | #else /* CURL VER < 7.34.0 */ | ||
78 | CURL_SSLVERSION_LAST /* bad value, not supported by this libcurl version */ | ||
79 | #endif /* CURL VER < 7.34.0 */ | ||
80 | }; | ||
81 | |||
82 | #if CURL_AT_LEAST_VERSION (7,54,0) | ||
83 | /** | ||
84 | * Map @a know_gnutls_tls_ids values to libcurl @a CURLOPT_SSLVERSION value | ||
85 | * for maximum supported TLS version. | ||
86 | */ | ||
87 | const long libcurl_tls_max_vers_map[KNOW_TLS_IDS_COUNT] = { | ||
88 | CURL_SSLVERSION_MAX_DEFAULT, /* bad value */ | ||
89 | CURL_SSLVERSION_MAX_DEFAULT, /* SSLv3 */ | ||
90 | CURL_SSLVERSION_MAX_TLSv1_0, | ||
91 | CURL_SSLVERSION_MAX_TLSv1_1, | ||
92 | CURL_SSLVERSION_MAX_TLSv1_2, | ||
93 | CURL_SSLVERSION_MAX_TLSv1_3 | ||
94 | }; | ||
95 | #endif /* CURL_AT_LEAST_VERSION(7,54,0) */ | ||
96 | |||
53 | /* | 97 | /* |
54 | * test HTTPS transfer | 98 | * test HTTPS transfer |
55 | */ | 99 | */ |
diff --git a/src/testcurl/https/tls_test_common.h b/src/testcurl/https/tls_test_common.h index 784ab173..074f5345 100644 --- a/src/testcurl/https/tls_test_common.h +++ b/src/testcurl/https/tls_test_common.h | |||
@@ -28,6 +28,14 @@ | |||
28 | #include <limits.h> | 28 | #include <limits.h> |
29 | #include <gnutls/gnutls.h> | 29 | #include <gnutls/gnutls.h> |
30 | 30 | ||
31 | #ifndef CURL_VERSION_BITS | ||
32 | #define CURL_VERSION_BITS(x,y,z) ((x) << 16 | (y) << 8 | (z)) | ||
33 | #endif /* ! CURL_VERSION_BITS */ | ||
34 | #ifndef CURL_AT_LEAST_VERSION | ||
35 | #define CURL_AT_LEAST_VERSION(x,y,z) \ | ||
36 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS (x, y, z)) | ||
37 | #endif /* ! CURL_AT_LEAST_VERSION */ | ||
38 | |||
31 | #define test_data "Hello World\n" | 39 | #define test_data "Hello World\n" |
32 | #define ca_cert_file_name SRCDIR "/test-ca.crt" | 40 | #define ca_cert_file_name SRCDIR "/test-ca.crt" |
33 | 41 | ||
@@ -44,6 +52,13 @@ | |||
44 | #define MHD_E_FAILED_TO_CONNECT \ | 52 | #define MHD_E_FAILED_TO_CONNECT \ |
45 | "Error: server connection could not be established\n" | 53 | "Error: server connection could not be established\n" |
46 | 54 | ||
55 | #ifndef MHD_STATICSTR_LEN_ | ||
56 | /** | ||
57 | * Determine length of static string / macro strings at compile time. | ||
58 | */ | ||
59 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) | ||
60 | #endif /* ! MHD_STATICSTR_LEN_ */ | ||
61 | |||
47 | 62 | ||
48 | /* The local copy if GnuTLS IDs to avoid long #ifdefs list with various | 63 | /* The local copy if GnuTLS IDs to avoid long #ifdefs list with various |
49 | * GnuTLS versions */ | 64 | * GnuTLS versions */ |
@@ -63,15 +78,29 @@ enum know_gnutls_tls_id | |||
63 | KNOWN_TLS_MAX = KNOWN_TLS_V1_3 /**< Maximum valid value */ | 78 | KNOWN_TLS_MAX = KNOWN_TLS_V1_3 /**< Maximum valid value */ |
64 | }; | 79 | }; |
65 | 80 | ||
81 | #define KNOW_TLS_IDS_COUNT 6 /* KNOWN_TLS_MAX + 1 */ | ||
66 | /** | 82 | /** |
67 | * Map @a know_gnutls_tls_ids values to printable names. | 83 | * Map @a know_gnutls_tls_ids values to printable names. |
68 | */ | 84 | */ |
69 | extern const char *tls_names[6]; | 85 | extern const char *tls_names[KNOW_TLS_IDS_COUNT]; |
70 | 86 | ||
71 | /** | 87 | /** |
72 | * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings. | 88 | * Map @a know_gnutls_tls_ids values to GnuTLS priorities strings. |
73 | */ | 89 | */ |
74 | extern const char *priorities_map[6]; | 90 | extern const char *priorities_map[KNOW_TLS_IDS_COUNT]; |
91 | |||
92 | /** | ||
93 | * Map @a know_gnutls_tls_ids values to libcurl @a CURLOPT_SSLVERSION value. | ||
94 | */ | ||
95 | extern const long libcurl_tls_vers_map[KNOW_TLS_IDS_COUNT]; | ||
96 | |||
97 | #if CURL_AT_LEAST_VERSION (7,54,0) | ||
98 | /** | ||
99 | * Map @a know_gnutls_tls_ids values to libcurl @a CURLOPT_SSLVERSION value | ||
100 | * for maximum supported TLS version. | ||
101 | */ | ||
102 | extern const long libcurl_tls_max_vers_map[KNOW_TLS_IDS_COUNT]; | ||
103 | #endif /* CURL_AT_LEAST_VERSION(7,54,0) */ | ||
75 | 104 | ||
76 | struct https_test_data | 105 | struct https_test_data |
77 | { | 106 | { |