xref: /openbsd-src/regress/lib/libssl/unit/ssl_versions.c (revision 58fbf5d6aa35e3d66f2c32c61d2f38824a990e85)
1 /* $OpenBSD: ssl_versions.c,v 1.11 2021/02/20 09:45:14 jsing Exp $ */
2 /*
3  * Copyright (c) 2016, 2017 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_3_VERSION,
35 		.want_minver = TLS1_VERSION,
36 		.want_maxver = TLS1_3_VERSION,
37 	},
38 	{
39 		.options = 0,
40 		.minver = TLS1_VERSION,
41 		.maxver = TLS1_2_VERSION,
42 		.want_minver = TLS1_VERSION,
43 		.want_maxver = TLS1_2_VERSION,
44 	},
45 	{
46 		.options = SSL_OP_NO_TLSv1,
47 		.minver = TLS1_VERSION,
48 		.maxver = TLS1_2_VERSION,
49 		.want_minver = TLS1_1_VERSION,
50 		.want_maxver = TLS1_2_VERSION,
51 	},
52 	{
53 		.options = SSL_OP_NO_TLSv1_3,
54 		.minver = TLS1_VERSION,
55 		.maxver = TLS1_3_VERSION,
56 		.want_minver = TLS1_VERSION,
57 		.want_maxver = TLS1_2_VERSION,
58 	},
59 	{
60 		.options = SSL_OP_NO_TLSv1_2,
61 		.minver = TLS1_VERSION,
62 		.maxver = TLS1_2_VERSION,
63 		.want_minver = TLS1_VERSION,
64 		.want_maxver = TLS1_1_VERSION,
65 	},
66 	{
67 		.options = SSL_OP_NO_TLSv1_1,
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_1,
75 		.minver = TLS1_VERSION,
76 		.maxver = TLS1_2_VERSION,
77 		.want_minver = TLS1_2_VERSION,
78 		.want_maxver = TLS1_2_VERSION,
79 	},
80 	{
81 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
82 		.minver = TLS1_VERSION,
83 		.maxver = TLS1_2_VERSION,
84 		.want_minver = TLS1_VERSION,
85 		.want_maxver = TLS1_VERSION,
86 	},
87 	{
88 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2,
89 		.minver = TLS1_VERSION,
90 		.maxver = TLS1_2_VERSION,
91 		.want_minver = TLS1_1_VERSION,
92 		.want_maxver = TLS1_1_VERSION,
93 	},
94 	{
95 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
96 		    SSL_OP_NO_TLSv1_2,
97 		.minver = TLS1_VERSION,
98 		.maxver = TLS1_2_VERSION,
99 		.want_minver = 0,
100 		.want_maxver = 0,
101 	},
102 	{
103 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
104 		    SSL_OP_NO_TLSv1_2,
105 		.minver = TLS1_VERSION,
106 		.maxver = TLS1_3_VERSION,
107 		.want_minver = TLS1_3_VERSION,
108 		.want_maxver = TLS1_3_VERSION,
109 	},
110 	{
111 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
112 		    SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3,
113 		.minver = TLS1_VERSION,
114 		.maxver = TLS1_3_VERSION,
115 		.want_minver = 0,
116 		.want_maxver = 0,
117 	},
118 	{
119 		.options = 0,
120 		.minver = TLS1_VERSION,
121 		.maxver = TLS1_2_VERSION,
122 		.want_minver = TLS1_VERSION,
123 		.want_maxver = TLS1_2_VERSION,
124 	},
125 	{
126 		.options = 0,
127 		.minver = TLS1_1_VERSION,
128 		.maxver = TLS1_2_VERSION,
129 		.want_minver = TLS1_1_VERSION,
130 		.want_maxver = TLS1_2_VERSION,
131 	},
132 	{
133 		.options = 0,
134 		.minver = TLS1_2_VERSION,
135 		.maxver = TLS1_2_VERSION,
136 		.want_minver = TLS1_2_VERSION,
137 		.want_maxver = TLS1_2_VERSION,
138 	},
139 	{
140 		.options = 0,
141 		.minver = TLS1_VERSION,
142 		.maxver = TLS1_3_VERSION,
143 		.want_minver = TLS1_VERSION,
144 		.want_maxver = TLS1_3_VERSION,
145 	},
146 	{
147 		.options = 0,
148 		.minver = TLS1_1_VERSION,
149 		.maxver = TLS1_3_VERSION,
150 		.want_minver = TLS1_1_VERSION,
151 		.want_maxver = TLS1_3_VERSION,
152 	},
153 	{
154 		.options = 0,
155 		.minver = TLS1_2_VERSION,
156 		.maxver = TLS1_3_VERSION,
157 		.want_minver = TLS1_2_VERSION,
158 		.want_maxver = TLS1_3_VERSION,
159 	},
160 	{
161 		.options = 0,
162 		.minver = TLS1_3_VERSION,
163 		.maxver = TLS1_3_VERSION,
164 		.want_minver = TLS1_3_VERSION,
165 		.want_maxver = TLS1_3_VERSION,
166 	},
167 	{
168 		.options = 0,
169 		.minver = TLS1_VERSION,
170 		.maxver = TLS1_1_VERSION,
171 		.want_minver = TLS1_VERSION,
172 		.want_maxver = TLS1_1_VERSION,
173 	},
174 	{
175 		.options = 0,
176 		.minver = TLS1_VERSION,
177 		.maxver = TLS1_VERSION,
178 		.want_minver = TLS1_VERSION,
179 		.want_maxver = TLS1_VERSION,
180 	},
181 };
182 
183 #define N_VERSION_RANGE_TESTS \
184     (sizeof(version_range_tests) / sizeof(*version_range_tests))
185 
186 static int
187 test_ssl_enabled_version_range(void)
188 {
189 	struct version_range_test *vrt;
190 	uint16_t minver, maxver;
191 	SSL_CTX *ssl_ctx = NULL;
192 	SSL *ssl = NULL;
193 	int failed = 1;
194 	size_t i;
195 
196 	fprintf(stderr, "INFO: starting enabled version range tests...\n");
197 
198 	if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL) {
199 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
200 		goto failure;
201 	}
202 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
203 		fprintf(stderr, "SSL_new() returned NULL\n");
204 		goto failure;
205 	}
206 
207 	failed = 0;
208 
209 	for (i = 0; i < N_VERSION_RANGE_TESTS; i++) {
210 		vrt = &version_range_tests[i];
211 
212 		SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
213 		    SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3);
214 		SSL_set_options(ssl, vrt->options);
215 
216 		minver = maxver = 0xffff;
217 		ssl->internal->min_version = vrt->minver;
218 		ssl->internal->max_version = vrt->maxver;
219 
220 		if (ssl_enabled_version_range(ssl, &minver, &maxver) != 1) {
221 			if (vrt->want_minver != 0 || vrt->want_maxver != 0) {
222 				fprintf(stderr, "FAIL: test %zu - failed but "
223 				    "wanted non-zero versions\n", i);
224 				failed++;
225 			}
226 			continue;
227 		}
228 		if (minver != vrt->want_minver) {
229 			fprintf(stderr, "FAIL: test %zu - got minver %x, "
230 			    "want %x\n", i, minver, vrt->want_minver);
231 			failed++;
232 		}
233 		if (maxver != vrt->want_maxver) {
234 			fprintf(stderr, "FAIL: test %zu - got maxver %x, "
235 			    "want %x\n", i, maxver, vrt->want_maxver);
236 			failed++;
237 		}
238 	}
239 
240  failure:
241 	SSL_CTX_free(ssl_ctx);
242 	SSL_free(ssl);
243 
244 	return (failed);
245 }
246 
247 struct shared_version_test {
248 	const SSL_METHOD *(*ssl_method)(void);
249 	const long options;
250 	const uint16_t minver;
251 	const uint16_t maxver;
252 	const uint16_t peerver;
253 	const uint16_t want_maxver;
254 };
255 
256 static struct shared_version_test shared_version_tests[] = {
257 	{
258 		.ssl_method = TLS_method,
259 		.options = 0,
260 		.minver = TLS1_VERSION,
261 		.maxver = TLS1_2_VERSION,
262 		.peerver = SSL2_VERSION,
263 		.want_maxver = 0,
264 	},
265 	{
266 		.ssl_method = TLS_method,
267 		.options = 0,
268 		.minver = TLS1_VERSION,
269 		.maxver = TLS1_2_VERSION,
270 		.peerver = SSL3_VERSION,
271 		.want_maxver = 0,
272 	},
273 	{
274 		.ssl_method = TLS_method,
275 		.options = 0,
276 		.minver = TLS1_VERSION,
277 		.maxver = TLS1_2_VERSION,
278 		.peerver = TLS1_VERSION,
279 		.want_maxver = TLS1_VERSION,
280 	},
281 	{
282 		.ssl_method = TLS_method,
283 		.options = 0,
284 		.minver = TLS1_VERSION,
285 		.maxver = TLS1_2_VERSION,
286 		.peerver = TLS1_1_VERSION,
287 		.want_maxver = TLS1_1_VERSION,
288 	},
289 	{
290 		.ssl_method = TLS_method,
291 		.options = 0,
292 		.minver = TLS1_VERSION,
293 		.maxver = TLS1_2_VERSION,
294 		.peerver = TLS1_2_VERSION,
295 		.want_maxver = TLS1_2_VERSION,
296 	},
297 	{
298 		.ssl_method = TLS_method,
299 		.options = 0,
300 		.minver = TLS1_VERSION,
301 		.maxver = TLS1_2_VERSION,
302 		.peerver = TLS1_3_VERSION,
303 		.want_maxver = TLS1_2_VERSION,
304 	},
305 	{
306 		.ssl_method = TLS_method,
307 		.options = 0,
308 		.minver = TLS1_VERSION,
309 		.maxver = TLS1_2_VERSION,
310 		.peerver = 0x7f12,
311 		.want_maxver = TLS1_2_VERSION,
312 	},
313 	{
314 		.ssl_method = TLS_method,
315 		.options = SSL_OP_NO_TLSv1_2,
316 		.minver = TLS1_VERSION,
317 		.maxver = TLS1_2_VERSION,
318 		.peerver = TLS1_2_VERSION,
319 		.want_maxver = TLS1_1_VERSION,
320 	},
321 	{
322 		.ssl_method = TLS_method,
323 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
324 		.minver = TLS1_VERSION,
325 		.maxver = TLS1_2_VERSION,
326 		.peerver = TLS1_2_VERSION,
327 		.want_maxver = TLS1_VERSION,
328 	},
329 	{
330 		.ssl_method = TLS_method,
331 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
332 		.minver = TLS1_VERSION,
333 		.maxver = TLS1_2_VERSION,
334 		.peerver = TLS1_2_VERSION,
335 		.want_maxver = 0,
336 	},
337 	{
338 		.ssl_method = TLS_method,
339 		.options = SSL_OP_NO_TLSv1,
340 		.minver = TLS1_VERSION,
341 		.maxver = TLS1_2_VERSION,
342 		.peerver = TLS1_1_VERSION,
343 		.want_maxver = TLS1_1_VERSION,
344 	},
345 	{
346 		.ssl_method = TLS_method,
347 		.options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
348 		.minver = TLS1_VERSION,
349 		.maxver = TLS1_2_VERSION,
350 		.peerver = TLS1_1_VERSION,
351 		.want_maxver = 0,
352 	},
353 	{
354 		.ssl_method = TLS_method,
355 		.options = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
356 		.minver = TLS1_VERSION,
357 		.maxver = TLS1_2_VERSION,
358 		.peerver = TLS1_1_VERSION,
359 		.want_maxver = TLS1_VERSION,
360 	},
361 	{
362 		.ssl_method = TLS_method,
363 		.options = SSL_OP_NO_TLSv1,
364 		.minver = TLS1_VERSION,
365 		.maxver = TLS1_2_VERSION,
366 		.peerver = TLS1_VERSION,
367 		.want_maxver = 0,
368 	},
369 	{
370 		.ssl_method = TLS_method,
371 		.options = 0,
372 		.minver = TLS1_VERSION,
373 		.maxver = TLS1_1_VERSION,
374 		.peerver = TLS1_2_VERSION,
375 		.want_maxver = TLS1_1_VERSION,
376 	},
377 	{
378 		.ssl_method = TLS_method,
379 		.options = 0,
380 		.minver = TLS1_VERSION,
381 		.maxver = TLS1_VERSION,
382 		.peerver = TLS1_2_VERSION,
383 		.want_maxver = TLS1_VERSION,
384 	},
385 	{
386 		.ssl_method = TLSv1_method,
387 		.options = 0,
388 		.minver = TLS1_VERSION,
389 		.maxver = TLS1_2_VERSION,
390 		.peerver = TLS1_VERSION,
391 		.want_maxver = TLS1_VERSION,
392 	},
393 	{
394 		.ssl_method = TLSv1_method,
395 		.options = 0,
396 		.minver = TLS1_1_VERSION,
397 		.maxver = TLS1_2_VERSION,
398 		.peerver = TLS1_VERSION,
399 		.want_maxver = 0,
400 	},
401 	{
402 		.ssl_method = TLSv1_1_method,
403 		.options = 0,
404 		.minver = TLS1_VERSION,
405 		.maxver = TLS1_2_VERSION,
406 		.peerver = TLS1_1_VERSION,
407 		.want_maxver = TLS1_1_VERSION,
408 	},
409 	{
410 		.ssl_method = DTLSv1_method,
411 		.options = 0,
412 		.minver = TLS1_VERSION,
413 		.maxver = TLS1_2_VERSION,
414 		.peerver = DTLS1_VERSION,
415 		.want_maxver = DTLS1_VERSION,
416 	},
417 	{
418 		.ssl_method = DTLSv1_method,
419 		.options = 0,
420 		.minver = TLS1_VERSION,
421 		.maxver = TLS1_2_VERSION,
422 		.peerver = TLS1_2_VERSION,
423 		.want_maxver = 0,
424 	},
425 };
426 
427 #define N_SHARED_VERSION_TESTS \
428     (sizeof(shared_version_tests) / sizeof(*shared_version_tests))
429 
430 static int
431 test_ssl_max_shared_version(void)
432 {
433 	struct shared_version_test *svt;
434 	SSL_CTX *ssl_ctx = NULL;
435 	SSL *ssl = NULL;
436 	uint16_t maxver;
437 	int failed = 0;
438 	size_t i;
439 
440 	failed = 0;
441 
442 	fprintf(stderr, "INFO: starting max shared version tests...\n");
443 
444 	for (i = 0; i < N_SHARED_VERSION_TESTS; i++) {
445 		svt = &shared_version_tests[i];
446 
447 		if ((ssl_ctx = SSL_CTX_new(svt->ssl_method())) == NULL) {
448 			fprintf(stderr, "SSL_CTX_new() returned NULL\n");
449 			return 1;
450 		}
451 		if ((ssl = SSL_new(ssl_ctx)) == NULL) {
452 			fprintf(stderr, "SSL_new() returned NULL\n");
453 			return 1;
454 		}
455 
456 		SSL_clear_options(ssl, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
457 		    SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3);
458 		SSL_set_options(ssl, svt->options);
459 
460 		maxver = 0;
461 		ssl->internal->min_version = svt->minver;
462 		ssl->internal->max_version = svt->maxver;
463 
464 		if (ssl_max_shared_version(ssl, svt->peerver, &maxver) != 1) {
465 			if (svt->want_maxver != 0) {
466 				fprintf(stderr, "FAIL: test %zu - failed but "
467 				    "wanted non-zero shared version\n", i);
468 				failed++;
469 			}
470 			continue;
471 		}
472 		if (maxver != svt->want_maxver) {
473 			fprintf(stderr, "FAIL: test %zu - got shared "
474 			    "version %x, want %x\n", i, maxver,
475 			    svt->want_maxver);
476 			failed++;
477 		}
478 
479 		SSL_CTX_free(ssl_ctx);
480 		SSL_free(ssl);
481 	}
482 
483 	return (failed);
484 }
485 
486 struct min_max_version_test {
487 	const SSL_METHOD *(*ssl_method)(void);
488 	const uint16_t minver;
489 	const uint16_t maxver;
490 	const uint16_t want_minver;
491 	const uint16_t want_maxver;
492 	const int want_min_fail;
493 	const int want_max_fail;
494 };
495 
496 static struct min_max_version_test min_max_version_tests[] = {
497 	{
498 		.ssl_method = TLS_method,
499 		.minver = 0,
500 		.maxver = 0,
501 		.want_minver = 0,
502 		.want_maxver = 0,
503 	},
504 	{
505 		.ssl_method = TLS_method,
506 		.minver = TLS1_VERSION,
507 		.maxver = 0,
508 		.want_minver = TLS1_VERSION,
509 		.want_maxver = 0,
510 	},
511 	{
512 		.ssl_method = TLS_method,
513 		.minver = 0,
514 		.maxver = TLS1_2_VERSION,
515 		.want_minver = 0,
516 		.want_maxver = TLS1_2_VERSION,
517 	},
518 	{
519 		.ssl_method = TLS_method,
520 		.minver = 0,
521 		.maxver = TLS1_3_VERSION,
522 		.want_minver = 0,
523 		.want_maxver = TLS1_3_VERSION,
524 	},
525 	{
526 		.ssl_method = TLS_method,
527 		.minver = TLS1_VERSION,
528 		.maxver = TLS1_2_VERSION,
529 		.want_minver = TLS1_VERSION,
530 		.want_maxver = TLS1_2_VERSION,
531 	},
532 	{
533 		.ssl_method = TLS_method,
534 		.minver = TLS1_1_VERSION,
535 		.maxver = 0,
536 		.want_minver = TLS1_1_VERSION,
537 		.want_maxver = 0,
538 	},
539 	{
540 		.ssl_method = TLS_method,
541 		.minver = TLS1_2_VERSION,
542 		.maxver = 0,
543 		.want_minver = TLS1_2_VERSION,
544 		.want_maxver = 0,
545 	},
546 	{
547 		.ssl_method = TLS_method,
548 		.minver = 0x0300,
549 		.maxver = 0,
550 		.want_minver = TLS1_VERSION,
551 		.want_maxver = 0,
552 	},
553 	{
554 		.ssl_method = TLS_method,
555 		.minver = 0x0305,
556 		.maxver = 0,
557 		.want_min_fail = 1,
558 	},
559 	{
560 		.ssl_method = TLS_method,
561 		.minver = 0,
562 		.maxver = 0x0305,
563 		.want_minver = 0,
564 		.want_maxver = TLS1_3_VERSION,
565 	},
566 	{
567 		.ssl_method = TLS_method,
568 		.minver = 0,
569 		.maxver = TLS1_1_VERSION,
570 		.want_minver = 0,
571 		.want_maxver = TLS1_1_VERSION,
572 	},
573 	{
574 		.ssl_method = TLS_method,
575 		.minver = 0,
576 		.maxver = TLS1_VERSION,
577 		.want_minver = 0,
578 		.want_maxver = TLS1_VERSION,
579 	},
580 	{
581 		.ssl_method = TLS_method,
582 		.minver = 0,
583 		.maxver = 0x0300,
584 		.want_max_fail = 1,
585 	},
586 	{
587 		.ssl_method = TLS_method,
588 		.minver = TLS1_2_VERSION,
589 		.maxver = TLS1_1_VERSION,
590 		.want_minver = TLS1_2_VERSION,
591 		.want_maxver = 0,
592 		.want_max_fail = 1,
593 	},
594 	{
595 		.ssl_method = TLSv1_1_method,
596 		.minver = 0,
597 		.maxver = 0,
598 		.want_minver = 0,
599 		.want_maxver = 0,
600 	},
601 	{
602 		.ssl_method = TLSv1_1_method,
603 		.minver = TLS1_VERSION,
604 		.maxver = TLS1_2_VERSION,
605 		.want_minver = TLS1_1_VERSION,
606 		.want_maxver = TLS1_1_VERSION,
607 	},
608 	{
609 		.ssl_method = TLSv1_1_method,
610 		.minver = TLS1_2_VERSION,
611 		.maxver = 0,
612 		.want_minver = 0,
613 		.want_maxver = 0,
614 		.want_min_fail = 1,
615 	},
616 	{
617 		.ssl_method = TLSv1_1_method,
618 		.minver = 0,
619 		.maxver = TLS1_VERSION,
620 		.want_minver = 0,
621 		.want_maxver = 0,
622 		.want_max_fail = 1,
623 	},
624 	{
625 		.ssl_method = DTLSv1_method,
626 		.minver = 0,
627 		.maxver = 0,
628 		.want_minver = 0,
629 		.want_maxver = 0,
630 	},
631 	{
632 		.ssl_method = DTLSv1_method,
633 		.minver = DTLS1_VERSION,
634 		.maxver = 0,
635 		.want_minver = DTLS1_VERSION,
636 		.want_maxver = 0,
637 	},
638 	{
639 		.ssl_method = DTLSv1_method,
640 		.minver = 0,
641 		.maxver = DTLS1_VERSION,
642 		.want_minver = 0,
643 		.want_maxver = DTLS1_VERSION,
644 	},
645 	{
646 		.ssl_method = DTLSv1_method,
647 		.minver = TLS1_VERSION,
648 		.maxver = TLS1_2_VERSION,
649 		.want_minver = 0,
650 		.want_maxver = 0,
651 		.want_min_fail = 1,
652 		.want_max_fail = 1,
653 	},
654 };
655 
656 #define N_MIN_MAX_VERSION_TESTS \
657     (sizeof(min_max_version_tests) / sizeof(*min_max_version_tests))
658 
659 static int
660 test_ssl_min_max_version(void)
661 {
662 	struct min_max_version_test *mmvt;
663 	SSL_CTX *ssl_ctx = NULL;
664 	SSL *ssl = NULL;
665 	int failed = 0;
666 	size_t i;
667 
668 	failed = 0;
669 
670 	fprintf(stderr, "INFO: starting min max version tests...\n");
671 
672 	for (i = 0; i < N_MIN_MAX_VERSION_TESTS; i++) {
673 		mmvt = &min_max_version_tests[i];
674 
675 		if ((ssl_ctx = SSL_CTX_new(mmvt->ssl_method())) == NULL) {
676 			fprintf(stderr, "SSL_CTX_new() returned NULL\n");
677 			return 1;
678 		}
679 
680 		if (!SSL_CTX_set_min_proto_version(ssl_ctx, mmvt->minver)) {
681 			if (!mmvt->want_min_fail) {
682 				fprintf(stderr, "FAIL: test %zu - failed to set "
683 				    "SSL_CTX min version\n", i);
684 				failed++;
685 			}
686 			goto next;
687 		}
688 		if (!SSL_CTX_set_max_proto_version(ssl_ctx, mmvt->maxver)) {
689 			if (!mmvt->want_max_fail) {
690 				fprintf(stderr, "FAIL: test %zu - failed to set "
691 				    "SSL_CTX min version\n", i);
692 				failed++;
693 			}
694 			goto next;
695 		}
696 
697 		if (mmvt->want_min_fail) {
698 			fprintf(stderr, "FAIL: test %zu - successfully set "
699 			    "SSL_CTX min version, should have failed\n", i);
700 			failed++;
701 			goto next;
702 		}
703 		if (mmvt->want_max_fail) {
704 			fprintf(stderr, "FAIL: test %zu - successfully set "
705 			    "SSL_CTX max version, should have failed\n", i);
706 			failed++;
707 			goto next;
708 		}
709 
710 		if (SSL_CTX_get_min_proto_version(ssl_ctx) != mmvt->want_minver) {
711 			fprintf(stderr, "FAIL: test %zu - got SSL_CTX min "
712 			    "version 0x%x, want 0x%x\n", i,
713 			    SSL_CTX_get_min_proto_version(ssl_ctx), mmvt->want_minver);
714 			failed++;
715 			goto next;
716 		}
717 		if (SSL_CTX_get_max_proto_version(ssl_ctx) != mmvt->want_maxver) {
718 			fprintf(stderr, "FAIL: test %zu - got SSL_CTX max "
719 			    "version 0x%x, want 0x%x\n", i,
720 			    SSL_CTX_get_max_proto_version(ssl_ctx), mmvt->want_maxver);
721 			failed++;
722 			goto next;
723 		}
724 
725 		if ((ssl = SSL_new(ssl_ctx)) == NULL) {
726 			fprintf(stderr, "SSL_new() returned NULL\n");
727 			return 1;
728 		}
729 
730 		if (SSL_get_min_proto_version(ssl) != mmvt->want_minver) {
731 			fprintf(stderr, "FAIL: test %zu - initial SSL min "
732 			    "version 0x%x, want 0x%x\n", i,
733 			    SSL_get_min_proto_version(ssl), mmvt->want_minver);
734 			failed++;
735 			goto next;
736 		}
737 		if (SSL_get_max_proto_version(ssl) != mmvt->want_maxver) {
738 			fprintf(stderr, "FAIL: test %zu - initial SSL max "
739 			    "version 0x%x, want 0x%x\n", i,
740 			    SSL_get_max_proto_version(ssl), mmvt->want_maxver);
741 			failed++;
742 			goto next;
743 		}
744 
745 		if (!SSL_set_min_proto_version(ssl, mmvt->minver)) {
746 			if (mmvt->want_min_fail) {
747 				fprintf(stderr, "FAIL: test %zu - failed to set "
748 				    "SSL min version\n", i);
749 				failed++;
750 			}
751 			goto next;
752 		}
753 		if (!SSL_set_max_proto_version(ssl, mmvt->maxver)) {
754 			if (mmvt->want_max_fail) {
755 				fprintf(stderr, "FAIL: test %zu - failed to set "
756 				    "SSL min version\n", i);
757 				failed++;
758 			}
759 			goto next;
760 		}
761 
762 		if (mmvt->want_min_fail) {
763 			fprintf(stderr, "FAIL: test %zu - successfully set SSL "
764 			    "min version, should have failed\n", i);
765 			failed++;
766 			goto next;
767 		}
768 		if (mmvt->want_max_fail) {
769 			fprintf(stderr, "FAIL: test %zu - successfully set SSL "
770 			    "max version, should have failed\n", i);
771 			failed++;
772 			goto next;
773 		}
774 
775 		if (SSL_get_min_proto_version(ssl) != mmvt->want_minver) {
776 			fprintf(stderr, "FAIL: test %zu - got SSL min "
777 			    "version 0x%x, want 0x%x\n", i,
778 			    SSL_get_min_proto_version(ssl), mmvt->want_minver);
779 			failed++;
780 			goto next;
781 		}
782 		if (SSL_get_max_proto_version(ssl) != mmvt->want_maxver) {
783 			fprintf(stderr, "FAIL: test %zu - got SSL max "
784 			    "version 0x%x, want 0x%x\n", i,
785 			    SSL_get_max_proto_version(ssl), mmvt->want_maxver);
786 			failed++;
787 			goto next;
788 		}
789 
790  next:
791 		SSL_CTX_free(ssl_ctx);
792 		SSL_free(ssl);
793 
794 		ssl_ctx = NULL;
795 		ssl = NULL;
796 	}
797 
798 	return (failed);
799 }
800 
801 int
802 main(int argc, char **argv)
803 {
804 	int failed = 0;
805 
806 	SSL_library_init();
807 
808 	/* XXX - Test ssl_supported_version_range() */
809 
810 	failed |= test_ssl_enabled_version_range();
811 	failed |= test_ssl_max_shared_version();
812 	failed |= test_ssl_min_max_version();
813 
814 	if (failed == 0)
815 		printf("PASS %s\n", __FILE__);
816 
817 	return (failed);
818 }
819