diff options
author | jsing <> | 2017-07-16 18:18:10 +0000 |
---|---|---|
committer | jsing <> | 2017-07-16 18:18:10 +0000 |
commit | 55ac24937341a4586566a62b1aae36d4693693b6 (patch) | |
tree | 2f904c0e86d2dc66e5bfdd1515d9af26ea0c9cb3 | |
parent | 231770c97badca4c3da92986469ccbd7bf13471d (diff) | |
download | openbsd-55ac24937341a4586566a62b1aae36d4693693b6.tar.gz openbsd-55ac24937341a4586566a62b1aae36d4693693b6.tar.bz2 openbsd-55ac24937341a4586566a62b1aae36d4693693b6.zip |
Provide a new regress test for TLS extension handlers, currently covering
the newly converted SNI code.
-rw-r--r-- | src/regress/lib/libssl/Makefile | 3 | ||||
-rw-r--r-- | src/regress/lib/libssl/tlsext/Makefile | 9 | ||||
-rw-r--r-- | src/regress/lib/libssl/tlsext/tlsexttest.c | 245 |
3 files changed, 256 insertions, 1 deletions
diff --git a/src/regress/lib/libssl/Makefile b/src/regress/lib/libssl/Makefile index d6ee2f160a..0cc3e156a3 100644 --- a/src/regress/lib/libssl/Makefile +++ b/src/regress/lib/libssl/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.25 2017/03/05 14:15:53 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.26 2017/07/16 18:18:10 jsing Exp $ |
2 | 2 | ||
3 | SUBDIR= \ | 3 | SUBDIR= \ |
4 | asn1 \ | 4 | asn1 \ |
@@ -8,6 +8,7 @@ SUBDIR= \ | |||
8 | pqueue \ | 8 | pqueue \ |
9 | server \ | 9 | server \ |
10 | ssl \ | 10 | ssl \ |
11 | tlsext \ | ||
11 | unit | 12 | unit |
12 | 13 | ||
13 | install: | 14 | install: |
diff --git a/src/regress/lib/libssl/tlsext/Makefile b/src/regress/lib/libssl/tlsext/Makefile new file mode 100644 index 0000000000..48b5bc1e25 --- /dev/null +++ b/src/regress/lib/libssl/tlsext/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2017/07/16 18:18:10 jsing Exp $ | ||
2 | |||
3 | PROG= tlsexttest | ||
4 | LDADD= ${SSL_INT} -lcrypto | ||
5 | DPADD= ${LIBCRYPTO} ${LIBSSL} | ||
6 | WARNINGS= Yes | ||
7 | CFLAGS+= -DLIBRESSL_INTERNAL -Wundef -Werror -I$(BSDSRCDIR)/lib/libssl | ||
8 | |||
9 | .include <bsd.regress.mk> | ||
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c new file mode 100644 index 0000000000..557c3ca409 --- /dev/null +++ b/src/regress/lib/libssl/tlsext/tlsexttest.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* $OpenBSD: tlsexttest.c,v 1.1 2017/07/16 18:18:10 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2017 Joel Sing <jsing@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 | #include <err.h> | ||
19 | |||
20 | #include "ssl_locl.h" | ||
21 | |||
22 | #include "bytestring.h" | ||
23 | #include "ssl_tlsext.h" | ||
24 | |||
25 | static void | ||
26 | hexdump(const unsigned char *buf, size_t len) | ||
27 | { | ||
28 | size_t i; | ||
29 | |||
30 | for (i = 1; i <= len; i++) | ||
31 | fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); | ||
32 | |||
33 | fprintf(stderr, "\n"); | ||
34 | } | ||
35 | |||
36 | #define TEST_SNI_SERVERNAME "www.libressl.org" | ||
37 | |||
38 | static unsigned char tlsext_sni_clienthello[] = { | ||
39 | 0x00, 0x13, 0x00, 0x00, 0x10, 0x77, 0x77, 0x77, | ||
40 | 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x73, 0x73, | ||
41 | 0x6c, 0x2e, 0x6f, 0x72, 0x67, | ||
42 | }; | ||
43 | |||
44 | static unsigned char tlsext_sni_serverhello[] = { | ||
45 | }; | ||
46 | |||
47 | static int | ||
48 | test_tlsext_sni_clienthello(void) | ||
49 | { | ||
50 | unsigned char *data = NULL; | ||
51 | SSL_CTX *ssl_ctx = NULL; | ||
52 | SSL *ssl = NULL; | ||
53 | int failure = 0; | ||
54 | size_t dlen; | ||
55 | int alert; | ||
56 | CBB cbb; | ||
57 | CBS cbs; | ||
58 | |||
59 | CBB_init(&cbb, 0); | ||
60 | |||
61 | if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) | ||
62 | errx(1, "failed to create SSL_CTX"); | ||
63 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
64 | errx(1, "failed to create SSL"); | ||
65 | |||
66 | if (tlsext_sni_clienthello_needs(ssl)) { | ||
67 | fprintf(stderr, "FAIL: clienthello should not need SNI\n"); | ||
68 | failure = 1; | ||
69 | goto done; | ||
70 | } | ||
71 | |||
72 | if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { | ||
73 | fprintf(stderr, "FAIL: client failed to set server name\n"); | ||
74 | failure = 1; | ||
75 | goto done; | ||
76 | } | ||
77 | |||
78 | if (!tlsext_sni_clienthello_needs(ssl)) { | ||
79 | fprintf(stderr, "FAIL: clienthello should need SNI\n"); | ||
80 | failure = 1; | ||
81 | goto done; | ||
82 | } | ||
83 | |||
84 | if (!tlsext_sni_clienthello_build(ssl, &cbb)) { | ||
85 | fprintf(stderr, "FAIL: clienthello failed to build SNI\n"); | ||
86 | failure = 1; | ||
87 | goto done; | ||
88 | } | ||
89 | |||
90 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
91 | errx(1, "failed to finish CBB"); | ||
92 | |||
93 | if (dlen != sizeof(tlsext_sni_clienthello)) { | ||
94 | fprintf(stderr, "FAIL: got clienthello SNI with length %zu, " | ||
95 | "want length %zu\n", dlen, sizeof(tlsext_sni_clienthello)); | ||
96 | failure = 1; | ||
97 | goto done; | ||
98 | } | ||
99 | |||
100 | if (memcmp(data, tlsext_sni_clienthello, dlen) != 0) { | ||
101 | fprintf(stderr, "FAIL: clienthello SNI differs:\n"); | ||
102 | fprintf(stderr, "received:\n"); | ||
103 | hexdump(data, dlen); | ||
104 | fprintf(stderr, "test data:\n"); | ||
105 | hexdump(tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); | ||
106 | failure = 1; | ||
107 | goto done; | ||
108 | } | ||
109 | |||
110 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
111 | errx(1, "failed to create session"); | ||
112 | |||
113 | ssl->internal->hit = 0; | ||
114 | |||
115 | CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); | ||
116 | if (!tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) { | ||
117 | fprintf(stderr, "FAIL: failed to parse clienthello SNI\n"); | ||
118 | failure = 1; | ||
119 | goto done; | ||
120 | } | ||
121 | |||
122 | if (ssl->session->tlsext_hostname == NULL) { | ||
123 | fprintf(stderr, "FAIL: no tlsext_hostname from clienthello SNI\n"); | ||
124 | failure = 1; | ||
125 | goto done; | ||
126 | } | ||
127 | |||
128 | if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || | ||
129 | strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, | ||
130 | strlen(TEST_SNI_SERVERNAME)) != 0) { | ||
131 | fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n", | ||
132 | ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); | ||
133 | failure = 1; | ||
134 | goto done; | ||
135 | } | ||
136 | |||
137 | done: | ||
138 | CBB_cleanup(&cbb); | ||
139 | SSL_CTX_free(ssl_ctx); | ||
140 | SSL_free(ssl); | ||
141 | free(data); | ||
142 | |||
143 | return (failure); | ||
144 | } | ||
145 | |||
146 | static int | ||
147 | test_tlsext_sni_serverhello(void) | ||
148 | { | ||
149 | unsigned char *data = NULL; | ||
150 | SSL_CTX *ssl_ctx = NULL; | ||
151 | SSL *ssl = NULL; | ||
152 | int failure = 0; | ||
153 | size_t dlen; | ||
154 | int alert; | ||
155 | CBB cbb; | ||
156 | CBS cbs; | ||
157 | |||
158 | CBB_init(&cbb, 0); | ||
159 | |||
160 | if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) | ||
161 | errx(1, "failed to create SSL_CTX"); | ||
162 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
163 | errx(1, "failed to create SSL"); | ||
164 | |||
165 | if ((ssl->session = SSL_SESSION_new()) == NULL) | ||
166 | errx(1, "failed to create session"); | ||
167 | |||
168 | if (tlsext_sni_serverhello_needs(ssl)) { | ||
169 | fprintf(stderr, "FAIL: serverhello should not need SNI\n"); | ||
170 | failure = 1; | ||
171 | goto done; | ||
172 | } | ||
173 | |||
174 | if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { | ||
175 | fprintf(stderr, "FAIL: client failed to set server name\n"); | ||
176 | failure = 1; | ||
177 | goto done; | ||
178 | } | ||
179 | |||
180 | if ((ssl->session->tlsext_hostname = strdup(TEST_SNI_SERVERNAME)) == | ||
181 | NULL) | ||
182 | errx(1, "failed to strdup tlsext_hostname"); | ||
183 | |||
184 | if (!tlsext_sni_serverhello_needs(ssl)) { | ||
185 | fprintf(stderr, "FAIL: serverhello should need SNI\n"); | ||
186 | failure = 1; | ||
187 | goto done; | ||
188 | } | ||
189 | |||
190 | if (!tlsext_sni_serverhello_build(ssl, &cbb)) { | ||
191 | fprintf(stderr, "FAIL: serverhello failed to build SNI\n"); | ||
192 | failure = 1; | ||
193 | goto done; | ||
194 | } | ||
195 | |||
196 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
197 | errx(1, "failed to finish CBB"); | ||
198 | |||
199 | if (dlen != sizeof(tlsext_sni_serverhello)) { | ||
200 | fprintf(stderr, "FAIL: got serverhello SNI with length %zu, " | ||
201 | "want length %zu\n", dlen, sizeof(tlsext_sni_serverhello)); | ||
202 | failure = 1; | ||
203 | goto done; | ||
204 | } | ||
205 | |||
206 | if (memcmp(data, tlsext_sni_serverhello, dlen) != 0) { | ||
207 | fprintf(stderr, "FAIL: serverhello SNI differs:\n"); | ||
208 | fprintf(stderr, "received:\n"); | ||
209 | hexdump(data, dlen); | ||
210 | fprintf(stderr, "test data:\n"); | ||
211 | hexdump(tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); | ||
212 | failure = 1; | ||
213 | goto done; | ||
214 | } | ||
215 | |||
216 | CBS_init(&cbs, tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); | ||
217 | if (!tlsext_sni_serverhello_parse(ssl, &cbs, &alert)) { | ||
218 | fprintf(stderr, "FAIL: failed to parse serverhello SNI\n"); | ||
219 | failure = 1; | ||
220 | goto done; | ||
221 | } | ||
222 | |||
223 | /* XXX - test parse with session with mismatched name. */ | ||
224 | |||
225 | done: | ||
226 | CBB_cleanup(&cbb); | ||
227 | SSL_CTX_free(ssl_ctx); | ||
228 | SSL_free(ssl); | ||
229 | free(data); | ||
230 | |||
231 | return (failure); | ||
232 | } | ||
233 | |||
234 | int | ||
235 | main(int argc, char **argv) | ||
236 | { | ||
237 | int failed = 0; | ||
238 | |||
239 | SSL_library_init(); | ||
240 | |||
241 | failed |= test_tlsext_sni_clienthello(); | ||
242 | failed |= test_tlsext_sni_serverhello(); | ||
243 | |||
244 | return (failed); | ||
245 | } | ||