summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2017-07-16 18:18:11 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2017-07-16 18:18:11 +0000
commit45d22d0339e5da3a4254d566d113df8c52f33964 (patch)
treeea6eb91c7fae80ed0bd1bc6cca960bd4872f946b /regress
parent961e337099bc1438a14bc62964633048ca8e3cc0 (diff)
Provide a new regress test for TLS extension handlers, currently covering
the newly converted SNI code.
Diffstat (limited to 'regress')
-rw-r--r--regress/lib/libssl/Makefile3
-rw-r--r--regress/lib/libssl/tlsext/Makefile9
-rw-r--r--regress/lib/libssl/tlsext/tlsexttest.c245
3 files changed, 256 insertions, 1 deletions
diff --git a/regress/lib/libssl/Makefile b/regress/lib/libssl/Makefile
index d6ee2f160a0..0cc3e156a30 100644
--- a/regress/lib/libssl/Makefile
+++ b/regress/lib/libssl/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.25 2017/03/05 14:15:53 jsing Exp $
+# $OpenBSD: Makefile,v 1.26 2017/07/16 18:18:10 jsing Exp $
SUBDIR= \
asn1 \
@@ -8,6 +8,7 @@ SUBDIR= \
pqueue \
server \
ssl \
+ tlsext \
unit
install:
diff --git a/regress/lib/libssl/tlsext/Makefile b/regress/lib/libssl/tlsext/Makefile
new file mode 100644
index 00000000000..48b5bc1e258
--- /dev/null
+++ b/regress/lib/libssl/tlsext/Makefile
@@ -0,0 +1,9 @@
+# $OpenBSD: Makefile,v 1.1 2017/07/16 18:18:10 jsing Exp $
+
+PROG= tlsexttest
+LDADD= ${SSL_INT} -lcrypto
+DPADD= ${LIBCRYPTO} ${LIBSSL}
+WARNINGS= Yes
+CFLAGS+= -DLIBRESSL_INTERNAL -Wundef -Werror -I$(BSDSRCDIR)/lib/libssl
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libssl/tlsext/tlsexttest.c b/regress/lib/libssl/tlsext/tlsexttest.c
new file mode 100644
index 00000000000..557c3ca4098
--- /dev/null
+++ b/regress/lib/libssl/tlsext/tlsexttest.c
@@ -0,0 +1,245 @@
+/* $OpenBSD: tlsexttest.c,v 1.1 2017/07/16 18:18:10 jsing Exp $ */
+/*
+ * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+
+#include "ssl_locl.h"
+
+#include "bytestring.h"
+#include "ssl_tlsext.h"
+
+static void
+hexdump(const unsigned char *buf, size_t len)
+{
+ size_t i;
+
+ for (i = 1; i <= len; i++)
+ fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
+
+ fprintf(stderr, "\n");
+}
+
+#define TEST_SNI_SERVERNAME "www.libressl.org"
+
+static unsigned char tlsext_sni_clienthello[] = {
+ 0x00, 0x13, 0x00, 0x00, 0x10, 0x77, 0x77, 0x77,
+ 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x73, 0x73,
+ 0x6c, 0x2e, 0x6f, 0x72, 0x67,
+};
+
+static unsigned char tlsext_sni_serverhello[] = {
+};
+
+static int
+test_tlsext_sni_clienthello(void)
+{
+ unsigned char *data = NULL;
+ SSL_CTX *ssl_ctx = NULL;
+ SSL *ssl = NULL;
+ int failure = 0;
+ size_t dlen;
+ int alert;
+ CBB cbb;
+ CBS cbs;
+
+ CBB_init(&cbb, 0);
+
+ if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL)
+ errx(1, "failed to create SSL_CTX");
+ if ((ssl = SSL_new(ssl_ctx)) == NULL)
+ errx(1, "failed to create SSL");
+
+ if (tlsext_sni_clienthello_needs(ssl)) {
+ fprintf(stderr, "FAIL: clienthello should not need SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) {
+ fprintf(stderr, "FAIL: client failed to set server name\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!tlsext_sni_clienthello_needs(ssl)) {
+ fprintf(stderr, "FAIL: clienthello should need SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!tlsext_sni_clienthello_build(ssl, &cbb)) {
+ fprintf(stderr, "FAIL: clienthello failed to build SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!CBB_finish(&cbb, &data, &dlen))
+ errx(1, "failed to finish CBB");
+
+ if (dlen != sizeof(tlsext_sni_clienthello)) {
+ fprintf(stderr, "FAIL: got clienthello SNI with length %zu, "
+ "want length %zu\n", dlen, sizeof(tlsext_sni_clienthello));
+ failure = 1;
+ goto done;
+ }
+
+ if (memcmp(data, tlsext_sni_clienthello, dlen) != 0) {
+ fprintf(stderr, "FAIL: clienthello SNI differs:\n");
+ fprintf(stderr, "received:\n");
+ hexdump(data, dlen);
+ fprintf(stderr, "test data:\n");
+ hexdump(tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello));
+ failure = 1;
+ goto done;
+ }
+
+ if ((ssl->session = SSL_SESSION_new()) == NULL)
+ errx(1, "failed to create session");
+
+ ssl->internal->hit = 0;
+
+ CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello));
+ if (!tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) {
+ fprintf(stderr, "FAIL: failed to parse clienthello SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (ssl->session->tlsext_hostname == NULL) {
+ fprintf(stderr, "FAIL: no tlsext_hostname from clienthello SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) ||
+ strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME,
+ strlen(TEST_SNI_SERVERNAME)) != 0) {
+ fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n",
+ ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME);
+ failure = 1;
+ goto done;
+ }
+
+ done:
+ CBB_cleanup(&cbb);
+ SSL_CTX_free(ssl_ctx);
+ SSL_free(ssl);
+ free(data);
+
+ return (failure);
+}
+
+static int
+test_tlsext_sni_serverhello(void)
+{
+ unsigned char *data = NULL;
+ SSL_CTX *ssl_ctx = NULL;
+ SSL *ssl = NULL;
+ int failure = 0;
+ size_t dlen;
+ int alert;
+ CBB cbb;
+ CBS cbs;
+
+ CBB_init(&cbb, 0);
+
+ if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL)
+ errx(1, "failed to create SSL_CTX");
+ if ((ssl = SSL_new(ssl_ctx)) == NULL)
+ errx(1, "failed to create SSL");
+
+ if ((ssl->session = SSL_SESSION_new()) == NULL)
+ errx(1, "failed to create session");
+
+ if (tlsext_sni_serverhello_needs(ssl)) {
+ fprintf(stderr, "FAIL: serverhello should not need SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) {
+ fprintf(stderr, "FAIL: client failed to set server name\n");
+ failure = 1;
+ goto done;
+ }
+
+ if ((ssl->session->tlsext_hostname = strdup(TEST_SNI_SERVERNAME)) ==
+ NULL)
+ errx(1, "failed to strdup tlsext_hostname");
+
+ if (!tlsext_sni_serverhello_needs(ssl)) {
+ fprintf(stderr, "FAIL: serverhello should need SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!tlsext_sni_serverhello_build(ssl, &cbb)) {
+ fprintf(stderr, "FAIL: serverhello failed to build SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ if (!CBB_finish(&cbb, &data, &dlen))
+ errx(1, "failed to finish CBB");
+
+ if (dlen != sizeof(tlsext_sni_serverhello)) {
+ fprintf(stderr, "FAIL: got serverhello SNI with length %zu, "
+ "want length %zu\n", dlen, sizeof(tlsext_sni_serverhello));
+ failure = 1;
+ goto done;
+ }
+
+ if (memcmp(data, tlsext_sni_serverhello, dlen) != 0) {
+ fprintf(stderr, "FAIL: serverhello SNI differs:\n");
+ fprintf(stderr, "received:\n");
+ hexdump(data, dlen);
+ fprintf(stderr, "test data:\n");
+ hexdump(tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello));
+ failure = 1;
+ goto done;
+ }
+
+ CBS_init(&cbs, tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello));
+ if (!tlsext_sni_serverhello_parse(ssl, &cbs, &alert)) {
+ fprintf(stderr, "FAIL: failed to parse serverhello SNI\n");
+ failure = 1;
+ goto done;
+ }
+
+ /* XXX - test parse with session with mismatched name. */
+
+ done:
+ CBB_cleanup(&cbb);
+ SSL_CTX_free(ssl_ctx);
+ SSL_free(ssl);
+ free(data);
+
+ return (failure);
+}
+
+int
+main(int argc, char **argv)
+{
+ int failed = 0;
+
+ SSL_library_init();
+
+ failed |= test_tlsext_sni_clienthello();
+ failed |= test_tlsext_sni_serverhello();
+
+ return (failed);
+}