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