Skip to content

Commit

Permalink
add wolfSSL_set_alpn_select_cb() for WOLFSSL-level ALPN select callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
cconlon committed Dec 13, 2023
1 parent 00a1c68 commit 269542e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
78 changes: 78 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 269542e

Please sign in to comment.