Skip to content

Commit 5e99d1f

Browse files
committed
[CHANGED] TLS: Changed SSL_verify_cb to natsSSLVerifyCb
The callback uses a `void*` that the user should cast to a `X509_STORE_CTX*`. This removes the `nats.h` dependency on `NATS_HAS_TLS` and openssl headers. Programs that have a verification callback would have to modify it to change to a `void*` and do a cast, as described in the doc for the `natsSSLVerifyCb` verification callback. I have tested that an application compiled dynamically (with 3.10.1) and code that directly uses the `X509_STORE_CTX*` would work without problems if linked to a library build with this code. Signed-off-by: Ivan Kozlovic <[email protected]>
1 parent ea2b716 commit 5e99d1f

File tree

5 files changed

+35
-49
lines changed

5 files changed

+35
-49
lines changed

src/conn.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -729,14 +729,10 @@ _makeTLSConn(natsConnection *nc)
729729
}
730730
if (s == NATS_OK)
731731
{
732-
#ifdef NATS_WITH_EXPERIMENTAL
733-
SSL_verify_cb cb = _collectSSLErr;
734732
if (nc->opts->sslCtx->callback != NULL)
735-
cb = nc->opts->sslCtx->callback;
736-
SSL_set_verify(ssl, SSL_VERIFY_PEER, cb);
737-
#else
738-
SSL_set_verify(ssl, SSL_VERIFY_PEER, _collectSSLErr);
739-
#endif // NATS_WITH_EXPERIMENTAL
733+
SSL_set_verify(ssl, SSL_VERIFY_PEER, (SSL_verify_cb) nc->opts->sslCtx->callback);
734+
else
735+
SSL_set_verify(ssl, SSL_VERIFY_PEER, _collectSSLErr);
740736
}
741737
}
742738
}

src/nats.h

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ extern "C" {
2727
#include "status.h"
2828
#include "version.h"
2929

30-
#ifdef NATS_WITH_EXPERIMENTAL
31-
32-
#if !defined(NATS_HAS_TLS)
33-
#error "natsOptions_SetSSLVerificationCallback requires NATS_HAS_TLS to be defined"
34-
#endif
35-
#include <openssl/ssl.h>
36-
#include <openssl/x509v3.h>
37-
38-
#endif // NATS_WITH_EXPERIMENTAL
39-
4030
/** \def NATS_EXTERN
4131
* \brief Needed for shared library.
4232
*
@@ -2278,6 +2268,31 @@ typedef void (*natsOnCompleteCB)(void *closure);
22782268
*/
22792269
typedef int64_t (*natsCustomReconnectDelayHandler)(natsConnection *nc, int attempts, void *closure);
22802270

2271+
/** \brief SSL certificate verification callback.
2272+
*
2273+
* This is invoked during SSL handshake and allows the user to inspect and validate
2274+
* the certificate chain.
2275+
*
2276+
* The `ctx` pointer should be cast to `(X509_STORE_CTX*)` before use:
2277+
*
2278+
* \code{.unparsed}
2279+
* int
2280+
* mySSLVerifyCb(int preverifyOk, void *ctx)
2281+
* {
2282+
* X509 *cert = X509_STORE_CTX_get_current_cert((X509_STORE_CTX*) ctx);
2283+
* ...
2284+
* }
2285+
* \endcode
2286+
*
2287+
* See https://docs.openssl.org/master/man3/SSL_CTX_set_verify/ for more details.
2288+
*
2289+
* @param preverifyOk indicates whether the verification of the certificate in question
2290+
* was passed (preverifyOk=1) or not (preverifyOk=0).
2291+
* @param ctx a pointer to the complete context used for the certificate chain verification.
2292+
* The application should cast this to `(X509_STORE_CTX*)` before use.
2293+
*/
2294+
typedef int (*natsSSLVerifyCb)(int preverifyOk, void *ctx);
2295+
22812296
#ifdef BUILD_IN_DOXYGEN
22822297
/** \brief Callback used to process asynchronous publish errors from JetStream.
22832298
*
@@ -3184,28 +3199,18 @@ natsOptions_SetExpectedHostname(natsOptions *opts, const char *hostname);
31843199
NATS_EXTERN natsStatus
31853200
natsOptions_SkipServerVerification(natsOptions *opts, bool skip);
31863201

3187-
#ifdef NATS_WITH_EXPERIMENTAL
3188-
31893202
/** \brief EXPERIMENTAL Sets the certificate validation callback.
31903203
*
31913204
* Sets a callback used to verify the SSL certificate.
31923205
*
31933206
* \note Setting a callback will enable SSL verification if disabled via
31943207
* natsOptions_SkipServerVerification().
31953208
*
3196-
* \warning This is an experimental API and is subject to change in future
3197-
* versions. To use this API compile the client code with
3198-
* `-DNATS_WITH_EXPERIMENTAL -DNATS_HAS_TLS`. `openssl` library must be
3199-
* installed and added to the include/link paths.
3200-
*
32013209
* @param opts the pointer to the #natsOptions object.
3202-
* @param callback the custom SSL verification handler to invoke. see
3203-
* https://docs.openssl.org/master/man3/SSL_CTX_set_verify/
3210+
* @param callback the custom SSL verification handler to invoke.
32043211
*/
32053212
NATS_EXTERN natsStatus
3206-
natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback);
3207-
3208-
#endif // NATS_WITH_EXPERIMENTAL
3213+
natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback);
32093214

