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