diff --git a/src/conn.c b/src/conn.c index 351414318..c21dda1aa 100644 --- a/src/conn.c +++ b/src/conn.c @@ -729,14 +729,10 @@ _makeTLSConn(natsConnection *nc) } if (s == NATS_OK) { -#ifdef NATS_WITH_EXPERIMENTAL - SSL_verify_cb cb = _collectSSLErr; if (nc->opts->sslCtx->callback != NULL) - cb = nc->opts->sslCtx->callback; - SSL_set_verify(ssl, SSL_VERIFY_PEER, cb); -#else - SSL_set_verify(ssl, SSL_VERIFY_PEER, _collectSSLErr); -#endif // NATS_WITH_EXPERIMENTAL + SSL_set_verify(ssl, SSL_VERIFY_PEER, (SSL_verify_cb) nc->opts->sslCtx->callback); + else + SSL_set_verify(ssl, SSL_VERIFY_PEER, _collectSSLErr); } } } diff --git a/src/nats.h b/src/nats.h index 514c5661d..2c82b0105 100644 --- a/src/nats.h +++ b/src/nats.h @@ -27,16 +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. * @@ -2278,6 +2268,31 @@ typedef void (*natsOnCompleteCB)(void *closure); */ typedef int64_t (*natsCustomReconnectDelayHandler)(natsConnection *nc, int attempts, void *closure); +/** \brief SSL certificate verification callback. + * + * This is invoked during SSL handshake and allows the user to inspect and validate + * the certificate chain. + * + * The `ctx` pointer should be cast to `(X509_STORE_CTX*)` before use: + * + * \code{.unparsed} + * int + * mySSLVerifyCb(int preverifyOk, void *ctx) + * { + * X509 *cert = X509_STORE_CTX_get_current_cert((X509_STORE_CTX*) ctx); + * ... + * } + * \endcode + * + * See https://docs.openssl.org/master/man3/SSL_CTX_set_verify/ for more details. + * + * @param preverifyOk indicates whether the verification of the certificate in question + * was passed (preverifyOk=1) or not (preverifyOk=0). + * @param ctx a pointer to the complete context used for the certificate chain verification. + * The application should cast this to `(X509_STORE_CTX*)` before use. + */ +typedef int (*natsSSLVerifyCb)(int preverifyOk, void *ctx); + #ifdef BUILD_IN_DOXYGEN /** \brief Callback used to process asynchronous publish errors from JetStream. * @@ -3184,8 +3199,6 @@ natsOptions_SetExpectedHostname(natsOptions *opts, const char *hostname); NATS_EXTERN natsStatus natsOptions_SkipServerVerification(natsOptions *opts, bool skip); -#ifdef NATS_WITH_EXPERIMENTAL - /** \brief EXPERIMENTAL Sets the certificate validation callback. * * Sets a callback used to verify the SSL certificate. @@ -3193,19 +3206,11 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip); * \note Setting a callback will enable SSL verification if disabled via * natsOptions_SkipServerVerification(). * - * \warning This is an experimental API and is subject to change in future - * versions. To use this API compile the client code with - * `-DNATS_WITH_EXPERIMENTAL -DNATS_HAS_TLS`. `openssl` library must be - * 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 verification handler to invoke. */ NATS_EXTERN natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback); - -#endif // NATS_WITH_EXPERIMENTAL +natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback); /** \brief Sets the verbose mode. * diff --git a/src/natsp.h b/src/natsp.h index cb429f62a..de7e61b20 100644 --- a/src/natsp.h +++ b/src/natsp.h @@ -206,10 +206,7 @@ typedef struct __natsSSLCtx bool skipVerify; char *certFileName; char *keyFileName; - -#ifdef NATS_WITH_EXPERIMENTAL - SSL_verify_cb callback; -#endif // NATS_WITH_EXPERIMENTAL + natsSSLVerifyCb callback; } natsSSLCtx; diff --git a/src/opts.c b/src/opts.c index 4c8aadd0e..499fb0f06 100644 --- a/src/opts.c +++ b/src/opts.c @@ -766,10 +766,8 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip) if (s == NATS_OK) { opts->sslCtx->skipVerify = skip; -#ifdef NATS_WITH_EXPERIMENTAL if (skip) opts->sslCtx->callback = NULL; -#endif // NATS_WITH_EXPERIMENTAL } UNLOCK_OPTS(opts); @@ -777,10 +775,8 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip) return s; } -#ifdef NATS_WITH_EXPERIMENTAL - natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback) +natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback) { natsStatus s = NATS_OK; @@ -801,8 +797,6 @@ natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback return s; } -#endif // NATS_WITH_EXPERIMENTAL - #else natsStatus @@ -861,17 +855,12 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip) return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR); } - -#ifdef NATS_WITH_EXPERIMENTAL - natsStatus -natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback) +natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback) { return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR); } -#endif // NATS_WITH_EXPERIMENTAL - #endif natsStatus diff --git a/test/test.c b/test/test.c index 08491028d..646ae86de 100644 --- a/test/test.c +++ b/test/test.c @@ -21631,8 +21631,9 @@ _logChain(STACK_OF(X509) *chain) } static int -_sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) +_sslVerifyCallback(int preverify_ok, void *pctx) { + X509_STORE_CTX *ctx = (X509_STORE_CTX*) pctx; X509 *cert = X509_STORE_CTX_get_current_cert(ctx); SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl); @@ -21694,7 +21695,6 @@ _sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) void test_SSLVerificationCallback(void) { -#ifdef NATS_WITH_EXPERIMENTAL #ifdef NATS_HAS_TLS natsStatus s; natsConnection *nc = NULL; @@ -21729,7 +21729,6 @@ void test_SSLVerificationCallback(void) test("Skipped when built with no SSL support: "); testCond(true); #endif // NATS_HAS_TLS -#endif // NATS_WITH_EXPERIMENTAL } void test_SSLCiphers(void)