1 /*-
2  * SSLsplit - transparent SSL/TLS interception
3  * https://www.roe.ch/SSLsplit
4  *
5  * Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "base64.h"
30 #include "ssl.h"
31 
32 #include <limits.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 
36 #include <check.h>
37 
38 #ifdef __APPLE__
39 #define DLSUFFIX "dylib"
40 #else
41 #define DLSUFFIX "so"
42 #endif
43 
44 #define TESTKEY "extra/pki/server.key"
45 #define TESTCERT "extra/pki/server.crt"
46 #define TESTCERT2 "extra/pki/rsa.crt"
47 #define ENGINE "extra/engine/dummy-engine."DLSUFFIX
48 
49 static void
ssl_setup(void)50 ssl_setup(void)
51 {
52 	if (ssl_init() == -1)
53 		exit(EXIT_FAILURE);
54 }
55 
56 static void
ssl_teardown(void)57 ssl_teardown(void)
58 {
59 	ssl_fini();
60 }
61 
62 static char wildcard1[] = "*.example.org";
63 static char wildcard2[] = "www.*.example.org";
64 static char wildcard3[] = "*.*.org";
65 static char wildcard4[] = "www*.example.org";
66 static char wildcard5[] = "*";
67 static char wildcard6[] = "*.xn--r-1ga.ch";
68 static char wildcard7[] = "xn--r-1ga*.xn--r-1ga.ch";
69 static char wildcard8[] = "xn--r-1ga.*.xn--r-1ga.ch";
70 static char name1[] = "www.example.org";
71 static char name2[] = "www.example.com";
72 static char name3[] = "example.org";
73 static char name4[] = "www.example.org.co.uk";
74 static char name5[] = "test.www.example.org";
75 static char name6[] = "www.test.example.org";
76 static char name7[] = "wwwtest.example.org";
77 static char name8[] = "ch";
78 static char name9[] = "www.xn--r-1ga.ch";
79 static char name10[] = "xn--r-1ga.xn--r-1ga.ch";
80 static char name11[] = "";
81 
START_TEST(ssl_wildcardify_01)82 START_TEST(ssl_wildcardify_01)
83 {
84 	char *wc = ssl_wildcardify(name1);
85 	fail_unless(!strcmp(wc, wildcard1), "mismatch for 'www.example.org'");
86 	free(wc);
87 }
88 END_TEST
89 
START_TEST(ssl_wildcardify_02)90 START_TEST(ssl_wildcardify_02)
91 {
92 	char *wc = ssl_wildcardify(name8);
93 	fail_unless(!strcmp(wc, wildcard5), "mismatch for 'ch'");
94 	free(wc);
95 }
96 END_TEST
97 
START_TEST(ssl_wildcardify_03)98 START_TEST(ssl_wildcardify_03)
99 {
100 	char *wc = ssl_wildcardify(name11);
101 	fail_unless(!strcmp(wc, wildcard5), "mismatch for ''");
102 	free(wc);
103 }
104 END_TEST
105 
START_TEST(ssl_dnsname_match_01)106 START_TEST(ssl_dnsname_match_01)
107 {
108 	fail_unless(
109 		ssl_dnsname_match(name1, sizeof(name1) - 1,
110 		                  name1, sizeof(name1) - 1),
111 		"Hostname does not match itself");
112 }
113 END_TEST
114 
START_TEST(ssl_dnsname_match_02)115 START_TEST(ssl_dnsname_match_02)
116 {
117 	fail_unless(
118 		!ssl_dnsname_match(name1, sizeof(name1) - 1,
119 		                   name2, sizeof(name2) - 1),
120 		"Hostname matches hostname with different TLD");
121 }
122 END_TEST
123 
START_TEST(ssl_dnsname_match_03)124 START_TEST(ssl_dnsname_match_03)
125 {
126 	fail_unless(
127 		ssl_dnsname_match(wildcard1, sizeof(wildcard1) - 1,
128 		                  name1, sizeof(name1) - 1),
129 		"Regular wildcard does not match");
130 }
131 END_TEST
132 
START_TEST(ssl_dnsname_match_04)133 START_TEST(ssl_dnsname_match_04)
134 {
135 	fail_unless(
136 		!ssl_dnsname_match(wildcard1, sizeof(wildcard1) - 1,
137 		                   name2, sizeof(name2) - 1),
138 		"Regular wildcard matches other TLD");
139 }
140 END_TEST
141 
START_TEST(ssl_dnsname_match_05)142 START_TEST(ssl_dnsname_match_05)
143 {
144 	fail_unless(
145 		!ssl_dnsname_match(wildcard1, sizeof(wildcard1) - 1,
146 		                   name3, sizeof(name3) - 1),
147 		"Regular wildcard matches upper level domain");
148 }
149 END_TEST
150 
START_TEST(ssl_dnsname_match_06)151 START_TEST(ssl_dnsname_match_06)
152 {
153 	fail_unless(
154 		!ssl_dnsname_match(wildcard1, sizeof(wildcard1) - 1,
155 		                   name4, sizeof(name4) - 1),
156 		"Regular wildcard matches despite added suffix");
157 }
158 END_TEST
159 
START_TEST(ssl_dnsname_match_07)160 START_TEST(ssl_dnsname_match_07)
161 {
162 	fail_unless(
163 		!ssl_dnsname_match(wildcard1, sizeof(wildcard1) - 1,
164 		                   name5, sizeof(name5) - 1),
165 		"Regular wildcard matches two elements");
166 }
167 END_TEST
168 
START_TEST(ssl_dnsname_match_08)169 START_TEST(ssl_dnsname_match_08)
170 {
171 	fail_unless(
172 		!ssl_dnsname_match(wildcard2, sizeof(wildcard2) - 1,
173 		                   name6, sizeof(name6) - 1),
174 		"Wildcard matches in non-leftmost element");
175 }
176 END_TEST
177 
START_TEST(ssl_dnsname_match_09)178 START_TEST(ssl_dnsname_match_09)
179 {
180 	fail_unless(
181 		!ssl_dnsname_match(wildcard3, sizeof(wildcard3) - 1,
182 		                   name5, sizeof(name5) - 1),
183 		"Multiple wildcard matches");
184 }
185 END_TEST
186 
START_TEST(ssl_dnsname_match_10)187 START_TEST(ssl_dnsname_match_10)
188 {
189 	fail_unless(
190 		!ssl_dnsname_match(wildcard4, sizeof(wildcard4) - 1,
191 		                   name7, sizeof(name7) - 1),
192 		"Partial label wildcard matches");
193 }
194 END_TEST
195 
START_TEST(ssl_dnsname_match_11)196 START_TEST(ssl_dnsname_match_11)
197 {
198 	fail_unless(
199 		!ssl_dnsname_match(wildcard5, sizeof(wildcard5) - 1,
200 		                   name1, sizeof(name1) - 1),
201 		"Global wildcard * matches fqdn");
202 }
203 END_TEST
204 
START_TEST(ssl_dnsname_match_12)205 START_TEST(ssl_dnsname_match_12)
206 {
207 	fail_unless(
208 		ssl_dnsname_match(wildcard5, sizeof(wildcard5) - 1,
209 		                  name8, sizeof(name8) - 1),
210 		"Global wildcard * does not match TLD");
211 }
212 END_TEST
213 
START_TEST(ssl_dnsname_match_13)214 START_TEST(ssl_dnsname_match_13)
215 {
216 	fail_unless(
217 		ssl_dnsname_match(wildcard6, sizeof(wildcard6) - 1,
218 		                  name9, sizeof(name9) - 1),
219 		"IDN wildcard does not match");
220 }
221 END_TEST
222 
START_TEST(ssl_dnsname_match_14)223 START_TEST(ssl_dnsname_match_14)
224 {
225 	fail_unless(
226 		ssl_dnsname_match(wildcard6, sizeof(wildcard6) - 1,
227 		                  name10, sizeof(name10) - 1),
228 		"IDN wildcard does not match IDN element");
229 }
230 END_TEST
231 
START_TEST(ssl_dnsname_match_15)232 START_TEST(ssl_dnsname_match_15)
233 {
234 	fail_unless(
235 		!ssl_dnsname_match(wildcard7, sizeof(wildcard7) - 1,
236 		                   name10, sizeof(name10) - 1),
237 		"Illegal IDN wildcard matches");
238 }
239 END_TEST
240 
START_TEST(ssl_dnsname_match_16)241 START_TEST(ssl_dnsname_match_16)
242 {
243 	fail_unless(
244 		!ssl_dnsname_match(wildcard8, sizeof(wildcard8) - 1,
245 		                   name10, sizeof(name10) - 1),
246 		"Illegal IDN wildcard matches IDN element");
247 }
248 END_TEST
249 
250 static unsigned char clienthello00[] =
251 	"\x80\x2b\x01\x00\x02\x00\x12\x00\x00\x00\x10\x07\x00\xc0\x03\x00"
252 	"\x80\x01\x00\x80\x06\x00\x40\x04\x00\x80\x02\x00\x80\xe0\xc3\x4a"
253 	"\xc6\xa4\x89\x23\x21\xb1\xbb\x51\xc7\x9c\x06\xa5\xff";
254 	/* SSL 2.0 */
255 
256 static unsigned char clienthello01[] =
257 	"\x80\x67\x01\x03\x00\x00\x4e\x00\x00\x00\x10\x01\x00\x80\x03\x00"
258 	"\x80\x07\x00\xc0\x06\x00\x40\x02\x00\x80\x04\x00\x80\x00\x00\x39"
259 	"\x00\x00\x38\x00\x00\x35\x00\x00\x33\x00\x00\x32\x00\x00\x04\x00"
260 	"\x00\x05\x00\x00\x2f\x00\x00\x16\x00\x00\x13\x00\xfe\xff\x00\x00"
261 	"\x0a\x00\x00\x15\x00\x00\x12\x00\xfe\xfe\x00\x00\x09\x00\x00\x64"
262 	"\x00\x00\x62\x00\x00\x03\x00\x00\x06\xa8\xb8\x93\xbb\x90\xe9\x2a"
263 	"\xa2\x4d\x6d\xcc\x1c\xe7\x2a\x80\x21";
264 	/* SSL 3.0 in SSL 2.0 record */
265 
266 static unsigned char clienthello02[] =
267 	"\x16\x03\x00\x00\x73\x01\x00\x00\x6f\x03\x00\x00\x34\x01\x1e\x67"
268 	"\x3a\xfa\xce\xd9\x51\xba\xe4\xfc\x64\x95\x03\x82\x63\x0f\xe3\x39"
269 	"\x6b\xc7\xbd\x2b\xe5\x51\x37\x23\x48\x5b\xfb\x20\xa3\xca\xad\x46"
270 	"\x95\x5d\x64\xbb\x33\xec\xb5\x12\x91\x21\xa3\x50\xd2\xc0\xc5\xf6"
271 	"\x67\xc3\xcc\x9e\xc0\x4a\x71\x1b\x92\xdc\x58\x55\x00\x28\x00\x39"
272 	"\x00\x38\x00\x35\x00\x33\x00\x32\x00\x04\x00\x05\x00\x2f\x00\x16"
273 	"\x00\x13\xfe\xff\x00\x0a\x00\x15\x00\x12\xfe\xfe\x00\x09\x00\x64"
274 	"\x00\x62\x00\x03\x00\x06\x01\x00";
275 	/* SSL 3.0, no TLS extensions */
276 
277 static unsigned char clienthello03[] =
278 	"\x16\x03\x01\x00\x9b\x01\x00\x00\x97\x03\x01\x4b\x99\x46\xac\x38"
279 	"\x08\xbb\xa7\x1c\x9b\xea\x79\xc5\xd6\x70\x3d\xed\x20\x80\x60\xb4"
280 	"\x7e\xb5\x07\x13\xcf\x9a\x1c\xec\x6f\x64\xe5\x00\x00\x46\xc0\x0a"
281 	"\xc0\x09\xc0\x07\xc0\x08\xc0\x13\xc0\x14\xc0\x11\xc0\x12\xc0\x04"
282 	"\xc0\x05\xc0\x02\xc0\x03\xc0\x0e\xc0\x0f\xc0\x0c\xc0\x0d\x00\x2f"
283 	"\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x06"
284 	"\x00\x32\x00\x33\x00\x38\x00\x39\x00\x16\x00\x15\x00\x14\x00\x13"
285 	"\x00\x12\x00\x11\x01\x00\x00\x28\x00\x00\x00\x12\x00\x10\x00\x00"
286 	"\x0d\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x30\x30\x2e\x34\x00\x0a"
287 	"\x00\x08\x00\x06\x00\x17\x00\x18\x00\x19\x00\x0b\x00\x02\x01\x00";
288 	/* TLS 1.0, SNI extension with hostname "192.168.100.4";
289 	 * Note: IP addresses are not legal values */
290 
291 static unsigned char clienthello04[] =
292 	"\x16\x03\x01\x00\x6c\x01\x00\x00\x68\x03\x01\x4a\x9d\x49\x75\xb2"
293 	"\x7e\xf9\xbc\xc3\x76\xac\x19\x78\xfb\x6a\xee\x50\x55\x5e\x35\x4c"
294 	"\xca\xf2\x21\x15\xf3\x8a\x2a\xfc\xb5\x35\xed\x00\x00\x28\x00\x39"
295 	"\x00\x38\x00\x35\x00\x16\x00\x13\x00\x0a\x00\x33\x00\x32\x00\x2f"
296 	"\x00\x07\x00\x05\x00\x04\x00\x15\x00\x12\x00\x09\x00\x14\x00\x11"
297 	"\x00\x08\x00\x06\x00\x03\x01\x00\x00\x17\x00\x00\x00\x0f\x00\x0d"
298 	"\x00\x00\x0a\x6b\x61\x6d\x65\x73\x68\x2e\x63\x6f\x6d\x00\x23\x00"
299 	"\x00";
300 	/* TLS 1.0, SNI extension with hostname "kamesh.com" */
301 
302 static unsigned char clienthello05[] =
303 	"\x16\x03\x03\x01\x7d\x01\x00\x01\x79\x03\x03\x4f\x7f\x27\xd0\x76"
304 	"\x5f\xc1\x3b\xba\x73\xd5\x07\x8b\xd9\x79\xf9\x51\xd4\xce\x7d\x9a"
305 	"\xdb\xdf\xf8\x4e\x95\x86\x38\x61\xdd\x84\x2a\x00\x00\xca\xc0\x30"
306 	"\xc0\x2c\xc0\x28\xc0\x24\xc0\x14\xc0\x0a\xc0\x22\xc0\x21\x00\xa3"
307 	"\x00\x9f\x00\x6b\x00\x6a\x00\x39\x00\x38\x00\x88\x00\x87\xc0\x19"
308 	"\xc0\x20\x00\xa7\x00\x6d\x00\x3a\x00\x89\xc0\x32\xc0\x2e\xc0\x2a"
309 	"\xc0\x26\xc0\x0f\xc0\x05\x00\x9d\x00\x3d\x00\x35\x00\x84\xc0\x12"
310 	"\xc0\x08\xc0\x1c\xc0\x1b\x00\x16\x00\x13\xc0\x17\xc0\x1a\x00\x1b"
311 	"\xc0\x0d\xc0\x03\x00\x0a\xc0\x2f\xc0\x2b\xc0\x27\xc0\x23\xc0\x13"
312 	"\xc0\x09\xc0\x1f\xc0\x1e\x00\xa2\x00\x9e\x00\x67\x00\x40\x00\x33"
313 	"\x00\x32\x00\x9a\x00\x99\x00\x45\x00\x44\xc0\x18\xc0\x1d\x00\xa6"
314 	"\x00\x6c\x00\x34\x00\x9b\x00\x46\xc0\x31\xc0\x2d\xc0\x29\xc0\x25"
315 	"\xc0\x0e\xc0\x04\x00\x9c\x00\x3c\x00\x2f\x00\x96\x00\x41\x00\x07"
316 	"\xc0\x11\xc0\x07\xc0\x16\x00\x18\xc0\x0c\xc0\x02\x00\x05\x00\x04"
317 	"\x00\x15\x00\x12\x00\x1a\x00\x09\x00\x14\x00\x11\x00\x19\x00\x08"
318 	"\x00\x06\x00\x17\x00\x03\x00\xff\x02\x01\x00\x00\x85\x00\x00\x00"
319 	"\x12\x00\x10\x00\x00\x0d\x64\x61\x6e\x69\x65\x6c\x2e\x72\x6f\x65"
320 	"\x2e\x63\x68\x00\x0b\x00\x04\x03\x00\x01\x02\x00\x0a\x00\x34\x00"
321 	"\x32\x00\x0e\x00\x0d\x00\x19\x00\x0b\x00\x0c\x00\x18\x00\x09\x00"
322 	"\x0a\x00\x16\x00\x17\x00\x08\x00\x06\x00\x07\x00\x14\x00\x15\x00"
323 	"\x04\x00\x05\x00\x12\x00\x13\x00\x01\x00\x02\x00\x03\x00\x0f\x00"
324 	"\x10\x00\x11\x00\x23\x00\x00\x00\x0d\x00\x22\x00\x20\x06\x01\x06"
325 	"\x02\x06\x03\x05\x01\x05\x02\x05\x03\x04\x01\x04\x02\x04\x03\x03"
326 	"\x01\x03\x02\x03\x03\x02\x01\x02\x02\x02\x03\x01\x01\x00\x0f\x00"
327 	"\x01\x01";
328 	/* TLS 1.2, SNI extension with hostname "daniel.roe.ch" */
329 
330 static unsigned char clienthello06[] =
331 	"I will start TLS now: "
332 	"\x16\x03\x03\x01\x7d\x01\x00\x01\x79\x03\x03\x4f\x7f\x27\xd0\x76"
333 	"\x5f\xc1\x3b\xba\x73\xd5\x07\x8b\xd9\x79\xf9\x51\xd4\xce\x7d\x9a"
334 	"\xdb\xdf\xf8\x4e\x95\x86\x38\x61\xdd\x84\x2a\x00\x00\xca\xc0\x30"
335 	"\xc0\x2c\xc0\x28\xc0\x24\xc0\x14\xc0\x0a\xc0\x22\xc0\x21\x00\xa3"
336 	"\x00\x9f\x00\x6b\x00\x6a\x00\x39\x00\x38\x00\x88\x00\x87\xc0\x19"
337 	"\xc0\x20\x00\xa7\x00\x6d\x00\x3a\x00\x89\xc0\x32\xc0\x2e\xc0\x2a"
338 	"\xc0\x26\xc0\x0f\xc0\x05\x00\x9d\x00\x3d\x00\x35\x00\x84\xc0\x12"
339 	"\xc0\x08\xc0\x1c\xc0\x1b\x00\x16\x00\x13\xc0\x17\xc0\x1a\x00\x1b"
340 	"\xc0\x0d\xc0\x03\x00\x0a\xc0\x2f\xc0\x2b\xc0\x27\xc0\x23\xc0\x13"
341 	"\xc0\x09\xc0\x1f\xc0\x1e\x00\xa2\x00\x9e\x00\x67\x00\x40\x00\x33"
342 	"\x00\x32\x00\x9a\x00\x99\x00\x45\x00\x44\xc0\x18\xc0\x1d\x00\xa6"
343 	"\x00\x6c\x00\x34\x00\x9b\x00\x46\xc0\x31\xc0\x2d\xc0\x29\xc0\x25"
344 	"\xc0\x0e\xc0\x04\x00\x9c\x00\x3c\x00\x2f\x00\x96\x00\x41\x00\x07"
345 	"\xc0\x11\xc0\x07\xc0\x16\x00\x18\xc0\x0c\xc0\x02\x00\x05\x00\x04"
346 	"\x00\x15\x00\x12\x00\x1a\x00\x09\x00\x14\x00\x11\x00\x19\x00\x08"
347 	"\x00\x06\x00\x17\x00\x03\x00\xff\x02\x01\x00\x00\x85\x00\x00\x00"
348 	"\x12\x00\x10\x00\x00\x0d\x64\x61\x6e\x69\x65\x6c\x2e\x72\x6f\x65"
349 	"\x2e\x63\x68\x00\x0b\x00\x04\x03\x00\x01\x02\x00\x0a\x00\x34\x00"
350 	"\x32\x00\x0e\x00\x0d\x00\x19\x00\x0b\x00\x0c\x00\x18\x00\x09\x00"
351 	"\x0a\x00\x16\x00\x17\x00\x08\x00\x06\x00\x07\x00\x14\x00\x15\x00"
352 	"\x04\x00\x05\x00\x12\x00\x13\x00\x01\x00\x02\x00\x03\x00\x0f\x00"
353 	"\x10\x00\x11\x00\x23\x00\x00\x00\x0d\x00\x22\x00\x20\x06\x01\x06"
354 	"\x02\x06\x03\x05\x01\x05\x02\x05\x03\x04\x01\x04\x02\x04\x03\x03"
355 	"\x01\x03\x02\x03\x03\x02\x01\x02\x02\x02\x03\x01\x01\x00\x0f\x00"
356 	"\x01\x01";
357 	/* TLS 1.2, SNI extension with hostname "daniel.roe.ch" */
358 
START_TEST(ssl_tls_clienthello_parse_00)359 START_TEST(ssl_tls_clienthello_parse_00)
360 {
361 	int rv;
362 	const unsigned char *ch = NULL;
363 	char *sni = (void *)0xDEADBEEF;
364 
365 	rv = ssl_tls_clienthello_parse(clienthello00,
366 	                               sizeof(clienthello00) - 1,
367 	                               0, &ch, &sni);
368 #ifdef HAVE_SSLV2
369 	fail_unless(rv == 0, "rv not 0");
370 	fail_unless(ch != NULL, "ch is NULL");
371 	fail_unless(sni == NULL, "sni not NULL");
372 #else /* !HAVE_SSLV2 */
373 	fail_unless(rv == 1, "rv not 1");
374 	fail_unless(ch == NULL, "ch not NULL");
375 	fail_unless(sni == (void*)0xDEADBEEF, "sni modified");
376 #endif /* !HAVE_SSLV2 */
377 }
378 END_TEST
379 
START_TEST(ssl_tls_clienthello_parse_01)380 START_TEST(ssl_tls_clienthello_parse_01)
381 {
382 	int rv;
383 	const unsigned char *ch = NULL;
384 	char *sni = (void *)0xDEADBEEF;
385 
386 	rv = ssl_tls_clienthello_parse(clienthello01,
387 	                               sizeof(clienthello01) - 1,
388 	                               0, &ch, &sni);
389 	fail_unless(rv == 0, "rv not 0");
390 	fail_unless(ch != NULL, "ch is NULL");
391 	fail_unless(sni == NULL, "sni not NULL");
392 }
393 END_TEST
394 
START_TEST(ssl_tls_clienthello_parse_02)395 START_TEST(ssl_tls_clienthello_parse_02)
396 {
397 	int rv;
398 	const unsigned char *ch = NULL;
399 	char *sni = (void *)0xDEADBEEF;
400 
401 	rv = ssl_tls_clienthello_parse(clienthello02,
402 	                                sizeof(clienthello02) - 1,
403 	                                0, &ch, &sni);
404 	fail_unless(rv == 0, "rv not 0");
405 	fail_unless(ch != NULL, "ch is NULL");
406 	fail_unless(sni == NULL, "sni not NULL");
407 }
408 END_TEST
409 
START_TEST(ssl_tls_clienthello_parse_03)410 START_TEST(ssl_tls_clienthello_parse_03)
411 {
412 	int rv;
413 	const unsigned char *ch = NULL;
414 	char *sni = NULL;
415 
416 	rv = ssl_tls_clienthello_parse(clienthello03,
417 	                                sizeof(clienthello03) - 1,
418 	                                0, &ch, &sni);
419 	fail_unless(rv == 0, "rv not 0");
420 	fail_unless(ch != NULL, "ch is NULL");
421 	fail_unless(sni && !strcmp(sni, "192.168.100.4"),
422 	            "sni not '192.168.100.4' but should be");
423 }
424 END_TEST
425 
START_TEST(ssl_tls_clienthello_parse_04)426 START_TEST(ssl_tls_clienthello_parse_04)
427 {
428 	int rv;
429 	const unsigned char *ch = NULL;
430 	char *sni = NULL;
431 
432 	rv = ssl_tls_clienthello_parse(clienthello04,
433 	                                sizeof(clienthello04) - 1,
434 	                                0, &ch, &sni);
435 	fail_unless(rv == 0, "rv not 0");
436 	fail_unless(ch != NULL, "ch is NULL");
437 	fail_unless(sni && !strcmp(sni, "kamesh.com"),
438 	            "sni not 'kamesh.com' but should be");
439 }
440 END_TEST
441 
START_TEST(ssl_tls_clienthello_parse_05)442 START_TEST(ssl_tls_clienthello_parse_05)
443 {
444 	for (size_t i = 0; i < sizeof(clienthello04) - 1; i++) {
445 		int rv;
446 		const unsigned char *ch = NULL;
447 		char *sni = (void*)0xDEADBEEF;
448 		ssize_t sz;
449 
450 		sz = (ssize_t)i;
451 		rv = ssl_tls_clienthello_parse(clienthello04, sz, 0, &ch, &sni);
452 		fail_unless(rv == 1, "rv not 1");
453 		fail_unless(ch != NULL, "ch is NULL");
454 		fail_unless(sni == (void*)0xDEADBEEF, "sni modified");
455 	}
456 }
457 END_TEST
458 
START_TEST(ssl_tls_clienthello_parse_06)459 START_TEST(ssl_tls_clienthello_parse_06)
460 {
461 	int rv;
462 	const unsigned char *ch = NULL;
463 	char *sni = NULL;
464 
465 	rv = ssl_tls_clienthello_parse(clienthello05,
466 	                                sizeof(clienthello05) - 1,
467 	                                0, &ch, &sni);
468 	fail_unless(rv == 0, "rv not 0");
469 	fail_unless(ch != NULL, "ch is NULL");
470 	fail_unless(sni && !strcmp(sni, "daniel.roe.ch"),
471 	            "sni not 'daniel.roe.ch' but should be");
472 }
473 END_TEST
474 
START_TEST(ssl_tls_clienthello_parse_07)475 START_TEST(ssl_tls_clienthello_parse_07)
476 {
477 	for (size_t i = 0; i < sizeof(clienthello05) - 1; i++) {
478 		int rv;
479 		const unsigned char *ch = NULL;
480 		char *sni = (void*)0xDEADBEEF;
481 		ssize_t sz;
482 
483 		sz = (ssize_t)i;
484 		rv = ssl_tls_clienthello_parse(clienthello05, sz, 0, &ch, &sni);
485 		fail_unless(rv == 1, "rv not 1");
486 		fail_unless(ch != NULL, "ch is NULL");
487 		fail_unless(sni == (void*)0xDEADBEEF, "sni modified");
488 	}
489 }
490 END_TEST
491 
START_TEST(ssl_tls_clienthello_parse_08)492 START_TEST(ssl_tls_clienthello_parse_08)
493 {
494 	int rv;
495 	const unsigned char *ch = (void *)0xDEADBEEF;
496 	char *sni = (void *)0xDEADBEEF;
497 
498 	rv = ssl_tls_clienthello_parse(clienthello06,
499 	                                sizeof(clienthello06) - 1,
500 	                                0, &ch, &sni);
501 	fail_unless(rv == 1, "rv not 1");
502 	fail_unless(ch == NULL, "ch not NULL");
503 	fail_unless(sni == (void*)0xDEADBEEF, "sni modified");
504 }
505 END_TEST
506 
START_TEST(ssl_tls_clienthello_parse_09)507 START_TEST(ssl_tls_clienthello_parse_09)
508 {
509 	int rv;
510 	const unsigned char *ch = NULL;
511 	char *sni = NULL;
512 
513 	rv = ssl_tls_clienthello_parse(clienthello06,
514 	                                sizeof(clienthello06) - 1,
515 	                                1, &ch, &sni);
516 	fail_unless(rv == 0, "rv not 0");
517 	fail_unless(ch != NULL, "ch is NULL");
518 	fail_unless((ch - clienthello06) != 21, "ch does not point to start");
519 	fail_unless(sni && !strcmp(sni, "daniel.roe.ch"),
520 	            "sni not 'daniel.roe.ch' but should be");
521 }
522 END_TEST
523 
START_TEST(ssl_tls_clienthello_parse_10)524 START_TEST(ssl_tls_clienthello_parse_10)
525 {
526 	int rv;
527 	const unsigned char *ch = NULL;
528 
529 	rv = ssl_tls_clienthello_parse(clienthello06,
530 	                                sizeof(clienthello06) - 1,
531 	                                1, &ch, NULL);
532 	fail_unless(rv == 0, "rv not 0");
533 	fail_unless(ch != NULL, "ch is NULL");
534 	fail_unless((ch - clienthello06) != 21, "ch does not point to start");
535 }
536 END_TEST
537 
START_TEST(ssl_key_identifier_sha1_01)538 START_TEST(ssl_key_identifier_sha1_01)
539 {
540 	X509 *c;
541 	EVP_PKEY *k;
542 	unsigned char keyid[SSL_KEY_IDSZ];
543 
544 	c = ssl_x509_load(TESTCERT);
545 	fail_unless(!!c, "loading certificate failed");
546 	k = ssl_key_load(TESTKEY);
547 	fail_unless(!!k, "loading key failed");
548 
549 	fail_unless(ssl_key_identifier_sha1(k, keyid) == 0,
550 	            "ssl_key_identifier_sha1() failed");
551 
552 	int loc = X509_get_ext_by_NID(c, NID_subject_key_identifier, -1);
553 	X509_EXTENSION *ext = X509_get_ext(c, loc);
554 	fail_unless(!!ext, "loading ext failed");
555 	ASN1_STRING *value = X509_EXTENSION_get_data(ext);
556 	fail_unless(ASN1_STRING_length(value) - 2 == SSL_KEY_IDSZ,
557 	             "extension length mismatch");
558 	fail_unless(!memcmp(ASN1_STRING_get0_data(value) + 2, keyid, SSL_KEY_IDSZ),
559 	            "key id mismatch");
560 	EVP_PKEY_free(k);
561 	X509_free(c);
562 }
563 END_TEST
564 
START_TEST(ssl_x509_names_01)565 START_TEST(ssl_x509_names_01)
566 {
567 	X509 *c;
568 	char **names, **p;
569 
570 	c = ssl_x509_load(TESTCERT);
571 	fail_unless(!!c, "loading certificate failed");
572 	names = ssl_x509_names(c);
573 	fail_unless(!!names, "parsing names failed");
574 	fail_unless(!!names[0], "first name");
575 	fail_unless(!strcmp(names[0], "daniel.roe.ch"), "first name");
576 	fail_unless(!!names[1], "second name");
577 	fail_unless(!strcmp(names[1], "daniel.roe.ch"), "second name");
578 	fail_unless(!!names[2], "third name");
579 	fail_unless(!strcmp(names[2], "www.roe.ch"), "third name");
580 	fail_unless(!!names[3], "fourth name");
581 	fail_unless(!strcmp(names[3], "*.roe.ch"), "fourth name");
582 	fail_unless(!names[4], "too many names");
583 	p = names;
584 	while (*p)
585 		free(*p++);
586 	free(names);
587 	X509_free(c);
588 }
589 END_TEST
590 
START_TEST(ssl_x509_names_to_str_01)591 START_TEST(ssl_x509_names_to_str_01)
592 {
593 	X509 *c;
594 	char *names;
595 
596 	c = ssl_x509_load(TESTCERT);
597 	fail_unless(!!c, "loading certificate failed");
598 	names = ssl_x509_names_to_str(c);
599 	fail_unless(!!names, "no string");
600 	fail_unless(!strcmp(names,
601 	            "daniel.roe.ch/daniel.roe.ch/www.roe.ch/*.roe.ch"),
602 	            "wrong name string");
603 	X509_free(c);
604 }
605 END_TEST
606 
START_TEST(ssl_x509_names_to_str_02)607 START_TEST(ssl_x509_names_to_str_02)
608 {
609 	X509 *c;
610 	char *names;
611 
612 	c = ssl_x509_load(TESTCERT2);
613 	fail_unless(!!c, "loading certificate failed");
614 	names = ssl_x509_names_to_str(c);
615 	fail_unless(!!names, "no string");
616 	fail_unless(!strcmp(names, "SSLsplit Root CA"), "wrong name string");
617 	X509_free(c);
618 }
619 END_TEST
620 
START_TEST(ssl_x509_subject_01)621 START_TEST(ssl_x509_subject_01)
622 {
623 	X509 *c;
624 	char *subject;
625 
626 	c = ssl_x509_load(TESTCERT);
627 	fail_unless(!!c, "loading certificate failed");
628 	subject = ssl_x509_subject(c);
629 	fail_unless(!!subject, "no string");
630 	fail_unless(!strcmp(subject, "/C=CH/O=SSLsplit Test Certificate/"
631 	                             "CN=daniel.roe.ch"),
632 	            "wrong subject string");
633 	X509_free(c);
634 }
635 END_TEST
636 
START_TEST(ssl_x509_subject_cn_01)637 START_TEST(ssl_x509_subject_cn_01)
638 {
639 	X509 *c;
640 	char *cn;
641 	size_t sz;
642 	size_t expsz = strlen("daniel.roe.ch") + 1;
643 
644 	c = ssl_x509_load(TESTCERT);
645 	fail_unless(!!c, "loading certificate failed");
646 	cn = ssl_x509_subject_cn(c, &sz);
647 	fail_unless(!!cn, "no string");
648 	fail_unless(sz >= expsz, "subject CN size too small");
649 	fail_unless(!strcmp(cn, "daniel.roe.ch"), "wrong subject CN string");
650 #if 0
651 	for (unsigned int i = expsz; i < sz; i++) {
652 		fail_unless(cn[i] == '\0', "extra byte != 0");
653 	}
654 #endif
655 	X509_free(c);
656 }
657 END_TEST
658 
START_TEST(ssl_x509_ocsps_01)659 START_TEST(ssl_x509_ocsps_01)
660 {
661 	X509 *c;
662 	char **ocsps, **p;
663 
664 	c = ssl_x509_load(TESTCERT);
665 	fail_unless(!!c, "loading certificate failed");
666 	ocsps = ssl_x509_ocsps(c);
667 	fail_unless(!!ocsps, "parsing OCSP extensions failed");
668 	fail_unless(!!ocsps[0], "first OCSP");
669 	fail_unless(!strcmp(ocsps[0], "http://daniel.roe.ch/test/ocsp"),
670 	                              "first OCSP");
671 	fail_unless(!ocsps[1], "too many OCSPs");
672 	p = ocsps;
673 	while (*p)
674 		free(*p++);
675 	free(ocsps);
676 	X509_free(c);
677 }
678 END_TEST
679 
START_TEST(ssl_x509_ocsps_02)680 START_TEST(ssl_x509_ocsps_02)
681 {
682 	X509 *c;
683 	char **ocsps;
684 
685 	c = ssl_x509_load(TESTCERT2);
686 	fail_unless(!!c, "loading certificate failed");
687 	ocsps = ssl_x509_ocsps(c);
688 	fail_unless(!ocsps, "unexpected OCSP extensions");
689 	X509_free(c);
690 }
691 END_TEST
692 
693 static char ocspreq01[] =
694 	"MEIwQDA+MDwwOjAJBgUrDgMCGgUABBT4cyABkyiCIhU4JpmIB"
695 	"ewdDnn8ZgQUbyBZ44kgy35o7xW5BMzM8FTvyTwCAQE=";
696 
START_TEST(ssl_is_ocspreq_01)697 START_TEST(ssl_is_ocspreq_01)
698 {
699 	unsigned char *buf;
700 	size_t sz;
701 
702 	buf = base64_dec(ocspreq01, sizeof(ocspreq01) - 1, &sz);
703 	fail_unless(!!buf, "failed to base64 decode");
704 	fail_unless(ssl_is_ocspreq(buf, sz), "is not ocsp req");
705 }
706 END_TEST
707 
START_TEST(ssl_features_01)708 START_TEST(ssl_features_01)
709 {
710 	long vdiff = ((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xfffff000L);
711 
712 	fail_unless(!vdiff, "OpenSSL version mismatch at runtime");
713 }
714 END_TEST
715 
START_TEST(ssl_features_02)716 START_TEST(ssl_features_02)
717 {
718 	int have_threads = 0;
719 #ifdef OPENSSL_THREADS
720 	have_threads = 1;
721 #endif /* OPENSSL_THREADS */
722 	fail_unless(have_threads, "!OPENSSL_THREADS: no threading support");
723 }
724 END_TEST
725 
START_TEST(ssl_key_refcount_inc_01)726 START_TEST(ssl_key_refcount_inc_01)
727 {
728 	EVP_PKEY *key;
729 
730 	key = ssl_key_load(TESTKEY);
731 	fail_unless(!!key, "loading key failed");
732 	ssl_key_refcount_inc(key);
733 	ssl_key_refcount_inc(key);
734 	ssl_key_refcount_inc(key);
735 	EVP_PKEY_free(key);
736 	/* these must not crash */
737 	EVP_PKEY_free(key);
738 	EVP_PKEY_free(key);
739 	EVP_PKEY_free(key);
740 }
741 END_TEST
742 
START_TEST(ssl_x509_refcount_inc_01)743 START_TEST(ssl_x509_refcount_inc_01)
744 {
745 	X509 *crt;
746 
747 	crt = ssl_x509_load(TESTCERT);
748 	fail_unless(!!crt, "loading certificate failed");
749 	ssl_x509_refcount_inc(crt);
750 	ssl_x509_refcount_inc(crt);
751 	ssl_x509_refcount_inc(crt);
752 	X509_free(crt);
753 	/* these must not crash */
754 	X509_free(crt);
755 	X509_free(crt);
756 	X509_free(crt);
757 }
758 END_TEST
759 
760 #ifndef OPENSSL_NO_ENGINE
START_TEST(ssl_engine_01)761 START_TEST(ssl_engine_01)
762 {
763 	char cwd[PATH_MAX];
764 	char *path;
765 
766 	fail_unless(getcwd(cwd, sizeof(cwd)) == cwd, "getcwd() failed");
767 	fail_unless(asprintf(&path, "%s/"ENGINE, cwd) != -1 && !!path,
768 	            "constructing engine path failed");
769 	fail_unless(ssl_engine(path) == 0, "loading OpenSSL engine failed");
770 	free(path);
771 }
772 END_TEST
773 #endif /* !OPENSSL_NO_ENGINE */
774 
775 Suite *
ssl_suite(void)776 ssl_suite(void)
777 {
778 	Suite *s;
779 	TCase *tc;
780 
781 	s = suite_create("ssl");
782 
783 	tc = tcase_create("ssl_wildcardify");
784 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
785 	tcase_add_test(tc, ssl_wildcardify_01);
786 	tcase_add_test(tc, ssl_wildcardify_02);
787 	tcase_add_test(tc, ssl_wildcardify_03);
788 	suite_add_tcase(s, tc);
789 
790 	tc = tcase_create("ssl_dnsname_match");
791 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
792 	tcase_add_test(tc, ssl_dnsname_match_01);
793 	tcase_add_test(tc, ssl_dnsname_match_02);
794 	tcase_add_test(tc, ssl_dnsname_match_03);
795 	tcase_add_test(tc, ssl_dnsname_match_04);
796 	tcase_add_test(tc, ssl_dnsname_match_05);
797 	tcase_add_test(tc, ssl_dnsname_match_06);
798 	tcase_add_test(tc, ssl_dnsname_match_07);
799 	tcase_add_test(tc, ssl_dnsname_match_08);
800 	tcase_add_test(tc, ssl_dnsname_match_09);
801 	tcase_add_test(tc, ssl_dnsname_match_10);
802 	tcase_add_test(tc, ssl_dnsname_match_11);
803 	tcase_add_test(tc, ssl_dnsname_match_12);
804 	tcase_add_test(tc, ssl_dnsname_match_13);
805 	tcase_add_test(tc, ssl_dnsname_match_14);
806 	tcase_add_test(tc, ssl_dnsname_match_15);
807 	tcase_add_test(tc, ssl_dnsname_match_16);
808 	suite_add_tcase(s, tc);
809 
810 	tc = tcase_create("ssl_tls_clienthello_parse");
811 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
812 	tcase_add_test(tc, ssl_tls_clienthello_parse_00);
813 	tcase_add_test(tc, ssl_tls_clienthello_parse_01);
814 	tcase_add_test(tc, ssl_tls_clienthello_parse_02);
815 	tcase_add_test(tc, ssl_tls_clienthello_parse_03);
816 	tcase_add_test(tc, ssl_tls_clienthello_parse_04);
817 	tcase_add_test(tc, ssl_tls_clienthello_parse_05);
818 	tcase_add_test(tc, ssl_tls_clienthello_parse_06);
819 	tcase_add_test(tc, ssl_tls_clienthello_parse_07);
820 	tcase_add_test(tc, ssl_tls_clienthello_parse_08);
821 	tcase_add_test(tc, ssl_tls_clienthello_parse_09);
822 	tcase_add_test(tc, ssl_tls_clienthello_parse_10);
823 	suite_add_tcase(s, tc);
824 
825 	tc = tcase_create("ssl_key_identifier_sha1");
826 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
827 	tcase_add_test(tc, ssl_key_identifier_sha1_01);
828 	suite_add_tcase(s, tc);
829 
830 	tc = tcase_create("ssl_x509_names");
831 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
832 	tcase_add_test(tc, ssl_x509_names_01);
833 	suite_add_tcase(s, tc);
834 
835 	tc = tcase_create("ssl_x509_names_to_str");
836 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
837 	tcase_add_test(tc, ssl_x509_names_to_str_01);
838 	tcase_add_test(tc, ssl_x509_names_to_str_02);
839 	suite_add_tcase(s, tc);
840 
841 	tc = tcase_create("ssl_x509_subject");
842 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
843 	tcase_add_test(tc, ssl_x509_subject_01);
844 	suite_add_tcase(s, tc);
845 
846 	tc = tcase_create("ssl_x509_subject_cn");
847 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
848 	tcase_add_test(tc, ssl_x509_subject_cn_01);
849 	suite_add_tcase(s, tc);
850 
851 	tc = tcase_create("ssl_x509_ocsps");
852 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
853 	tcase_add_test(tc, ssl_x509_ocsps_01);
854 	tcase_add_test(tc, ssl_x509_ocsps_02);
855 	suite_add_tcase(s, tc);
856 
857 	tc = tcase_create("ssl_is_ocspreq");
858 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
859 	tcase_add_test(tc, ssl_is_ocspreq_01);
860 	suite_add_tcase(s, tc);
861 
862 	tc = tcase_create("ssl_features");
863 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
864 	tcase_add_test(tc, ssl_features_01);
865 	tcase_add_test(tc, ssl_features_02);
866 	suite_add_tcase(s, tc);
867 
868 	tc = tcase_create("ssl_key_refcount_inc");
869 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
870 	tcase_add_test(tc, ssl_key_refcount_inc_01);
871 	suite_add_tcase(s, tc);
872 
873 	tc = tcase_create("ssl_x509_refcount_inc");
874 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
875 	tcase_add_test(tc, ssl_x509_refcount_inc_01);
876 	suite_add_tcase(s, tc);
877 
878 #ifndef OPENSSL_NO_ENGINE
879 	tc = tcase_create("ssl_engine");
880 	tcase_add_checked_fixture(tc, ssl_setup, ssl_teardown);
881 	tcase_add_test(tc, ssl_engine_01);
882 	suite_add_tcase(s, tc);
883 #else /* OPENSSL_NO_ENGINE */
884 	fprintf(stderr, "ssl: 1 test omitted because OpenSSL has no "
885 	                "engine support\n");
886 #endif /* OPENSSL_NO_ENGINE */
887 
888 	return s;
889 }
890 
891 /* vim: set noet ft=c: */
892