1 /* $OpenBSD: ssl_methods.c,v 1.2 2020/12/01 08:05:06 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 = DTLS_method, 146 .name = "DTLS_method", 147 .server = 1, 148 .dtls = 1, 149 }, 150 { 151 .method = DTLS_server_method, 152 .name = "DTLS_server_method", 153 .server = 1, 154 .dtls = 1, 155 }, 156 { 157 .method = DTLS_client_method, 158 .name = "DTLS_client_method", 159 .server = 0, 160 .dtls = 1, 161 }, 162 }; 163 164 #define N_METHOD_TESTS (sizeof(ssl_method_tests) / sizeof(ssl_method_tests[0])) 165 166 int test_client_or_server_method(struct ssl_method_test_data *); 167 int test_dtls_method(struct ssl_method_test_data *); 168 169 int 170 test_client_or_server_method(struct ssl_method_test_data *testcase) 171 { 172 SSL_CTX *ssl_ctx; 173 SSL *ssl = NULL; 174 int failed = 1; 175 176 if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) { 177 fprintf(stderr, "SSL_CTX_new returned NULL\n"); 178 goto err; 179 } 180 181 if ((ssl = SSL_new(ssl_ctx)) == NULL) { 182 fprintf(stderr, "SSL_CTX_new returned NULL\n"); 183 goto err; 184 } 185 186 if (SSL_is_server(ssl) != testcase->server) { 187 fprintf(stderr, "%s: SSL_is_server: want %d, got %d\n", 188 testcase->name, testcase->server, SSL_is_server(ssl)); 189 goto err; 190 } 191 192 failed = 0; 193 194 err: 195 SSL_free(ssl); 196 SSL_CTX_free(ssl_ctx); 197 198 return failed; 199 } 200 201 int 202 test_dtls_method(struct ssl_method_test_data *testcase) 203 { 204 SSL_CTX *ssl_ctx; 205 SSL *ssl = NULL; 206 int failed = 1; 207 208 if ((ssl_ctx = SSL_CTX_new(testcase->method())) == NULL) { 209 fprintf(stderr, "SSL_CTX_new returned NULL\n"); 210 goto err; 211 } 212 213 if ((ssl = SSL_new(ssl_ctx)) == NULL) { 214 fprintf(stderr, "SSL_CTX_new returned NULL\n"); 215 goto err; 216 } 217 218 if (SSL_is_dtls(ssl) != testcase->dtls) { 219 fprintf(stderr, "%s: SSL_is_dtls: want %d, got %d\n", 220 testcase->name, testcase->dtls, SSL_is_dtls(ssl)); 221 goto err; 222 } 223 224 failed = 0; 225 226 err: 227 SSL_free(ssl); 228 SSL_CTX_free(ssl_ctx); 229 230 return failed; 231 } 232 233 int 234 main(int argc, char **argv) 235 { 236 size_t i; 237 int failed = 0; 238 239 for (i = 0; i < N_METHOD_TESTS; i++) { 240 failed |= test_client_or_server_method(&ssl_method_tests[i]); 241 failed |= test_dtls_method(&ssl_method_tests[i]); 242 } 243 244 if (failed == 0) 245 printf("PASS %s\n", __FILE__); 246 247 return failed; 248 } 249