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, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xcc, 0x14, 156 0xcc, 0x13, 0xcc, 0x15, 0xff, 0x85, 0x00, 0xc4, 157 0x00, 0xc3, 0x00, 0x88, 0x00, 0x87, 0x00, 0x81, 158 0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 159 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 160 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f, 161 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, 162 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, 163 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0x00, 0xbe, 164 0x00, 0xbd, 0x00, 0x45, 0x00, 0x44, 0xc0, 0x31, 165 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, 166 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 167 0x00, 0xba, 0x00, 0x41, 0x00, 0x07, 0xc0, 0x11, 168 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05, 169 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 170 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 171 0x00, 0x15, 0x00, 0x12, 0x00, 0x09, 0x00, 0xff, 172 }; 173 174 static unsigned char cipher_list_tls12_chacha[] = { 175 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xcc, 0x14, 176 0xcc, 0x13, 0xcc, 0x15, 0xc0, 0x30, 0xc0, 0x2c, 177 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, 178 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x6a, 179 0x00, 0x39, 0x00, 0x38, 0xff, 0x85, 0x00, 0xc4, 180 0x00, 0xc3, 0x00, 0x88, 0x00, 0x87, 0x00, 0x81, 181 0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 182 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 183 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f, 184 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, 185 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, 186 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0x00, 0xbe, 187 0x00, 0xbd, 0x00, 0x45, 0x00, 0x44, 0xc0, 0x31, 188 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, 189 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 190 0x00, 0xba, 0x00, 0x41, 0x00, 0x07, 0xc0, 0x11, 191 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05, 192 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 193 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 194 0x00, 0x15, 0x00, 0x12, 0x00, 0x09, 0x00, 0xff, 195 }; 196 197 static unsigned char client_hello_tls12[] = { 198 0x16, 0x03, 0x01, 0x01, 0x41, 0x01, 0x00, 0x01, 199 0x3d, 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, 0xa0, 0xcc, 0xa9, 204 0xcc, 0xa8, 0xcc, 0xaa, 0xcc, 0x14, 0xcc, 0x13, 205 0xcc, 0x15, 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, 206 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0xa3, 207 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x39, 208 0x00, 0x38, 0xff, 0x85, 0x00, 0xc4, 0x00, 0xc3, 209 0x00, 0x88, 0x00, 0x87, 0x00, 0x81, 0xc0, 0x32, 210 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, 211 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 212 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 213 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 214 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, 0x00, 0x40, 215 0x00, 0x33, 0x00, 0x32, 0x00, 0xbe, 0x00, 0xbd, 216 0x00, 0x45, 0x00, 0x44, 0xc0, 0x31, 0xc0, 0x2d, 217 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, 0xc0, 0x04, 218 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 219 0x00, 0x41, 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 220 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 221 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, 222 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0x00, 0x15, 223 0x00, 0x12, 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 224 0x00, 0x74, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 225 0x01, 0x02, 0x00, 0x0a, 0x00, 0x3a, 0x00, 0x38, 226 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x1c, 227 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1b, 0x00, 0x18, 228 0x00, 0x09, 0x00, 0x0a, 0x00, 0x1a, 0x00, 0x16, 229 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 230 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, 231 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 232 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 233 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x26, 234 0x00, 0x24, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 235 0xef, 0xef, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 236 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0xee, 0xee, 237 0xed, 0xed, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 238 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 239 }; 240 241 struct client_hello_test { 242 const unsigned char *desc; 243 const int protocol; 244 const size_t random_start; 245 const SSL_METHOD *(*ssl_method)(void); 246 const long ssl_options; 247 }; 248 249 static struct client_hello_test client_hello_tests[] = { 250 { 251 .desc = "DTLSv1 client", 252 .protocol = DTLS1_VERSION, 253 .random_start = DTLS_RANDOM_OFFSET, 254 .ssl_method = DTLSv1_client_method, 255 }, 256 { 257 .desc = "TLSv1 client", 258 .protocol = TLS1_VERSION, 259 .random_start = SSL3_RANDOM_OFFSET, 260 .ssl_method = TLSv1_client_method, 261 }, 262 { 263 .desc = "TLSv1_1 client", 264 .protocol = TLS1_1_VERSION, 265 .random_start = SSL3_RANDOM_OFFSET, 266 .ssl_method = TLSv1_1_client_method, 267 }, 268 { 269 .desc = "TLSv1_2 client", 270 .protocol = TLS1_2_VERSION, 271 .random_start = SSL3_RANDOM_OFFSET, 272 .ssl_method = TLSv1_2_client_method, 273 }, 274 { 275 .desc = "SSLv23 default", 276 .protocol = TLS1_2_VERSION, 277 .random_start = SSL3_RANDOM_OFFSET, 278 .ssl_method = SSLv23_client_method, 279 .ssl_options = 0, 280 }, 281 { 282 .desc = "SSLv23 (no TLSv1.2)", 283 .protocol = TLS1_1_VERSION, 284 .random_start = SSL3_RANDOM_OFFSET, 285 .ssl_method = SSLv23_client_method, 286 .ssl_options = SSL_OP_NO_TLSv1_2, 287 }, 288 { 289 .desc = "SSLv23 (no TLSv1.1)", 290 .protocol = TLS1_VERSION, 291 .random_start = SSL3_RANDOM_OFFSET, 292 .ssl_method = SSLv23_client_method, 293 .ssl_options = SSL_OP_NO_TLSv1_1, 294 }, 295 { 296 .desc = "TLS default", 297 .protocol = TLS1_2_VERSION, 298 .random_start = SSL3_RANDOM_OFFSET, 299 .ssl_method = TLS_client_method, 300 .ssl_options = 0, 301 }, 302 { 303 .desc = "TLS (no TLSv1.2)", 304 .protocol = TLS1_1_VERSION, 305 .random_start = SSL3_RANDOM_OFFSET, 306 .ssl_method = TLS_client_method, 307 .ssl_options = SSL_OP_NO_TLSv1_2, 308 }, 309 { 310 .desc = "TLS (no TLSv1.1)", 311 .protocol = TLS1_VERSION, 312 .random_start = SSL3_RANDOM_OFFSET, 313 .ssl_method = TLS_client_method, 314 .ssl_options = SSL_OP_NO_TLSv1_1, 315 }, 316 { 317 .desc = "TLS (no TLSv1.0, no TLSv1.1)", 318 .protocol = TLS1_2_VERSION, 319 .random_start = SSL3_RANDOM_OFFSET, 320 .ssl_method = TLS_client_method, 321 .ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1, 322 }, 323 }; 324 325 #define N_CLIENT_HELLO_TESTS \ 326 (sizeof(client_hello_tests) / sizeof(*client_hello_tests)) 327 328 static void 329 hexdump(const unsigned char *buf, size_t len) 330 { 331 size_t i; 332 333 for (i = 1; i <= len; i++) 334 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 335 336 fprintf(stderr, "\n"); 337 } 338 339 static inline int 340 ssl_aes_is_accelerated(void) 341 { 342 #if defined(__i386__) || defined(__x86_64__) 343 return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); 344 #else 345 return (0); 346 #endif 347 } 348 349 static int 350 make_client_hello(int protocol, char **out, size_t *outlen) 351 { 352 size_t client_hello_len, cipher_list_len, cipher_list_offset; 353 const char *client_hello, *cipher_list; 354 char *p; 355 356 *out = NULL; 357 *outlen = 0; 358 359 switch (protocol) { 360 case DTLS1_VERSION: 361 client_hello = client_hello_dtls1; 362 client_hello_len = sizeof(client_hello_dtls1); 363 cipher_list = cipher_list_dtls1; 364 cipher_list_len = sizeof(cipher_list_dtls1); 365 cipher_list_offset = DTLS_CIPHER_OFFSET; 366 break; 367 368 case TLS1_VERSION: 369 client_hello = client_hello_tls10; 370 client_hello_len = sizeof(client_hello_tls10); 371 cipher_list = cipher_list_tls10; 372 cipher_list_len = sizeof(cipher_list_tls10); 373 cipher_list_offset = SSL3_CIPHER_OFFSET; 374 break; 375 376 case TLS1_1_VERSION: 377 client_hello = client_hello_tls11; 378 client_hello_len = sizeof(client_hello_tls11); 379 cipher_list = cipher_list_tls11; 380 cipher_list_len = sizeof(cipher_list_tls11); 381 cipher_list_offset = SSL3_CIPHER_OFFSET; 382 break; 383 384 case TLS1_2_VERSION: 385 client_hello = client_hello_tls12; 386 client_hello_len = sizeof(client_hello_tls12); 387 if (ssl_aes_is_accelerated() == 1) 388 cipher_list = cipher_list_tls12_aes; 389 else 390 cipher_list = cipher_list_tls12_chacha; 391 cipher_list_len = sizeof(cipher_list_tls12_chacha); 392 cipher_list_offset = SSL3_CIPHER_OFFSET; 393 break; 394 395 default: 396 return (-1); 397 } 398 399 if ((p = malloc(client_hello_len)) == NULL) 400 return (-1); 401 402 memcpy(p, client_hello, client_hello_len); 403 memcpy(p + cipher_list_offset, cipher_list, cipher_list_len); 404 405 *out = p; 406 *outlen = client_hello_len; 407 408 return (0); 409 } 410 411 static int 412 client_hello_test(int testno, struct client_hello_test *cht) 413 { 414 BIO *rbio = NULL, *wbio = NULL; 415 SSL_CTX *ssl_ctx = NULL; 416 SSL *ssl = NULL; 417 char *client_hello = NULL; 418 size_t client_hello_len; 419 char *wbuf, rbuf[1]; 420 int ret = 1; 421 size_t i; 422 long len; 423 424 fprintf(stderr, "Test %i - %s\n", testno, cht->desc); 425 426 /* Providing a small buf causes *_get_server_hello() to return. */ 427 if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) { 428 fprintf(stderr, "Failed to setup rbio\n"); 429 goto failure; 430 } 431 if ((wbio = BIO_new(BIO_s_mem())) == NULL) { 432 fprintf(stderr, "Failed to setup wbio\n"); 433 goto failure; 434 } 435 436 if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) { 437 fprintf(stderr, "SSL_CTX_new() returned NULL\n"); 438 goto failure; 439 } 440 441 SSL_CTX_set_options(ssl_ctx, cht->ssl_options); 442 443 if ((ssl = SSL_new(ssl_ctx)) == NULL) { 444 fprintf(stderr, "SSL_new() returned NULL\n"); 445 goto failure; 446 } 447 448 rbio->references = 2; 449 wbio->references = 2; 450 451 SSL_set_bio(ssl, rbio, wbio); 452 453 if (SSL_connect(ssl) != 0) { 454 fprintf(stderr, "SSL_connect() returned non-zero\n"); 455 goto failure; 456 } 457 458 len = BIO_get_mem_data(wbio, &wbuf); 459 460 if (make_client_hello(cht->protocol, &client_hello, 461 &client_hello_len) != 0) 462 goto failure; 463 464 if ((size_t)len != client_hello_len) { 465 fprintf(stderr, "FAIL: test returned ClientHello length %li, " 466 "want %zu\n", len, client_hello_len); 467 fprintf(stderr, "received:\n"); 468 hexdump(wbuf, len); 469 goto failure; 470 } 471 472 /* We expect the client random to differ. */ 473 i = cht->random_start + SSL3_RANDOM_SIZE; 474 if (memcmp(client_hello, wbuf, cht->random_start) != 0 || 475 memcmp(&client_hello[cht->random_start], 476 &wbuf[cht->random_start], SSL3_RANDOM_SIZE) == 0 || 477 memcmp(&client_hello[i], &wbuf[i], len - i) != 0) { 478 fprintf(stderr, "FAIL: ClientHello differs:\n"); 479 fprintf(stderr, "received:\n"); 480 hexdump(wbuf, len); 481 fprintf(stderr, "test data:\n"); 482 hexdump(client_hello, client_hello_len); 483 fprintf(stderr, "\n"); 484 goto failure; 485 } 486 487 ret = 0; 488 489 failure: 490 SSL_CTX_free(ssl_ctx); 491 SSL_free(ssl); 492 493 rbio->references = 1; 494 wbio->references = 1; 495 496 BIO_free(rbio); 497 BIO_free(wbio); 498 499 free(client_hello); 500 501 return (ret); 502 } 503 504 int 505 main(int argc, char **argv) 506 { 507 int failed = 0; 508 size_t i; 509 510 SSL_library_init(); 511 512 for (i = 0; i < N_CLIENT_HELLO_TESTS; i++) 513 failed |= client_hello_test(i, &client_hello_tests[i]); 514 515 return (failed); 516 } 517