xref: /openbsd-src/regress/lib/libssl/unit/ssl_versions.c (revision d59bb9942320b767f2a19aaa7690c8c6e30b724c)
1 /* $OpenBSD: ssl_versions.c,v 1.3 2017/01/25 11:11:21 jsing Exp $ */
2 /*
3  * Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/ssl.h>
19 
20 #include "ssl_locl.h"
21 
22 struct version_range_test {
23 	const long options;
24 	const uint16_t minver;
25 	const uint16_t maxver;
26 	const uint16_t want_minver;
27 	const uint16_t want_maxver;
28 };
29 
30 static struct version_range_test version_range_tests[] = {
31 	{
32 		.options = 0,
33 		.minver = TLS1_VERSION,
34 		.maxver = TLS1_2_VERSION,
35 		.want_minver = TLS1_VERSION,
36 		.want_maxver = TLS1_2_VERSION,
37 	},
38 	{
39 		.options = SSL_OP_NO_TLSv1,
40 		.minver = TLS1_VERSION,
41 		.maxver = TLS1_2_VERSION,
42 		.want_minver = TLS1_1_VERSION,
43 		.want_maxver = TLS1_2_VERSION,
44 	},
45 	{
46 		.options = SSL_OP_NO_TLSv1_2,
47 		.minver = TLS1_VERSION,
48 		.maxver = TLS1_2_VERSION,
49 		.want_minver = TLS1_VERSION,
50 		.want_maxver = TLS1_1_VERSION,
51 	},
52 	{
53 		.options = SSL_OP_NO_TLSv1_1,
54 		.minver = TLS1_VERSION,
55 		.maxver = TLS1_2_VERSION,
56 		.want_minver = TLS1_VERSION,
57 		.want_maxver = TLS1_VERSION,
58 	},
59 	{
60 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
61 		.minver = TLS1_VERSION,
62 		.maxver = TLS1_2_VERSION,
63 		.want_minver = TLS1_2_VERSION,
64 		.want_maxver = TLS1_2_VERSION,
65 	},
66 	{
67 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
68 		.minver = TLS1_VERSION,
69 		.maxver = TLS1_2_VERSION,
70 		.want_minver = TLS1_VERSION,
71 		.want_maxver = TLS1_VERSION,
72 	},
73 	{
74 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2,
75 		.minver = TLS1_VERSION,
76 		.maxver = TLS1_2_VERSION,
77 		.want_minver = TLS1_1_VERSION,
78 		.want_maxver = TLS1_1_VERSION,
79 	},
80 	{
81 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
82 		.minver = TLS1_VERSION,
83 		.maxver = TLS1_2_VERSION,
84 		.want_minver = 0,
85 		.want_maxver = 0,
86 	},
87 	{
88 		.options = 0,
89 		.minver = TLS1_VERSION,
90 		.maxver = TLS1_2_VERSION,
91 		.want_minver = TLS1_VERSION,
92 		.want_maxver = TLS1_2_VERSION,
93 	},
94 	{
95 		.options = 0,
96 		.minver = TLS1_1_VERSION,
97 		.maxver = TLS1_2_VERSION,
98 		.want_minver = TLS1_1_VERSION,
99 		.want_maxver = TLS1_2_VERSION,
100 	},
101 	{
102 		.options = 0,
103 		.minver = TLS1_2_VERSION,
104 		.maxver = TLS1_2_VERSION,
105 		.want_minver = TLS1_2_VERSION,
106 		.want_maxver = TLS1_2_VERSION,
107 	},
108 	{
109 		.options = 0,
110 		.minver = TLS1_VERSION,
111 		.maxver = TLS1_1_VERSION,
112 		.want_minver = TLS1_VERSION,
113 		.want_maxver = TLS1_1_VERSION,
114 	},
115 	{
116 		.options = 0,
117 		.minver = TLS1_VERSION,
118 		.maxver = TLS1_VERSION,
119 		.want_minver = TLS1_VERSION,
120 		.want_maxver = TLS1_VERSION,
121 	},
122 };
123 
124 #define N_VERSION_RANGE_TESTS \
125     (sizeof(version_range_tests) / sizeof(*version_range_tests))
126 
127 static int
128 test_ssl_enabled_version_range(void)
129 {
130 	struct version_range_test *vrt;
131 	uint16_t minver, maxver;
132 	SSL_CTX *ssl_ctx = NULL;
133 	SSL *ssl = NULL;
134 	int failed = 1;
135 	size_t i;
136 
137 	if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) {
138 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
139 		goto failure;
140 	}
141 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
142 		fprintf(stderr, "SSL_new() returned NULL\n");
143 		goto failure;
144 	}
145 
146 	failed = 0;
147 
148 	for (i = 0; i < N_VERSION_RANGE_TESTS; i++) {
149 		vrt = &version_range_tests[i];
150 
151 		SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
152 		    SSL_OP_NO_TLSv1_2);
153 		SSL_set_options(ssl, vrt->options);
154 
155 		minver = maxver = 0xffff;
156 		ssl->internal->min_version = vrt->minver;
157 		ssl->internal->max_version = vrt->maxver;
158 
159 		if (ssl_enabled_version_range(ssl, &minver, &maxver) != 1) {
160 			if (vrt->want_minver != 0 || vrt->want_maxver != 0) {
161 				fprintf(stderr, "FAIL: test %zu - failed but "
162 				    "wanted non-zero versions\n", i);
163 				failed++;
164 			}
165 			continue;
166 		}
167 		if (minver != vrt->want_minver) {
168 			fprintf(stderr, "FAIL: test %zu - got minver %x, "
169 			    "want %x\n", i, minver, vrt->want_minver);
170 			failed++;
171 		}
172 		if (maxver != vrt->want_maxver) {
173 			fprintf(stderr, "FAIL: test %zu - got maxver %x, "
174 			    "want %x\n", i, maxver, vrt->want_maxver);
175 			failed++;
176 		}
177 	}
178 
179  failure:
180 	SSL_CTX_free(ssl_ctx);
181 	SSL_free(ssl);
182 
183 	return (failed);
184 }
185 
186 struct shared_version_test {
187 	const SSL_METHOD *(*ssl_method)(void);
188 	const long options;
189 	const uint16_t minver;
190 	const uint16_t maxver;
191 	const uint16_t peerver;
192 	const uint16_t want_maxver;
193 };
194 
195 static struct shared_version_test shared_version_tests[] = {
196 	{
197 		.ssl_method = TLS_method,
198 		.options = 0,
199 		.minver = TLS1_VERSION,
200 		.maxver = TLS1_2_VERSION,
201 		.peerver = SSL2_VERSION,
202 		.want_maxver = 0,
203 	},
204 	{
205 		.ssl_method = TLS_method,
206 		.options = 0,
207 		.minver = TLS1_VERSION,
208 		.maxver = TLS1_2_VERSION,
209 		.peerver = SSL3_VERSION,
210 		.want_maxver = 0,
211 	},
212 	{
213 		.ssl_method = TLS_method,
214 		.options = 0,
215 		.minver = TLS1_VERSION,
216 		.maxver = TLS1_2_VERSION,
217 		.peerver = TLS1_VERSION,
218 		.want_maxver = TLS1_VERSION,
219 	},
220 	{
221 		.ssl_method = TLS_method,
222 		.options = 0,
223 		.minver = TLS1_VERSION,
224 		.maxver = TLS1_2_VERSION,
225 		.peerver = TLS1_1_VERSION,
226 		.want_maxver = TLS1_1_VERSION,
227 	},
228 	{
229 		.ssl_method = TLS_method,
230 		.options = 0,
231 		.minver = TLS1_VERSION,
232 		.maxver = TLS1_2_VERSION,
233 		.peerver = TLS1_2_VERSION,
234 		.want_maxver = TLS1_2_VERSION,
235 	},
236 	{
237 		.ssl_method = TLS_method,
238 		.options = 0,
239 		.minver = TLS1_VERSION,
240 		.maxver = TLS1_2_VERSION,
241 		.peerver = 0x7f12,
242 		.want_maxver = TLS1_2_VERSION,
243 	},
244 	{
245 		.ssl_method = TLS_method,
246 		.options = SSL_OP_NO_TLSv1_2,
247 		.minver = TLS1_VERSION,
248 		.maxver = TLS1_2_VERSION,
249 		.peerver = TLS1_2_VERSION,
250 		.want_maxver = TLS1_1_VERSION,
251 	},
252 	{
253 		.ssl_method = TLS_method,
254 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
255 		.minver = TLS1_VERSION,
256 		.maxver = TLS1_2_VERSION,
257 		.peerver = TLS1_2_VERSION,
258 		.want_maxver = TLS1_VERSION,
259 	},
260 	{
261 		.ssl_method = TLS_method,
262 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
263 		.minver = TLS1_VERSION,
264 		.maxver = TLS1_2_VERSION,
265 		.peerver = TLS1_2_VERSION,
266 		.want_maxver = 0,
267 	},
268 	{
269 		.ssl_method = TLS_method,
270 		.options = SSL_OP_NO_TLSv1,
271 		.minver = TLS1_VERSION,
272 		.maxver = TLS1_2_VERSION,
273 		.peerver = TLS1_1_VERSION,
274 		.want_maxver = TLS1_1_VERSION,
275 	},
276 	{
277 		.ssl_method = TLS_method,
278 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
279 		.minver = TLS1_VERSION,
280 		.maxver = TLS1_2_VERSION,
281 		.peerver = TLS1_1_VERSION,
282 		.want_maxver = 0,
283 	},
284 	{
285 		.ssl_method = TLS_method,
286 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
287 		.minver = TLS1_VERSION,
288 		.maxver = TLS1_2_VERSION,
289 		.peerver = TLS1_1_VERSION,
290 		.want_maxver = TLS1_VERSION,
291 	},
292 	{
293 		.ssl_method = TLS_method,
294 		.options = SSL_OP_NO_TLSv1,
295 		.minver = TLS1_VERSION,
296 		.maxver = TLS1_2_VERSION,
297 		.peerver = TLS1_VERSION,
298 		.want_maxver = 0,
299 	},
300 	{
301 		.ssl_method = TLS_method,
302 		.options = 0,
303 		.minver = TLS1_VERSION,
304 		.maxver = TLS1_1_VERSION,
305 		.peerver = TLS1_2_VERSION,
306 		.want_maxver = TLS1_1_VERSION,
307 	},
308 	{
309 		.ssl_method = TLS_method,
310 		.options = 0,
311 		.minver = TLS1_VERSION,
312 		.maxver = TLS1_VERSION,
313 		.peerver = TLS1_2_VERSION,
314 		.want_maxver = TLS1_VERSION,
315 	},
316 	{
317 		.ssl_method = TLSv1_method,
318 		.options = 0,
319 		.minver = TLS1_VERSION,
320 		.maxver = TLS1_2_VERSION,
321 		.peerver = TLS1_VERSION,
322 		.want_maxver = TLS1_VERSION,
323 	},
324 	{
325 		.ssl_method = TLSv1_method,
326 		.options = 0,
327 		.minver = TLS1_1_VERSION,
328 		.maxver = TLS1_2_VERSION,
329 		.peerver = TLS1_VERSION,
330 		.want_maxver = 0,
331 	},
332 	{
333 		.ssl_method = TLSv1_1_method,
334 		.options = 0,
335 		.minver = TLS1_VERSION,
336 		.maxver = TLS1_2_VERSION,
337 		.peerver = TLS1_1_VERSION,
338 		.want_maxver = TLS1_1_VERSION,
339 	},
340 	{
341 		.ssl_method = DTLSv1_method,
342 		.options = 0,
343 		.minver = TLS1_VERSION,
344 		.maxver = TLS1_2_VERSION,
345 		.peerver = DTLS1_VERSION,
346 		.want_maxver = DTLS1_VERSION,
347 	},
348 	{
349 		.ssl_method = DTLSv1_method,
350 		.options = 0,
351 		.minver = TLS1_VERSION,
352 		.maxver = TLS1_2_VERSION,
353 		.peerver = TLS1_2_VERSION,
354 		.want_maxver = 0,
355 	},
356 };
357 
358 #define N_SHARED_VERSION_TESTS \
359     (sizeof(shared_version_tests) / sizeof(*shared_version_tests))
360 
361 static int
362 test_ssl_max_shared_version(void)
363 {
364 	struct shared_version_test *srt;
365 	SSL_CTX *ssl_ctx = NULL;
366 	SSL *ssl = NULL;
367 	uint16_t maxver;
368 	int failed = 0;
369 	size_t i;
370 
371 	failed = 0;
372 
373 	for (i = 0; i < N_SHARED_VERSION_TESTS; i++) {
374 		srt = &shared_version_tests[i];
375 
376 		if ((ssl_ctx = SSL_CTX_new(srt->ssl_method())) == NULL) {
377 			fprintf(stderr, "SSL_CTX_new() returned NULL\n");
378 			return 1;
379 		}
380 		if ((ssl = SSL_new(ssl_ctx)) == NULL) {
381 			fprintf(stderr, "SSL_new() returned NULL\n");
382 			return 1;
383 		}
384 
385 		SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
386 		    SSL_OP_NO_TLSv1_2);
387 		SSL_set_options(ssl, srt->options);
388 
389 		maxver = 0;
390 		ssl->internal->min_version = srt->minver;
391 		ssl->internal->max_version = srt->maxver;
392 
393 		if (ssl_max_shared_version(ssl, srt->peerver, &maxver) != 1) {
394 			if (srt->want_maxver != 0) {
395 				fprintf(stderr, "FAIL: test %zu - failed but "
396 				    "wanted non-zero shared version\n", i);
397 				failed++;
398 			}
399 			continue;
400 		}
401 		if (maxver != srt->want_maxver) {
402 			fprintf(stderr, "FAIL: test %zu - got shared "
403 			    "version %x, want %x\n", i, maxver,
404 			    srt->want_maxver);
405 			failed++;
406 		}
407 
408 		SSL_CTX_free(ssl_ctx);
409 		SSL_free(ssl);
410 	}
411 
412 	return (failed);
413 }
414 
415 int
416 main(int argc, char **argv)
417 {
418 	int failed = 0;
419 
420 	SSL_library_init();
421 
422 	failed |= test_ssl_enabled_version_range();
423 	failed |= test_ssl_max_shared_version();
424 
425 	if (failed == 0)
426 		printf("PASS %s\n", __FILE__);
427 
428         return (failed);
429 }
430