Commit | Line | Data |
---|---|---|
de0e0e4d | 1 | /* $OpenBSD: tls_server.c,v 1.48 2022/01/19 11:10:55 inoguchi Exp $ */ |
f5b1c8a1 JM |
2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | |
4 | * | |
5 | * Permission to use, copy, modify, and distribute this software for any | |
6 | * purpose with or without fee is hereby granted, provided that the above | |
7 | * copyright notice and this permission notice appear in all copies. | |
8 | * | |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
16 | */ | |
17 | ||
72c33676 MA |
18 | #include <sys/socket.h> |
19 | ||
20 | #include <arpa/inet.h> | |
21 | ||
f5b1c8a1 JM |
22 | #include <openssl/ec.h> |
23 | #include <openssl/err.h> | |
24 | #include <openssl/ssl.h> | |
25 | ||
26 | #include <tls.h> | |
27 | #include "tls_internal.h" | |
28 | ||
29 | struct tls * | |
30 | tls_server(void) | |
31 | { | |
32 | struct tls *ctx; | |
33 | ||
72c33676 MA |
34 | if (tls_init() == -1) |
35 | return (NULL); | |
36 | ||
f5b1c8a1 JM |
37 | if ((ctx = tls_new()) == NULL) |
38 | return (NULL); | |
39 | ||
40 | ctx->flags |= TLS_SERVER; | |
41 | ||
42 | return (ctx); | |
43 | } | |
44 | ||
45 | struct tls * | |
46 | tls_server_conn(struct tls *ctx) | |
47 | { | |
48 | struct tls *conn_ctx; | |
49 | ||
50 | if ((conn_ctx = tls_new()) == NULL) | |
51 | return (NULL); | |
52 | ||
53 | conn_ctx->flags |= TLS_SERVER_CONN; | |
54 | ||
cca6fc52 | 55 | pthread_mutex_lock(&ctx->config->mutex); |
72c33676 | 56 | ctx->config->refcount++; |
cca6fc52 | 57 | pthread_mutex_unlock(&ctx->config->mutex); |
72c33676 MA |
58 | |
59 | conn_ctx->config = ctx->config; | |
60 | conn_ctx->keypair = ctx->config->keypair; | |
61 | ||
f5b1c8a1 JM |
62 | return (conn_ctx); |
63 | } | |
64 | ||
72c33676 MA |
65 | static int |
66 | tls_server_alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, | |
67 | const unsigned char *in, unsigned int inlen, void *arg) | |
68 | { | |
69 | struct tls *ctx = arg; | |
70 | ||
71 | if (SSL_select_next_proto((unsigned char**)out, outlen, | |
72 | ctx->config->alpn, ctx->config->alpn_len, in, inlen) == | |
73 | OPENSSL_NPN_NEGOTIATED) | |
74 | return (SSL_TLSEXT_ERR_OK); | |
75 | ||
76 | return (SSL_TLSEXT_ERR_NOACK); | |
77 | } | |
78 | ||
79 | static int | |
80 | tls_servername_cb(SSL *ssl, int *al, void *arg) | |
81 | { | |
82 | struct tls *ctx = (struct tls *)arg; | |
83 | struct tls_sni_ctx *sni_ctx; | |
84 | union tls_addr addrbuf; | |
85 | struct tls *conn_ctx; | |
86 | const char *name; | |
87 | int match; | |
88 | ||
89 | if ((conn_ctx = SSL_get_app_data(ssl)) == NULL) | |
90 | goto err; | |
91 | ||
92 | if ((name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) == | |
93 | NULL) { | |
94 | /* | |
95 | * The servername callback gets called even when there is no | |
96 | * TLS servername extension provided by the client. Sigh! | |
97 | */ | |
98 | return (SSL_TLSEXT_ERR_NOACK); | |
99 | } | |
100 | ||
101 | /* | |
102 | * Per RFC 6066 section 3: ensure that name is not an IP literal. | |
103 | * | |
104 | * While we should treat this as an error, a number of clients | |
105 | * (Python, Ruby and Safari) are not RFC compliant. To avoid handshake | |
106 | * failures, pretend that we did not receive the extension. | |
107 | */ | |
108 | if (inet_pton(AF_INET, name, &addrbuf) == 1 || | |
109 | inet_pton(AF_INET6, name, &addrbuf) == 1) | |
110 | return (SSL_TLSEXT_ERR_NOACK); | |
111 | ||
de0e0e4d | 112 | free(conn_ctx->servername); |
72c33676 MA |
113 | if ((conn_ctx->servername = strdup(name)) == NULL) |
114 | goto err; | |
115 | ||
116 | /* Find appropriate SSL context for requested servername. */ | |
117 | for (sni_ctx = ctx->sni_ctx; sni_ctx != NULL; sni_ctx = sni_ctx->next) { | |
118 | if (tls_check_name(ctx, sni_ctx->ssl_cert, name, | |
119 | &match) == -1) | |
120 | goto err; | |
121 | if (match) { | |
122 | conn_ctx->keypair = sni_ctx->keypair; | |
123 | SSL_set_SSL_CTX(conn_ctx->ssl_conn, sni_ctx->ssl_ctx); | |
124 | return (SSL_TLSEXT_ERR_OK); | |
125 | } | |
126 | } | |
127 | ||
128 | /* No match, use the existing context/certificate. */ | |
129 | return (SSL_TLSEXT_ERR_OK); | |
130 | ||
131 | err: | |
132 | /* | |
133 | * There is no way to tell libssl that an internal failure occurred. | |
134 | * The only option we have is to return a fatal alert. | |
135 | */ | |
de0e0e4d | 136 | *al = SSL_AD_INTERNAL_ERROR; |
72c33676 MA |
137 | return (SSL_TLSEXT_ERR_ALERT_FATAL); |
138 | } | |
139 | ||
140 | static struct tls_ticket_key * | |
141 | tls_server_ticket_key(struct tls_config *config, unsigned char *keyname) | |
142 | { | |
143 | struct tls_ticket_key *key = NULL; | |
144 | time_t now; | |
145 | int i; | |
146 | ||
147 | now = time(NULL); | |
148 | if (config->ticket_autorekey == 1) { | |
149 | if (now - 3 * (config->session_lifetime / 4) > | |
150 | config->ticket_keys[0].time) { | |
151 | if (tls_config_ticket_autorekey(config) == -1) | |
152 | return (NULL); | |
153 | } | |
154 | } | |
155 | for (i = 0; i < TLS_NUM_TICKETS; i++) { | |
156 | struct tls_ticket_key *tk = &config->ticket_keys[i]; | |
157 | if (now - config->session_lifetime > tk->time) | |
158 | continue; | |
159 | if (keyname == NULL || timingsafe_memcmp(keyname, | |
160 | tk->key_name, sizeof(tk->key_name)) == 0) { | |
161 | key = tk; | |
162 | break; | |
163 | } | |
164 | } | |
165 | return (key); | |
166 | } | |
167 | ||
168 | static int | |
169 | tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv, | |
170 | EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int mode) | |
171 | { | |
172 | struct tls_ticket_key *key; | |
173 | struct tls *tls_ctx; | |
174 | ||
175 | if ((tls_ctx = SSL_get_app_data(ssl)) == NULL) | |
176 | return (-1); | |
177 | ||
178 | if (mode == 1) { | |
179 | /* create new session */ | |
180 | key = tls_server_ticket_key(tls_ctx->config, NULL); | |
181 | if (key == NULL) { | |
182 | tls_set_errorx(tls_ctx, "no valid ticket key found"); | |
183 | return (-1); | |
184 | } | |
185 | ||
186 | memcpy(keyname, key->key_name, sizeof(key->key_name)); | |
187 | arc4random_buf(iv, EVP_MAX_IV_LENGTH); | |
de0e0e4d AHJ |
188 | if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, |
189 | key->aes_key, iv)) { | |
190 | tls_set_errorx(tls_ctx, "failed to init encrypt"); | |
191 | return (-1); | |
192 | } | |
193 | if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), | |
194 | EVP_sha256(), NULL)) { | |
195 | tls_set_errorx(tls_ctx, "failed to init hmac"); | |
196 | return (-1); | |
197 | } | |
72c33676 MA |
198 | return (0); |
199 | } else { | |
200 | /* get key by name */ | |
201 | key = tls_server_ticket_key(tls_ctx->config, keyname); | |
202 | if (key == NULL) | |
203 | return (0); | |
204 | ||
de0e0e4d AHJ |
205 | if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, |
206 | key->aes_key, iv)) { | |
207 | tls_set_errorx(tls_ctx, "failed to init decrypt"); | |
208 | return (-1); | |
209 | } | |
210 | if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), | |
211 | EVP_sha256(), NULL)) { | |
212 | tls_set_errorx(tls_ctx, "failed to init hmac"); | |
213 | return (-1); | |
214 | } | |
72c33676 MA |
215 | |
216 | /* time to renew the ticket? is it the primary key? */ | |
217 | if (key != &tls_ctx->config->ticket_keys[0]) | |
218 | return (2); | |
219 | return (1); | |
220 | } | |
221 | } | |
222 | ||
223 | static int | |
224 | tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, | |
225 | struct tls_keypair *keypair) | |
f5b1c8a1 | 226 | { |
72c33676 | 227 | SSL_CTX_free(*ssl_ctx); |
f5b1c8a1 | 228 | |
72c33676 | 229 | if ((*ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) { |
f5b1c8a1 JM |
230 | tls_set_errorx(ctx, "ssl context failure"); |
231 | goto err; | |
232 | } | |
233 | ||
72c33676 MA |
234 | SSL_CTX_set_options(*ssl_ctx, SSL_OP_NO_CLIENT_RENEGOTIATION); |
235 | ||
236 | if (SSL_CTX_set_tlsext_servername_callback(*ssl_ctx, | |
237 | tls_servername_cb) != 1) { | |
238 | tls_set_error(ctx, "failed to set servername callback"); | |
239 | goto err; | |
240 | } | |
241 | if (SSL_CTX_set_tlsext_servername_arg(*ssl_ctx, ctx) != 1) { | |
242 | tls_set_error(ctx, "failed to set servername callback arg"); | |
243 | goto err; | |
244 | } | |
245 | ||
246 | if (tls_configure_ssl(ctx, *ssl_ctx) != 0) | |
f5b1c8a1 | 247 | goto err; |
72c33676 | 248 | if (tls_configure_ssl_keypair(ctx, *ssl_ctx, keypair, 1) != 0) |
f5b1c8a1 JM |
249 | goto err; |
250 | if (ctx->config->verify_client != 0) { | |
251 | int verify = SSL_VERIFY_PEER; | |
252 | if (ctx->config->verify_client == 1) | |
253 | verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; | |
72c33676 | 254 | if (tls_configure_ssl_verify(ctx, *ssl_ctx, verify) == -1) |
f5b1c8a1 JM |
255 | goto err; |
256 | } | |
257 | ||
72c33676 MA |
258 | if (ctx->config->alpn != NULL) |
259 | SSL_CTX_set_alpn_select_cb(*ssl_ctx, tls_server_alpn_cb, | |
260 | ctx); | |
261 | ||
f5b1c8a1 | 262 | if (ctx->config->dheparams == -1) |
72c33676 | 263 | SSL_CTX_set_dh_auto(*ssl_ctx, 1); |
f5b1c8a1 | 264 | else if (ctx->config->dheparams == 1024) |
72c33676 MA |
265 | SSL_CTX_set_dh_auto(*ssl_ctx, 2); |
266 | ||
267 | if (ctx->config->ecdhecurves != NULL) { | |
268 | SSL_CTX_set_ecdh_auto(*ssl_ctx, 1); | |
269 | if (SSL_CTX_set1_groups(*ssl_ctx, ctx->config->ecdhecurves, | |
270 | ctx->config->ecdhecurves_len) != 1) { | |
271 | tls_set_errorx(ctx, "failed to set ecdhe curves"); | |
f5b1c8a1 JM |
272 | goto err; |
273 | } | |
f5b1c8a1 JM |
274 | } |
275 | ||
276 | if (ctx->config->ciphers_server == 1) | |
72c33676 | 277 | SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); |
f5b1c8a1 | 278 | |
72c33676 MA |
279 | if (SSL_CTX_set_tlsext_status_cb(*ssl_ctx, tls_ocsp_stapling_cb) != 1) { |
280 | tls_set_errorx(ctx, "failed to add OCSP stapling callback"); | |
281 | goto err; | |
282 | } | |
283 | ||
284 | if (ctx->config->session_lifetime > 0) { | |
285 | /* set the session lifetime and enable tickets */ | |
286 | SSL_CTX_set_timeout(*ssl_ctx, ctx->config->session_lifetime); | |
287 | SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET); | |
288 | if (!SSL_CTX_set_tlsext_ticket_key_cb(*ssl_ctx, | |
289 | tls_server_ticket_cb)) { | |
290 | tls_set_error(ctx, | |
291 | "failed to set the TLS ticket callback"); | |
292 | goto err; | |
293 | } | |
294 | } | |
295 | ||
296 | if (SSL_CTX_set_session_id_context(*ssl_ctx, ctx->config->session_id, | |
297 | sizeof(ctx->config->session_id)) != 1) { | |
298 | tls_set_error(ctx, "failed to set session id context"); | |
f5b1c8a1 JM |
299 | goto err; |
300 | } | |
301 | ||
302 | return (0); | |
303 | ||
72c33676 MA |
304 | err: |
305 | SSL_CTX_free(*ssl_ctx); | |
306 | *ssl_ctx = NULL; | |
307 | ||
308 | return (-1); | |
309 | } | |
310 | ||
311 | static int | |
312 | tls_configure_server_sni(struct tls *ctx) | |
313 | { | |
314 | struct tls_sni_ctx **sni_ctx; | |
315 | struct tls_keypair *kp; | |
316 | ||
317 | if (ctx->config->keypair->next == NULL) | |
318 | return (0); | |
319 | ||
320 | /* Set up additional SSL contexts for SNI. */ | |
321 | sni_ctx = &ctx->sni_ctx; | |
322 | for (kp = ctx->config->keypair->next; kp != NULL; kp = kp->next) { | |
323 | if ((*sni_ctx = tls_sni_ctx_new()) == NULL) { | |
324 | tls_set_errorx(ctx, "out of memory"); | |
325 | goto err; | |
326 | } | |
327 | (*sni_ctx)->keypair = kp; | |
328 | if (tls_configure_server_ssl(ctx, &(*sni_ctx)->ssl_ctx, kp) == -1) | |
329 | goto err; | |
330 | if (tls_keypair_load_cert(kp, &ctx->error, | |
331 | &(*sni_ctx)->ssl_cert) == -1) | |
332 | goto err; | |
333 | sni_ctx = &(*sni_ctx)->next; | |
334 | } | |
335 | ||
336 | return (0); | |
337 | ||
f5b1c8a1 JM |
338 | err: |
339 | return (-1); | |
340 | } | |
341 | ||
342 | int | |
72c33676 | 343 | tls_configure_server(struct tls *ctx) |
f5b1c8a1 | 344 | { |
72c33676 MA |
345 | if (tls_configure_server_ssl(ctx, &ctx->ssl_ctx, |
346 | ctx->config->keypair) == -1) | |
347 | goto err; | |
348 | if (tls_configure_server_sni(ctx) == -1) | |
349 | goto err; | |
350 | ||
351 | return (0); | |
352 | ||
353 | err: | |
354 | return (-1); | |
f5b1c8a1 JM |
355 | } |
356 | ||
72c33676 MA |
357 | static struct tls * |
358 | tls_accept_common(struct tls *ctx) | |
f5b1c8a1 JM |
359 | { |
360 | struct tls *conn_ctx = NULL; | |
361 | ||
362 | if ((ctx->flags & TLS_SERVER) == 0) { | |
363 | tls_set_errorx(ctx, "not a server context"); | |
364 | goto err; | |
365 | } | |
366 | ||
367 | if ((conn_ctx = tls_server_conn(ctx)) == NULL) { | |
368 | tls_set_errorx(ctx, "connection context failure"); | |
369 | goto err; | |
370 | } | |
371 | ||
372 | if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { | |
373 | tls_set_errorx(ctx, "ssl failure"); | |
374 | goto err; | |
375 | } | |
72c33676 | 376 | |
f5b1c8a1 JM |
377 | if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { |
378 | tls_set_errorx(ctx, "ssl application data failure"); | |
379 | goto err; | |
380 | } | |
72c33676 MA |
381 | |
382 | return conn_ctx; | |
383 | ||
384 | err: | |
385 | tls_free(conn_ctx); | |
386 | ||
387 | return (NULL); | |
388 | } | |
389 | ||
390 | int | |
391 | tls_accept_socket(struct tls *ctx, struct tls **cctx, int s) | |
392 | { | |
393 | return (tls_accept_fds(ctx, cctx, s, s)); | |
394 | } | |
395 | ||
396 | int | |
397 | tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write) | |
398 | { | |
399 | struct tls *conn_ctx; | |
400 | ||
401 | if ((conn_ctx = tls_accept_common(ctx)) == NULL) | |
402 | goto err; | |
403 | ||
f5b1c8a1 JM |
404 | if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || |
405 | SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { | |
406 | tls_set_errorx(ctx, "ssl file descriptor failure"); | |
407 | goto err; | |
408 | } | |
409 | ||
410 | *cctx = conn_ctx; | |
411 | ||
412 | return (0); | |
f5b1c8a1 JM |
413 | err: |
414 | tls_free(conn_ctx); | |
72c33676 MA |
415 | *cctx = NULL; |
416 | ||
417 | return (-1); | |
418 | } | |
419 | ||
420 | int | |
421 | tls_accept_cbs(struct tls *ctx, struct tls **cctx, | |
422 | tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg) | |
423 | { | |
424 | struct tls *conn_ctx; | |
425 | ||
426 | if ((conn_ctx = tls_accept_common(ctx)) == NULL) | |
427 | goto err; | |
f5b1c8a1 | 428 | |
72c33676 MA |
429 | if (tls_set_cbs(conn_ctx, read_cb, write_cb, cb_arg) != 0) |
430 | goto err; | |
431 | ||
432 | *cctx = conn_ctx; | |
433 | ||
434 | return (0); | |
435 | err: | |
436 | tls_free(conn_ctx); | |
f5b1c8a1 JM |
437 | *cctx = NULL; |
438 | ||
439 | return (-1); | |
440 | } | |
441 | ||
442 | int | |
443 | tls_handshake_server(struct tls *ctx) | |
444 | { | |
445 | int ssl_ret; | |
446 | int rv = -1; | |
447 | ||
448 | if ((ctx->flags & TLS_SERVER_CONN) == 0) { | |
449 | tls_set_errorx(ctx, "not a server connection context"); | |
450 | goto err; | |
451 | } | |
452 | ||
72c33676 MA |
453 | ctx->state |= TLS_SSL_NEEDS_SHUTDOWN; |
454 | ||
f5b1c8a1 JM |
455 | ERR_clear_error(); |
456 | if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) { | |
457 | rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); | |
458 | goto err; | |
459 | } | |
460 | ||
461 | ctx->state |= TLS_HANDSHAKE_COMPLETE; | |
462 | rv = 0; | |
463 | ||
464 | err: | |
465 | return (rv); | |
466 | } |