xref: /openbsd-src/regress/lib/libssl/unit/tls_ext_alpn.c (revision c9675a23de50ec5aa20be3956f170f2eccffb293)
1*c9675a23Stb /*	$OpenBSD: tls_ext_alpn.c,v 1.9 2022/11/26 16:08:57 tb Exp $	*/
27239aaccSdoug /*
37239aaccSdoug  * Copyright (c) 2015 Doug Hogan <doug@openbsd.org>
47239aaccSdoug  *
57239aaccSdoug  * Permission to use, copy, modify, and distribute this software for any
67239aaccSdoug  * purpose with or without fee is hereby granted, provided that the above
77239aaccSdoug  * copyright notice and this permission notice appear in all copies.
87239aaccSdoug  *
97239aaccSdoug  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
107239aaccSdoug  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
117239aaccSdoug  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
127239aaccSdoug  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
137239aaccSdoug  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
147239aaccSdoug  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
157239aaccSdoug  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
167239aaccSdoug  */
177239aaccSdoug 
187239aaccSdoug /*
197239aaccSdoug  * Test TLS extension Application-Layer Protocol Negotiation (RFC 7301).
207239aaccSdoug  */
217239aaccSdoug #include <stdio.h>
227239aaccSdoug #include <openssl/ssl.h>
237239aaccSdoug 
24*c9675a23Stb #include "ssl_local.h"
25ca479b1dSjsing #include "ssl_tlsext.h"
267239aaccSdoug 
2731dc53efSjsing #include "tests.h"
287239aaccSdoug 
297239aaccSdoug /*
307239aaccSdoug  * In the ProtocolNameList, ProtocolNames must not include empty strings and
317239aaccSdoug  * byte strings must not be truncated.
327239aaccSdoug  *
337239aaccSdoug  * This uses some of the IANA approved protocol names from:
347239aaccSdoug  * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
357239aaccSdoug  */
367239aaccSdoug 
377239aaccSdoug /* Valid for client and server since it only has one name. */
387239aaccSdoug static uint8_t proto_single[] = {
397239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
407239aaccSdoug 	0x00, 0x0f, /* len */
417239aaccSdoug 	/* ExtensionType extension_type */
427239aaccSdoug 	0x00, 0x10, /* ALPN */
437239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
447239aaccSdoug 	0x00, 0x0b, /* len */
457239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
467239aaccSdoug 	0x00, 0x09, /* len of all names */
477239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
487239aaccSdoug 	0x08, /* len */
497239aaccSdoug 	0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31
507239aaccSdoug };
517239aaccSdoug 
527239aaccSdoug /* Valid for client, but NOT server.  Server must have exactly one name. */
537239aaccSdoug static uint8_t proto_multiple1[] = {
547239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
557239aaccSdoug 	0x00, 0x19, /* len */
567239aaccSdoug 	/* ExtensionType extension_type */
577239aaccSdoug 	0x00, 0x10, /* ALPN */
587239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
597239aaccSdoug 	0x00, 0x15, /* len */
607239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
617239aaccSdoug 	0x00, 0x13, /* len of all names */
627239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
637239aaccSdoug 	0x08, /* len */
647239aaccSdoug 	0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
657239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */
667239aaccSdoug 	0x09, /* len */
677239aaccSdoug 	0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e
687239aaccSdoug };
697239aaccSdoug 
707239aaccSdoug /* Valid for client, but NOT server.  Server must have exactly one name. */
717239aaccSdoug static uint8_t proto_multiple2[] = {
727239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
737239aaccSdoug 	0x00, 0x1c, /* len */
747239aaccSdoug 	/* ExtensionType extension_type */
757239aaccSdoug 	0x00, 0x10, /* ALPN */
767239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
777239aaccSdoug 	0x00, 0x18, /* len */
787239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
797239aaccSdoug 	0x00, 0x16, /* len of all names */
807239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
817239aaccSdoug 	0x08, /* len */
827239aaccSdoug 	0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
837239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2' */
847239aaccSdoug 	0x02, /* len */
857239aaccSdoug 	0x68, 0x32,
867239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */
877239aaccSdoug 	0x09, /* len */
887239aaccSdoug 	0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e
897239aaccSdoug };
907239aaccSdoug 
917239aaccSdoug /* Valid for client, but NOT server.  Server must have exactly one name. */
927239aaccSdoug static uint8_t proto_multiple3[] = {
937239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
947239aaccSdoug 	0x00, 0x20, /* len */
957239aaccSdoug 	/* ExtensionType extension_type */
967239aaccSdoug 	0x00, 0x10, /* ALPN */
977239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
987239aaccSdoug 	0x00, 0x1c, /* len */
997239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1007239aaccSdoug 	0x00, 0x1a, /* len of all names */
1017239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
1027239aaccSdoug 	0x08, /* len */
1037239aaccSdoug 	0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
1047239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2' */
1057239aaccSdoug 	0x02, /* len */
1067239aaccSdoug 	0x68, 0x32,
1077239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'stun.nat' */
1087239aaccSdoug 	0x09, /* len */
1097239aaccSdoug 	0x73, 0x74, 0x75, 0x6e, 0x2e, 0x74, 0x75, 0x72, 0x6e,
1107239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1117239aaccSdoug 	0x03, /* len */
1127239aaccSdoug 	0x68, 0x32, 0x63
1137239aaccSdoug };
1147239aaccSdoug 
1157239aaccSdoug static uint8_t proto_empty[] = {
1167239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions. */
1177239aaccSdoug 	0x00, 0x00, /* none present. */
1187239aaccSdoug };
1197239aaccSdoug 
1207239aaccSdoug /* Invalid for both client and server.  Length is wrong. */
1217239aaccSdoug static uint8_t proto_invalid_len1[] = {
1227239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1237239aaccSdoug 	0x00, 0x0a, /* len */
1247239aaccSdoug 	/* ExtensionType extension_type */
1257239aaccSdoug 	0x00, 0x10, /* ALPN */
1267239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1277239aaccSdoug 	0x00, 0x06, /* len */
1287239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1297239aaccSdoug 	0x00, 0x04, /* len of all names */
1307239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1317239aaccSdoug 	0x04, /* XXX len too large */
1327239aaccSdoug 	0x68, 0x32, 0x63
1337239aaccSdoug };
1347239aaccSdoug static uint8_t proto_invalid_len2[] = {
1357239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1367239aaccSdoug 	0x00, 0x0a, /* len */
1377239aaccSdoug 	/* ExtensionType extension_type */
1387239aaccSdoug 	0x00, 0x10, /* ALPN */
1397239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1407239aaccSdoug 	0x00, 0x06, /* len */
1417239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1427239aaccSdoug 	0x00, 0x04, /* len of all names */
1437239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1447239aaccSdoug 	0x02, /* XXX len too small */
1457239aaccSdoug 	0x68, 0x32, 0x63
1467239aaccSdoug };
1477239aaccSdoug static uint8_t proto_invalid_len3[] = {
1487239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1497239aaccSdoug 	0x00, 0x0a, /* len */
1507239aaccSdoug 	/* ExtensionType extension_type */
1517239aaccSdoug 	0x00, 0x10, /* ALPN */
1527239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1537239aaccSdoug 	0x00, 0x06, /* len */
1547239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1557239aaccSdoug 	0x00, 0x03, /* XXX len too small */
1567239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1577239aaccSdoug 	0x03, /* len */
1587239aaccSdoug 	0x68, 0x32, 0x63
1597239aaccSdoug };
1607239aaccSdoug static uint8_t proto_invalid_len4[] = {
1617239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1627239aaccSdoug 	0x00, 0x0a, /* len */
1637239aaccSdoug 	/* ExtensionType extension_type */
1647239aaccSdoug 	0x00, 0x10, /* ALPN */
1657239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1667239aaccSdoug 	0x00, 0x06, /* len */
1677239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1687239aaccSdoug 	0x00, 0x06, /* XXX len too large */
1697239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1707239aaccSdoug 	0x03, /* len */
1717239aaccSdoug 	0x68, 0x32, 0x63
1727239aaccSdoug };
1737239aaccSdoug static uint8_t proto_invalid_len5[] = {
1747239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1757239aaccSdoug 	0x00, 0x0a, /* len */
1767239aaccSdoug 	/* ExtensionType extension_type */
1777239aaccSdoug 	0x00, 0x10, /* ALPN */
1787239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1797239aaccSdoug 	0x01, 0x08, /* XXX len too large */
1807239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1817239aaccSdoug 	0x00, 0x04, /* len */
1827239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1837239aaccSdoug 	0x03, /* len */
1847239aaccSdoug 	0x68, 0x32, 0x63
1857239aaccSdoug };
1867239aaccSdoug static uint8_t proto_invalid_len6[] = {
1877239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
1887239aaccSdoug 	0x00, 0x0a, /* len */
1897239aaccSdoug 	/* ExtensionType extension_type */
1907239aaccSdoug 	0x00, 0x10, /* ALPN */
1917239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
1927239aaccSdoug 	0x00, 0x05, /* XXX len too small */
1937239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
1947239aaccSdoug 	0x00, 0x04, /* len */
1957239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
1967239aaccSdoug 	0x03, /* len */
1977239aaccSdoug 	0x68, 0x32, 0x63
1987239aaccSdoug };
1997239aaccSdoug static uint8_t proto_invalid_len7[] = {
2007239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2017239aaccSdoug 	0x00, 0x06, /* XXX len too small */
2027239aaccSdoug 	/* ExtensionType extension_type */
2037239aaccSdoug 	0x00, 0x10, /* ALPN */
2047239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2057239aaccSdoug 	0x00, 0x06, /* len */
2067239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2077239aaccSdoug 	0x00, 0x04, /* len */
2087239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
2097239aaccSdoug 	0x03, /* len */
2107239aaccSdoug 	0x68, 0x32, 0x63
2117239aaccSdoug };
2127239aaccSdoug static uint8_t proto_invalid_len8[] = {
2137239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2147239aaccSdoug 	0x00, 0x0b, /* XXX len too large */
2157239aaccSdoug 	/* ExtensionType extension_type */
2167239aaccSdoug 	0x00, 0x10, /* ALPN */
2177239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2187239aaccSdoug 	0x00, 0x06, /* len */
2197239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2207239aaccSdoug 	0x00, 0x04, /* len */
2217239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
2227239aaccSdoug 	0x03, /* len */
2237239aaccSdoug 	0x68, 0x32, 0x63
2247239aaccSdoug };
2257239aaccSdoug 
2267239aaccSdoug /* Invalid for client and server since it is missing data. */
2277239aaccSdoug static uint8_t proto_invalid_missing1[] = {
2287239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2297239aaccSdoug 	0x00, 0x0a, /* len */
2307239aaccSdoug 	/* ExtensionType extension_type */
2317239aaccSdoug 	0x00, 0x10, /* ALPN */
2327239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2337239aaccSdoug 	0x00, 0x06, /* len */
2347239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2357239aaccSdoug 	0x00, 0x04, /* len of all names */
2367239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2c' */
2377239aaccSdoug 	/* XXX missing */
2387239aaccSdoug };
2397239aaccSdoug static uint8_t proto_invalid_missing2[] = {
2407239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2417239aaccSdoug 	0x00, 0x0a, /* len */
2427239aaccSdoug 	/* ExtensionType extension_type */
2437239aaccSdoug 	0x00, 0x10, /* ALPN */
2447239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2457239aaccSdoug 	0x00, 0x00, /* XXX missing name list */
2467239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2477239aaccSdoug };
2487239aaccSdoug static uint8_t proto_invalid_missing3[] = {
2497239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2507239aaccSdoug 	0x00, 0x0a, /* len */
2517239aaccSdoug 	/* ExtensionType extension_type */
2527239aaccSdoug 	0x00, 0x10, /* ALPN */
2537239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2547239aaccSdoug 	0x00, 0x02, /* XXX size is sufficient but missing data for name list */
2557239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2567239aaccSdoug };
2577239aaccSdoug static uint8_t proto_invalid_missing4[] = {
2587239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2597239aaccSdoug 	0x00, 0x0a, /* len */
2607239aaccSdoug 	/* ExtensionType extension_type */
2617239aaccSdoug 	0x00, 0x10, /* ALPN */
2627239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2637239aaccSdoug 	/* XXX missing */
2647239aaccSdoug };
2657239aaccSdoug static uint8_t proto_invalid_missing5[] = {
2667239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2677239aaccSdoug 	0x00, 0x1c, /* len */
2687239aaccSdoug 	/* ExtensionType extension_type */
2697239aaccSdoug 	0x00, 0x10, /* ALPN */
2707239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2717239aaccSdoug 	0x00, 0x18, /* len */
2727239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2737239aaccSdoug 	0x00, 0x16, /* len of all names */
2747239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
2757239aaccSdoug 	0x08, /* len */
2767239aaccSdoug 	0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
2777239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'h2' */
2787239aaccSdoug 	0x02, /* len */
2797239aaccSdoug 	0x68, 0x32,
2807239aaccSdoug 	/* XXX missing name */
2817239aaccSdoug };
2827239aaccSdoug static uint8_t proto_invalid_missing6[] = {
2837239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2847239aaccSdoug 	0x00, 0x07, /* len */
2857239aaccSdoug 	/* ExtensionType extension_type */
2867239aaccSdoug 	0x00, 0x10, /* ALPN */
2877239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
2887239aaccSdoug 	0x00, 0x03, /* len */
2897239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
2907239aaccSdoug 	0x00, 0x01, /* XXX len must be at least 2 */
2917239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
2927239aaccSdoug 	0x00, /* XXX len cannot be 0 */
2937239aaccSdoug };
2947239aaccSdoug static uint8_t proto_invalid_missing7[] = {
2957239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
2967239aaccSdoug 	0x00, 0x07, /* len */
2977239aaccSdoug 	/* ExtensionType extension_type */
2987239aaccSdoug 	0x00, 0x10, /* ALPN */
2997239aaccSdoug 	/* opaque extension_data<0..2^16-1> */
3007239aaccSdoug 	0x00, 0x03, /* len */
3017239aaccSdoug 	/* ProtocolName protocol_name_list<2..2^16-1> -- ALPN names */
3027239aaccSdoug 	0x00, 0x02, /* XXX len is at least 2 but not correct. */
3037239aaccSdoug 	/* opaque ProtocolName<1..2^8-1> -- 'http/1.1' */
3047239aaccSdoug 	0x00, /* XXX len cannot be 0 */
3057239aaccSdoug };
3067239aaccSdoug static uint8_t proto_invalid_missing8[] = {
3077239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
3087239aaccSdoug 	0x00, 0x01, /* len */
3097239aaccSdoug 	/* ExtensionType extension_type */
3107239aaccSdoug 	0x00, /* XXX need a 2 byte type */
3117239aaccSdoug };
3127239aaccSdoug static uint8_t proto_invalid_missing9[] = {
3137239aaccSdoug 	/* Extension extensions<0..2^16-1> -- All TLS extensions */
3147239aaccSdoug 	0x0a, /* XXX need a 2 byte len */
3157239aaccSdoug };
3167239aaccSdoug 
3177239aaccSdoug 
3187239aaccSdoug #define CHECK_BOTH(c_val, s_val, proto) do {				\
3197239aaccSdoug 	{								\
320ca479b1dSjsing 		CBS cbs;						\
3217239aaccSdoug 		int al;							\
322ca479b1dSjsing 									\
323ca479b1dSjsing 		CBS_init(&cbs, proto, sizeof(proto));			\
324f4c23e70Stb 		CHECK(c_val == tlsext_server_parse(s, SSL_TLSEXT_MSG_CH, &cbs, &al)); \
325d8dcd3a5Sjsing 		CBS_init(&cbs, proto, sizeof(proto));			\
326f4c23e70Stb 		CHECK(s_val == tlsext_client_parse(s, SSL_TLSEXT_MSG_SH, &cbs, &al)); \
3277239aaccSdoug 	}								\
3287239aaccSdoug } while (0)
3297239aaccSdoug 
3307239aaccSdoug static int dummy_alpn_cb(SSL *ssl, const unsigned char **out,
3317239aaccSdoug     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
3327239aaccSdoug     void *arg);
3337239aaccSdoug 
3347239aaccSdoug static int
check_valid_alpn(SSL * s)3357239aaccSdoug check_valid_alpn(SSL *s)
3367239aaccSdoug {
3377239aaccSdoug 	const uint8_t str[] = {
3387239aaccSdoug 		0x08, /* len */
3397239aaccSdoug 		0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */
3407239aaccSdoug 	};
3417239aaccSdoug 
3427239aaccSdoug 	/* Setup in order to test ALPN. */
3437239aaccSdoug 	CHECK(! SSL_set_alpn_protos(s, str, 9));
3447239aaccSdoug 	SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL);
3457239aaccSdoug 
3467239aaccSdoug 	/* Prerequisites to test these. */
3471ce7ecd4Sjsing 	CHECK(s->alpn_client_proto_list != NULL);
3481ce7ecd4Sjsing 	CHECK(s->ctx->alpn_select_cb != NULL);
34931dc53efSjsing 	//CHECK(s->s3->tmp.finish_md_len == 0);
3507239aaccSdoug 
3517239aaccSdoug 	CHECK_BOTH(1, 1, proto_single);
3527239aaccSdoug 	CHECK_BOTH(1, 1, proto_empty);
3537239aaccSdoug 
3547239aaccSdoug 	/* Multiple protocol names are only valid for client */
3557239aaccSdoug 	CHECK_BOTH(1, 0, proto_multiple1);
3567239aaccSdoug 	CHECK_BOTH(1, 0, proto_multiple2);
3577239aaccSdoug 	CHECK_BOTH(1, 0, proto_multiple3);
3587239aaccSdoug 
3597239aaccSdoug 	return 1;
3607239aaccSdoug }
3617239aaccSdoug 
3627239aaccSdoug /*
3637239aaccSdoug  * Some of the IANA approved IDs from:
3647239aaccSdoug  * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
3657239aaccSdoug  */
3667239aaccSdoug static int
check_invalid_alpn(SSL * s)3677239aaccSdoug check_invalid_alpn(SSL *s)
3687239aaccSdoug {
3697239aaccSdoug 	const uint8_t str[] = {
3707239aaccSdoug 		0x08, /* len */
3717239aaccSdoug 		0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 /* http/1.1 */
3727239aaccSdoug 	};
3737239aaccSdoug 
3747239aaccSdoug 	/* Setup in order to test ALPN. */
3757239aaccSdoug 	CHECK(! SSL_set_alpn_protos(s, str, 9));
3767239aaccSdoug 	SSL_CTX_set_alpn_select_cb(s->ctx, dummy_alpn_cb, NULL);
3777239aaccSdoug 
3787239aaccSdoug 	/* Prerequisites to test these. */
3791ce7ecd4Sjsing 	CHECK(s->alpn_client_proto_list != NULL);
3801ce7ecd4Sjsing 	CHECK(s->ctx->alpn_select_cb != NULL);
38131dc53efSjsing 	//CHECK(s->s3->tmp.finish_md_len == 0);
3827239aaccSdoug 
3837239aaccSdoug 	/* None of these are valid for client or server */
3847239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len1);
3857239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len2);
3867239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len3);
3877239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len4);
3887239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len5);
3897239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len6);
3907239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len7);
3917239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_len8);
3927239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing1);
3937239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing2);
3947239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing3);
3957239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing4);
3967239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing5);
3977239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing6);
3987239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing7);
3997239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing8);
4007239aaccSdoug 	CHECK_BOTH(0, 0, proto_invalid_missing9);
4017239aaccSdoug 
4027239aaccSdoug 	return 1;
4037239aaccSdoug }
4047239aaccSdoug 
4057239aaccSdoug int
dummy_alpn_cb(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)4067239aaccSdoug dummy_alpn_cb(SSL *ssl __attribute__((unused)), const unsigned char **out,
4077239aaccSdoug     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
4087239aaccSdoug     void *arg __attribute__((unused)))
4097239aaccSdoug {
4107239aaccSdoug 	*out = in;
4117239aaccSdoug 	*outlen = (unsigned char)inlen;
4127239aaccSdoug 
4137239aaccSdoug 	return 0;
4147239aaccSdoug }
4157239aaccSdoug 
4167239aaccSdoug int
main(void)4177239aaccSdoug main(void)
4187239aaccSdoug {
4197239aaccSdoug 	SSL_CTX *ctx = NULL;
4207239aaccSdoug 	SSL *s = NULL;
4217239aaccSdoug 	int rv = 1;
4227239aaccSdoug 
4237239aaccSdoug 	SSL_library_init();
4247239aaccSdoug 
4257239aaccSdoug 	CHECK_GOTO((ctx = SSL_CTX_new(TLSv1_2_client_method())) != NULL);
4267239aaccSdoug 	CHECK_GOTO((s = SSL_new(ctx)) != NULL);
4277239aaccSdoug 
4287239aaccSdoug 	if (!check_valid_alpn(s))
4297239aaccSdoug 		goto err;
4307239aaccSdoug 	if (!check_invalid_alpn(s))
4317239aaccSdoug 		goto err;
4327239aaccSdoug 
4337239aaccSdoug 	rv = 0;
4347239aaccSdoug 
4357239aaccSdoug err:
4367239aaccSdoug 	SSL_CTX_free(ctx);
4377239aaccSdoug 	SSL_free(s);
4387239aaccSdoug 
4397239aaccSdoug 	if (!rv)
4407239aaccSdoug 		printf("PASS %s\n", __FILE__);
4417239aaccSdoug 	return rv;
4427239aaccSdoug }
443