Skip to content

Commit

Permalink
tls: Remove the individual TLS configuration options
Browse files Browse the repository at this point in the history
This is a breaking change.

TLS configuration changes are to be made using TLS configuration
objects, and then set on a listener or dialer with NNG_OPT_TLS_CONFIG.
This should be a bit less racy, and allows for simpler code.
  • Loading branch information
gdamore committed Oct 28, 2024
1 parent 54c99d8 commit 7f5f857
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 205 deletions.
2 changes: 0 additions & 2 deletions docs/man/nng_tls.7.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ Note that setting these must be done before the transport is started.
* xref:nng_options.5.adoc#NNG_OPT_REMADDR[`NNG_OPT_REMADDR`]
* xref:nng_tcp_options.5.adoc#NNG_OPT_TCP_KEEPALIVE[`NNG_OPT_TCP_KEEPALIVE`]
* xref:nng_tcp_options.5.adoc#NNG_OPT_TCP_NODELAY[`NNG_OPT_TCP_NODELAY`]
* xref:nng_tls_options.5.adoc#NNG_OPT_TLS_CA_FILE[`NNG_OPT_TLS_CA_FILE`]
* xref:nng_tls_options.5.adoc#NNG_OPT_TLS_CERT_KEY_FILE[`NNG_OPT_TLS_CERT_KEY_FILE`]
* xref:nng_tls_options.5.adoc#NNG_OPT_TLS_CONFIG[`NNG_OPT_TLS_CONFIG`]
* xref:nng_tls_options.5.adoc#NNG_OPT_TLS_VERIFIED[`NNG_OPT_TLS_VERIFIED_`]
* xref:nng_tls_options.5.adoc#NNG_OPT_TLS_PEER_CN[`NNG_OPT_TLS_PEER_CN`]
Expand Down
24 changes: 0 additions & 24 deletions docs/man/nng_tls_options.5.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ nng_tls_options - TLS-specific options
----
#include <nng/nng.h>
#define NNG_OPT_TLS_CA_FILE "tls-ca-file"
#define NNG_OPT_TLS_CERT_KEY_FILE "tls-cert-key-file"
#define NNG_OPT_TLS_CONFIG "tls-config"
#define NNG_OPT_TLS_SERVER_NAME "tls-server-name"
#define NNG_OPT_TLS_VERIFIED "tls-verified"
#define NNG_OPT_TLS_PEER_CN "tls-peer-cn"
#define NNG_OPT_TLS_PEER_ALT_NAMES "tls-peer-alt-names"
Expand All @@ -46,19 +43,6 @@ description of the option.

=== TLS Options

[[NNG_OPT_TLS_CA_FILE]]((`NNG_OPT_TLS_CA_FILE`))::
(string) Write-only option naming a file containing certificates to
use for peer validation.
See xref:nng_tls_config_ca_file.3tls.adoc[`nng_tls_config_ca_file()`] for more
information.

[[NNG_OPT_TLS_CERT_KEY_FILE]]((`NNG_OPT_TLS_CERT_KEY_FILE`))::
(string) Write-only option naming a file containing the local certificate and
associated private key.
The private key used must be unencrypted.
See xref:nng_tls_config_own_cert.3tls.adoc[`nng_tls_config_own_cert()`] for more
information.

[[NNG_OPT_TLS_CONFIG]]((`NNG_OPT_TLS_CONFIG`))::
(`nng_tls_config *`)
This option references the underlying
Expand All @@ -72,14 +56,6 @@ longer needs the TLS configuration object.
+
TIP: Use this option when more advanced TLS configuration is required.

[[NNG_OPT_TLS_SERVER_NAME]]((`NNG_OPT_TLS_SERVER_NAME`))::
(string)
This write-only option is used to specify the name of the server.
When used with a dialer, this potentially configures SNI (server name
indication, which is used as a hint by a multihosting server to choose the
appropriate certificate to provide) and also is used to validate the
name presented in the server's x509 certificate.

