1 /* $OpenBSD: tls_ext_alpn.c,v 1.3 2017/01/22 08:19:36 jsing Exp $ */ 2 /* 3 * Copyright (c) 2015 Doug Hogan <doug@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * Test TLS extension Application-Layer Protocol Negotiation (RFC 7301). 20 */ 21 #include <stdio.h> 22 #include <openssl/ssl.h> 23 24 #include "ssl_locl.h" 25 26 #include "tests.h" 27 28 /* 29 * In the ProtocolNameList, ProtocolNames must not include empty strings and 30 * byte strings must not be truncated. 31 * 32 * This uses some of the IANA approved protocol names from: 33 * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml 34 */ 35 36 /* Valid for client and server since it only has one name. */ 37 static uint8_t proto_single[] = { 38 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 39 0x00, 0x0f, /* len */ 40 /* ExtensionType extension_type */ 41 0x00, 0x10, /* ALPN */ 42 /* opaque extension_data<0..2^16-1> */ 43 0x00, 0x0b, /* len */ 44 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 45 0x00, 0x09, /* len of all names */ 46 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 47 0x08, /* len */ 48 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 49 }; 50 51 /* Valid for client, but NOT server. Server must have exactly one name. */ 52 static uint8_t proto_multiple1[] = { 53 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 54 0x00, 0x19, /* len */ 55 /* ExtensionType extension_type */ 56 0x00, 0x10, /* ALPN */ 57 /* opaque extension_data<0..2^16-1> */ 58 0x00, 0x15, /* len */ 59 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 60 0x00, 0x13, /* len of all names */ 61 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 62 0x08, /* len */ 63 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 64 /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ 65 0x09, /* len */ 66 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e 67 }; 68 69 /* Valid for client, but NOT server. Server must have exactly one name. */ 70 static uint8_t proto_multiple2[] = { 71 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 72 0x00, 0x1c, /* len */ 73 /* ExtensionType extension_type */ 74 0x00, 0x10, /* ALPN */ 75 /* opaque extension_data<0..2^16-1> */ 76 0x00, 0x18, /* len */ 77 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 78 0x00, 0x16, /* len of all names */ 79 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 80 0x08, /* len */ 81 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 82 /* opaque ProtocolName<1..2^8-1> -- 'h2' */ 83 0x02, /* len */ 84 0x68, 0x32, 85 /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ 86 0x09, /* len */ 87 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e 88 }; 89 90 /* Valid for client, but NOT server. Server must have exactly one name. */ 91 static uint8_t proto_multiple3[] = { 92 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 93 0x00, 0x20, /* len */ 94 /* ExtensionType extension_type */ 95 0x00, 0x10, /* ALPN */ 96 /* opaque extension_data<0..2^16-1> */ 97 0x00, 0x1c, /* len */ 98 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 99 0x00, 0x1a, /* len of all names */ 100 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 101 0x08, /* len */ 102 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 103 /* opaque ProtocolName<1..2^8-1> -- 'h2' */ 104 0x02, /* len */ 105 0x68, 0x32, 106 /* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */ 107 0x09, /* len */ 108 0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e, 109 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 110 0x03, /* len */ 111 0x68, 0x32, 0x63 112 }; 113 114 static uint8_t proto_empty[] = { 115 /* Extension extensions<0..2^16-1> -- All TLS extensions. */ 116 0x00, 0x00, /* none present. */ 117 }; 118 119 /* Invalid for both client and server. Length is wrong. */ 120 static uint8_t proto_invalid_len1[] = { 121 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 122 0x00, 0x0a, /* len */ 123 /* ExtensionType extension_type */ 124 0x00, 0x10, /* ALPN */ 125 /* opaque extension_data<0..2^16-1> */ 126 0x00, 0x06, /* len */ 127 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 128 0x00, 0x04, /* len of all names */ 129 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 130 0x04, /* XXX len too large */ 131 0x68, 0x32, 0x63 132 }; 133 static uint8_t proto_invalid_len2[] = { 134 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 135 0x00, 0x0a, /* len */ 136 /* ExtensionType extension_type */ 137 0x00, 0x10, /* ALPN */ 138 /* opaque extension_data<0..2^16-1> */ 139 0x00, 0x06, /* len */ 140 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 141 0x00, 0x04, /* len of all names */ 142 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 143 0x02, /* XXX len too small */ 144 0x68, 0x32, 0x63 145 }; 146 static uint8_t proto_invalid_len3[] = { 147 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 148 0x00, 0x0a, /* len */ 149 /* ExtensionType extension_type */ 150 0x00, 0x10, /* ALPN */ 151 /* opaque extension_data<0..2^16-1> */ 152 0x00, 0x06, /* len */ 153 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 154 0x00, 0x03, /* XXX len too small */ 155 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 156 0x03, /* len */ 157 0x68, 0x32, 0x63 158 }; 159 static uint8_t proto_invalid_len4[] = { 160 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 161 0x00, 0x0a, /* len */ 162 /* ExtensionType extension_type */ 163 0x00, 0x10, /* ALPN */ 164 /* opaque extension_data<0..2^16-1> */ 165 0x00, 0x06, /* len */ 166 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 167 0x00, 0x06, /* XXX len too large */ 168 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 169 0x03, /* len */ 170 0x68, 0x32, 0x63 171 }; 172 static uint8_t proto_invalid_len5[] = { 173 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 174 0x00, 0x0a, /* len */ 175 /* ExtensionType extension_type */ 176 0x00, 0x10, /* ALPN */ 177 /* opaque extension_data<0..2^16-1> */ 178 0x01, 0x08, /* XXX len too large */ 179 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 180 0x00, 0x04, /* len */ 181 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 182 0x03, /* len */ 183 0x68, 0x32, 0x63 184 }; 185 static uint8_t proto_invalid_len6[] = { 186 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 187 0x00, 0x0a, /* len */ 188 /* ExtensionType extension_type */ 189 0x00, 0x10, /* ALPN */ 190 /* opaque extension_data<0..2^16-1> */ 191 0x00, 0x05, /* XXX len too small */ 192 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 193 0x00, 0x04, /* len */ 194 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 195 0x03, /* len */ 196 0x68, 0x32, 0x63 197 }; 198 static uint8_t proto_invalid_len7[] = { 199 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 200 0x00, 0x06, /* XXX len too small */ 201 /* ExtensionType extension_type */ 202 0x00, 0x10, /* ALPN */ 203 /* opaque extension_data<0..2^16-1> */ 204 0x00, 0x06, /* len */ 205 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 206 0x00, 0x04, /* len */ 207 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 208 0x03, /* len */ 209 0x68, 0x32, 0x63 210 }; 211 static uint8_t proto_invalid_len8[] = { 212 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 213 0x00, 0x0b, /* XXX len too large */ 214 /* ExtensionType extension_type */ 215 0x00, 0x10, /* ALPN */ 216 /* opaque extension_data<0..2^16-1> */ 217 0x00, 0x06, /* len */ 218 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 219 0x00, 0x04, /* len */ 220 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 221 0x03, /* len */ 222 0x68, 0x32, 0x63 223 }; 224 225 /* Invalid for client and server since it is missing data. */ 226 static uint8_t proto_invalid_missing1[] = { 227 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 228 0x00, 0x0a, /* len */ 229 /* ExtensionType extension_type */ 230 0x00, 0x10, /* ALPN */ 231 /* opaque extension_data<0..2^16-1> */ 232 0x00, 0x06, /* len */ 233 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 234 0x00, 0x04, /* len of all names */ 235 /* opaque ProtocolName<1..2^8-1> -- 'h2c' */ 236 /* XXX missing */ 237 }; 238 static uint8_t proto_invalid_missing2[] = { 239 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 240 0x00, 0x0a, /* len */ 241 /* ExtensionType extension_type */ 242 0x00, 0x10, /* ALPN */ 243 /* opaque extension_data<0..2^16-1> */ 244 0x00, 0x00, /* XXX missing name list */ 245 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 246 }; 247 static uint8_t proto_invalid_missing3[] = { 248 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 249 0x00, 0x0a, /* len */ 250 /* ExtensionType extension_type */ 251 0x00, 0x10, /* ALPN */ 252 /* opaque extension_data<0..2^16-1> */ 253 0x00, 0x02, /* XXX size is sufficient but missing data for name list */ 254 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 255 }; 256 static uint8_t proto_invalid_missing4[] = { 257 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 258 0x00, 0x0a, /* len */ 259 /* ExtensionType extension_type */ 260 0x00, 0x10, /* ALPN */ 261 /* opaque extension_data<0..2^16-1> */ 262 /* XXX missing */ 263 }; 264 static uint8_t proto_invalid_missing5[] = { 265 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 266 0x00, 0x1c, /* len */ 267 /* ExtensionType extension_type */ 268 0x00, 0x10, /* ALPN */ 269 /* opaque extension_data<0..2^16-1> */ 270 0x00, 0x18, /* len */ 271 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 272 0x00, 0x16, /* len of all names */ 273 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 274 0x08, /* len */ 275 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 276 /* opaque ProtocolName<1..2^8-1> -- 'h2' */ 277 0x02, /* len */ 278 0x68, 0x32, 279 /* XXX missing name */ 280 }; 281 static uint8_t proto_invalid_missing6[] = { 282 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 283 0x00, 0x07, /* len */ 284 /* ExtensionType extension_type */ 285 0x00, 0x10, /* ALPN */ 286 /* opaque extension_data<0..2^16-1> */ 287 0x00, 0x03, /* len */ 288 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 289 0x00, 0x01, /* XXX len must be at least 2 */ 290 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 291 0x00, /* XXX len cannot be 0 */ 292 }; 293 static uint8_t proto_invalid_missing7[] = { 294 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 295 0x00, 0x07, /* len */ 296 /* ExtensionType extension_type */ 297 0x00, 0x10, /* ALPN */ 298 /* opaque extension_data<0..2^16-1> */ 299 0x00, 0x03, /* len */ 300 /* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */ 301 0x00, 0x02, /* XXX len is at least 2 but not correct. */ 302 /* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */ 303 0x00, /* XXX len cannot be 0 */ 304 }; 305 static uint8_t proto_invalid_missing8[] = { 306 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 307 0x00, 0x01, /* len */ 308 /* ExtensionType extension_type */ 309 0x00, /* XXX need a 2 byte type */ 310 }; 311 static uint8_t proto_invalid_missing9[] = { 312 /* Extension extensions<0..2^16-1> -- All TLS extensions */ 313 0x0a, /* XXX need a 2 byte len */ 314 }; 315 316 317 #define CHECK_BOTH(c_val,s_val,proto) do { \ 318 { \ 319 unsigned char *p = proto; \ 320 int al; \ 321 CHECK(c_val == ssl_parse_clienthello_tlsext(s, &p, \ 322 proto, sizeof(proto), &al)); \ 323 p = proto; \ 324 CHECK(s_val == ssl_parse_serverhello_tlsext(s, &p, \ 325 sizeof(proto), &al)); \ 326 } \ 327 } while (0) 328 329 static int dummy_alpn_cb(SSL *ssl, const unsigned char **out, 330 unsigned char *outlen, const unsigned char *in, unsigned int inlen, 331 void *arg); 332 333 static int 334 check_valid_alpn(SSL *s) 335 { 336 const uint8_t str[] = { 337 0x08, /* len */ 338 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */ 339 }; 340 341 /* Setup in order to test ALPN. */ 342 CHECK(! SSL_set_alpn_protos(s, str, 9)); 343 SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL); 344 345 /* Prerequisites to test these. */ 346 CHECK(s->internal->alpn_client_proto_list != NULL); 347 CHECK(s->ctx->internal->alpn_select_cb != NULL); 348 //CHECK(s->s3->tmp.finish_md_len == 0); 349 350 CHECK_BOTH(1, 1, proto_single); 351 CHECK_BOTH(1, 1, proto_empty); 352 353 /* Multiple protocol names are only valid for client */ 354 CHECK_BOTH(1, 0, proto_multiple1); 355 CHECK_BOTH(1, 0, proto_multiple2); 356 CHECK_BOTH(1, 0, proto_multiple3); 357 358 return 1; 359 } 360 361 /* 362 * Some of the IANA approved IDs from: 363 * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml 364 */ 365 static int 366 check_invalid_alpn(SSL *s) 367 { 368 const uint8_t str[] = { 369 0x08, /* len */ 370 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */ 371 }; 372 373 /* Setup in order to test ALPN. */ 374 CHECK(! SSL_set_alpn_protos(s, str, 9)); 375 SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL); 376 377 /* Prerequisites to test these. */ 378 CHECK(s->internal->alpn_client_proto_list != NULL); 379 CHECK(s->ctx->internal->alpn_select_cb != NULL); 380 //CHECK(s->s3->tmp.finish_md_len == 0); 381 382 /* None of these are valid for client or server */ 383 CHECK_BOTH(0, 0, proto_invalid_len1); 384 CHECK_BOTH(0, 0, proto_invalid_len2); 385 CHECK_BOTH(0, 0, proto_invalid_len3); 386 CHECK_BOTH(0, 0, proto_invalid_len4); 387 CHECK_BOTH(0, 0, proto_invalid_len5); 388 CHECK_BOTH(0, 0, proto_invalid_len6); 389 CHECK_BOTH(0, 0, proto_invalid_len7); 390 CHECK_BOTH(0, 0, proto_invalid_len8); 391 CHECK_BOTH(0, 0, proto_invalid_missing1); 392 CHECK_BOTH(0, 0, proto_invalid_missing2); 393 CHECK_BOTH(0, 0, proto_invalid_missing3); 394 CHECK_BOTH(0, 0, proto_invalid_missing4); 395 CHECK_BOTH(0, 0, proto_invalid_missing5); 396 CHECK_BOTH(0, 0, proto_invalid_missing6); 397 CHECK_BOTH(0, 0, proto_invalid_missing7); 398 CHECK_BOTH(0, 0, proto_invalid_missing8); 399 CHECK_BOTH(0, 0, proto_invalid_missing9); 400 401 return 1; 402 } 403 404 int 405 dummy_alpn_cb(SSL *ssl __attribute__((unused)), const unsigned char **out, 406 unsigned char *outlen, const unsigned char *in, unsigned int inlen, 407 void *arg __attribute__((unused))) 408 { 409 *out = in; 410 *outlen = (unsigned char)inlen; 411 412 return 0; 413 } 414 415 int 416 main(void) 417 { 418 SSL_CTX *ctx = NULL; 419 SSL *s = NULL; 420 int rv = 1; 421 422 SSL_library_init(); 423 424 CHECK_GOTO((ctx = SSL_CTX_new(TLSv1_2_client_method())) != NULL); 425 CHECK_GOTO((s = SSL_new(ctx)) != NULL); 426 427 if (!check_valid_alpn(s)) 428 goto err; 429 if (!check_invalid_alpn(s)) 430 goto err; 431 432 rv = 0; 433 434 err: 435 SSL_CTX_free(ctx); 436 SSL_free(s); 437 438 if (!rv) 439 printf("PASS %s\n", __FILE__); 440 return rv; 441 } 442