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