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