From: Ben Laurie Date: Sun, 5 Sep 2010 16:35:10 +0000 (+0000) Subject: NPN tests. X-Git-Tag: OpenSSL-fips-2_0-rc1~987 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=d9a268b9f903588e4d89e18bea76107ce78109c0;hp=5df2a2497a3e1ad7d5a386bbe34d3be9eb3a0ba3 NPN tests. --- diff --git a/ssl/ssltest.c b/ssl/ssltest.c index 175635881d..032a477f09 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -249,6 +249,81 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned static BIO *bio_err=NULL; static BIO *bio_stdout=NULL; +#ifndef OPENSSL_NO_NPN +/* 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 client_len; + const unsigned char *server_s; + unsigned 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; @@ -316,6 +391,11 @@ static void sv_usage(void) " (default is sect163r2).\n"); #endif fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); +#ifndef OPENSSL_NO_NPN + 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 print_details(SSL *c_ssl, const char *prefix) @@ -680,6 +760,20 @@ int main(int argc, char *argv[]) { test_cipherlist = 1; } +#ifndef OPENSSL_NO_NPN + 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); @@ -941,6 +1035,26 @@ bad: #endif } +#ifndef OPENSSL_NO_NPN + 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); @@ -1391,6 +1505,13 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (verbose) print_details(c_ssl, "DONE via BIO pair: "); +#ifndef OPENSSL_NO_NPN + if (verify_npn(c_ssl, s_ssl) < 0) + { + ret = 1; + goto end; + } +#endif end: ret = 0; @@ -1686,6 +1807,13 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) if (verbose) print_details(c_ssl, "DONE: "); +#ifndef OPENSSL_NO_NPN + 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/test/testssl b/test/testssl index f9d7c5d65f..ad32bccdca 100644 --- a/test/testssl +++ b/test/testssl @@ -148,4 +148,15 @@ $ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1 echo test tls1 with PSK via BIO pair $ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1 +############################################################################# +# Next Protocol Negotiation Tests + +$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 + exit 0