1 /*	$OpenBSD: ssl_methods.c,v 1.4 2021/04/04 20:21:43 tb Exp $ */
2 /*
3  * Copyright (c) 2020 Theo Buehler <tb@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 <stdio.h>
19 
20 #include <openssl/ssl.h>
21 
22 struct ssl_method_test_data {
23 	const SSL_METHOD *(*method)(void);
24 	const char *name;
25 	int server;
26 	int dtls;
27 };
28 
29 struct ssl_method_test_data ssl_method_tests[] = {
30 	{
31 		.method = SSLv23_method,
32 		.name = "SSLv23_method",
33 		.server = 1,
34 		.dtls = 0,
35 	},
36 	{
37 		.method = SSLv23_server_method,
38 		.name = "SSLv23_server_method",
39 		.server = 1,
40 		.dtls = 0,
41 	},
42 	{
43 		.method = SSLv23_client_method,
44 		.name = "SSLv23_client_method",
45 		.server = 0,
46 		.dtls = 0,
47 	},
48 
49 	{
50 		.method = TLSv1_method,
51 		.name = "TLSv1_method",
52 		.server = 1,
53 		.dtls = 0,
54 	},
55 	{
56 		.method = TLSv1_server_method,
57 		.name = "TLSv1_server_method",
58 		.server = 1,
59 		.dtls = 0,
60 	},
61 	{
62 		.method = TLSv1_client_method,
63 		.name = "TLSv1_client_method",
64 		.server = 0,
65 		.dtls = 0,
66 	},
67 
68 	{
69 		.method = TLSv1_1_method,
70 		.name = "TLSv1_1_method",
71 		.server = 1,
72 		.dtls = 0,
73 	},
74 	{
75 		.method = TLSv1_1_server_method,
76 		.name = "TLSv1_1_server_method",
77 		.server = 1,
78 		.dtls = 0,
79 	},
80 	{
81 		.method = TLSv1_1_client_method,
82 		.name = "TLSv1_1_client_method",
83 		.server = 0,
84 		.dtls = 0,
85 	},
86 
87 	{
88 		.method = TLSv1_2_method,
89 		.name = "TLSv1_2_method",
90 		.server = 1,
91 		.dtls = 0,
92 	},
93 	{
94 		.method = TLSv1_2_server_method,
95 		.name = "TLSv1_2_server_method",
96 		.server = 1,
97 		.dtls = 0,
98 	},
99 	{
100 		.method = TLSv1_2_client_method,
101 		.name = "TLSv1_2_client_method",
102 		.server = 0,
103 		.dtls = 0,
104 	},
105 
106 	{
107 		.method = TLS_method,
108 		.name = "TLS_method",
109 		.server = 1,
110 		.dtls = 0,
111 	},
112 	{
113 		.method = TLS_server_method,
114 		.name = "TLS_server_method",
115 		.server = 1,
116 		.dtls = 0,
117 	},
118 	{
119 		.method = TLS_client_method,
120 		.name = "TLS_client_method",
121 		.server = 0,
122 		.dtls = 0,
123 	},
124 
125 	{
126 		.method = DTLSv1_method,
127 		.name = "DTLSv1_method",
128 		.server = 1,
129 		.dtls = 1,
130 	},
131 	{
132 		.method = DTLSv1_server_method,
133 		.name = "DTLSv1_server_method",
134 		.server = 1,
135 		.dtls = 1,
136 	},
137 	{
138 		.method = DTLSv1_client_method,
139 		.name = "DTLSv1_client_method",
140 		.server = 0,
141 		.dtls = 1,
142 	},
143 
144 	{
145 		.method = DTLSv1_2_method,
146 		.name = "DTLSv1_2_method",
147 		.server = 1,
148 		.dtls = 1,
149 	},
150 	{
151 		.method = DTLSv1_2_server_method,
152 		.name = "DTLSv1_2_server_method",
153 		.server = 1,
154 		.dtls = 1,
155 	},
156 	{
157 		.method = DTLSv1_2_client_method,
158 		.name = "DTLSv1_2_client_method",
159 		.server = 0,
160 		.dtls = 1,
161 	},
162 
163 	{
164 		.method = DTLS_method,
165 		.name = "DTLS_method",
166 		.server = 1,
167 		.dtls = 1,
168 	},
169 	{
170 		.method = DTLS_server_method,
171 		.name = "DTLS_server_method",
172 		.server = 1,
173 		.dtls = 1,
174 	},
175 	{
176 		.method = DTLS_client_method,
177 		.name = "DTLS_client_method",
178 		.server = 0,
179 		.dtls = 1,
180 	},
181 };
182 
183 #define N_METHOD_TESTS (sizeof(ssl_method_tests) / sizeof(ssl_method_tests[0]))
184 
185 int test_client_or_server_method(struct ssl_method_test_data *);
186 int test_dtls_method(struct ssl_method_test_data *);
187 
188 int
test_client_or_server_method(struct ssl_method_test_data * testcase)189 test_client_or_server_method(struct ssl_method_test_data *testcase)
190 {
191 	SSL_CTX *ssl_ctx;
192 	SSL *ssl = NULL;
193 	int failed = 1;
194 
195 	if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) {
196 		fprintf(stderr, "SSL_CTX_new returned NULL\n");
197 		goto err;
198 	}
199 
200 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
201 		fprintf(stderr, "SSL_new returned NULL\n");
202 		goto err;
203 	}
204 
205 	if (SSL_is_server(ssl) != testcase->server) {
206 		fprintf(stderr, "%s: SSL_is_server: want %d, got %d\n",
207 		    testcase->name, testcase->server, SSL_is_server(ssl));
208 		goto err;
209 	}
210 
211 	failed = 0;
212 
213  err:
214 	SSL_free(ssl);
215 	SSL_CTX_free(ssl_ctx);
216 
217 	return failed;
218 }
219 
220 int
test_dtls_method(struct ssl_method_test_data * testcase)221 test_dtls_method(struct ssl_method_test_data *testcase)
222 {
223 	SSL_CTX *ssl_ctx;
224 	SSL *ssl = NULL;
225 	int failed = 1;
226 
227 	if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) {
228 		fprintf(stderr, "SSL_CTX_new returned NULL\n");
229 		goto err;
230 	}
231 
232 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
233 		fprintf(stderr, "SSL_new returned NULL\n");
234 		goto err;
235 	}
236 
237 	if (SSL_is_dtls(ssl) != testcase->dtls) {
238 		fprintf(stderr, "%s: SSL_is_dtls: want %d, got %d\n",
239 		    testcase->name, testcase->dtls, SSL_is_dtls(ssl));
240 		goto err;
241 	}
242 
243 	failed = 0;
244 
245  err:
246 	SSL_free(ssl);
247 	SSL_CTX_free(ssl_ctx);
248 
249 	return failed;
250 }
251 
252 int
main(int argc,char ** argv)253 main(int argc, char **argv)
254 {
255 	size_t i;
256 	int failed = 0;
257 
258 	for (i = 0; i < N_METHOD_TESTS; i++) {
259 		failed |= test_client_or_server_method(&ssl_method_tests[i]);
260 		failed |= test_dtls_method(&ssl_method_tests[i]);
261 	}
262 
263 	if (failed == 0)
264 		printf("PASS %s\n", __FILE__);
265 
266 	return failed;
267 }
268