32103215
/** \brief Sets the verbose mode.
32113216
*

src/natsp.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,7 @@ typedef struct __natsSSLCtx
206206
bool skipVerify;
207207
char *certFileName;
208208
char *keyFileName;
209-
210-
#ifdef NATS_WITH_EXPERIMENTAL
211-
SSL_verify_cb callback;
212-
#endif // NATS_WITH_EXPERIMENTAL
209+
natsSSLVerifyCb callback;
213210

214211
} natsSSLCtx;
215212

src/opts.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -766,21 +766,17 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip)
766766
if (s == NATS_OK)
767767
{
768768
opts->sslCtx->skipVerify = skip;
769-
#ifdef NATS_WITH_EXPERIMENTAL
770769
if (skip)
771770
opts->sslCtx->callback = NULL;
772-
#endif // NATS_WITH_EXPERIMENTAL
773771
}
774772

775773
UNLOCK_OPTS(opts);
776774

777775
return s;
778776
}
779777

780-
#ifdef NATS_WITH_EXPERIMENTAL
781-
782778
natsStatus
783-
natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback)
779+
natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback)
784780
{
785781
natsStatus s = NATS_OK;
786782

@@ -801,8 +797,6 @@ natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback
801797
return s;
802798
}
803799

804-
#endif // NATS_WITH_EXPERIMENTAL
805-
806800
#else
807801

808802
natsStatus
@@ -861,17 +855,12 @@ natsOptions_SkipServerVerification(natsOptions *opts, bool skip)
861855
return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR);
862856
}
863857

864-
865-
#ifdef NATS_WITH_EXPERIMENTAL
866-
867858
natsStatus
868-
natsOptions_SetSSLVerificationCallback(natsOptions *opts, SSL_verify_cb callback)
859+
natsOptions_SetSSLVerificationCallback(natsOptions *opts, natsSSLVerifyCb callback)
869860
{
870861
return nats_setError(NATS_ILLEGAL_STATE, "%s", NO_SSL_ERR);
871862
}
872863

873-
#endif // NATS_WITH_EXPERIMENTAL
874-
875864
#endif
876865

877866
natsStatus

test/test.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21631,8 +21631,9 @@ _logChain(STACK_OF(X509) *chain)
2163121631
}
2163221632

2163321633
static int
21634-
_sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
21634+
_sslVerifyCallback(int preverify_ok, void *pctx)
2163521635
{
21636+
X509_STORE_CTX *ctx = (X509_STORE_CTX*) pctx;
2163621637
X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
2163721638
SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2163821639
STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);
@@ -21694,7 +21695,6 @@ _sslVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
2169421695

2169521696
void test_SSLVerificationCallback(void)
2169621697
{
21697-
#ifdef NATS_WITH_EXPERIMENTAL
2169821698
#ifdef NATS_HAS_TLS
2169921699
natsStatus s;
2170021700
natsConnection *nc = NULL;
@@ -21729,7 +21729,6 @@ void test_SSLVerificationCallback(void)
2172921729
test("Skipped when built with no SSL support: ");
2173021730
testCond(true);
2173121731
#endif // NATS_HAS_TLS
21732-
#endif // NATS_WITH_EXPERIMENTAL
2173321732
}
2173421733

2173521734
void test_SSLCiphers(void)

0 commit comments

Comments
 (0)