test_tls_authentication.c (4107B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007 Christian Grothoff 4 Copyright (C) 2016-2022 Evgeny Grin (Karlson2k) 5 6 libmicrohttpd is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published 8 by the Free Software Foundation; either version 2, or (at your 9 option) any later version. 10 11 libmicrohttpd is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with libmicrohttpd; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20 */ 21 22 /** 23 * @file test_tls_authentication.c 24 * @brief Testcase for libmicrohttpd HTTPS GET operations with CA-signed TLS server certificate 25 * @author Sagie Amir 26 * @author Karlson2k (Evgeny Grin) 27 */ 28 29 #include "platform.h" 30 #include "microhttpd.h" 31 #include <curl/curl.h> 32 #include <limits.h> 33 #include <sys/stat.h> 34 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 35 #include <gcrypt.h> 36 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 37 #include "tls_test_common.h" 38 #include "tls_test_keys.h" 39 40 41 /* perform a HTTP GET request via SSL/TLS */ 42 static unsigned int 43 test_secure_get (void *cls, const char *cipher_suite, int proto_version) 44 { 45 enum test_get_result ret; 46 struct MHD_Daemon *d; 47 uint16_t port; 48 (void) cls; /* Unused. Silent compiler warning. */ 49 50 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) 51 port = 0; 52 else 53 port = 3075; 54 55 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 56 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS 57 | MHD_USE_ERROR_LOG, port, 58 NULL, NULL, &http_ahc, NULL, 59 MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem, 60 MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem, 61 MHD_OPTION_END); 62 63 if (d == NULL) 64 { 65 fprintf (stderr, MHD_E_SERVER_INIT); 66 return 1; 67 } 68 if (0 == port) 69 { 70 const union MHD_DaemonInfo *dinfo; 71 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 72 if ((NULL == dinfo) || (0 == dinfo->port) ) 73 { 74 MHD_stop_daemon (d); 75 return 1; 76 } 77 port = dinfo->port; 78 } 79 80 ret = test_daemon_get (NULL, cipher_suite, proto_version, port, 1); 81 82 MHD_stop_daemon (d); 83 if (TEST_GET_HARD_ERROR == ret) 84 return 99; 85 if (TEST_GET_CURL_GEN_ERROR == ret) 86 { 87 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 88 return 99; 89 } 90 if ((TEST_GET_CURL_CA_ERROR == ret) || 91 (TEST_GET_CURL_NOT_IMPLT == ret)) 92 { 93 fprintf (stderr, "libcurl TLS backend does not support custom CA.\n" 94 "Test skipped.\n"); 95 return 77; 96 } 97 return TEST_GET_OK == ret ? 0 : 1; 98 } 99 100 101 int 102 main (int argc, char *const *argv) 103 { 104 unsigned int errorCount; 105 (void) argc; 106 (void) argv; /* Unused. Silent compiler warning. */ 107 108 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 109 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 110 #ifdef GCRYCTL_INITIALIZATION_FINISHED 111 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 112 #endif 113 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 114 if (! testsuite_curl_global_init ()) 115 return 99; 116 if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version) 117 { 118 fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n"); 119 curl_global_cleanup (); 120 return 77; 121 } 122 #if ! CURL_AT_LEAST_VERSION (7,60,0) 123 if (curl_tls_is_schannel ()) 124 { 125 fprintf (stderr, "libcurl before version 7.60.0 does not support " 126 "custom CA with Schannel backend.\nTest skipped.\n"); 127 curl_global_cleanup (); 128 return 77; 129 } 130 #endif /* ! CURL_AT_LEAST_VERSION(7,60,0) */ 131 132 errorCount = 133 test_secure_get (NULL, NULL, CURL_SSLVERSION_DEFAULT); 134 135 print_test_result (errorCount, argv[0]); 136 137 curl_global_cleanup (); 138 if (77 == errorCount) 139 return 77; 140 if (99 == errorCount) 141 return 77; 142 return errorCount != 0 ? 1 : 0; 143 }