[[NNG_OPT_TLS_VERIFIED]]((`NNG_OPT_TLS_VERIFIED`))::
(`bool`)
This read-only option indicates whether the remote peer has been properly verified using TLS
Expand Down
13 changes: 0 additions & 13 deletions docs/man/nng_ws.7.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,6 @@ longer needs the TLS configuration.

TIP: Use this option when advanced TLS configuration is required.

((`NNG_OPT_TLS_CA_FILE`))::
(string) Write-only option naming a file containing certificates to
use for peer validation.
See xref:nng_tls_config_ca_file.3tls.adoc[`nng_tls_config_ca_file()`] for more
information.

((`NNG_OPT_TLS_CERT_KEY_FILE`))::
(string) Write-only option naming a file containing the local certificate and
associated private key.
The private key used must be unencrypted.
See xref:nng_tls_config_own_cert.3tls.adoc[`nng_tls_config_own_cert()`] for more
information.

`NNG_OPT_TLS_VERIFIED`::
(`bool`) Whether the remote peer has been properly verified using TLS
authentication.
Expand Down
7 changes: 7 additions & 0 deletions docs/ref/migrate/nng1.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ The `NNG_OPT_WSS_REQUEST_HEADERS` and `NNG_OPT_WSS_RESPONSE_HEADERS` aliases for
Just convert any use of them to `NNG_OPT_WS_REQUEST_HEADERS` or
`NNG_OPT_WS_RESPONSE_HEADERS` as appropriate.

## TLS Options

The support for configuring TLS via `NNG_TLS_AUTH_MODE`, `NNG_OPT_TLS_CA_FILE`, `NNG_OPT_TLS_SERVER_NAME`,
and similar has been removed. Instead configuration must be performed by allocating
a `nng_tls_config` object, and then setting fields on it using the appropriate functions,
after which it may be configured on a listener or dialer using the `NNG_OPT_TLS_CONFIG` option.

## Option Functions

The previously deprecated `nng_pipe_getopt_xxx` family of functions is removed.
Expand Down
21 changes: 0 additions & 21 deletions include/nng/nng.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,27 +741,6 @@ NNG_DECL nng_listener nng_pipe_listener(nng_pipe);
// after the endpoint it is associated with is closed.
#define NNG_OPT_TLS_CONFIG "tls-config"

// NNG_OPT_TLS_CERT_KEY_FILE names a single file that contains a certificate
// and key identifying the endpoint. This is a write-only value. This can be
// set multiple times for different keys/certs corresponding to
// different algorithms on listeners, whereas dialers only support one. The
// file must contain both cert and key as PEM blocks, and the key must
// not be encrypted. (If more flexibility is needed, use the TLS configuration
// directly, via NNG_OPT_TLS_CONFIG.)
#define NNG_OPT_TLS_CERT_KEY_FILE "tls-cert-key-file"

// NNG_OPT_TLS_CA_FILE names a single file that contains certificate(s) for a
// CA, and optionally CRLs, which are used to validate the peer's certificate.
// This is a write-only value, but multiple CAs can be loaded by setting this
// multiple times.
#define NNG_OPT_TLS_CA_FILE "tls-ca-file"

// NNG_OPT_TLS_SERVER_NAME is a write-only string that can typically be
// set on dialers to check the CN of the server for a match. This
// can also affect SNI (server name indication). It usually has no effect
// on listeners.
#define NNG_OPT_TLS_SERVER_NAME "tls-server-name"

// NNG_OPT_TLS_VERIFIED returns a boolean indicating whether the peer has
// been verified (true) or not (false). Typically, this is read-only, and
// only available for pipes. This option may return incorrect results if
Expand Down
125 changes: 0 additions & 125 deletions src/supplemental/tls/tls_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,23 +190,6 @@ tls_dialer_dial(void *arg, nng_aio *aio)
nng_stream_dialer_dial(d->d, &conn->conn_aio);
}

