1 /* $OpenBSD: clienttest.c,v 1.28 2021/02/08 17:21:50 jsing Exp $ */ 2 /* 3 * Copyright (c) 2015 Joel Sing <jsing@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 <openssl/ssl.h> 19 20 #include <openssl/dtls1.h> 21 #include <openssl/ssl3.h> 22 23 #include <err.h> 24 #include <stdio.h> 25 #include <string.h> 26 27 #define DTLS_HM_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH) 28 #define DTLS_RANDOM_OFFSET (DTLS_HM_OFFSET + 2) 29 #define DTLS_CIPHER_OFFSET (DTLS_HM_OFFSET + 38) 30 31 #define SSL3_HM_OFFSET (SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH) 32 #define SSL3_RANDOM_OFFSET (SSL3_HM_OFFSET + 2) 33 #define SSL3_CIPHER_OFFSET (SSL3_HM_OFFSET + 37) 34 35 static unsigned char cipher_list_dtls1[] = { 36 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 37 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 38 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 39 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 40 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, 41 }; 42 43 static unsigned char client_hello_dtls1[] = { 44 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 45 0x00, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 46 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x68, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0xc0, 52 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 53 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 54 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 55 0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00, 56 0x16, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, 57 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 58 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 59 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x23, 0x00, 60 0x00, 61 }; 62 63 static unsigned char cipher_list_tls10[] = { 64 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 65 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 66 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 67 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 68 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 69 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, 70 }; 71 72 static unsigned char client_hello_tls10[] = { 73 0x16, 0x03, 0x01, 0x00, 0x73, 0x01, 0x00, 0x00, 74 0x6f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xc0, 0x14, 79 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88, 80 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13, 81 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f, 82 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 83 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 84 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, 0x18, 85 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 86 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 87 0x00, 0x18, 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, 88 }; 89 90 static unsigned char cipher_list_tls11[] = { 91 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 92 0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 93 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 94 0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 95 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 96 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, 97 }; 98 99 static unsigned char client_hello_tls11[] = { 100 0x16, 0x03, 0x01, 0x00, 0x73, 0x01, 0x00, 0x00, 101 0x6f, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xc0, 0x14, 106 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88, 107 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13, 108 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f, 109 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 110 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 111 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, 0x18, 112 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 113 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 114 0x00, 0x18, 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, 115 }; 116 117 static unsigned char cipher_list_tls12_aes[] = { 118 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 119 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 120 0x00, 0x39, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 121 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 122 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 123 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 124 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 125 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 126 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 127 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 128 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 129 0x00, 0x0a, 0x00, 0xff, 130 }; 131 132 static unsigned char cipher_list_tls12_chacha[] = { 133 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, 134 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 135 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, 136 0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 137 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 138 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 139 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 140 0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 141 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 142 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 143 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 144 0x00, 0x0a, 0x00, 0xff, 145 }; 146 147 static unsigned char client_hello_tls12[] = { 148 0x16, 0x03, 0x01, 0x00, 0xbd, 0x01, 0x00, 0x00, 149 0xb9, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0xc0, 0x30, 154 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 155 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, 156 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xff, 0x85, 157 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, 158 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 159 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 160 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, 161 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, 162 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, 163 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0x00, 0x04, 164 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 165 0x00, 0xff, 0x01, 0x00, 0x00, 0x34, 0x00, 0x0b, 166 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 167 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 168 0x00, 0x19, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 169 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 170 0x06, 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 171 0x08, 0x04, 0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 172 0x02, 0x03, 173 }; 174 175 struct client_hello_test { 176 const unsigned char *desc; 177 const int protocol; 178 const size_t random_start; 179 const SSL_METHOD *(*ssl_method)(void); 180 const long ssl_options; 181 }; 182 183 static struct client_hello_test client_hello_tests[] = { 184 { 185 .desc = "DTLSv1 client", 186 .protocol = DTLS1_VERSION, 187 .random_start = DTLS_RANDOM_OFFSET, 188 .ssl_method = DTLSv1_client_method, 189 }, 190 { 191 .desc = "TLSv1 client", 192 .protocol = TLS1_VERSION, 193 .random_start = SSL3_RANDOM_OFFSET, 194 .ssl_method = TLSv1_client_method, 195 }, 196 { 197 .desc = "TLSv1_1 client", 198 .protocol = TLS1_1_VERSION, 199 .random_start = SSL3_RANDOM_OFFSET, 200 .ssl_method = TLSv1_1_client_method, 201 }, 202 { 203 .desc = "TLSv1_2 client", 204 .protocol = TLS1_2_VERSION, 205 .random_start = SSL3_RANDOM_OFFSET, 206 .ssl_method = TLSv1_2_client_method, 207 }, 208 #if 0 209 { 210 .desc = "SSLv23 default", 211 .protocol = TLS1_3_VERSION, 212 .random_start = SSL3_RANDOM_OFFSET, 213 .ssl_method = SSLv23_client_method, 214 .ssl_options = 0, 215 }, 216 #endif 217 { 218 .desc = "SSLv23 default (no TLSv1.3)", 219 .protocol = TLS1_2_VERSION, 220 .random_start = SSL3_RANDOM_OFFSET, 221 .ssl_method = SSLv23_client_method, 222 .ssl_options = SSL_OP_NO_TLSv1_3, 223 }, 224 { 225 .desc = "SSLv23 (no TLSv1.2)", 226 .protocol = TLS1_1_VERSION, 227 .random_start = SSL3_RANDOM_OFFSET, 228 .ssl_method = SSLv23_client_method, 229 .ssl_options = SSL_OP_NO_TLSv1_2, 230 }, 231 { 232 .desc = "SSLv23 (no TLSv1.1)", 233 .protocol = TLS1_VERSION, 234 .random_start = SSL3_RANDOM_OFFSET, 235 .ssl_method = SSLv23_client_method, 236 .ssl_options = SSL_OP_NO_TLSv1_1, 237 }, 238 #if 0 239 { 240 .desc = "TLS default", 241 .protocol = TLS1_3_VERSION, 242 .random_start = SSL3_RANDOM_OFFSET, 243 .ssl_method = TLS_client_method, 244 .ssl_options = 0, 245 }, 246 #endif 247 { 248 .desc = "TLS (no TLSv1.3)", 249 .protocol = TLS1_2_VERSION, 250 .random_start = SSL3_RANDOM_OFFSET, 251 .ssl_method = TLS_client_method, 252 .ssl_options = SSL_OP_NO_TLSv1_3, 253 }, 254 { 255 .desc = "TLS (no TLSv1.2)", 256 .protocol = TLS1_1_VERSION, 257 .random_start = SSL3_RANDOM_OFFSET, 258 .ssl_method = TLS_client_method, 259 .ssl_options = SSL_OP_NO_TLSv1_2, 260 }, 261 { 262 .desc = "TLS (no TLSv1.1)", 263 .protocol = TLS1_VERSION, 264 .random_start = SSL3_RANDOM_OFFSET, 265 .ssl_method = TLS_client_method, 266 .ssl_options = SSL_OP_NO_TLSv1_1, 267 }, 268 #if 0 269 { 270 .desc = "TLS (no TLSv1.0, no TLSv1.1)", 271 .protocol = TLS1_3_VERSION, 272 .random_start = SSL3_RANDOM_OFFSET, 273 .ssl_method = TLS_client_method, 274 .ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, 275 }, 276 #endif 277 #if 0 278 { 279 .desc = "TLS (no TLSv1.0, no TLSv1.1, no TLSv1.2)", 280 .protocol = TLS1_3_VERSION, 281 .random_start = SSL3_RANDOM_OFFSET, 282 .ssl_method = TLS_client_method, 283 .ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2, 284 }, 285 #endif 286 }; 287 288 #define N_CLIENT_HELLO_TESTS \ 289 (sizeof(client_hello_tests) / sizeof(*client_hello_tests)) 290 291 static void 292 hexdump(const unsigned char *buf, size_t len) 293 { 294 size_t i; 295 296 for (i = 1; i <= len; i++) 297 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 && i != len ? "" : "\n"); 298 299 fprintf(stderr, "\n"); 300 } 301 302 static inline int 303 ssl_aes_is_accelerated(void) 304 { 305 #if defined(__i386__) || defined(__x86_64__) 306 return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); 307 #else 308 return (0); 309 #endif 310 } 311 312 static int 313 make_client_hello(int protocol, char **out, size_t *outlen) 314 { 315 size_t client_hello_len, cipher_list_len, cipher_list_offset; 316 const char *client_hello, *cipher_list; 317 char *p; 318 319 *out = NULL; 320 *outlen = 0; 321 322 switch (protocol) { 323 case DTLS1_VERSION: 324 client_hello = client_hello_dtls1; 325 client_hello_len = sizeof(client_hello_dtls1); 326 cipher_list = cipher_list_dtls1; 327 cipher_list_len = sizeof(cipher_list_dtls1); 328 cipher_list_offset = DTLS_CIPHER_OFFSET; 329 break; 330 331 case TLS1_VERSION: 332 client_hello = client_hello_tls10; 333 client_hello_len = sizeof(client_hello_tls10); 334 cipher_list = cipher_list_tls10; 335 cipher_list_len = sizeof(cipher_list_tls10); 336 cipher_list_offset = SSL3_CIPHER_OFFSET; 337 break; 338 339 case TLS1_1_VERSION: 340 client_hello = client_hello_tls11; 341 client_hello_len = sizeof(client_hello_tls11); 342 cipher_list = cipher_list_tls11; 343 cipher_list_len = sizeof(cipher_list_tls11); 344 cipher_list_offset = SSL3_CIPHER_OFFSET; 345 break; 346 347 case TLS1_2_VERSION: 348 client_hello = client_hello_tls12; 349 client_hello_len = sizeof(client_hello_tls12); 350 if (ssl_aes_is_accelerated()) 351 cipher_list = cipher_list_tls12_aes; 352 else 353 cipher_list = cipher_list_tls12_chacha; 354 cipher_list_len = sizeof(cipher_list_tls12_chacha); 355 cipher_list_offset = SSL3_CIPHER_OFFSET; 356 break; 357 358 default: 359 return (-1); 360 } 361 362 if ((p = malloc(client_hello_len)) == NULL) 363 return (-1); 364 365 memcpy(p, client_hello, client_hello_len); 366 memcpy(p + cipher_list_offset, cipher_list, cipher_list_len); 367 368 *out = p; 369 *outlen = client_hello_len; 370 371 return (0); 372 } 373 374 static int 375 client_hello_test(int testno, struct client_hello_test *cht) 376 { 377 BIO *rbio = NULL, *wbio = NULL; 378 SSL_CTX *ssl_ctx = NULL; 379 SSL *ssl = NULL; 380 char *client_hello = NULL; 381 size_t client_hello_len; 382 char *wbuf, rbuf[1]; 383 int ret = 1; 384 long len; 385 386 fprintf(stderr, "Test %i - %s\n", testno, cht->desc); 387 388 /* Providing a small buf causes *_get_server_hello() to return. */ 389 if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) { 390 fprintf(stderr, "Failed to setup rbio\n"); 391 goto failure; 392 } 393 if ((wbio = BIO_new(BIO_s_mem())) == NULL) { 394 fprintf(stderr, "Failed to setup wbio\n"); 395 goto failure; 396 } 397 398 if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) { 399 fprintf(stderr, "SSL_CTX_new() returned NULL\n"); 400 goto failure; 401 } 402 403 SSL_CTX_set_options(ssl_ctx, cht->ssl_options); 404 405 if ((ssl = SSL_new(ssl_ctx)) == NULL) { 406 fprintf(stderr, "SSL_new() returned NULL\n"); 407 goto failure; 408 } 409 410 rbio->references = 2; 411 wbio->references = 2; 412 413 SSL_set_bio(ssl, rbio, wbio); 414 415 if (SSL_connect(ssl) != 0) { 416 fprintf(stderr, "SSL_connect() returned non-zero\n"); 417 goto failure; 418 } 419 420 len = BIO_get_mem_data(wbio, &wbuf); 421 422 if (make_client_hello(cht->protocol, &client_hello, 423 &client_hello_len) != 0) 424 errx(1, "failed to make client hello"); 425 426 if ((size_t)len != client_hello_len) { 427 fprintf(stderr, "FAIL: test returned ClientHello length %li, " 428 "want %zu\n", len, client_hello_len); 429 fprintf(stderr, "received:\n"); 430 hexdump(wbuf, len); 431 fprintf(stderr, "test data:\n"); 432 hexdump(client_hello, client_hello_len); 433 fprintf(stderr, "\n"); 434 goto failure; 435 } 436 437 /* We expect the client random to differ. */ 438 if (memcmp(&client_hello[cht->random_start], &wbuf[cht->random_start], 439 SSL3_RANDOM_SIZE) == 0) { 440 fprintf(stderr, "FAIL: ClientHello has zeroed random\n"); 441 goto failure; 442 } 443 444 memset(&wbuf[cht->random_start], 0, SSL3_RANDOM_SIZE); 445 446 if (memcmp(client_hello, wbuf, client_hello_len) != 0) { 447 fprintf(stderr, "FAIL: ClientHello differs:\n"); 448 fprintf(stderr, "received:\n"); 449 hexdump(wbuf, len); 450 fprintf(stderr, "test data:\n"); 451 hexdump(client_hello, client_hello_len); 452 fprintf(stderr, "\n"); 453 goto failure; 454 } 455 456 ret = 0; 457 458 failure: 459 SSL_CTX_free(ssl_ctx); 460 SSL_free(ssl); 461 462 if (rbio != NULL) 463 rbio->references = 1; 464 if (wbio != NULL) 465 wbio->references = 1; 466 467 BIO_free(rbio); 468 BIO_free(wbio); 469 470 free(client_hello); 471 472 return (ret); 473 } 474 475 int 476 main(int argc, char **argv) 477 { 478 int failed = 0; 479 size_t i; 480 481 SSL_library_init(); 482 483 for (i = 0; i < N_CLIENT_HELLO_TESTS; i++) 484 failed |= client_hello_test(i, &client_hello_tests[i]); 485 486 return (failed); 487 } 488