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 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 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 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