1*5c10583eStb /* $OpenBSD: servertest.c,v 1.9 2023/07/11 11:52:35 tb Exp $ */
2d59bb994Sjsing /*
3d59bb994Sjsing * Copyright (c) 2015, 2016, 2017 Joel Sing <jsing@openbsd.org>
4d59bb994Sjsing *
5d59bb994Sjsing * Permission to use, copy, modify, and distribute this software for any
6d59bb994Sjsing * purpose with or without fee is hereby granted, provided that the above
7d59bb994Sjsing * copyright notice and this permission notice appear in all copies.
8d59bb994Sjsing *
9d59bb994Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10d59bb994Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11d59bb994Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12d59bb994Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13d59bb994Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14d59bb994Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15d59bb994Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16d59bb994Sjsing */
17d59bb994Sjsing
18d59bb994Sjsing #include <openssl/ssl.h>
19d59bb994Sjsing
20d59bb994Sjsing #include <openssl/err.h>
21d59bb994Sjsing #include <openssl/dtls1.h>
22d59bb994Sjsing #include <openssl/ssl3.h>
23d59bb994Sjsing
24d59bb994Sjsing #include <err.h>
25d59bb994Sjsing #include <stdio.h>
26d59bb994Sjsing #include <string.h>
27d59bb994Sjsing
28df17eac1Sjsing const SSL_METHOD *tls_legacy_method(void);
2937720da1Sjsing
30d59bb994Sjsing char *server_ca_file;
31d59bb994Sjsing char *server_cert_file;
32d59bb994Sjsing char *server_key_file;
33d59bb994Sjsing
34d59bb994Sjsing static unsigned char sslv2_client_hello_tls10[] = {
35d59bb994Sjsing 0x80, 0x6a, 0x01, 0x03, 0x01, 0x00, 0x51, 0x00,
36d59bb994Sjsing 0x00, 0x00, 0x10, 0x00, 0x00, 0x39, 0x00, 0x00,
37d59bb994Sjsing 0x38, 0x00, 0x00, 0x35, 0x00, 0x00, 0x16, 0x00,
38d59bb994Sjsing 0x00, 0x13, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x33,
39d59bb994Sjsing 0x00, 0x00, 0x32, 0x00, 0x00, 0x2f, 0x00, 0x00,
40d59bb994Sjsing 0x07, 0x00, 0x00, 0x66, 0x00, 0x00, 0x05, 0x00,
41d59bb994Sjsing 0x00, 0x04, 0x00, 0x00, 0x63, 0x00, 0x00, 0x62,
42d59bb994Sjsing 0x00, 0x00, 0x61, 0x00, 0x00, 0x15, 0x00, 0x00,
43d59bb994Sjsing 0x12, 0x00, 0x00, 0x09, 0x00, 0x00, 0x65, 0x00,
44d59bb994Sjsing 0x00, 0x64, 0x00, 0x00, 0x60, 0x00, 0x00, 0x14,
45d59bb994Sjsing 0x00, 0x00, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00,
46d59bb994Sjsing 0x06, 0x00, 0x00, 0x03, 0xdd, 0xb6, 0x59, 0x26,
47d59bb994Sjsing 0x46, 0xe6, 0x79, 0x77, 0xf4, 0xec, 0x42, 0x76,
48d59bb994Sjsing 0xc8, 0x73, 0xad, 0x9c,
49d59bb994Sjsing };
50d59bb994Sjsing
51d59bb994Sjsing static unsigned char sslv2_client_hello_tls12[] = {
52d59bb994Sjsing 0x80, 0xcb, 0x01, 0x03, 0x03, 0x00, 0xa2, 0x00,
53d59bb994Sjsing 0x00, 0x00, 0x20, 0x00, 0x00, 0xa5, 0x00, 0x00,
54d59bb994Sjsing 0xa3, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x9f, 0x00,
55d59bb994Sjsing 0x00, 0x6b, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x69,
56d59bb994Sjsing 0x00, 0x00, 0x68, 0x00, 0x00, 0x39, 0x00, 0x00,
57d59bb994Sjsing 0x38, 0x00, 0x00, 0x37, 0x00, 0x00, 0x36, 0x00,
58d59bb994Sjsing 0x00, 0x88, 0x00, 0x00, 0x87, 0x00, 0x00, 0x86,
59d59bb994Sjsing 0x00, 0x00, 0x85, 0x00, 0x00, 0x9d, 0x00, 0x00,
60d59bb994Sjsing 0x3d, 0x00, 0x00, 0x35, 0x00, 0x00, 0x84, 0x00,
61d59bb994Sjsing 0x00, 0xa4, 0x00, 0x00, 0xa2, 0x00, 0x00, 0xa0,
62d59bb994Sjsing 0x00, 0x00, 0x9e, 0x00, 0x00, 0x67, 0x00, 0x00,
63d59bb994Sjsing 0x40, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3e, 0x00,
64d59bb994Sjsing 0x00, 0x33, 0x00, 0x00, 0x32, 0x00, 0x00, 0x31,
65d59bb994Sjsing 0x00, 0x00, 0x30, 0x00, 0x00, 0x9a, 0x00, 0x00,
66d59bb994Sjsing 0x99, 0x00, 0x00, 0x98, 0x00, 0x00, 0x97, 0x00,
67d59bb994Sjsing 0x00, 0x45, 0x00, 0x00, 0x44, 0x00, 0x00, 0x43,
68d59bb994Sjsing 0x00, 0x00, 0x42, 0x00, 0x00, 0x9c, 0x00, 0x00,
69d59bb994Sjsing 0x3c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x96, 0x00,
70d59bb994Sjsing 0x00, 0x41, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05,
71d59bb994Sjsing 0x00, 0x00, 0x04, 0x00, 0x00, 0x16, 0x00, 0x00,
72d59bb994Sjsing 0x13, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0d, 0x00,
73d59bb994Sjsing 0x00, 0x0a, 0x00, 0x00, 0xff, 0x1d, 0xfd, 0x90,
74d59bb994Sjsing 0x03, 0x61, 0x3c, 0x5a, 0x22, 0x83, 0xed, 0x11,
75d59bb994Sjsing 0x85, 0xf4, 0xea, 0x36, 0x59, 0xd9, 0x1b, 0x27,
76d59bb994Sjsing 0x22, 0x01, 0x14, 0x07, 0x66, 0xb2, 0x24, 0xf5,
77d59bb994Sjsing 0x4e, 0x7d, 0x9d, 0x9c, 0x52,
78d59bb994Sjsing };
79d59bb994Sjsing
80d59bb994Sjsing struct server_hello_test {
81d59bb994Sjsing const unsigned char *desc;
82d59bb994Sjsing unsigned char *client_hello;
83d59bb994Sjsing const size_t client_hello_len;
84d59bb994Sjsing const SSL_METHOD *(*ssl_method)(void);
854d444bd0Sjsing const long ssl_clear_options;
864d444bd0Sjsing const long ssl_set_options;
870b5493cbStb int accept_fails;
88d59bb994Sjsing };
89d59bb994Sjsing
90d59bb994Sjsing static struct server_hello_test server_hello_tests[] = {
91d59bb994Sjsing {
92d59bb994Sjsing .desc = "TLSv1.0 in SSLv2 record",
93d59bb994Sjsing .client_hello = sslv2_client_hello_tls10,
94d59bb994Sjsing .client_hello_len = sizeof(sslv2_client_hello_tls10),
95df17eac1Sjsing .ssl_method = tls_legacy_method,
964d444bd0Sjsing .ssl_clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
974d444bd0Sjsing .ssl_set_options = 0,
980b5493cbStb .accept_fails = 1,
99d59bb994Sjsing },
100d59bb994Sjsing {
101d59bb994Sjsing .desc = "TLSv1.2 in SSLv2 record",
102d59bb994Sjsing .client_hello = sslv2_client_hello_tls12,
103d59bb994Sjsing .client_hello_len = sizeof(sslv2_client_hello_tls12),
104df17eac1Sjsing .ssl_method = tls_legacy_method,
1054d444bd0Sjsing .ssl_clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
1064d444bd0Sjsing .ssl_set_options = 0,
1070b5493cbStb .accept_fails = 1,
108d59bb994Sjsing },
109d59bb994Sjsing };
110d59bb994Sjsing
111d59bb994Sjsing #define N_SERVER_HELLO_TESTS \
112d59bb994Sjsing (sizeof(server_hello_tests) / sizeof(*server_hello_tests))
113d59bb994Sjsing
114d59bb994Sjsing static int
server_hello_test(int testno,struct server_hello_test * sht)115d59bb994Sjsing server_hello_test(int testno, struct server_hello_test *sht)
116d59bb994Sjsing {
117d59bb994Sjsing BIO *rbio = NULL, *wbio = NULL;
118d59bb994Sjsing SSL_CTX *ssl_ctx = NULL;
119d59bb994Sjsing SSL *ssl = NULL;
120d59bb994Sjsing int ret = 1;
121d59bb994Sjsing
122c0a6a244Stb fprintf(stderr, "Test %d - %s\n", testno, sht->desc);
123d59bb994Sjsing
124d59bb994Sjsing if ((rbio = BIO_new_mem_buf(sht->client_hello,
125d59bb994Sjsing sht->client_hello_len)) == NULL) {
126d59bb994Sjsing fprintf(stderr, "Failed to setup rbio\n");
127d59bb994Sjsing goto failure;
128d59bb994Sjsing }
129d59bb994Sjsing if ((wbio = BIO_new(BIO_s_mem())) == NULL) {
130d59bb994Sjsing fprintf(stderr, "Failed to setup wbio\n");
131d59bb994Sjsing goto failure;
132d59bb994Sjsing }
133d59bb994Sjsing
134d59bb994Sjsing if ((ssl_ctx = SSL_CTX_new(sht->ssl_method())) == NULL) {
135d59bb994Sjsing fprintf(stderr, "SSL_CTX_new() returned NULL\n");
136d59bb994Sjsing goto failure;
137d59bb994Sjsing }
138d59bb994Sjsing
139d59bb994Sjsing if (SSL_CTX_use_certificate_file(ssl_ctx, server_cert_file,
140d59bb994Sjsing SSL_FILETYPE_PEM) != 1) {
141d59bb994Sjsing fprintf(stderr, "Failed to load server certificate");
142d59bb994Sjsing goto failure;
143d59bb994Sjsing }
144d59bb994Sjsing if (SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key_file,
145d59bb994Sjsing SSL_FILETYPE_PEM) != 1) {
146d59bb994Sjsing fprintf(stderr, "Failed to load server private key");
147d59bb994Sjsing goto failure;
148d59bb994Sjsing }
149d59bb994Sjsing
150d59bb994Sjsing SSL_CTX_set_dh_auto(ssl_ctx, 1);
151d59bb994Sjsing SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
1524d444bd0Sjsing
1534d444bd0Sjsing SSL_CTX_clear_options(ssl_ctx, sht->ssl_clear_options);
1544d444bd0Sjsing SSL_CTX_set_options(ssl_ctx, sht->ssl_set_options);
155d59bb994Sjsing
156d59bb994Sjsing if ((ssl = SSL_new(ssl_ctx)) == NULL) {
157d59bb994Sjsing fprintf(stderr, "SSL_new() returned NULL\n");
158d59bb994Sjsing goto failure;
159d59bb994Sjsing }
160d59bb994Sjsing
161ef70a379Stb BIO_up_ref(rbio);
162ef70a379Stb BIO_up_ref(wbio);
163d59bb994Sjsing SSL_set_bio(ssl, rbio, wbio);
164d59bb994Sjsing
165d59bb994Sjsing if (SSL_accept(ssl) != 0) {
1660b5493cbStb if (sht->accept_fails)
167*5c10583eStb goto done;
168d59bb994Sjsing fprintf(stderr, "SSL_accept() returned non-zero\n");
169d59bb994Sjsing ERR_print_errors_fp(stderr);
170d59bb994Sjsing goto failure;
171d59bb994Sjsing }
172d59bb994Sjsing
173*5c10583eStb done:
174d59bb994Sjsing ret = 0;
175d59bb994Sjsing
176d59bb994Sjsing failure:
177d59bb994Sjsing SSL_CTX_free(ssl_ctx);
178d59bb994Sjsing SSL_free(ssl);
179d59bb994Sjsing
180d59bb994Sjsing BIO_free(rbio);
181d59bb994Sjsing BIO_free(wbio);
182d59bb994Sjsing
183d59bb994Sjsing return (ret);
184d59bb994Sjsing }
185d59bb994Sjsing
186d59bb994Sjsing int
main(int argc,char ** argv)187d59bb994Sjsing main(int argc, char **argv)
188d59bb994Sjsing {
189d59bb994Sjsing int failed = 0;
190d59bb994Sjsing size_t i;
191d59bb994Sjsing
192d59bb994Sjsing if (argc != 4) {
193d59bb994Sjsing fprintf(stderr, "usage: %s keyfile certfile cafile\n",
194d59bb994Sjsing argv[0]);
195d59bb994Sjsing exit(1);
196d59bb994Sjsing }
197d59bb994Sjsing
198d59bb994Sjsing server_key_file = argv[1];
199d59bb994Sjsing server_cert_file = argv[2];
200d59bb994Sjsing server_ca_file = argv[3];
201d59bb994Sjsing
202d59bb994Sjsing SSL_library_init();
203d59bb994Sjsing SSL_load_error_strings();
204d59bb994Sjsing
205d59bb994Sjsing for (i = 0; i < N_SERVER_HELLO_TESTS; i++)
206d59bb994Sjsing failed |= server_hello_test(i, &server_hello_tests[i]);
207d59bb994Sjsing
208d59bb994Sjsing return (failed);
209d59bb994Sjsing }
210