xref: /openbsd-src/regress/lib/libtls/tls/tlstest.c (revision 0c5dcecc66318b2dbe970b0c714ad357b0f912cf)
1*0c5dceccStb /* $OpenBSD: tlstest.c,v 1.16 2024/08/02 15:02:22 tb Exp $ */
2d7e18552Sjsing /*
3d7e18552Sjsing  * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4d7e18552Sjsing  *
5d7e18552Sjsing  * Permission to use, copy, modify, and distribute this software for any
6d7e18552Sjsing  * purpose with or without fee is hereby granted, provided that the above
7d7e18552Sjsing  * copyright notice and this permission notice appear in all copies.
8d7e18552Sjsing  *
9d7e18552Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10d7e18552Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11d7e18552Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12d7e18552Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13d7e18552Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14d7e18552Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15d7e18552Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16d7e18552Sjsing  */
17d7e18552Sjsing 
18d7e18552Sjsing #include <sys/socket.h>
19d7e18552Sjsing 
20d7e18552Sjsing #include <err.h>
21d7e18552Sjsing #include <fcntl.h>
22d7e18552Sjsing #include <stdio.h>
23d7e18552Sjsing #include <string.h>
24d7e18552Sjsing #include <unistd.h>
25d7e18552Sjsing 
26d7e18552Sjsing #include <tls.h>
27d7e18552Sjsing 
28d7e18552Sjsing #define CIRCULAR_BUFFER_SIZE 512
29d7e18552Sjsing 
30d7e18552Sjsing unsigned char client_buffer[CIRCULAR_BUFFER_SIZE];
31d7e18552Sjsing unsigned char *client_readptr, *client_writeptr;
32d7e18552Sjsing 
33d7e18552Sjsing unsigned char server_buffer[CIRCULAR_BUFFER_SIZE];
34d7e18552Sjsing unsigned char *server_readptr, *server_writeptr;
35d7e18552Sjsing 
365825962cSjsing char *cafile, *certfile, *keyfile;
375825962cSjsing 
38d7e18552Sjsing int debug = 0;
39d7e18552Sjsing 
40d7e18552Sjsing static void
41d7e18552Sjsing circular_init(void)
42d7e18552Sjsing {
43d7e18552Sjsing 	client_readptr = client_writeptr = client_buffer;
44d7e18552Sjsing 	server_readptr = server_writeptr = server_buffer;
45d7e18552Sjsing }
46d7e18552Sjsing 
47d7e18552Sjsing static ssize_t
48d7e18552Sjsing circular_read(char *name, unsigned char *buf, size_t bufsize,
49d7e18552Sjsing     unsigned char **readptr, unsigned char *writeptr,
50d7e18552Sjsing     unsigned char *outbuf, size_t outlen)
51d7e18552Sjsing {
52d7e18552Sjsing 	unsigned char *nextptr = *readptr;
53d7e18552Sjsing 	size_t n = 0;
54d7e18552Sjsing 
55d7e18552Sjsing 	while (n < outlen) {
56d7e18552Sjsing 		if (nextptr == writeptr)
57d7e18552Sjsing 			break;
58d7e18552Sjsing 		*outbuf++ = *nextptr++;
59d7e18552Sjsing 		if ((size_t)(nextptr - buf) >= bufsize)
60d7e18552Sjsing 			nextptr = buf;
61d7e18552Sjsing 		*readptr = nextptr;
62d7e18552Sjsing 		n++;
63d7e18552Sjsing 	}
64d7e18552Sjsing 
65d7e18552Sjsing 	if (debug && n > 0)
66d7e18552Sjsing 		fprintf(stderr, "%s buffer: read %zi bytes\n", name, n);
67d7e18552Sjsing 
68d7e18552Sjsing 	return (n > 0 ? (ssize_t)n : TLS_WANT_POLLIN);
69d7e18552Sjsing }
70d7e18552Sjsing 
71d7e18552Sjsing static ssize_t
72d7e18552Sjsing circular_write(char *name, unsigned char *buf, size_t bufsize,
73d7e18552Sjsing     unsigned char *readptr, unsigned char **writeptr,
74d7e18552Sjsing     const unsigned char *inbuf, size_t inlen)
75d7e18552Sjsing {
76d7e18552Sjsing 	unsigned char *nextptr = *writeptr;
77d7e18552Sjsing 	unsigned char *prevptr;
78d7e18552Sjsing 	size_t n = 0;
79d7e18552Sjsing 
80d7e18552Sjsing 	while (n < inlen) {
81d7e18552Sjsing 		prevptr = nextptr++;
82d7e18552Sjsing 		if ((size_t)(nextptr - buf) >= bufsize)
83d7e18552Sjsing 			nextptr = buf;
84d7e18552Sjsing 		if (nextptr == readptr)
85d7e18552Sjsing 			break;
86d7e18552Sjsing 		*prevptr = *inbuf++;
87d7e18552Sjsing 		*writeptr = nextptr;
88d7e18552Sjsing 		n++;
89d7e18552Sjsing 	}
90d7e18552Sjsing 
91d7e18552Sjsing 	if (debug && n > 0)
92d7e18552Sjsing 		fprintf(stderr, "%s buffer: wrote %zi bytes\n", name, n);
93d7e18552Sjsing 
94d7e18552Sjsing 	return (n > 0 ? (ssize_t)n : TLS_WANT_POLLOUT);
95d7e18552Sjsing }
96d7e18552Sjsing 
97d7e18552Sjsing static ssize_t
98d7e18552Sjsing client_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
99d7e18552Sjsing {
100d7e18552Sjsing 	return circular_read("client", client_buffer, sizeof(client_buffer),
101d7e18552Sjsing 	    &client_readptr, client_writeptr, buf, buflen);
102d7e18552Sjsing }
103d7e18552Sjsing 
104d7e18552Sjsing static ssize_t
105d7e18552Sjsing client_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
106d7e18552Sjsing {
107d7e18552Sjsing 	return circular_write("server", server_buffer, sizeof(server_buffer),
108d7e18552Sjsing 	    server_readptr, &server_writeptr, buf, buflen);
109d7e18552Sjsing }
110d7e18552Sjsing 
111d7e18552Sjsing static ssize_t
112d7e18552Sjsing server_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
113d7e18552Sjsing {
114d7e18552Sjsing 	return circular_read("server", server_buffer, sizeof(server_buffer),
115d7e18552Sjsing 	    &server_readptr, server_writeptr, buf, buflen);
116d7e18552Sjsing }
117d7e18552Sjsing 
118d7e18552Sjsing static ssize_t
119d7e18552Sjsing server_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
120d7e18552Sjsing {
121d7e18552Sjsing 	return circular_write("client", client_buffer, sizeof(client_buffer),
122d7e18552Sjsing 	    client_readptr, &client_writeptr, buf, buflen);
123d7e18552Sjsing }
124d7e18552Sjsing 
125d7e18552Sjsing static int
126d7e18552Sjsing do_tls_handshake(char *name, struct tls *ctx)
127d7e18552Sjsing {
128d7e18552Sjsing 	int rv;
129d7e18552Sjsing 
130d7e18552Sjsing 	rv = tls_handshake(ctx);
131d7e18552Sjsing 	if (rv == 0)
132d7e18552Sjsing 		return (1);
133d7e18552Sjsing 	if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT)
134d7e18552Sjsing 		return (0);
135d7e18552Sjsing 
136d7e18552Sjsing 	errx(1, "%s handshake failed: %s", name, tls_error(ctx));
137d7e18552Sjsing }
138d7e18552Sjsing 
139d7e18552Sjsing static int
140d7e18552Sjsing do_tls_close(char *name, struct tls *ctx)
141d7e18552Sjsing {
142d7e18552Sjsing 	int rv;
143d7e18552Sjsing 
144d7e18552Sjsing 	rv = tls_close(ctx);
145d7e18552Sjsing 	if (rv == 0)
146d7e18552Sjsing 		return (1);
147d7e18552Sjsing 	if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT)
148d7e18552Sjsing 		return (0);
149d7e18552Sjsing 
150d7e18552Sjsing 	errx(1, "%s close failed: %s", name, tls_error(ctx));
151d7e18552Sjsing }
152d7e18552Sjsing 
153d7e18552Sjsing static int
1543695f442Sjsing do_client_server_handshake(char *desc, struct tls *client,
1553695f442Sjsing     struct tls *server_cctx)
156d7e18552Sjsing {
157d7e18552Sjsing 	int i, client_done, server_done;
158d7e18552Sjsing 
159d7e18552Sjsing 	i = client_done = server_done = 0;
160d7e18552Sjsing 	do {
161d7e18552Sjsing 		if (client_done == 0)
162d7e18552Sjsing 			client_done = do_tls_handshake("client", client);
163d7e18552Sjsing 		if (server_done == 0)
164d7e18552Sjsing 			server_done = do_tls_handshake("server", server_cctx);
165d7e18552Sjsing 	} while (i++ < 100 && (client_done == 0 || server_done == 0));
166d7e18552Sjsing 
167d7e18552Sjsing 	if (client_done == 0 || server_done == 0) {
168d7e18552Sjsing 		printf("FAIL: %s TLS handshake did not complete\n", desc);
169d7e18552Sjsing 		return (1);
170d7e18552Sjsing 	}
171d7e18552Sjsing 
1723695f442Sjsing 	return (0);
1733695f442Sjsing }
1743695f442Sjsing 
1753695f442Sjsing static int
1763695f442Sjsing do_client_server_close(char *desc, struct tls *client, struct tls *server_cctx)
1773695f442Sjsing {
1783695f442Sjsing 	int i, client_done, server_done;
179d7e18552Sjsing 
180d7e18552Sjsing 	i = client_done = server_done = 0;
181d7e18552Sjsing 	do {
182d7e18552Sjsing 		if (client_done == 0)
183d7e18552Sjsing 			client_done = do_tls_close("client", client);
184d7e18552Sjsing 		if (server_done == 0)
185d7e18552Sjsing 			server_done = do_tls_close("server", server_cctx);
186d7e18552Sjsing 	} while (i++ < 100 && (client_done == 0 || server_done == 0));
187d7e18552Sjsing 
188d7e18552Sjsing 	if (client_done == 0 || server_done == 0) {
189d7e18552Sjsing 		printf("FAIL: %s TLS close did not complete\n", desc);
190d7e18552Sjsing 		return (1);
191d7e18552Sjsing 	}
1923695f442Sjsing 
1933695f442Sjsing 	return (0);
1943695f442Sjsing }
1953695f442Sjsing 
1963695f442Sjsing static int
1973695f442Sjsing do_client_server_test(char *desc, struct tls *client, struct tls *server_cctx)
1983695f442Sjsing {
1993695f442Sjsing 	if (do_client_server_handshake(desc, client, server_cctx) != 0)
2003695f442Sjsing 		return (1);
2013695f442Sjsing 
2023695f442Sjsing 	printf("INFO: %s TLS handshake completed successfully\n", desc);
2033695f442Sjsing 
2043695f442Sjsing 	/* XXX - Do some reads and writes... */
2053695f442Sjsing 
2063695f442Sjsing 	if (do_client_server_close(desc, client, server_cctx) != 0)
2073695f442Sjsing 		return (1);
2083695f442Sjsing 
209d7e18552Sjsing 	printf("INFO: %s TLS close completed successfully\n", desc);
210d7e18552Sjsing 
211d7e18552Sjsing 	return (0);
212d7e18552Sjsing }
213d7e18552Sjsing 
214d7e18552Sjsing static int
215d7e18552Sjsing test_tls_cbs(struct tls *client, struct tls *server)
216d7e18552Sjsing {
217d7e18552Sjsing 	struct tls *server_cctx;
218d7e18552Sjsing 	int failure;
219d7e18552Sjsing 
220d7e18552Sjsing 	circular_init();
221d7e18552Sjsing 
222d7e18552Sjsing 	if (tls_accept_cbs(server, &server_cctx, server_read, server_write,
223d7e18552Sjsing 	    NULL) == -1)
224d7e18552Sjsing 		errx(1, "failed to accept: %s", tls_error(server));
225d7e18552Sjsing 
226d7e18552Sjsing 	if (tls_connect_cbs(client, client_read, client_write, NULL,
227d7e18552Sjsing 	    "test") == -1)
228d7e18552Sjsing 		errx(1, "failed to connect: %s", tls_error(client));
229d7e18552Sjsing 
230d7e18552Sjsing 	failure = do_client_server_test("callback", client, server_cctx);
231d7e18552Sjsing 
232d7e18552Sjsing 	tls_free(server_cctx);
233d7e18552Sjsing 
234d7e18552Sjsing 	return (failure);
235d7e18552Sjsing }
236d7e18552Sjsing 
237d7e18552Sjsing static int
238d7e18552Sjsing test_tls_fds(struct tls *client, struct tls *server)
239d7e18552Sjsing {
240d7e18552Sjsing 	struct tls *server_cctx;
241d7e18552Sjsing 	int cfds[2], sfds[2];
242d7e18552Sjsing 	int failure;
243d7e18552Sjsing 
244d7e18552Sjsing 	if (pipe2(cfds, O_NONBLOCK) == -1)
245d7e18552Sjsing 		err(1, "failed to create pipe");
246d7e18552Sjsing 	if (pipe2(sfds, O_NONBLOCK) == -1)
247d7e18552Sjsing 		err(1, "failed to create pipe");
248d7e18552Sjsing 
249d7e18552Sjsing 	if (tls_accept_fds(server, &server_cctx, sfds[0], cfds[1]) == -1)
250d7e18552Sjsing 		errx(1, "failed to accept: %s", tls_error(server));
251d7e18552Sjsing 
252d7e18552Sjsing 	if (tls_connect_fds(client, cfds[0], sfds[1], "test") == -1)
253d7e18552Sjsing 		errx(1, "failed to connect: %s", tls_error(client));
254d7e18552Sjsing 
255d7e18552Sjsing 	failure = do_client_server_test("file descriptor", client, server_cctx);
256d7e18552Sjsing 
257d7e18552Sjsing 	tls_free(server_cctx);
258d7e18552Sjsing 
259d7e18552Sjsing 	close(cfds[0]);
260d7e18552Sjsing 	close(cfds[1]);
261d7e18552Sjsing 	close(sfds[0]);
262d7e18552Sjsing 	close(sfds[1]);
263d7e18552Sjsing 
264d7e18552Sjsing 	return (failure);
265d7e18552Sjsing }
266d7e18552Sjsing 
267d7e18552Sjsing static int
268d7e18552Sjsing test_tls_socket(struct tls *client, struct tls *server)
269d7e18552Sjsing {
270d7e18552Sjsing 	struct tls *server_cctx;
271d7e18552Sjsing 	int failure;
272d7e18552Sjsing 	int sv[2];
273d7e18552Sjsing 
274d7e18552Sjsing 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC,
275d7e18552Sjsing 	    sv) == -1)
276d7e18552Sjsing 		err(1, "failed to create socketpair");
277d7e18552Sjsing 
278d7e18552Sjsing 	if (tls_accept_socket(server, &server_cctx, sv[0]) == -1)
279d7e18552Sjsing 		errx(1, "failed to accept: %s", tls_error(server));
280d7e18552Sjsing 
281d7e18552Sjsing 	if (tls_connect_socket(client, sv[1], "test") == -1)
282d7e18552Sjsing 		errx(1, "failed to connect: %s", tls_error(client));
283d7e18552Sjsing 
284d7e18552Sjsing 	failure = do_client_server_test("socket", client, server_cctx);
285d7e18552Sjsing 
286d7e18552Sjsing 	tls_free(server_cctx);
287d7e18552Sjsing 
288d7e18552Sjsing 	close(sv[0]);
289d7e18552Sjsing 	close(sv[1]);
290d7e18552Sjsing 
291d7e18552Sjsing 	return (failure);
292d7e18552Sjsing }
293d7e18552Sjsing 
2945825962cSjsing static int
295dc41c420Sjsing test_tls(char *client_protocols, char *server_protocols, char *ciphers)
296dc41c420Sjsing {
297dc41c420Sjsing 	struct tls_config *client_cfg, *server_cfg;
298dc41c420Sjsing 	struct tls *client, *server;
299dc41c420Sjsing 	uint32_t protocols;
3001591f3f7Stb 	int failure = 0;
301dc41c420Sjsing 
302dc41c420Sjsing 	if ((client = tls_client()) == NULL)
303dc41c420Sjsing 		errx(1, "failed to create tls client");
304dc41c420Sjsing 	if ((client_cfg = tls_config_new()) == NULL)
305dc41c420Sjsing 		errx(1, "failed to create tls client config");
306dc41c420Sjsing 	tls_config_insecure_noverifyname(client_cfg);
307dc41c420Sjsing 	if (tls_config_parse_protocols(&protocols, client_protocols) == -1)
308dc41c420Sjsing 		errx(1, "failed to parse protocols: %s", tls_config_error(client_cfg));
309dc41c420Sjsing 	if (tls_config_set_protocols(client_cfg, protocols) == -1)
310dc41c420Sjsing 		errx(1, "failed to set protocols: %s", tls_config_error(client_cfg));
311dc41c420Sjsing 	if (tls_config_set_ciphers(client_cfg, ciphers) == -1)
312dc41c420Sjsing 		errx(1, "failed to set ciphers: %s", tls_config_error(client_cfg));
313dc41c420Sjsing 	if (tls_config_set_ca_file(client_cfg, cafile) == -1)
314dc41c420Sjsing 		errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
315dc41c420Sjsing 
316dc41c420Sjsing 	if ((server = tls_server()) == NULL)
317dc41c420Sjsing 		errx(1, "failed to create tls server");
318dc41c420Sjsing 	if ((server_cfg = tls_config_new()) == NULL)
319dc41c420Sjsing 		errx(1, "failed to create tls server config");
320dc41c420Sjsing 	if (tls_config_parse_protocols(&protocols, server_protocols) == -1)
321dc41c420Sjsing 		errx(1, "failed to parse protocols: %s", tls_config_error(server_cfg));
322dc41c420Sjsing 	if (tls_config_set_protocols(server_cfg, protocols) == -1)
323dc41c420Sjsing 		errx(1, "failed to set protocols: %s", tls_config_error(server_cfg));
324dc41c420Sjsing 	if (tls_config_set_ciphers(server_cfg, ciphers) == -1)
325dc41c420Sjsing 		errx(1, "failed to set ciphers: %s", tls_config_error(server_cfg));
326dc41c420Sjsing 	if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1)
327dc41c420Sjsing 		errx(1, "failed to set keypair: %s",
328dc41c420Sjsing 		    tls_config_error(server_cfg));
329dc41c420Sjsing 
330dc41c420Sjsing 	if (tls_configure(client, client_cfg) == -1)
331dc41c420Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
332dc41c420Sjsing 	tls_reset(server);
333dc41c420Sjsing 	if (tls_configure(server, server_cfg) == -1)
334dc41c420Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
335dc41c420Sjsing 
3361591f3f7Stb 	tls_config_free(client_cfg);
3371591f3f7Stb 	tls_config_free(server_cfg);
3381591f3f7Stb 
3391591f3f7Stb 	failure |= test_tls_cbs(client, server);
3401591f3f7Stb 
3411591f3f7Stb 	tls_free(client);
3421591f3f7Stb 	tls_free(server);
3431591f3f7Stb 
3441591f3f7Stb 	return (failure);
345dc41c420Sjsing }
346dc41c420Sjsing 
347dc41c420Sjsing static int
3485825962cSjsing do_tls_tests(void)
349d7e18552Sjsing {
350d7e18552Sjsing 	struct tls_config *client_cfg, *server_cfg;
351d7e18552Sjsing 	struct tls *client, *server;
352d7e18552Sjsing 	int failure = 0;
353d7e18552Sjsing 
354dc41c420Sjsing 	printf("== TLS tests ==\n");
355dc41c420Sjsing 
356d7e18552Sjsing 	if ((client = tls_client()) == NULL)
357d7e18552Sjsing 		errx(1, "failed to create tls client");
358d7e18552Sjsing 	if ((client_cfg = tls_config_new()) == NULL)
359d7e18552Sjsing 		errx(1, "failed to create tls client config");
360d7e18552Sjsing 	tls_config_insecure_noverifyname(client_cfg);
3615825962cSjsing 	if (tls_config_set_ca_file(client_cfg, cafile) == -1)
362d7e18552Sjsing 		errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
363d7e18552Sjsing 
364d7e18552Sjsing 	if ((server = tls_server()) == NULL)
365d7e18552Sjsing 		errx(1, "failed to create tls server");
366d7e18552Sjsing 	if ((server_cfg = tls_config_new()) == NULL)
367d7e18552Sjsing 		errx(1, "failed to create tls server config");
3685825962cSjsing 	if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1)
369d7e18552Sjsing 		errx(1, "failed to set keypair: %s",
370d7e18552Sjsing 		    tls_config_error(server_cfg));
371d7e18552Sjsing 
372d7e18552Sjsing 	tls_reset(client);
373d7e18552Sjsing 	if (tls_configure(client, client_cfg) == -1)
374d7e18552Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
375d7e18552Sjsing 	tls_reset(server);
376d7e18552Sjsing 	if (tls_configure(server, server_cfg) == -1)
377d7e18552Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
378d7e18552Sjsing 
379d7e18552Sjsing 	failure |= test_tls_cbs(client, server);
380d7e18552Sjsing 
381d7e18552Sjsing 	tls_reset(client);
382d7e18552Sjsing 	if (tls_configure(client, client_cfg) == -1)
383d7e18552Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
384d7e18552Sjsing 	tls_reset(server);
385d7e18552Sjsing 	if (tls_configure(server, server_cfg) == -1)
386d7e18552Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
387d7e18552Sjsing 
388d7e18552Sjsing 	failure |= test_tls_fds(client, server);
389d7e18552Sjsing 
390d7e18552Sjsing 	tls_reset(client);
391d7e18552Sjsing 	if (tls_configure(client, client_cfg) == -1)
392d7e18552Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
393d7e18552Sjsing 	tls_reset(server);
394d7e18552Sjsing 	if (tls_configure(server, server_cfg) == -1)
395d7e18552Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
396d7e18552Sjsing 
397d7736651Sjsing 	tls_config_free(client_cfg);
398d7736651Sjsing 	tls_config_free(server_cfg);
399d7736651Sjsing 
400d7e18552Sjsing 	failure |= test_tls_socket(client, server);
401d7e18552Sjsing 
402d7e18552Sjsing 	tls_free(client);
403d7e18552Sjsing 	tls_free(server);
404d7e18552Sjsing 
405dc41c420Sjsing 	printf("\n");
406dc41c420Sjsing 
407d7e18552Sjsing 	return (failure);
408d7e18552Sjsing }
4095825962cSjsing 
410ef75dc35Sjsing static int
411ef75dc35Sjsing do_tls_ordering_tests(void)
412ef75dc35Sjsing {
413ef75dc35Sjsing 	struct tls *client = NULL, *server = NULL, *server_cctx = NULL;
414ef75dc35Sjsing 	struct tls_config *client_cfg, *server_cfg;
415ef75dc35Sjsing 	int failure = 0;
416ef75dc35Sjsing 
417dc41c420Sjsing 	printf("== TLS ordering tests ==\n");
418ef75dc35Sjsing 
419ef75dc35Sjsing 	if ((client = tls_client()) == NULL)
420ef75dc35Sjsing 		errx(1, "failed to create tls client");
421ef75dc35Sjsing 	if ((client_cfg = tls_config_new()) == NULL)
422ef75dc35Sjsing 		errx(1, "failed to create tls client config");
423ef75dc35Sjsing 	tls_config_insecure_noverifyname(client_cfg);
424ef75dc35Sjsing 	if (tls_config_set_ca_file(client_cfg, cafile) == -1)
425ef75dc35Sjsing 		errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
426ef75dc35Sjsing 
427ef75dc35Sjsing 	if ((server = tls_server()) == NULL)
428ef75dc35Sjsing 		errx(1, "failed to create tls server");
429ef75dc35Sjsing 	if ((server_cfg = tls_config_new()) == NULL)
430ef75dc35Sjsing 		errx(1, "failed to create tls server config");
431ef75dc35Sjsing 	if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1)
432ef75dc35Sjsing 		errx(1, "failed to set keypair: %s",
433ef75dc35Sjsing 		    tls_config_error(server_cfg));
434ef75dc35Sjsing 
435ef75dc35Sjsing 	if (tls_configure(client, client_cfg) == -1)
436ef75dc35Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
437ef75dc35Sjsing 	if (tls_configure(server, server_cfg) == -1)
438ef75dc35Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
439ef75dc35Sjsing 
440ef75dc35Sjsing 	tls_config_free(client_cfg);
441ef75dc35Sjsing 	tls_config_free(server_cfg);
442ef75dc35Sjsing 
443fcb81bb6Sjsing 	if (tls_handshake(client) != -1) {
444fcb81bb6Sjsing 		printf("FAIL: TLS handshake succeeded on unconnnected "
445fcb81bb6Sjsing 		    "client context\n");
446fcb81bb6Sjsing 		failure = 1;
447fcb81bb6Sjsing 		goto done;
448fcb81bb6Sjsing 	}
449fcb81bb6Sjsing 
450cfee7a70Sjsing 	circular_init();
451cfee7a70Sjsing 
452ef75dc35Sjsing 	if (tls_accept_cbs(server, &server_cctx, server_read, server_write,
453ef75dc35Sjsing 	    NULL) == -1)
454ef75dc35Sjsing 		errx(1, "failed to accept: %s", tls_error(server));
455ef75dc35Sjsing 
456ef75dc35Sjsing 	if (tls_connect_cbs(client, client_read, client_write, NULL,
457ef75dc35Sjsing 	    "test") == -1)
458ef75dc35Sjsing 		errx(1, "failed to connect: %s", tls_error(client));
459ef75dc35Sjsing 
460ef75dc35Sjsing 	if (do_client_server_handshake("ordering", client, server_cctx) != 0) {
461ef75dc35Sjsing 		failure = 1;
462ef75dc35Sjsing 		goto done;
463ef75dc35Sjsing 	}
464ef75dc35Sjsing 
465e289e929Sjsing 	if (tls_handshake(client) != -1) {
466e289e929Sjsing 		printf("FAIL: TLS handshake succeeded twice\n");
467e289e929Sjsing 		failure = 1;
468e289e929Sjsing 		goto done;
469e289e929Sjsing 	}
470e289e929Sjsing 
471ab928952Sjsing 	if (tls_handshake(server_cctx) != -1) {
472ab928952Sjsing 		printf("FAIL: TLS handshake succeeded twice\n");
473ab928952Sjsing 		failure = 1;
474ab928952Sjsing 		goto done;
475ab928952Sjsing 	}
476ab928952Sjsing 
477ef75dc35Sjsing 	if (do_client_server_close("ordering", client, server_cctx) != 0) {
478ef75dc35Sjsing 		failure = 1;
479ef75dc35Sjsing 		goto done;
480ef75dc35Sjsing 	}
481ef75dc35Sjsing 
482ef75dc35Sjsing  done:
483ef75dc35Sjsing 	tls_free(client);
484ef75dc35Sjsing 	tls_free(server);
485ef75dc35Sjsing 	tls_free(server_cctx);
486ef75dc35Sjsing 
487dc41c420Sjsing 	printf("\n");
488dc41c420Sjsing 
489ef75dc35Sjsing 	return (failure);
490ef75dc35Sjsing }
491ef75dc35Sjsing 
492dc41c420Sjsing struct test_versions {
493dc41c420Sjsing 	char *client;
494dc41c420Sjsing 	char *server;
495dc41c420Sjsing };
496dc41c420Sjsing 
497dc41c420Sjsing static struct test_versions tls_test_versions[] = {
498dc41c420Sjsing 	{"tlsv1.3", "all"},
499dc41c420Sjsing 	{"tlsv1.2", "all"},
500dc41c420Sjsing 	{"all", "tlsv1.3"},
501dc41c420Sjsing 	{"all", "tlsv1.2"},
502*0c5dceccStb 	{"all:!tlsv1.1", "tlsv1.2"},
503*0c5dceccStb 	{"all:!tlsv1.2", "tlsv1.3"},
504*0c5dceccStb 	{"all:!tlsv1.3", "tlsv1.2"},
505*0c5dceccStb 	{"all:!tlsv1.2:!tlsv1.1", "tlsv1.3"},
506*0c5dceccStb 	{"all:!tlsv1.2:!tlsv1.1:!tlsv1.0", "tlsv1.3"},
507dc41c420Sjsing 	{"tlsv1.3", "tlsv1.3"},
508dc41c420Sjsing 	{"tlsv1.2", "tlsv1.2"},
509dc41c420Sjsing };
510dc41c420Sjsing 
511dc41c420Sjsing #define N_TLS_VERSION_TESTS \
512dc41c420Sjsing     (sizeof(tls_test_versions) / sizeof(*tls_test_versions))
513dc41c420Sjsing 
514dc41c420Sjsing static int
515dc41c420Sjsing do_tls_version_tests(void)
516dc41c420Sjsing {
517dc41c420Sjsing 	struct test_versions *tv;
518dc41c420Sjsing 	int failure = 0;
519dc41c420Sjsing 	size_t i;
520dc41c420Sjsing 
521dc41c420Sjsing 	printf("== TLS version tests ==\n");
522dc41c420Sjsing 
523dc41c420Sjsing 	for (i = 0; i < N_TLS_VERSION_TESTS; i++) {
524dc41c420Sjsing 		tv = &tls_test_versions[i];
525dc41c420Sjsing 		printf("INFO: version test %zu - client versions '%s' "
526dc41c420Sjsing 		    "and server versions '%s'\n", i, tv->client, tv->server);
527dc41c420Sjsing 		failure |= test_tls(tv->client, tv->server, "legacy");
528dc41c420Sjsing 		printf("\n");
529dc41c420Sjsing 	}
530dc41c420Sjsing 
531dc41c420Sjsing 	return failure;
532dc41c420Sjsing }
533dc41c420Sjsing 
5345825962cSjsing int
5355825962cSjsing main(int argc, char **argv)
5365825962cSjsing {
5375825962cSjsing 	int failure = 0;
5385825962cSjsing 
5395825962cSjsing 	if (argc != 4) {
5405825962cSjsing 		fprintf(stderr, "usage: %s cafile certfile keyfile\n",
5415825962cSjsing 		    argv[0]);
5425825962cSjsing 		return (1);
5435825962cSjsing 	}
5445825962cSjsing 
5455825962cSjsing 	cafile = argv[1];
5465825962cSjsing 	certfile = argv[2];
5475825962cSjsing 	keyfile = argv[3];
5485825962cSjsing 
5495825962cSjsing 	failure |= do_tls_tests();
550ef75dc35Sjsing 	failure |= do_tls_ordering_tests();
551dc41c420Sjsing 	failure |= do_tls_version_tests();
5525825962cSjsing 
5535825962cSjsing 	return (failure);
5545825962cSjsing }
555