call alpn selection call-back at server side only (#4377)

* call alpn selection call-back at server side only

* addressed review comment

* addressed jenkins failure
This commit is contained in:
Hideki Miyazaki
2021-09-15 09:02:18 +09:00
committed by GitHub
parent 3c21996002
commit d9767207b7
3 changed files with 126 additions and 1 deletions

View File

@ -6255,6 +6255,20 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->alpnSelect = ctx->alpnSelect;
ssl->alpnSelectArg = ctx->alpnSelectArg;
#endif
#if !defined(NO_BIO) && defined(OPENSSL_EXTRA)
if (ctx->alpn_cli_protos != NULL && ctx->alpn_cli_protos_len > 0) {
ret = wolfSSL_set_alpn_protos(ssl, ctx->alpn_cli_protos,
ctx->alpn_cli_protos_len);
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
if (ret) {
#else
if (!ret) {
#endif
WOLFSSL_MSG("failed to set alpn protos to ssl object");
return ret;
}
}
#endif
#endif
#ifdef HAVE_SUPPORTED_CURVES
ssl->options.userCurves = ctx->userCurves;

View File

@ -1623,13 +1623,16 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, const byte *input, word16 length,
TLSX_APPLICATION_LAYER_PROTOCOL);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
if (ssl->alpnSelect != NULL) {
if (ssl->alpnSelect != NULL && ssl->options.side == WOLFSSL_SERVER_END) {
const byte* out;
unsigned char outLen;
if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size,
ssl->alpnSelectArg) == 0) {
WOLFSSL_MSG("ALPN protocol match");
/* clears out all current ALPN extensions set */
TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap)
== WOLFSSL_SUCCESS) {
if (extension == NULL) {

View File

@ -6449,6 +6449,102 @@ static void test_wolfSSL_UseALPN_params(void)
}
#endif /* HAVE_ALPN */
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)) && \
(defined(HAVE_ALPN) && defined(HAVE_SNI)) &&\
defined(HAVE_IO_TESTS_DEPENDENCIES)
static void CTX_set_alpn_protos(SSL_CTX *ctx)
{
unsigned char p[] = {
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
6, 's', 'p', 'd', 'y', '/', '2',
6, 's', 'p', 'd', 'y', '/', '1',
};
unsigned char p_len = sizeof(p);
int ret;
ret = SSL_CTX_set_alpn_protos(ctx, p, p_len);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(ret, 0);
#else
AssertIntEQ(ret, SSL_SUCCESS);
#endif
}
static void set_alpn_protos(SSL* ssl)
{
unsigned char p[] = {
6, 's', 'p', 'd', 'y', '/', '3',
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
6, 's', 'p', 'd', 'y', '/', '2',
6, 's', 'p', 'd', 'y', '/', '1',
};
unsigned char p_len = sizeof(p);
int ret;
ret = SSL_set_alpn_protos(ssl, p, p_len);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(ret, 0);
#else
AssertIntEQ(ret, SSL_SUCCESS);
#endif
}
static void verify_alpn_matching_spdy3(WOLFSSL* ssl)
{
/* "spdy/3" */
char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
const unsigned char *proto;
unsigned int protoSz = 0;
SSL_get0_alpn_selected(ssl, &proto, &protoSz);
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void verify_alpn_matching_http1(WOLFSSL* ssl)
{
/* "http/1.1" */
char nego_proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
const unsigned char *proto;
unsigned int protoSz = 0;
SSL_get0_alpn_selected(ssl, &proto, &protoSz);
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void test_wolfSSL_set_alpn_protos()
{
unsigned long i;
callback_functions callbacks[] = {
/* use CTX_alpn_protos */
{0, CTX_set_alpn_protos, 0, 0, 0, 0},
{0, CTX_set_alpn_protos, 0, verify_alpn_matching_http1, 0, 0},
/* use set_alpn_protos */
{0, 0, set_alpn_protos, 0, 0, 0},
{0, 0, set_alpn_protos, verify_alpn_matching_spdy3, 0, 0},
};
for (i = 0; i < sizeof(callbacks) / sizeof(callback_functions); i += 2) {
callbacks[i ].method = wolfSSLv23_client_method;
callbacks[i + 1].method = wolfSSLv23_server_method;
test_wolfSSL_client_server(&callbacks[i], &callbacks[i + 1]);
}
}
#endif
static void test_wolfSSL_UseALPN(void)
{
#if defined(HAVE_ALPN) && !defined(NO_WOLFSSL_SERVER) &&\
@ -6456,6 +6552,18 @@ static void test_wolfSSL_UseALPN(void)
test_wolfSSL_UseALPN_connection();
test_wolfSSL_UseALPN_params();
#endif
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_BIO)
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)) && \
(defined(HAVE_ALPN) && defined(HAVE_SNI)) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
test_wolfSSL_set_alpn_protos();
#endif
#endif
}
static void test_wolfSSL_DisableExtendedMasterSecret(void)