diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-10-13 13:42:40 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-10-13 13:42:40 +0000 |
commit | bc71cde68d310f3f1e3ce7186af254575524f758 (patch) | |
tree | 83704e0cb2b988c76294fac8e847c915974e981b /regress/lib/libssl | |
parent | b14276e1a5fdf154b65b8db459a34978edac9305 (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.c | 135 | ||||
-rw-r--r-- | regress/lib/libssl/ssl/testssl | 14 |
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 |