diff --git a/src/conn.c b/src/conn.c index 376b643d..3ab911dc 100644 --- a/src/conn.c +++ b/src/conn.c @@ -737,12 +737,10 @@ _makeTLSConn(natsConnection *nc) } if (s == NATS_OK) { - SSL_verify_cb cb = _collectSSLErr; -#ifdef NATS_WITH_EXPERIMENTAL if (nc->opts->sslCtx->callback != NULL) - cb = nc->opts->sslCtx->callback; -#endif // NATS_WITH_EXPERIMENTAL - SSL_set_verify(ssl, SSL_VERIFY_PEER, cb); + nc->opts->sslCtx->callback((void*)ssl); + else + SSL_set_verify(ssl, SSL_VERIFY_PEER, _collectSSLErr); } } } diff --git a/src/nats.h b/src/nats.h index 75fbc863..a80c365b 100644 --- a/src/nats.h +++ b/src/nats.h @@ -27,15 +27,6 @@ extern "C" { #include "status.h" #include "version.h" -#ifdef NATS_WITH_EXPERIMENTAL - -#if !defined(NATS_HAS_TLS) -#error "natsOptions_SetSSLVerificationCallback requires NATS_HAS_TLS to be defined" -#endif -#include -#include - -#endif // NATS_WITH_EXPERIMENTAL /** \def NATS_EXTERN * \brief Needed for shared library. @@ -1781,6 +1772,33 @@ typedef void (*natsOnCompleteCB)(void *closure); */ typedef int64_t (*natsCustomReconnectDelayHandler)(natsConnection *nc, int attempts, void *closure); +/** \brief Callback used to setup SSL on connection. + * + * This callback is used to allow the user to customize the SSL setup for a connection + * typically to set up custom certificate verification. The user should cast the + * ssl pointer to the appropriate SSL type and then set up the additional SSL + * callbacks as needed. + * + * \code{.unparsed} + * #include + * + * int _sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) + * { + * // Custom verification code here... + * } + * + * void _sslCallback(void *ssl) + * { + * SSL_set_verify((SSL *)ssl, SSL_VERIFY_PEER, _sslVerifyCallback); + * } + * \endcode + * + * see also https://docs.openssl.org/master/man3/SSL_CTX_set_verify/ + * + * @param ssl the pointer to the SSL struct. Must be cast to the SSL type. + */ +typedef void (*natsCustomSSLHandler)(void *ssl); + #ifdef BUILD_IN_DOXYGEN /** \brief Callback used to process asynchronous publish errors from JetStream. * @@ -2671,9 +2689,10 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip); #ifdef NATS_WITH_EXPERIMENTAL -/** \brief EXPERIMENTAL Sets the certificate validation callback. +/** \brief EXPERIMENTAL Sets the SSL callback. * - * Sets a callback used to verify the SSL certificate. + * Sets a callback used to create additional SSL setup for the connection such as + * setting up custom certificate verification. * * \note Setting a callback will enable SSL verification if disabled via * natsOptions_SkipServerVerification(). @@ -2684,11 +2703,10 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip); * installed and added to the include/link paths. * * @param opts the pointer to the #natsOptions object. - * @param callback the custom SSL verification handler to invoke. see - * https://docs.openssl.org/master/man3/SSL_CTX_set_verify/ + * @param callback the custom SSL handler to invoke. See the #natsCustomSSLHandler prototype. */ NATS_EXTERN natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback); +natsOptions_SetSSLCallback(natsOptions *opts, natsCustomSSLHandler callback); #endif // NATS_WITH_EXPERIMENTAL diff --git a/src/natsp.h b/src/natsp.h index b3b753c6..eb9f49f0 100644 --- a/src/natsp.h +++ b/src/natsp.h @@ -182,15 +182,12 @@ typedef struct __natsServerInfo typedef struct __natsSSLCtx { - natsMutex *lock; - int refs; - SSL_CTX *ctx; - char *expectedHostname; - bool skipVerify; - -#ifdef NATS_WITH_EXPERIMENTAL - SSL_verify_cb callback; -#endif // NATS_WITH_EXPERIMENTAL + natsMutex *lock; + int refs; + SSL_CTX *ctx; + char *expectedHostname; + bool skipVerify; + natsCustomSSLHandler callback; } natsSSLCtx; diff --git a/src/opts.c b/src/opts.c index 48c75382..8331a595 100644 --- a/src/opts.c +++ b/src/opts.c @@ -735,7 +735,7 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip) #ifdef NATS_WITH_EXPERIMENTAL natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback) +natsOptions_SetSSLCallback(natsOptions *opts, natsCustomSSLHandler callback) { natsStatus s = NATS_OK; @@ -820,7 +820,7 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip) #ifdef NATS_WITH_EXPERIMENTAL natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback) +natsOptions_SetSSLCallback(natsOptions *opts, natsCustomSSLHandler callback) { return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR); } diff --git a/test/test.c b/test/test.c index eeea6780..6224708c 100644 --- a/test/test.c +++ b/test/test.c @@ -21191,6 +21191,13 @@ _sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) testf("verfiy result: %d\n", result); return result; } + +static void +_sslCallback(void *ssl) +{ + SSL_set_verify((SSL *)ssl, SSL_VERIFY_PEER, _sslVerifyCallback); +} + #endif // NATS_HAS_TLS void test_SSLVerificationCallback(void) @@ -21218,7 +21225,7 @@ void test_SSLVerificationCallback(void) test("Check that connect succeeds with validation callback:\n"); s = natsOptions_SetURL(opts, "nats://127.0.0.1:4443"); - IFOK(s, natsOptions_SetSSLVerificationCallback(opts, _sslVerifyCallback)); + IFOK(s, natsOptions_SetSSLCallback(opts, _sslCallback)); IFOK(s, natsConnection_Connect(&nc, opts)); testCond(s == NATS_OK); natsConnection_Destroy(nc);