From 06d6d80f8c92ef1d3bd7c00c919e10a411183cb3 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 5 Oct 2025 16:51:15 -0700 Subject: fixes #2173 New TLS cert API - replaces the properties for CN and ALTNAMES. This will replace the NNG_OPT_TLS_PEER_ALTNAMES and NNG_OPT_TLS_PEER_CN properties, and gives a bit more access to the certificate, as well as direct access to the raw DER form, which should allow use in other APIs. --- include/nng/http.h | 4 ++++ include/nng/nng.h | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/nng/http.h b/include/nng/http.h index 08099cbe..f8bfb679 100644 --- a/include/nng/http.h +++ b/include/nng/http.h @@ -207,6 +207,10 @@ NNG_DECL void nng_http_set_body(nng_http *, void *, size_t); // makes a local copy. It can fail due to NNG_ENOMEM. NNG_DECL nng_err nng_http_copy_body(nng_http *, const void *, size_t); +// nng_http_peer_cert returns the HTTP peer cert, if the one is available. +// Only available for HTTPS connections. +NNG_DECL nng_err nng_http_peer_cert(nng_http *, nng_tls_cert **); + // nng_http_handler is a handler used on the server side to handle HTTP // requests coming into a specific URL. // diff --git a/include/nng/nng.h b/include/nng/nng.h index fb61b0de..69c5ee89 100644 --- a/include/nng/nng.h +++ b/include/nng/nng.h @@ -24,6 +24,7 @@ extern "C" { #include #include #include +#include // NNG_DECL is used on declarations to deal with scope. // For building Windows DLLs, it should be the appropriate __declspec(). @@ -176,6 +177,10 @@ typedef struct nng_url nng_url; // and so forth. A TLS configuration cannot be changed once it is in use. typedef struct nng_tls_config nng_tls_config; +// This is a representation of X.509 certificate as used in TLS transports. +// Internal details are opaque. +typedef struct nng_tls_cert_s nng_tls_cert; + // Initializers. // clang-format off #define NNG_PIPE_INITIALIZER { 0 } @@ -767,6 +772,7 @@ NNG_DECL nng_err nng_pipe_get_ms(nng_pipe, const char *, nng_duration *); NNG_DECL nng_err nng_pipe_get_size(nng_pipe, const char *, size_t *); NNG_DECL nng_err nng_pipe_get_string(nng_pipe, const char *, char **); NNG_DECL nng_err nng_pipe_get_addr(nng_pipe, const char *, nng_sockaddr *); +NNG_DECL nng_err nng_pipe_peer_cert(nng_pipe, nng_tls_cert **); NNG_DECL nng_err nng_pipe_close(nng_pipe); NNG_DECL int nng_pipe_id(nng_pipe); @@ -803,13 +809,6 @@ NNG_DECL nng_listener nng_pipe_listener(nng_pipe); // peer authentication is disabled with `NNG_TLS_AUTH_MODE_NONE`. #define NNG_OPT_TLS_PEER_CN "tls-peer-cn" -// NNG_OPT_TLS_PEER_ALT_NAMES returns string list with the -// subject alternative names of the peer certificate. Typically this is -// read-only and only available for pipes. This option may return -// incorrect results if peer authentication is disabled with -// `NNG_TLS_AUTH_MODE_NONE`. -#define NNG_OPT_TLS_PEER_ALT_NAMES "tls-peer-alt-names" - // TCP options. These may be supported on various transports that use // TCP underneath such as TLS, or not. @@ -1145,6 +1144,7 @@ NNG_DECL nng_err nng_stream_get_uint64(nng_stream *, const char *, uint64_t *); NNG_DECL nng_err nng_stream_get_string(nng_stream *, const char *, char **); NNG_DECL nng_err nng_stream_get_addr( nng_stream *, const char *, nng_sockaddr *); +NNG_DECL nng_err nng_stream_peer_cert(nng_stream *, nng_tls_cert **); NNG_DECL nng_err nng_stream_dialer_alloc(nng_stream_dialer **, const char *); NNG_DECL nng_err nng_stream_dialer_alloc_url( @@ -1624,6 +1624,30 @@ NNG_DECL const char *nng_tls_engine_description(void); // nng_tls_engine_fips_mode returns true if the engine is in FIPS 140 mode. NNG_DECL bool nng_tls_engine_fips_mode(void); +// nng_tls_cert_parse parses PEM content to obtain an object suitable for +// use with TLS APIs. +NNG_DECL nng_err nng_tls_cert_parse_pem(nng_tls_cert **, const char *, size_t); + +// nng_tls_cert_parse_der parses a DER (distinguished encoding rules) format +// certificate. +NNG_DECL nng_err nng_tls_cert_parse_der( + nng_tls_cert **, const uint8_t *, size_t); + +// nng_tls_cert_der extracts the certificate as DER content. This can be +// useful for importing into other APIs such as OpenSSL or mbedTLS directly. +NNG_DECL void nng_tls_cert_der(nng_tls_cert *cert, uint8_t *, size_t *); + +// nng_tls_cert_free releases the certificate from memory. +NNG_DECL void nng_tls_cert_free(nng_tls_cert *); + +NNG_DECL nng_err nng_tls_cert_subject(nng_tls_cert *, char **); +NNG_DECL nng_err nng_tls_cert_issuer(nng_tls_cert *, char **); +NNG_DECL nng_err nng_tls_cert_serial_number(nng_tls_cert *, char **); +NNG_DECL nng_err nng_tls_cert_subject_cn(nng_tls_cert *, char **); +NNG_DECL nng_err nng_tls_cert_next_alt(nng_tls_cert *, char **); +NNG_DECL nng_err nng_tls_cert_not_before(nng_tls_cert *, struct tm *); +NNG_DECL nng_err nng_tls_cert_not_after(nng_tls_cert *, struct tm *); + // Public ID map support. typedef struct nng_id_map_s nng_id_map; -- cgit v1.2.3-70-g09d2