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