aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/https/tls_extension_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/https/tls_extension_test.c')
-rw-r--r--src/testcurl/https/tls_extension_test.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/testcurl/https/tls_extension_test.c b/src/testcurl/https/tls_extension_test.c
new file mode 100644
index 00000000..6f185bac
--- /dev/null
+++ b/src/testcurl/https/tls_extension_test.c
@@ -0,0 +1,264 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 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 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file tls_extension_test.c
23 * @brief: test daemon response to TLS client hello requests containing extensions
24 *
25 * @author Sagie Amir
26 */
27
28#include "platform.h"
29#include "microhttpd.h"
30#include "gnutls_int.h"
31#include "gnutls_handshake.h" // MHD_gtls_send_handshake
32#include "gnutls_num.h" // MHD_gtls_write_x
33#include "common.h" // MHD_gtls_version_x
34
35
36#include "tls_test_common.h"
37#define MAX_EXT_DATA_LENGTH 256
38
39extern int
40MHD__gnutls_copy_ciphersuites (MHD_gtls_session_t session,
41 opaque * ret_data, size_t ret_data_size);
42
43extern const char srv_key_pem[];
44extern const char srv_self_signed_cert_pem[];
45
46/**
47 * Test daemon response to TLS client hello requests containing extensions
48 *
49 * @param session
50 * @param exten_t - the type of extension being appended to client hello request
51 * @param ext_count - the number of consecutive extension replicas inserted into request
52 * @param ext_length - the length of each appended extension
53 * @return 0 on successful test completion, -1 otherwise
54 */
55static int
56test_hello_extension (MHD_gtls_session_t session, extensions_t exten_t,
57 int ext_count, int ext_length)
58{
59 int i, sd, ret = 0, pos = 0;
60 int exten_data_len, ciphersuite_len, datalen;
61 struct sockaddr_in sa;
62 char url[255];
63 opaque *data = NULL;
64 uint8_t session_id_len = 0;
65 opaque rnd[TLS_RANDOM_SIZE];
66 opaque extdata[MAX_EXT_DATA_LENGTH];
67
68 /* single, null compression */
69 unsigned char comp[] = { 0x01, 0x00 };
70 struct CBC cbc;
71
72 memset (&cbc, 0, sizeof (struct CBC));
73 if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
74 {
75 fprintf (stderr, MHD_E_MEM);
76 ret = -1;
77 goto cleanup;
78 }
79 cbc.size = 256;
80
81 sd = socket (AF_INET, SOCK_STREAM, 0);
82 memset (&sa, '\0', sizeof (struct sockaddr_in));
83 sa.sin_family = AF_INET;
84 sa.sin_port = htons (DEAMON_TEST_PORT);
85 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
86
87 enum MHD_GNUTLS_Protocol hver;
88
89 /* init hash functions */
90 session->internals.handshake_mac_handle_md5 =
91 MHD_gtls_hash_init (MHD_GNUTLS_MAC_MD5);
92 session->internals.handshake_mac_handle_sha =
93 MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
94
95 /* version = 2 , random = [4 for unix time + 28 for random bytes] */
96 datalen = TLS_VERSION_SIZE + TLS_RANDOM_SIZE + (session_id_len + 1);
97
98 data = MHD_gnutls_malloc (datalen);
99
100 hver = MHD_gtls_version_max (session);
101 data[pos++] = MHD_gtls_version_get_major (hver);
102 data[pos++] = MHD_gtls_version_get_minor (hver);
103
104 /* Set the version we advertise as maximum (RSA uses it). */
105 set_adv_version (session, MHD_gtls_version_get_major (hver),
106 MHD_gtls_version_get_minor (hver));
107
108 session->security_parameters.version = hver;
109 session->security_parameters.timestamp = time (NULL);
110
111 /* generate session client random */
112 memset (session->security_parameters.client_random, 0, TLS_RANDOM_SIZE);
113 MHD_gtls_write_uint32 (time (NULL), rnd);
114 MHD_gc_nonce ((char *) &rnd[4], TLS_RANDOM_SIZE - 4);
115 memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE);
116 memcpy (&data[pos], rnd, TLS_RANDOM_SIZE);
117 pos += TLS_RANDOM_SIZE;
118
119 /* Copy the Session ID */
120 data[pos++] = session_id_len;
121
122 /*
123 * len = ciphersuite data + 2 bytes ciphersuite length \
124 * 1 byte compression length + 1 byte compression data + \
125 * 2 bytes extension length, extensions data
126 */
127 ciphersuite_len = MHD__gnutls_copy_ciphersuites (session, extdata,
128 sizeof (extdata));
129 exten_data_len = ext_count * (2 + 2 + ext_length);
130 datalen += ciphersuite_len + 2 + 2 + exten_data_len;
131 data = MHD_gtls_realloc_fast (data, datalen);
132 memcpy (&data[pos], extdata, sizeof (ciphersuite_len));
133 pos += ciphersuite_len;
134
135 /* set compression */
136 memcpy (&data[pos], comp, sizeof (comp));
137 pos += 2;
138
139 /* set extensions length = 2 type bytes + 2 length bytes + extension length */
140 MHD_gtls_write_uint16 (exten_data_len, &data[pos]);
141 pos += 2;
142 for (i = 0; i < ext_count; ++i)
143 {
144 /* write extension type */
145 MHD_gtls_write_uint16 (exten_t, &data[pos]);
146 pos += 2;
147 MHD_gtls_write_uint16 (ext_length, &data[pos]);
148 pos += 2;
149 /* we might want to generate random data here */
150 memset (&data[pos], 0, ext_length);
151 pos += ext_length;
152 }
153
154 if (connect (sd, &sa, sizeof (struct sockaddr_in)) < 0)
155 {
156 fprintf (stderr, "%s\n", MHD_E_FAILED_TO_CONNECT);
157 ret = -1;
158 goto cleanup;
159 }
160
161 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd);
162
163 if (gen_test_file_url (url, DEAMON_TEST_PORT))
164 {
165 ret = -1;
166 goto cleanup;
167 }
168
169 /* this should crash the server */
170 ret = MHD_gtls_send_handshake (session, data, datalen,
171 GNUTLS_HANDSHAKE_CLIENT_HELLO);
172
173 /* advance to STATE2 */
174 session->internals.handshake_state = STATE2;
175 ret = MHD__gnutls_handshake (session);
176 ret = MHD__gnutls_bye (session, GNUTLS_SHUT_WR);
177
178 MHD_gnutls_free (data);
179
180 /* make sure daemon is still functioning */
181 if (CURLE_OK != send_curl_req (url, &cbc, "AES128-SHA",
182 MHD_GNUTLS_PROTOCOL_TLS1_2))
183 {
184 ret = -1;
185 goto cleanup;
186 }
187
188cleanup:
189 close (sd);
190 MHD_gnutls_free (cbc.buf);
191 return ret;
192}
193
194int
195main (int argc, char *const *argv)
196{
197 int i, errorCount = 0;
198 FILE *test_fd;
199 struct MHD_Daemon *d;
200 MHD_gtls_session_t session;
201 MHD_gnutls_datum_t key;
202 MHD_gnutls_datum_t cert;
203 MHD_gtls_cert_credentials_t xcred;
204
205 int ext_arr[] = { GNUTLS_EXTENSION_SERVER_NAME,
206 -1
207 };
208
209 MHD__gnutls_global_init ();
210 MHD_gtls_global_set_log_level (11);
211
212 if ((test_fd = setup_test_file ()) == NULL)
213 {
214 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
215 return -1;
216 }
217
218 if (0 != curl_global_init (CURL_GLOBAL_ALL))
219 {
220 fprintf (stderr, "Error: %s\n", strerror (errno));
221 return -1;
222 }
223
224 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
225 MHD_USE_DEBUG, DEAMON_TEST_PORT,
226 NULL, NULL, &http_ahc, NULL,
227 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
228 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
229 MHD_OPTION_END);
230
231 if (d == NULL)
232 {
233 fprintf (stderr, "%s\n", MHD_E_SERVER_INIT);
234 return -1;
235 }
236
237 i = 0;
238 while (ext_arr[i] != -1)
239 {
240 setup_session (&session, &key, &cert, &xcred);
241 errorCount += test_hello_extension (session, ext_arr[i], 1, 16);
242 teardown_session (session, &key, &cert, xcred);
243
244 setup_session (&session, &key, &cert, &xcred);
245 errorCount += test_hello_extension (session, ext_arr[i], 3, 8);
246 teardown_session (session, &key, &cert, xcred);
247
248 /* this test specifically tests the issue raised in CVE-2008-1948 */
249 setup_session (&session, &key, &cert, &xcred);
250 errorCount += test_hello_extension (session, ext_arr[i], 6, 0);
251 teardown_session (session, &key, &cert, xcred);
252 i++;
253 }
254
255 print_test_result (errorCount, argv[0]);
256
257 MHD_stop_daemon (d);
258 MHD__gnutls_global_deinit ();
259
260 curl_global_cleanup ();
261 fclose (test_fd);
262
263 return errorCount;
264}