Merge pull request #7054 from cconlon/sslAlpnSelectCb

Add wolfSSL_set_alpn_select_cb() for setting ALPN select callback on WOLFSSL session
This commit is contained in:
David Garske
2023-12-13 09:24:07 -08:00
committed by GitHub
3 changed files with 99 additions and 0 deletions

View File

@ -30233,6 +30233,20 @@ int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
return OPENSSL_NPN_NO_OVERLAP;
}
void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
int (*cb) (WOLFSSL *ssl,
const unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
unsigned int inlen,
void *arg), void *arg)
{
if (ssl != NULL) {
ssl->alpnSelect = cb;
ssl->alpnSelectArg = arg;
}
}
void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
int (*cb) (WOLFSSL *ssl,
const unsigned char **out,

View File

@ -10670,6 +10670,60 @@ static void verify_ALPN_client_list(WOLFSSL* ssl)
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_FreePeerProtocol(ssl, &clist));
}
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
/* ALPN select callback, success with spdy/2 */
static int select_ALPN_spdy2(WOLFSSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg)
{
/* spdy/2 */
const char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
(void)ssl;
(void)arg;
/* adding +1 since LEN byte comes first */
if (inlen < sizeof(proto) + 1) {
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
if (XMEMCMP(in + 1, proto, sizeof(proto)) == 0) {
*out = in + 1;
*outlen = (unsigned char)sizeof(proto);
return SSL_TLSEXT_ERR_OK;
}
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
/* ALPN select callback, force failure */
static int select_ALPN_failure(WOLFSSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg)
{
(void)ssl;
(void)out;
(void)outlen;
(void)in;
(void)inlen;
(void)arg;
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
static void use_ALPN_spdy2_callback(WOLFSSL* ssl)
{
wolfSSL_set_alpn_select_cb(ssl, select_ALPN_spdy2, NULL);
}
static void use_ALPN_failure_callback(WOLFSSL* ssl)
{
wolfSSL_set_alpn_select_cb(ssl, select_ALPN_failure, NULL);
}
#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY | QUIC */
static int test_wolfSSL_UseALPN_connection(void)
{
int res = TEST_SKIPPED;
@ -10725,6 +10779,30 @@ static int test_wolfSSL_UseALPN_connection(void)
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_unknown; server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
test_wolfSSL_client_server(&client_cb, &server_cb);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
/* WOLFSSL-level ALPN select callback tests */
/* Callback: success (one protocol, spdy/2) */
client_cb.ctx_ready = NULL;
client_cb.ssl_ready = use_ALPN_one;
client_cb.on_result = verify_ALPN_matching_spdy2;
server_cb.ctx_ready = NULL;
server_cb.ssl_ready = use_ALPN_spdy2_callback;
server_cb.on_result = verify_ALPN_matching_spdy2;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* Callback: failure (one client protocol, spdy/2) */
client_cb.ctx_ready = NULL;
client_cb.ssl_ready = use_ALPN_one;
client_cb.on_result = NULL;
server_cb.ctx_ready = NULL;
server_cb.ssl_ready = use_ALPN_failure_callback;
server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
test_wolfSSL_client_server(&client_cb, &server_cb);
#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY */
res = TEST_RES_CHECK(1);
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
return res;

View File

@ -5025,6 +5025,13 @@ WOLFSSL_API int wolfSSL_select_next_proto(unsigned char **out,
const unsigned char *in, unsigned int inlen,
const unsigned char *client,
unsigned int client_len);
WOLFSSL_API void wolfSSL_set_alpn_select_cb(WOLFSSL *ssl,
int (*cb) (WOLFSSL *ssl,
const unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
unsigned int inlen,
void *arg), void *arg);
WOLFSSL_API void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
int (*cb) (WOLFSSL *ssl,
const unsigned char **out,