1 /*  Copyright (C) 2016 American Civil Liberties Union (ACLU)
2  *  SPDX-License-Identifier: GPL-3.0-or-later
3 */
4 
5 #pragma once
6 
7 #include <uv.h>
8 #include <gnutls/gnutls.h>
9 #include <libknot/packet/pkt.h>
10 #include "lib/defines.h"
11 #include "lib/generic/array.h"
12 #include "lib/generic/trie.h"
13 #include "lib/utils.h"
14 
15 #define MAX_TLS_PADDING KR_EDNS_PAYLOAD
16 #define TLS_MAX_UNCORK_RETRIES 100
17 
18 /* rfc 5476, 7.3 - handshake Protocol overview
19  * https://tools.ietf.org/html/rfc5246#page-33
20  * Message flow for a full handshake (only mandatory messages)
21  * ClientHello           -------->
22                                         ServerHello
23                          <--------      ServerHelloDone
24    ClientKeyExchange
25    Finished              -------->
26                          <--------      Finished
27  *
28  * See also https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/
29  * So it takes 2 RTT.
30  * As we use session tickets, there are additional messages, add one RTT mode.
31  */
32  #define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * 3)
33 
34 /** Transport session (opaque). */
35 struct session;
36 
37 struct tls_ctx;
38 struct tls_client_ctx;
39 struct tls_credentials {
40 	int count;
41 	char *tls_cert;
42 	char *tls_key;
43 	gnutls_certificate_credentials_t credentials;
44 	time_t valid_until;
45 	char *ephemeral_servicename;
46 };
47 
48 
49 #define TLS_SHA256_RAW_LEN 32 /* gnutls_hash_get_len(GNUTLS_DIG_SHA256) */
50 /** Required buffer length for pin_sha256, including the zero terminator. */
51 #define TLS_SHA256_BASE64_BUFLEN (((TLS_SHA256_RAW_LEN * 8 + 4) / 6) + 3 + 1)
52 
53 #if GNUTLS_VERSION_NUMBER >= 0x030400
54 	#define TLS_CAN_USE_PINS 1
55 #else
56 	#define TLS_CAN_USE_PINS 0
57 #endif
58 
59 
60 /** TLS authentication parameters for a single address-port pair. */
61 typedef struct {
62 	uint32_t refs; /**< Reference count; consider TLS sessions in progress. */
63 	bool insecure; /**< Use no authentication. */
64 	const char *hostname; /**< Server name for SNI and certificate check, lowercased.  */
65 	array_t(const char *) ca_files; /**< Paths to certificate files; not really used. */
66 	array_t(const uint8_t *) pins; /**< Certificate pins as raw unterminated strings.*/
67 	gnutls_certificate_credentials_t credentials; /**< CA creds. in gnutls format.  */
68 	gnutls_datum_t session_data; /**< Session-resumption data gets stored here.    */
69 } tls_client_param_t;
70 /** Holds configuration for TLS authentication for all potential servers.
71  * Special case: NULL pointer also means empty. */
72 typedef trie_t tls_client_params_t;
73 
74 /** Get a pointer-to-pointer to TLS auth params.
75  * If it didn't exist, it returns NULL (if !do_insert) or pointer to NULL. */
76 tls_client_param_t ** tls_client_param_getptr(tls_client_params_t **params,
77 				const struct sockaddr *addr, bool do_insert);
78 
79 /** Get a pointer to TLS auth params or NULL. */
80 static inline tls_client_param_t *
tls_client_param_get(tls_client_params_t * params,const struct sockaddr * addr)81 	tls_client_param_get(tls_client_params_t *params, const struct sockaddr *addr)
82 {
83 	tls_client_param_t **pe = tls_client_param_getptr(&params, addr, false);
84 	return pe ? *pe : NULL;
85 }
86 
87 /** Allocate and initialize the structure (with ->ref = 1). */
88 tls_client_param_t * tls_client_param_new();
89 /** Reference-counted free(); any inside data is freed alongside. */
90 void tls_client_param_unref(tls_client_param_t *entry);
91 
92 int tls_client_param_remove(tls_client_params_t *params, const struct sockaddr *addr);
93 /** Free TLS authentication parameters. */
94 void tls_client_params_free(tls_client_params_t *params);
95 
96 
97 struct worker_ctx;
98 struct qr_task;
99 struct network;
100 struct engine;
101 
102 typedef enum tls_client_hs_state {
103 	TLS_HS_NOT_STARTED = 0,
104 	TLS_HS_IN_PROGRESS,
105 	TLS_HS_DONE,
106 	TLS_HS_CLOSING,
107 	TLS_HS_LAST
108 } tls_hs_state_t;
109 
110 typedef int (*tls_handshake_cb) (struct session *session, int status);
111 
112 
113 struct tls_common_ctx {
114 	bool client_side;
115 	gnutls_session_t tls_session;
116 	tls_hs_state_t handshake_state;
117 	struct session *session;
118 	/* for reading from the network */
119 	const uint8_t *buf;
120 	ssize_t nread;
121 	ssize_t consumed;
122 	uint8_t recv_buf[16384];
123 	tls_handshake_cb handshake_cb;
124 	struct worker_ctx *worker;
125 	size_t write_queue_size;
126 };
127 
128 struct tls_ctx {
129 	/*
130 	 * Since pointer to tls_ctx needs to be casted
131 	 * to  tls_ctx_common in some functions,
132 	 * this field must be always at first position
133 	 */
134 	struct tls_common_ctx c;
135 	struct tls_credentials *credentials;
136 };
137 
138 struct tls_client_ctx {
139 	/*
140 	 * Since pointer to tls_client_ctx needs to be casted
141 	 * to  tls_ctx_common in some functions,
142 	 * this field must be always at first position
143 	 */
144 	struct tls_common_ctx c;
145 	tls_client_param_t *params; /**< It's reference-counted. */
146 };
147 
148 /*! Create an empty TLS context in query context */
149 struct tls_ctx* tls_new(struct worker_ctx *worker);
150 
151 /*! Close a TLS context (call gnutls_bye()) */
152 void tls_close(struct tls_common_ctx *ctx);
153 
154 /*! Release a TLS context */
155 void tls_free(struct tls_ctx* tls);
156 
157 /*! Push new data to TLS context for sending */
158 int tls_write(uv_write_t *req, uv_handle_t* handle, knot_pkt_t * pkt, uv_write_cb cb);
159 
160 /*! Unwrap incoming data from a TLS stream and pass them to TCP session.
161  * @return the number of newly-completed requests (>=0) or an error code
162  */
163 ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nread);
164 
165 /*! Set TLS certificate and key from files. */
166 int tls_certificate_set(struct network *net, const char *tls_cert, const char *tls_key);
167 
168 /*! Borrow TLS credentials for context. */
169 struct tls_credentials *tls_credentials_reserve(struct tls_credentials *tls_credentials);
170 
171 /*! Release TLS credentials for context (decrements refcount or frees). */
172 int tls_credentials_release(struct tls_credentials *tls_credentials);
173 
174 /*! Free TLS credentials, must not be called if it holds positive refcount. */
175 void tls_credentials_free(struct tls_credentials *tls_credentials);
176 
177 /*! Log DNS-over-TLS OOB key-pin form of current credentials:
178  * https://tools.ietf.org/html/rfc7858#appendix-A */
179 void tls_credentials_log_pins(struct tls_credentials *tls_credentials);
180 
181 /*! Generate new ephemeral TLS credentials. */
182 struct tls_credentials * tls_get_ephemeral_credentials(struct engine *engine);
183 
184 /*! Get TLS handshake state. */
185 tls_hs_state_t tls_get_hs_state(const struct tls_common_ctx *ctx);
186 
187 /*! Set TLS handshake state. */
188 int tls_set_hs_state(struct tls_common_ctx *ctx, tls_hs_state_t state);
189 
190 
191 /*! Allocate new client TLS context */
192 struct tls_client_ctx *tls_client_ctx_new(tls_client_param_t *entry,
193 					    struct worker_ctx *worker);
194 
195 /*! Free client TLS context */
196 void tls_client_ctx_free(struct tls_client_ctx *ctx);
197 
198 int tls_client_connect_start(struct tls_client_ctx *client_ctx,
199 			     struct session *session,
200 			     tls_handshake_cb handshake_cb);
201 
202 int tls_client_ctx_set_session(struct tls_client_ctx *ctx, struct session *session);
203 
204 
205 /* Session tickets, server side.  Implementation in ./tls_session_ticket-srv.c */
206 
207 /*! Opaque struct used by tls_session_ticket_* functions. */
208 struct tls_session_ticket_ctx;
209 
210 /*! Suggested maximum reasonable secret length. */
211 #define TLS_SESSION_TICKET_SECRET_MAX_LEN 1024
212 
213 /*! Create a session ticket context and initialize it (secret gets copied inside).
214  *
215  * Passing zero-length secret implies using a random key, i.e. not synchronized
216  * between multiple instances.
217  *
218  * Beware that knowledge of the secret (if nonempty) breaks forward secrecy,
219  * so you should rotate the secret regularly and securely erase all past secrets.
220  * With TLS < 1.3 it's probably too risky to set nonempty secret.
221  */
222 struct tls_session_ticket_ctx * tls_session_ticket_ctx_create(
223 		uv_loop_t *loop, const char *secret, size_t secret_len);
224 
225 /*! Try to enable session tickets for a server session. */
226 void tls_session_ticket_enable(struct tls_session_ticket_ctx *ctx, gnutls_session_t session);
227 
228 /*! Free all resources of the session ticket context.  NULL is accepted as well. */
229 void tls_session_ticket_ctx_destroy(struct tls_session_ticket_ctx *ctx);
230 
231