Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions src/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
49 changes: 27 additions & 22 deletions src/nats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <openssl/ssl.h>
#include <openssl/x509v3.h>

#endif // NATS_WITH_EXPERIMENTAL

/** \def NATS_EXTERN
* \brief Needed for shared library.
*
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -3184,28 +3199,18 @@ 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.
*
* \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.
*
Expand Down
5 changes: 1 addition & 4 deletions src/natsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
15 changes: 2 additions & 13 deletions src/opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,21 +766,17 @@
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);

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;

Expand All @@ -801,8 +797,6 @@
return s;
}

#endif // NATS_WITH_EXPERIMENTAL

#else

natsStatus
Expand Down Expand Up @@ -861,17 +855,12 @@
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)

Check warning on line 859 in src/opts.c

View check run for this annotation

Codecov / codecov/patch

src/opts.c#L859

Added line #L859 was not covered by tests
{
return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR);
}

#endif // NATS_WITH_EXPERIMENTAL

#endif

natsStatus
Expand Down
5 changes: 2 additions & 3 deletions test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
Loading