static int
tls_check_string(const void *v, size_t sz, nni_opt_type t)
{
switch (t) {
case NNI_TYPE_OPAQUE:
if (nni_strnlen(v, sz) >= sz) {
return (NNG_EINVAL);
}
return (0);
case NNI_TYPE_STRING:
// Caller is assumed to pass a good string.
return (0);
default:
return (NNG_EBADTYPE);
}
}

static int
tls_dialer_set_config(void *arg, const void *buf, size_t sz, nni_type t)
{
Expand Down Expand Up @@ -249,66 +232,12 @@ tls_dialer_get_config(void *arg, void *buf, size_t *szp, nni_type t)
return (rv);
}

static int
tls_dialer_set_server_name(void *arg, const void *buf, size_t sz, nni_type t)
{
tls_dialer *d = arg;
int rv;
if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&d->lk);
rv = nng_tls_config_server_name(d->cfg, buf);
nni_mtx_unlock(&d->lk);
}
return (rv);
}

static int
tls_dialer_set_ca_file(void *arg, const void *buf, size_t sz, nni_opt_type t)
{
tls_dialer *d = arg;
int rv;

if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&d->lk);
rv = nng_tls_config_ca_file(d->cfg, buf);
nni_mtx_unlock(&d->lk);
}
return (rv);
}

static int
tls_dialer_set_cert_key_file(
void *arg, const void *buf, size_t sz, nni_opt_type t)
{
tls_dialer *d = arg;
int rv;

if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&d->lk);
rv = nng_tls_config_cert_key_file(d->cfg, buf, NULL);
nni_mtx_unlock(&d->lk);
}
return (rv);
}

static const nni_option tls_dialer_opts[] = {
{
.o_name = NNG_OPT_TLS_CONFIG,
.o_get = tls_dialer_get_config,
.o_set = tls_dialer_set_config,
},
{
.o_name = NNG_OPT_TLS_SERVER_NAME,
.o_set = tls_dialer_set_server_name,
},
{
.o_name = NNG_OPT_TLS_CA_FILE,
.o_set = tls_dialer_set_ca_file,
},
{
.o_name = NNG_OPT_TLS_CERT_KEY_FILE,
.o_set = tls_dialer_set_cert_key_file,
},
{
.o_name = NULL,
},
Expand Down Expand Up @@ -487,66 +416,12 @@ tls_listener_get_config(void *arg, void *buf, size_t *szp, nni_type t)
return (rv);
}

static int
tls_listener_set_server_name(void *arg, const void *buf, size_t sz, nni_type t)
{
tls_listener *l = arg;
int rv;
if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&l->lk);
rv = nng_tls_config_server_name(l->cfg, buf);
nni_mtx_unlock(&l->lk);
}
return (rv);
}

static int
tls_listener_set_ca_file(void *arg, const void *buf, size_t sz, nni_opt_type t)
{
tls_listener *l = arg;
int rv;

if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&l->lk);
rv = nng_tls_config_ca_file(l->cfg, buf);
nni_mtx_unlock(&l->lk);
}
return (rv);
}

static int
tls_listener_set_cert_key_file(
void *arg, const void *buf, size_t sz, nni_opt_type t)
{
tls_listener *l = arg;
int rv;

if ((rv = tls_check_string(buf, sz, t)) == 0) {
nni_mtx_lock(&l->lk);
rv = nng_tls_config_cert_key_file(l->cfg, buf, NULL);
nni_mtx_unlock(&l->lk);
}
return (rv);
}

