pansen
2019-01-28 48e524d7135bff2a32759a642c9aa7298a881e31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// 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 <stddef.h>
#include <stdint.h>
 
// 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