// // Copyright 2018 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this // file was obtained (LICENSE.txt). A copy of the license may also be // found online at https://opensource.org/licenses/MIT. // #ifndef NNG_SUPPLEMENTAL_TLS_TLS_H #define NNG_SUPPLEMENTAL_TLS_TLS_H #ifdef __cplusplus extern "C" { #endif #include #include // Note that TLS functions may be stubbed out if TLS is not enabled in // the build. // For some transports, we need TLS configuration, including certificates // and so forth. A TLS configuration cannot be changed once it is in use. typedef struct nng_tls_config nng_tls_config; typedef enum nng_tls_mode { NNG_TLS_MODE_CLIENT = 0, NNG_TLS_MODE_SERVER = 1, } nng_tls_mode; typedef enum nng_tls_auth_mode { NNG_TLS_AUTH_MODE_NONE = 0, // No verification is performed NNG_TLS_AUTH_MODE_OPTIONAL = 1, // Verify cert if presented NNG_TLS_AUTH_MODE_REQUIRED = 2, // Verify cert, close if invalid } nng_tls_auth_mode; // nng_tls_config_alloc creates a TLS configuration using // reasonable defaults. This configuration can be shared // with multiple pipes or services/servers. NNG_DECL int nng_tls_config_alloc(nng_tls_config **, nng_tls_mode); // nng_tls_config_hold increments the reference count on the TLS // configuration object. The hold can be dropped by calling // nng_tls_config_free later. NNG_DECL void nng_tls_config_hold(nng_tls_config *); // nng_tls_config_free drops the reference count on the TLS // configuration object, and if zero, deallocates it. NNG_DECL void nng_tls_config_free(nng_tls_config *); // nng_tls_config_server_name sets the server name. This is // called by clients to set the name that the server supplied // certificate should be matched against. This can also cause // the SNI to be sent to the server to tell it which cert to // use if it supports more than one. NNG_DECL int nng_tls_config_server_name(nng_tls_config *, const char *); // nng_tls_config_ca_cert configures one or more CAs used for validation // of peer certificates. Multiple CAs (and their chains) may be configured // by either calling this multiple times, or by specifying a list of // certificates as concatenated data. The final argument is an optional CRL // (revokation list) for the CA, also in PEM. Both PEM strings are ASCIIZ // format (except that the CRL may be NULL). NNG_DECL int nng_tls_config_ca_chain( nng_tls_config *, const char *, const char *); // nng_tls_config_own_cert is used to load our own certificate and public // key. For servers, this may be called more than once to configure multiple // different keys, for example with different algorithms depending on what // the peer supports. On the client, only a single option is available. // The first two arguments are the cert (or validation chain) and the // key as PEM format ASCIIZ strings. The final argument is an optional // password and may be NULL. NNG_DECL int nng_tls_config_own_cert( nng_tls_config *, const char *, const char *, const char *); // nng_tls_config_key is used to pass our own private key. NNG_DECL int nng_tls_config_key(nng_tls_config *, const uint8_t *, size_t); // nng_tls_config_pass is used to pass a password used to decrypt // private keys that are encrypted. NNG_DECL int nng_tls_config_pass(nng_tls_config *, const char *); // nng_tls_config_auth_mode is used to configure the authentication mode use. // The default is that servers have this off (i.e. no client authentication) // and clients have it on (they verify the server), which matches typical // practice. NNG_DECL int nng_tls_config_auth_mode(nng_tls_config *, nng_tls_auth_mode); // nng_tls_config_ca_file is used to pass a CA chain and optional CRL // via the filesystem. If CRL data is present, it must be contained // in the file, along with the CA certificate data. The format is PEM. // The path name must be a legal file name. NNG_DECL int nng_tls_config_ca_file(nng_tls_config *, const char *); // nng_tls_config_cert_key_file is used to pass our own certificate and // private key data via the filesystem. Both the key and certificate // must be present as PEM blocks in the same file. A password is used to // decrypt the private key if it is encrypted and the password supplied is not // NULL. This may be called multiple times on servers, but only once on a // client. (Servers can support multiple different certificates and keys for // different cryptographic algorithms. Clients only get one.) NNG_DECL int nng_tls_config_cert_key_file( nng_tls_config *, const char *, const char *); // The rest of the definitions in this file rely upon having support for the // TLS supplemental API enabled. If you don't have this configured in your // library, then your programs will not link. // nng_tls represents a TLS connection over TCP. typedef struct nng_tls_s nng_tls; // nng_tls_dialer is a dialer that creates TLS connections (nng_tls objects) // by establishing outgoing connections. typedef struct nng_tls_dialer_s nng_tls_dialer; // nng_tls_listener is a listener that creates TLS connections (nng_tls // objects) by accepting incoming connections. typedef struct nng_tls_listener_s nng_tls_listener; // nng_tls_close closes a TLS connection, without releasing the underlying // resources. Use nng_tls_free to release the resources. NNG_DECL void nng_tls_close(nng_tls *); // nng_tls_free frees a TLS connection, and will implicity also close the // connection if not already done so. NNG_DECL void nng_tls_free(nng_tls *); NNG_DECL void nng_tls_send(nng_tls *, nng_aio *); NNG_DECL void nng_tls_recv(nng_tls *, nng_aio *); NNG_DECL int nng_tls_getopt(nng_tls *, const char *, void *, size_t *); // nng_tls_dialer_alloc allocates a dialer that creates TLS connections // (nng_tls structures) by connecting to remote servers. NNG_DECL int nng_tls_dialer_alloc(nng_tls_dialer **); // nng_tls_dialer_close closes the dialer, but does not free it's resources. NNG_DECL void nng_tls_dialer_close(nng_tls_dialer *); // nng_tls_dialer_free frees the dialer, implicitly closing it as well. NNG_DECL void nng_tls_dialer_free(nng_tls_dialer *); // nng_tls_dialer_dial attempts to create a new connection (nng_tls object) // by dialing to the remote server specified in the aio. Note that the // TLS connection may be returned before the TLS handshake is complete. // The remote server will only be verified if a server name has been configured // with the NNG_OPT_TLS_SERVER_NAME option (using nng_tls_dialer_setopt). NNG_DECL void nng_tls_dialer_dial( nng_tls_dialer *, const nng_sockaddr *, nng_aio *); // nng_tls_dialer_getopt returns options from the dialer. NNG_DECL int nng_tls_dialer_getopt( nng_tls_dialer *, const char *, void *, size_t *); // nng_tls_dialer_setopt sets options on the dialer. Options may include // NNG_OPT_TLS_CONFIG, as well as various other NNG_OPT_TLS_ options and // the TCP options that are valid for TCP dialers as well. NNG_DECL int nng_tls_dialer_setopt( nng_tls_dialer *, const char *, const void *, size_t); NNG_DECL int nng_tls_listener_alloc(nng_tls_listener **); NNG_DECL void nng_tls_listener_close(nng_tls_listener *); NNG_DECL void nng_tls_listener_free(nng_tls_listener *); NNG_DECL int nng_tls_listener_listen(nng_tls_listener *, const nng_sockaddr *); NNG_DECL void nng_tls_listener_accept(nng_tls_listener *, nng_aio *); NNG_DECL int nng_tls_listener_getopt( nng_tls_listener *, const char *, void *, size_t *); NNG_DECL int nng_tls_listener_setopt( nng_tls_listener *, const char *, const void *, size_t); #ifdef __cplusplus } #endif #endif // NNG_SUPPLEMENTAL_TLS_TLS_H