test_https_session_info.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. This file is part of libmicrohttpd
  3. (C) 2007 Christian Grothoff
  4. libmicrohttpd is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 2, or (at your
  7. option) any later version.
  8. libmicrohttpd is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with libmicrohttpd; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file mhds_session_info_test.c
  19. * @brief Testcase for libmicrohttpd HTTPS connection querying operations
  20. * @author Sagie Amir
  21. */
  22. #include "platform.h"
  23. #include "microhttpd.h"
  24. #include <curl/curl.h>
  25. #include <gcrypt.h>
  26. #include "tls_test_common.h"
  27. extern int curl_check_version (const char *req_version, ...);
  28. extern const char srv_key_pem[];
  29. extern const char srv_self_signed_cert_pem[];
  30. struct MHD_Daemon *d;
  31. /*
  32. * HTTP access handler call back
  33. * used to query negotiated security parameters
  34. */
  35. static int
  36. query_session_ahc (void *cls, struct MHD_Connection *connection,
  37. const char *url, const char *method,
  38. const char *upload_data, const char *version,
  39. size_t *upload_data_size, void **ptr)
  40. {
  41. struct MHD_Response *response;
  42. int ret;
  43. if (NULL == *ptr)
  44. {
  45. *ptr = &query_session_ahc;
  46. return MHD_YES;
  47. }
  48. if (GNUTLS_SSL3 !=
  49. (ret = MHD_get_connection_info
  50. (connection,
  51. MHD_CONNECTION_INFO_PROTOCOL)->protocol))
  52. {
  53. fprintf (stderr, "Error: requested protocol mismatch (wanted %d, got %d)\n",
  54. GNUTLS_SSL3,
  55. ret);
  56. return -1;
  57. }
  58. response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE),
  59. (void *) EMPTY_PAGE,
  60. MHD_RESPMEM_PERSISTENT);
  61. ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  62. MHD_destroy_response (response);
  63. return ret;
  64. }
  65. /**
  66. * negotiate a secure connection with server & query negotiated security parameters
  67. */
  68. static int
  69. test_query_session ()
  70. {
  71. CURL *c;
  72. struct CBC cbc;
  73. CURLcode errornum;
  74. char url[256];
  75. if (NULL == (cbc.buf = malloc (sizeof (char) * 255)))
  76. return 16;
  77. cbc.size = 255;
  78. cbc.pos = 0;
  79. gen_test_file_url (url, DEAMON_TEST_PORT);
  80. /* setup test */
  81. d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
  82. MHD_USE_DEBUG, DEAMON_TEST_PORT,
  83. NULL, NULL, &query_session_ahc, NULL,
  84. MHD_OPTION_HTTPS_PRIORITIES, "NORMAL:+ARCFOUR-128",
  85. MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
  86. MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
  87. MHD_OPTION_END);
  88. if (d == NULL)
  89. return 2;
  90. const char *aes256_sha = "AES256-SHA";
  91. if (curl_uses_nss_ssl() == 0)
  92. {
  93. aes256_sha = "rsa_aes_256_sha";
  94. }
  95. c = curl_easy_init ();
  96. #if DEBUG_HTTPS_TEST
  97. curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
  98. #endif
  99. curl_easy_setopt (c, CURLOPT_URL, url);
  100. curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  101. curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
  102. curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
  103. curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  104. curl_easy_setopt (c, CURLOPT_FILE, &cbc);
  105. /* TLS options */
  106. curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
  107. curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
  108. /* currently skip any peer authentication */
  109. curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
  110. curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
  111. curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  112. // NOTE: use of CONNECTTIMEOUT without also
  113. // setting NOSIGNAL results in really weird
  114. // crashes on my system!
  115. curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  116. if (CURLE_OK != (errornum = curl_easy_perform (c)))
  117. {
  118. fprintf (stderr, "curl_easy_perform failed: `%s'\n",
  119. curl_easy_strerror (errornum));
  120. MHD_stop_daemon (d);
  121. curl_easy_cleanup (c);
  122. free (cbc.buf);
  123. return -1;
  124. }
  125. curl_easy_cleanup (c);
  126. MHD_stop_daemon (d);
  127. free (cbc.buf);
  128. return 0;
  129. }
  130. int
  131. main (int argc, char *const *argv)
  132. {
  133. unsigned int errorCount = 0;
  134. gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
  135. #ifdef GCRYCTL_INITIALIZATION_FINISHED
  136. gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  137. #endif
  138. if (0 != curl_global_init (CURL_GLOBAL_ALL))
  139. {
  140. fprintf (stderr, "Error (code: %u)\n", errorCount);
  141. return -1;
  142. }
  143. errorCount += test_query_session ();
  144. print_test_result (errorCount, argv[0]);
  145. curl_global_cleanup ();
  146. if (errorCount > 0)
  147. fprintf (stderr, "Error (code: %u)\n", errorCount);
  148. return errorCount;
  149. }