summaryrefslogtreecommitdiff
path: root/regress/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-10-13 13:42:40 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-10-13 13:42:40 +0000
commitbc71cde68d310f3f1e3ce7186af254575524f758 (patch)
tree83704e0cb2b988c76294fac8e847c915974e981b /regress/lib/libssl
parentb14276e1a5fdf154b65b8db459a34978edac9305 (diff)
Add NPN regress tests from OpenSSL. However, unlike OpenSSL, actually exit
with a failure if the NPN verification fails.
Diffstat (limited to 'regress/lib/libssl')
-rw-r--r--regress/lib/libssl/ssl/ssltest.c135
-rw-r--r--regress/lib/libssl/ssl/testssl14
2 files changed, 146 insertions, 3 deletions
diff --git a/regress/lib/libssl/ssl/ssltest.c b/regress/lib/libssl/ssl/ssltest.c
index 4346cf44656..5587c0e424e 100644
--- a/regress/lib/libssl/ssl/ssltest.c
+++ b/regress/lib/libssl/ssl/ssltest.c
@@ -208,6 +208,89 @@ static DH *get_dh1024dsa(void);
static BIO *bio_err = NULL;
static BIO *bio_stdout = NULL;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* Note that this code assumes that this is only a one element list: */
+static const char NEXT_PROTO_STRING[] = "\x09testproto";
+int npn_client = 0;
+int npn_server = 0;
+int npn_server_reject = 0;
+
+static int
+cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg)
+{
+ /*
+ * This callback only returns the protocol string, rather than a length
+ * prefixed set. We assume that NEXT_PROTO_STRING is a one element list
+ * and remove the first byte to chop off the length prefix.
+ */
+ *out = (unsigned char *)NEXT_PROTO_STRING + 1;
+ *outlen = sizeof(NEXT_PROTO_STRING) - 2;
+ return (SSL_TLSEXT_ERR_OK);
+}
+
+static int
+cb_server_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
+{
+ *data = (const unsigned char *)NEXT_PROTO_STRING;
+ *len = sizeof(NEXT_PROTO_STRING) - 1;
+ return (SSL_TLSEXT_ERR_OK);
+}
+
+static int
+cb_server_rejects_npn(SSL *s, const unsigned char **data, unsigned int *len,
+ void *arg)
+{
+ return (SSL_TLSEXT_ERR_NOACK);
+}
+
+static int
+verify_npn(SSL *client, SSL *server)
+{
+ const unsigned char *client_s;
+ unsigned int client_len;
+ const unsigned char *server_s;
+ unsigned int server_len;
+
+ SSL_get0_next_proto_negotiated(client, &client_s, &client_len);
+ SSL_get0_next_proto_negotiated(server, &server_s, &server_len);
+
+ if (client_len) {
+ BIO_printf(bio_stdout, "Client NPN: ");
+ BIO_write(bio_stdout, client_s, client_len);
+ BIO_printf(bio_stdout, "\n");
+ }
+
+ if (server_len) {
+ BIO_printf(bio_stdout, "Server NPN: ");
+ BIO_write(bio_stdout, server_s, server_len);
+ BIO_printf(bio_stdout, "\n");
+ }
+
+ /*
+ * If an NPN string was returned, it must be the protocol that we
+ * expected to negotiate.
+ */
+ if (client_len && (client_len != sizeof(NEXT_PROTO_STRING) - 2 ||
+ memcmp(client_s, NEXT_PROTO_STRING + 1, client_len)))
+ return (-1);
+ if (server_len && (server_len != sizeof(NEXT_PROTO_STRING) - 2 ||
+ memcmp(server_s, NEXT_PROTO_STRING + 1, server_len)))
+ return (-1);
+
+ if (!npn_client && client_len)
+ return (-1);
+ if (!npn_server && server_len)
+ return (-1);
+ if (npn_server_reject && server_len)
+ return (-1);
+ if (npn_client && npn_server && (!client_len || !server_len))
+ return (-1);
+
+ return (0);
+}
+#endif
+
static char *cipher = NULL;
static int verbose = 0;
static int debug = 0;
@@ -253,6 +336,11 @@ sv_usage(void)
" Use \"openssl ecparam -list_curves\" for all names\n" \
" (default is sect163r2).\n");
fprintf(stderr, " -test_cipherlist - verifies the order of the ssl cipher lists\n");
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ fprintf(stderr, " -npn_client - have client side offer NPN\n");
+ fprintf(stderr, " -npn_server - have server side offer NPN\n");
+ fprintf(stderr, " -npn_server_reject - have server reject NPN\n");
+#endif
}
static void
@@ -495,7 +583,17 @@ main(int argc, char *argv[])
app_verify_arg.allow_proxy_certs = 1;
} else if (strcmp(*argv, "-test_cipherlist") == 0) {
test_cipherlist = 1;
- } else {
+ }
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ else if (strcmp(*argv, "-npn_client") == 0) {
+ npn_client = 1;
+ } else if (strcmp(*argv, "-npn_server") == 0) {
+ npn_server = 1;
+ } else if (strcmp(*argv, "-npn_server_reject") == 0) {
+ npn_server_reject = 1;
+ }
+#endif
+ else {
fprintf(stderr, "unknown option %s\n", *argv);
badop = 1;
break;
@@ -541,7 +639,6 @@ bad:
SSL_library_init();
SSL_load_error_strings();
-
if (dtls1)
meth = DTLSv1_method();
else if (tls1)
@@ -653,6 +750,24 @@ bad:
(void *)&session_id_context, sizeof(session_id_context));
}
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ if (npn_client)
+ SSL_CTX_set_next_proto_select_cb(c_ctx, cb_client_npn, NULL);
+ if (npn_server) {
+ if (npn_server_reject) {
+ BIO_printf(bio_err, "Can't have both -npn_server and "
+ "-npn_server_reject\n");
+ goto end;
+ }
+ SSL_CTX_set_next_protos_advertised_cb(s_ctx,
+ cb_server_npn, NULL);
+ }
+ if (npn_server_reject) {
+ SSL_CTX_set_next_protos_advertised_cb(s_ctx,
+ cb_server_rejects_npn, NULL);
+ }
+#endif
+
c_ssl = SSL_new(c_ctx);
s_ssl = SSL_new(s_ctx);
@@ -1054,6 +1169,14 @@ doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time,
if (verbose)
print_details(c_ssl, "DONE via BIO pair: ");
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ if (verify_npn(c_ssl, s_ssl) < 0) {
+ ret = 1;
+ goto err;
+ }
+#endif
+
end:
ret = 0;
@@ -1305,6 +1428,14 @@ doit(SSL *s_ssl, SSL *c_ssl, long count)
if (verbose)
print_details(c_ssl, "DONE: ");
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ if (verify_npn(c_ssl, s_ssl) < 0) {
+ ret = 1;
+ goto err;
+ }
+#endif
+
ret = 0;
err:
/* We have to set the BIO's to NULL otherwise they will be
diff --git a/regress/lib/libssl/ssl/testssl b/regress/lib/libssl/ssl/testssl
index a4fa4112dfd..ca974a68c90 100644
--- a/regress/lib/libssl/ssl/testssl
+++ b/regress/lib/libssl/ssl/testssl
@@ -143,7 +143,7 @@ fi
#fi
#
-# DTLS
+# DTLS tests
#
echo test dtlsv1
@@ -171,3 +171,15 @@ for protocol in SSLv3; do
fi
done
done
+
+#
+# Next Protocol Negotiation tests
+#
+echo "Testing NPN..."
+$ssltest -bio_pair -tls1 -npn_client || exit 1
+$ssltest -bio_pair -tls1 -npn_server || exit 1
+$ssltest -bio_pair -tls1 -npn_server_reject || exit 1
+$ssltest -bio_pair -tls1 -npn_client -npn_server_reject || exit 1
+$ssltest -bio_pair -tls1 -npn_client -npn_server || exit 1
+$ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 || exit 1
+$ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 -reuse || exit 1