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