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