提交 a8989362 编写于 作者: A Adam Langley 提交者: Ben Laurie

Add tests for ALPN functionality.

Conflicts:
	ssl/ssltest.c
上级 a108f841
......@@ -1329,6 +1329,7 @@ bad:
goto end;
}
SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
OPENSSL_free(alpn);
}
#endif
#ifndef OPENSSL_NO_TLSEXT
......
......@@ -370,6 +370,127 @@ static int verify_npn(SSL *client, SSL *server)
}
#endif
static const char *alpn_client;
static const char *alpn_server;
static const char *alpn_expected;
static unsigned char *alpn_selected;
/* next_protos_parse parses a comma separated list of strings into a string
* in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
* outlen: (output) set to the length of the resulting buffer on success.
* err: (maybe NULL) on failure, an error message line is written to this BIO.
* in: a NUL termianted string like "abc,def,ghi"
*
* returns: a malloced buffer or NULL on failure.
*/
static unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
{
size_t len;
unsigned char *out;
size_t i, start = 0;
len = strlen(in);
if (len >= 65535)
return NULL;
out = OPENSSL_malloc(strlen(in) + 1);
if (!out)
return NULL;
for (i = 0; i <= len; ++i)
{
if (i == len || in[i] == ',')
{
if (i - start > 255)
{
OPENSSL_free(out);
return NULL;
}
out[start] = i - start;
start = i + 1;
}
else
out[i+1] = in[i];
}
*outlen = len + 1;
return out;
}
static int cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
{
unsigned char *protos;
unsigned short protos_len;
protos = next_protos_parse(&protos_len, alpn_server);
if (protos == NULL)
{
fprintf(stderr, "failed to parser ALPN server protocol string: %s\n", alpn_server);
abort();
}
if (SSL_select_next_proto((unsigned char**) out, outlen, protos, protos_len, in, inlen) !=
OPENSSL_NPN_NEGOTIATED)
{
OPENSSL_free(protos);
return SSL_TLSEXT_ERR_NOACK;
}
/* Make a copy of the selected protocol which will be freed in verify_alpn. */
alpn_selected = OPENSSL_malloc(*outlen);
memcpy(alpn_selected, *out, *outlen);
*out = alpn_selected;
OPENSSL_free(protos);
return SSL_TLSEXT_ERR_OK;
}
static int verify_alpn(SSL *client, SSL *server)
{
const unsigned char *client_proto, *server_proto;
unsigned int client_proto_len = 0, server_proto_len = 0;
SSL_get0_alpn_selected(client, &client_proto, &client_proto_len);
SSL_get0_alpn_selected(server, &server_proto, &server_proto_len);
if (alpn_selected != NULL)
{
OPENSSL_free(alpn_selected);
alpn_selected = NULL;
}
if (client_proto_len != server_proto_len ||
memcmp(client_proto, server_proto, client_proto_len) != 0)
{
BIO_printf(bio_stdout, "ALPN selected protocols differ!\n");
goto err;
}
if (client_proto_len > 0 && alpn_expected == NULL)
{
BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n");
goto err;
}
if (alpn_expected != NULL &&
(client_proto_len != strlen(alpn_expected) ||
memcmp(client_proto, alpn_expected, client_proto_len) != 0))
{
BIO_printf(bio_stdout, "ALPN selected protocols not equal to expected protocol: %s\n", alpn_expected);
goto err;
}
return 0;
err:
BIO_printf(bio_stdout, "ALPN results: client: '");
BIO_write(bio_stdout, client_proto, client_proto_len);
BIO_printf(bio_stdout, "', server: '");
BIO_write(bio_stdout, server_proto, server_proto_len);
BIO_printf(bio_stdout, "'\n");
BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", alpn_client, alpn_server);
return -1;
}
#define SCT_EXT_TYPE 18
/* WARNING : below extension types are *NOT* IETF assigned, and
......@@ -689,6 +810,9 @@ static void sv_usage(void)
fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n");
fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n");
fprintf(stderr," -custom_ext - try various custom extension callbacks\n");
fprintf(stderr," -alpn_client <string> - have client side offer ALPN\n");
fprintf(stderr," -alpn_server <string> - have server side offer ALPN\n");
fprintf(stderr," -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
}
static void print_details(SSL *c_ssl, const char *prefix)
......@@ -1118,6 +1242,21 @@ int main(int argc, char *argv[])
{
custom_ext = 1;
}
else if (strcmp(*argv,"-alpn_client") == 0)
{
if (--argc < 1) goto bad;
alpn_client = *(++argv);
}
else if (strcmp(*argv,"-alpn_server") == 0)
{
if (--argc < 1) goto bad;
alpn_server = *(++argv);
}
else if (strcmp(*argv,"-alpn_expected") == 0)
{
if (--argc < 1) goto bad;
alpn_expected = *(++argv);
}
else
{
fprintf(stderr,"unknown option %s\n",*argv);
......@@ -1487,6 +1626,23 @@ bad:
custom_ext_3_srv_second_cb, NULL);
}
if (alpn_server)
SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL);
if (alpn_client)
{
unsigned short alpn_len;
unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client);
if (alpn == NULL)
{
BIO_printf(bio_err, "Error parsing -alpn_client argument\n");
goto end;
}
SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len);
OPENSSL_free(alpn);
}
c_ssl=SSL_new(c_ctx);
s_ssl=SSL_new(s_ctx);
......@@ -1949,6 +2105,11 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
ret = 1;
goto err;
}
if (verify_alpn(c_ssl, s_ssl) < 0)
{
ret = 1;
goto err;
}
if (custom_ext_error)
{
......
......@@ -195,6 +195,18 @@ $ssltest -bio_pair -tls1 -serverinfo_file $serverinfo -serverinfo_sct -serverinf
$ssltest -bio_pair -tls1 -custom_ext -serverinfo_file $serverinfo -serverinfo_sct -serverinfo_tack || exit 1
#############################################################################
# ALPN tests
$ssltest -bio_pair -tls1 -alpn_client foo -alpn_server bar || exit 1
$ssltest -bio_pair -tls1 -alpn_client foo -alpn_server foo -alpn_expected foo || exit 1
$ssltest -bio_pair -tls1 -alpn_client foo,bar -alpn_server foo -alpn_expected foo || exit 1
$ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server foo -alpn_expected foo || exit 1
$ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server foo,bar -alpn_expected foo || exit 1
$ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server bar,foo -alpn_expected bar || exit 1
$ssltest -bio_pair -tls1 -alpn_client foo,bar -alpn_server bar,foo -alpn_expected bar || exit 1
$ssltest -bio_pair -tls1 -alpn_client baz -alpn_server bar,foo || exit 1
if ../util/shlib_wrap.sh ../apps/openssl no-srp; then
echo skipping SRP tests
else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册