static const nni_option tls_listener_opts[] = {
{
.o_name = NNG_OPT_TLS_CONFIG,
.o_get = tls_listener_get_config,
.o_set = tls_listener_set_config,
},
{
.o_name = NNG_OPT_TLS_SERVER_NAME,
.o_set = tls_listener_set_server_name,
},
{
.o_name = NNG_OPT_TLS_CA_FILE,
.o_set = tls_listener_set_ca_file,
},
{
.o_name = NNG_OPT_TLS_CERT_KEY_FILE,
.o_set = tls_listener_set_cert_key_file,
},
{
.o_name = NULL,
},
Expand Down
41 changes: 21 additions & 20 deletions src/supplemental/websocket/wssfile_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//

#include "core/nng_impl.h"
#include "nng/supplemental/tls/tls.h"

#include <nuts.h>

Expand All @@ -20,26 +21,30 @@
static void
init_dialer_wss_file(nng_dialer d)
{
char *tmpdir;
char *pth;
char *tmpdir;
char *pth;
nng_tls_config *c;

NUTS_ASSERT((tmpdir = nni_plat_temp_dir()) != NULL);
NUTS_ASSERT((pth = nni_file_join(tmpdir, CACERT)) != NULL);
nng_strfree(tmpdir);
NUTS_PASS(nni_file_put(pth, nuts_server_crt, strlen(nuts_server_crt)));
NUTS_PASS(nng_dialer_set_string(d, NNG_OPT_TLS_CA_FILE, pth));
NUTS_PASS(
nng_dialer_set_string(d, NNG_OPT_TLS_SERVER_NAME, "localhost"));
NUTS_PASS(nng_tls_config_alloc(&c, NNG_TLS_MODE_CLIENT));
NUTS_PASS(nng_tls_config_ca_file(c, pth));
NUTS_PASS(nng_tls_config_server_name(c, "localhost"));
NUTS_PASS(nng_dialer_set_ptr(d, NNG_OPT_TLS_CONFIG, c));
nni_file_delete(pth);
nng_strfree(pth);
nng_tls_config_free(c);
}

static void
init_listener_wss_file(nng_listener l)
{
char *tmpdir;
char *pth;
char *cert_key;
char *tmpdir;
char *pth;
char *cert_key;
nng_tls_config *c;

NUTS_ASSERT((tmpdir = nni_plat_temp_dir()) != NULL);
NUTS_ASSERT((pth = nni_file_join(tmpdir, CERT_KEY)) != NULL);
Expand All @@ -50,7 +55,9 @@ init_listener_wss_file(nng_listener l)

NUTS_PASS(nni_file_put(pth, cert_key, strlen(cert_key)));
nng_strfree(cert_key);
NUTS_PASS(nng_listener_set_string(l, NNG_OPT_TLS_CERT_KEY_FILE, pth));
NUTS_PASS(nng_tls_config_alloc(&c, NNG_TLS_MODE_SERVER));
NUTS_PASS(nng_tls_config_cert_key_file(c, pth, pth));
NUTS_PASS(nng_listener_set_ptr(l, NNG_OPT_TLS_CONFIG, c));

nni_file_delete(pth);
nng_strfree(pth);
Expand Down Expand Up @@ -124,8 +131,6 @@ test_no_verify(void)
snprintf(addr, sizeof(addr), "wss://127.0.0.1:%u/test", port);
NUTS_PASS(nng_dialer_create(&d, s2, addr));
init_dialer_wss_file(d);
NUTS_PASS(
nng_dialer_set_string(d, NNG_OPT_TLS_SERVER_NAME, "localhost"));

NUTS_PASS(nng_dialer_start(d, 0));
nng_msleep(100);
Expand Down Expand Up @@ -199,17 +204,13 @@ test_verify_works(void)
static void
test_cert_file_not_present(void)
{
nng_socket s1;
nng_listener l;

NUTS_PASS(nng_pair_open(&s1));
NUTS_PASS(nng_listener_create(&l, s1, "wss4://:0/test"));
nng_tls_config *c;

NUTS_FAIL(nng_listener_set_string(
l, NNG_OPT_TLS_CERT_KEY_FILE, "no-such-file.pem"),
NUTS_PASS(nng_tls_config_alloc(&c, NNG_TLS_MODE_SERVER));
NUTS_FAIL(nng_tls_config_cert_key_file(
c, "no-such-file.pem", "no-such-file.pem"),
NNG_ENOENT);

NUTS_PASS(nng_close(s1));
nng_tls_config_free(c);
}

#endif
Expand Down

0 comments on commit 7f5f857

Please sign in to comment.