From 70e53d1a345a01f8dc1ff0cfc7d61f9d6711f3ae Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 7 Jul 2025 08:41:22 +1000 Subject: [PATCH] ALPN: don't use BIO Fix wolfSSL_set_alpn_protos to not use BIO. When compiling with -Os and newer gcc, the compiler gets confused with the void* cast in the wolfSSL_BIO_get_mem_data call. --- src/ssl.c | 32 +++++++++++++++++++------------- tests/api.c | 16 ++++++++++++---- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 56882dbf0..736c2db5f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23587,12 +23587,13 @@ int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, int wolfSSL_set_alpn_protos(WOLFSSL* ssl, const unsigned char* p, unsigned int p_len) { - WOLFSSL_BIO* bio; char* pt = NULL; - + unsigned int ptIdx; unsigned int sz; unsigned int idx = 0; int alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH; + int ret; + WOLFSSL_ENTER("wolfSSL_set_alpn_protos"); if (ssl == NULL || p_len <= 1) { @@ -23606,8 +23607,9 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, #endif } - bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); - if (bio == NULL) { + /* Replacing leading number with trailing ',' and adding '\0'. */ + pt = (char*)XMALLOC(p_len + 1, ssl->heap, DYNAMIC_TYPE_OPENSSL); + if (pt == NULL) { #if defined(WOLFSSL_ERROR_CODE_OPENSSL) /* 0 on success in OpenSSL, non-0 on failure in OpenSSL * the function reverses the return value convention. @@ -23618,6 +23620,7 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, #endif } + ptIdx = 0; /* convert into comma separated list */ while (idx < p_len - 1) { unsigned int i; @@ -23625,7 +23628,7 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, sz = p[idx++]; if (idx + sz > p_len) { WOLFSSL_MSG("Bad list format"); - wolfSSL_BIO_free(bio); + XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL); #if defined(WOLFSSL_ERROR_CODE_OPENSSL) /* 0 on success in OpenSSL, non-0 on failure in OpenSSL * the function reverses the return value convention. @@ -23637,27 +23640,30 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, } if (sz > 0) { for (i = 0; i < sz; i++) { - wolfSSL_BIO_write(bio, &p[idx++], 1); + pt[ptIdx++] = p[idx++]; + } + if (idx < p_len - 1) { + pt[ptIdx++] = ','; } - if (idx < p_len - 1) - wolfSSL_BIO_write(bio, ",", 1); } } - wolfSSL_BIO_write(bio, "\0", 1); + pt[ptIdx++] = '\0'; /* clears out all current ALPN extensions set */ TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap); - if ((sz = (unsigned int)wolfSSL_BIO_get_mem_data(bio, &pt)) > 0) { - wolfSSL_UseALPN(ssl, pt, sz, (byte) alpn_opt); - } - wolfSSL_BIO_free(bio); + ret = wolfSSL_UseALPN(ssl, pt, ptIdx, (byte)alpn_opt); + XFREE(pt, ssl->heap, DYNAMIC_TYPE_OPENSSL); #if defined(WOLFSSL_ERROR_CODE_OPENSSL) /* 0 on success in OpenSSL, non-0 on failure in OpenSSL * the function reverses the return value convention. */ + if (ret != WOLFSSL_SUCCESS) + return 1; return 0; #else + if (ret != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; #endif } diff --git a/tests/api.c b/tests/api.c index 1c20975fc..b1c339a6c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -13037,13 +13037,21 @@ static int test_wolfSSL_set_alpn_protos(void) server_cb.devId = testDevId; /* use CTX_alpn_protos */ - client_cb.ctx_ready = CTX_set_alpn_protos; client_cb.ssl_ready = NULL; client_cb.on_result = NULL; - server_cb.ctx_ready = CTX_set_alpn_protos; server_cb.ssl_ready = NULL; server_cb.on_result = verify_alpn_matching_http1; + client_cb.ctx_ready = CTX_set_alpn_protos; + client_cb.ssl_ready = NULL; + client_cb.on_result = NULL; + server_cb.ctx_ready = CTX_set_alpn_protos; + server_cb.ssl_ready = NULL; + server_cb.on_result = verify_alpn_matching_http1; test_wolfSSL_client_server(&client_cb, &server_cb); /* use set_alpn_protos */ - client_cb.ctx_ready = NULL; client_cb.ssl_ready = set_alpn_protos; client_cb.on_result = NULL; - server_cb.ctx_ready = NULL; server_cb.ssl_ready = set_alpn_protos; server_cb.on_result = verify_alpn_matching_spdy3; + client_cb.ctx_ready = NULL; + client_cb.ssl_ready = set_alpn_protos; + client_cb.on_result = NULL; + server_cb.ctx_ready = NULL; + server_cb.ssl_ready = set_alpn_protos; + server_cb.on_result = verify_alpn_matching_spdy3; test_wolfSSL_client_server(&client_cb, &server_cb); res = TEST_SUCCESS;