diff --git a/docs/man/nng_tls.7.adoc b/docs/man/nng_tls.7.adoc index d4ab2709a..73a63a9f7 100644 --- a/docs/man/nng_tls.7.adoc +++ b/docs/man/nng_tls.7.adoc @@ -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`] diff --git a/docs/man/nng_tls_options.5.adoc b/docs/man/nng_tls_options.5.adoc index 24d63c8dd..cf2a99cfc 100644 --- a/docs/man/nng_tls_options.5.adoc +++ b/docs/man/nng_tls_options.5.adoc @@ -20,10 +20,7 @@ nng_tls_options - TLS-specific options ---- #include -#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" @@ -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 @@ -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 diff --git a/docs/man/nng_ws.7.adoc b/docs/man/nng_ws.7.adoc index 2d6f249cb..07c6cd142 100644 --- a/docs/man/nng_ws.7.adoc +++ b/docs/man/nng_ws.7.adoc @@ -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. diff --git a/docs/ref/migrate/nng1.md b/docs/ref/migrate/nng1.md index f9fe641f6..35224bb8c 100644 --- a/docs/ref/migrate/nng1.md +++ b/docs/ref/migrate/nng1.md @@ -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. diff --git a/include/nng/nng.h b/include/nng/nng.h index c156fbaf8..418995107 100644 --- a/include/nng/nng.h +++ b/include/nng/nng.h @@ -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 diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c index 619022949..02ca1442d 100644 --- a/src/supplemental/tls/tls_common.c +++ b/src/supplemental/tls/tls_common.c @@ -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) { @@ -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, }, @@ -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, }, diff --git a/src/supplemental/websocket/wssfile_test.c b/src/supplemental/websocket/wssfile_test.c index bff686925..d7bcf5a23 100644 --- a/src/supplemental/websocket/wssfile_test.c +++ b/src/supplemental/websocket/wssfile_test.c @@ -9,6 +9,7 @@ // #include "core/nng_impl.h" +#include "nng/supplemental/tls/tls.h" #include @@ -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); @@ -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); @@ -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); @@ -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