Skip to content

Add support for wolfSSL TLS backend #867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

kerbert101
Copy link
Contributor

This adds support for wolfSSL as the TLS backend. It uses the OpenSSL Compatibility Layer of wolfSSL (wolfSSL must be compiled with --enable-opensslextra)

More information about the compatibility layer:

https://www.wolfssl.com/documentation/manuals/wolfssl/chapter13.html

@levb levb requested review from levb and kozlovic April 9, 2025 09:53
Copy link
Collaborator

@levb levb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kerbert101 Do you mind adding a GitHub action job that sets up a VM with WolfSSL and runs the tests on it? The relevant places to change would be

if [[ "${{ inputs.tls }}" == "TLS" ]]; then
and to add Coverage-WolfSSL job. I can do it myself, but would need to a) help with the setup of WolfSSL if its not trivial, and b) permission to push to your fork/branch.

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if you were to add GitHub actions as instructed by @levb, the test would still use OpenSSL since you did not add the WolfSSL include/link in the test's CMakeFile.

If we are going to support another backend, we need to have more generic "SSL" build variables that will represent the chosen SSL library.

My other concern is that it looks like WolfSSL is GPLv2 and may not be compatible with Apache 2.0 license. But I don't know enough about it to know if it would be "safe" in this context.

endif(NATS_BUILD_WITH_TLS AND NOT NATS_BUILD_WITH_WOLFSSL)

if(NATS_BUILD_WITH_WOLFSSL)
if(DEFINED ENV{NATS_WOLFSSL_DIR})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this is a bit complex, no? Look at what we do for OpenSSL: find_package(OpenSSL REQUIRED). Is there no equivalent for that?

add_definitions(-D${NATS_OS})
add_definitions(-D_REENTRANT)
if(NATS_BUILD_WITH_TLS)

if(NATS_BUILD_WITH_TLS OR NATS_BUILD_WITH_WOLFSSL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I don't see where you would set NATS_BUILD_WITH_TLS to "false" when using WolfSSL, then not sure the "OR" is needed here, but we should also question if the following settings make sense if using WolfSSL library.

@@ -10,6 +10,10 @@ if(NATS_BUILD_WITH_TLS)
set(NATS_OPENSSL_LIBS "${OPENSSL_LIBRARIES}")
endif(NATS_BUILD_WITH_TLS)

if(NATS_BUILD_WITH_WOLFSSL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then just above we possibly include OpenSSL libraries, is that the right thing to do?

@@ -37,15 +41,15 @@ endif(NATS_BUILD_STREAMING)
# --------------------------------------
if(NATS_BUILD_LIB_SHARED)
add_library(nats SHARED ${SOURCES} ${GLIB_SOURCES} ${PS_SOURCES} ${S_SOURCES})
target_link_libraries(nats ${NATS_OPENSSL_LIBS} ${NATS_EXTRA_LIB} ${NATS_PROTOBUF_LIBRARIES} ${NATS_SODIUM_LIBRARIES})
target_link_libraries(nats ${NATS_OPENSSL_LIBS} ${NATS_WOLFSSL_LIBRARIES} ${NATS_EXTRA_LIB} ${NATS_PROTOBUF_LIBRARIES} ${NATS_SODIUM_LIBRARIES})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we support different SSL libraries, I think we should have a NATS_SSL_LIBS that would be set to either one.

set_target_properties(nats PROPERTIES
VERSION ${NATS_VERSION_MAJOR}.${NATS_VERSION_MINOR}.${NATS_VERSION_PATCH}
SOVERSION ${NATS_VERSION_MAJOR}.${NATS_VERSION_MINOR})
endif(NATS_BUILD_LIB_SHARED)

if(NATS_BUILD_LIB_STATIC)
add_library(nats_static STATIC ${SOURCES} ${GLIB_SOURCES} ${PS_SOURCES} ${S_SOURCES})
target_link_libraries(nats_static ${NATS_OPENSSL_LIBS} ${NATS_PROTOBUF_LIBRARIES} ${NATS_SODIUM_LIBRARIES})
target_link_libraries(nats_static ${NATS_OPENSSL_LIBS} ${NATS_WOLFSSL_LIBRARIES} ${NATS_PROTOBUF_LIBRARIES} ${NATS_SODIUM_LIBRARIES})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

@@ -44,6 +44,10 @@
#define NATS_EVENT_ACTION_ADD (true)
#define NATS_EVENT_ACTION_REMOVE (false)

#ifdef NATS_HAS_WOLFSSL
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that not defined in WolfSSL?

#if defined(NATS_USE_OPENSSL_1_1)
// the SSL_set_hostflags function is not available in the
// wolfSSL OpenSSL compatibility layer, so use the new function instead
#if defined(NATS_USE_OPENSSL_1_1) && !defined(NATS_HAS_WOLFSSL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the comment in the main CMakeFile.txt. If NATS_USE_OPENSSL_1_1 does not make sense in the context of WolfSSL, then it should not have been set in the make file.

@kerbert101
Copy link
Contributor Author

@levb In principle, I can fix the tests—I don't expect that to be a problem. I see that the protobuf and sodium libraries are included in the nats.c.deps repository. I think a similar approach should be taken for the wolfSSL dependency.

@kozlovic: I agree with your comments. I reused the block for protobuf-c to find wolfSSL. It might be improved, but I haven’t fully looked into it yet.

The 1.1.1 flag should indeed probably be set to false by default for the wolfSSL implementation.

Regarding the licenses: I currently don't have enough knowledge to say whether combining GPLv2 and Apache 2.0 is possible.

It might be a good idea to first consider whether it's desirable to support multiple TLS backends.

@kozlovic
Copy link
Member

I see that the protobuf and sodium libraries are included in the nats.c.deps repository. I think a similar approach should be taken for the wolfSSL dependency.

That for sure would NOT be good, because unlike those, we can distribute and have the LICENSE file attached. Having the wolfSSL library (GPLv2) in the nats.c.deps repo (Apache 2.0) would not be legal.
What I am not sure of is your PR on its own, where we would just have basically the "include <>" line, but not any file of the library actually in our repo.

It might be a good idea to first consider whether it's desirable to support multiple TLS backends.

Agreed that it should be the first thing to decide on. Maybe @levb and the rest of the team can discuss that and get back to you.

@kerbert101 kerbert101 marked this pull request as draft April 10, 2025 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants