xref: /openbsd/lib/libtls/tls_server.c (revision 40ae7d6b)
1*40ae7d6bSjoshua /* $OpenBSD: tls_server.c,v 1.51 2024/03/26 08:54:48 joshua Exp $ */
2b600beedSjsing /*
3b600beedSjsing  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4b600beedSjsing  *
5b600beedSjsing  * Permission to use, copy, modify, and distribute this software for any
6b600beedSjsing  * purpose with or without fee is hereby granted, provided that the above
7b600beedSjsing  * copyright notice and this permission notice appear in all copies.
8b600beedSjsing  *
9b600beedSjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10b600beedSjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11b600beedSjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12b600beedSjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13b600beedSjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14b600beedSjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15b600beedSjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16b600beedSjsing  */
17b600beedSjsing 
18f89edc01Sjsing #include <sys/socket.h>
19f89edc01Sjsing 
20f89edc01Sjsing #include <arpa/inet.h>
21f89edc01Sjsing 
22e6d77be9Sop #include <string.h>
23e6d77be9Sop 
24b600beedSjsing #include <openssl/ec.h>
259ba095aaSjsing #include <openssl/err.h>
26b600beedSjsing #include <openssl/ssl.h>
27b600beedSjsing 
28b600beedSjsing #include <tls.h>
29b600beedSjsing #include "tls_internal.h"
30b600beedSjsing 
31b600beedSjsing struct tls *
tls_server(void)32b600beedSjsing tls_server(void)
33b600beedSjsing {
34b600beedSjsing 	struct tls *ctx;
35b600beedSjsing 
36b9573a74Sjsing 	if (tls_init() == -1)
37b9573a74Sjsing 		return (NULL);
38b9573a74Sjsing 
39b600beedSjsing 	if ((ctx = tls_new()) == NULL)
40b600beedSjsing 		return (NULL);
41b600beedSjsing 
42b600beedSjsing 	ctx->flags |= TLS_SERVER;
43b600beedSjsing 
44b600beedSjsing 	return (ctx);
45b600beedSjsing }
46b600beedSjsing 
47b600beedSjsing struct tls *
tls_server_conn(struct tls * ctx)48b600beedSjsing tls_server_conn(struct tls *ctx)
49b600beedSjsing {
50b600beedSjsing 	struct tls *conn_ctx;
51b600beedSjsing 
52b600beedSjsing 	if ((conn_ctx = tls_new()) == NULL)
53b600beedSjsing 		return (NULL);
54b600beedSjsing 
55b600beedSjsing 	conn_ctx->flags |= TLS_SERVER_CONN;
5688c10dabSjsing 
57565eed69Sbcook 	pthread_mutex_lock(&ctx->config->mutex);
5888c10dabSjsing 	ctx->config->refcount++;
59565eed69Sbcook 	pthread_mutex_unlock(&ctx->config->mutex);
609ee433b9Sjsing 
61668bec95Sbeck 	conn_ctx->config = ctx->config;
629ee433b9Sjsing 	conn_ctx->keypair = ctx->config->keypair;
63b600beedSjsing 
64b600beedSjsing 	return (conn_ctx);
65b600beedSjsing }
66b600beedSjsing 
67183da8c6Sjsing static int
tls_server_alpn_cb(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)68183da8c6Sjsing tls_server_alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
69183da8c6Sjsing     const unsigned char *in, unsigned int inlen, void *arg)
70183da8c6Sjsing {
71183da8c6Sjsing 	struct tls *ctx = arg;
72183da8c6Sjsing 
73183da8c6Sjsing 	if (SSL_select_next_proto((unsigned char**)out, outlen,
74183da8c6Sjsing 	    ctx->config->alpn, ctx->config->alpn_len, in, inlen) ==
75183da8c6Sjsing 	    OPENSSL_NPN_NEGOTIATED)
76183da8c6Sjsing 		return (SSL_TLSEXT_ERR_OK);
77183da8c6Sjsing 
78183da8c6Sjsing 	return (SSL_TLSEXT_ERR_NOACK);
79183da8c6Sjsing }
80183da8c6Sjsing 
81991d42a1Sjsing static int
tls_servername_cb(SSL * ssl,int * al,void * arg)82f89edc01Sjsing tls_servername_cb(SSL *ssl, int *al, void *arg)
83f89edc01Sjsing {
84f89edc01Sjsing 	struct tls *ctx = (struct tls *)arg;
85f89edc01Sjsing 	struct tls_sni_ctx *sni_ctx;
86f89edc01Sjsing 	union tls_addr addrbuf;
87f89edc01Sjsing 	struct tls *conn_ctx;
88f89edc01Sjsing 	const char *name;
895f3c5205Sjsing 	int match;
90f89edc01Sjsing 
91f89edc01Sjsing 	if ((conn_ctx = SSL_get_app_data(ssl)) == NULL)
92f89edc01Sjsing 		goto err;
93f89edc01Sjsing 
945f3c5205Sjsing 	if ((name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) ==
955f3c5205Sjsing 	    NULL) {
96f89edc01Sjsing 		/*
97f89edc01Sjsing 		 * The servername callback gets called even when there is no
98f89edc01Sjsing 		 * TLS servername extension provided by the client. Sigh!
99f89edc01Sjsing 		 */
100f89edc01Sjsing 		return (SSL_TLSEXT_ERR_NOACK);
101f89edc01Sjsing 	}
102f89edc01Sjsing 
103dd391ab5Sjsing 	/*
104dd391ab5Sjsing 	 * Per RFC 6066 section 3: ensure that name is not an IP literal.
105dd391ab5Sjsing 	 *
106dd391ab5Sjsing 	 * While we should treat this as an error, a number of clients
107dd391ab5Sjsing 	 * (Python, Ruby and Safari) are not RFC compliant. To avoid handshake
108dd391ab5Sjsing 	 * failures, pretend that we did not receive the extension.
109dd391ab5Sjsing 	 */
110f89edc01Sjsing 	if (inet_pton(AF_INET, name, &addrbuf) == 1 ||
111f89edc01Sjsing             inet_pton(AF_INET6, name, &addrbuf) == 1)
112dd391ab5Sjsing 		return (SSL_TLSEXT_ERR_NOACK);
113f89edc01Sjsing 
11409626e4bStb 	free(conn_ctx->servername);
115f89edc01Sjsing 	if ((conn_ctx->servername = strdup(name)) == NULL)
116f89edc01Sjsing 		goto err;
117f89edc01Sjsing 
118f89edc01Sjsing 	/* Find appropriate SSL context for requested servername. */
119f89edc01Sjsing 	for (sni_ctx = ctx->sni_ctx; sni_ctx != NULL; sni_ctx = sni_ctx->next) {
1205f3c5205Sjsing 		if (tls_check_name(ctx, sni_ctx->ssl_cert, name,
1215f3c5205Sjsing 		    &match) == -1)
1225f3c5205Sjsing 			goto err;
1235f3c5205Sjsing 		if (match) {
1249ee433b9Sjsing 			conn_ctx->keypair = sni_ctx->keypair;
125f89edc01Sjsing 			SSL_set_SSL_CTX(conn_ctx->ssl_conn, sni_ctx->ssl_ctx);
126f89edc01Sjsing 			return (SSL_TLSEXT_ERR_OK);
127f89edc01Sjsing 		}
128f89edc01Sjsing 	}
129f89edc01Sjsing 
130f89edc01Sjsing 	/* No match, use the existing context/certificate. */
131f89edc01Sjsing 	return (SSL_TLSEXT_ERR_OK);
132f89edc01Sjsing 
133f89edc01Sjsing  err:
134f89edc01Sjsing 	/*
135f89edc01Sjsing 	 * There is no way to tell libssl that an internal failure occurred.
136f89edc01Sjsing 	 * The only option we have is to return a fatal alert.
137f89edc01Sjsing 	 */
13879d77232Stb 	*al = SSL_AD_INTERNAL_ERROR;
139f89edc01Sjsing 	return (SSL_TLSEXT_ERR_ALERT_FATAL);
140f89edc01Sjsing }
141f89edc01Sjsing 
14247c43cfeSclaudio static struct tls_ticket_key *
tls_server_ticket_key(struct tls_config * config,unsigned char * keyname)14347c43cfeSclaudio tls_server_ticket_key(struct tls_config *config, unsigned char *keyname)
14447c43cfeSclaudio {
14547c43cfeSclaudio 	struct tls_ticket_key *key = NULL;
14647c43cfeSclaudio 	time_t now;
14747c43cfeSclaudio 	int i;
14847c43cfeSclaudio 
14947c43cfeSclaudio 	now = time(NULL);
15047c43cfeSclaudio 	if (config->ticket_autorekey == 1) {
15147c43cfeSclaudio 		if (now - 3 * (config->session_lifetime / 4) >
15247c43cfeSclaudio 		    config->ticket_keys[0].time) {
15347c43cfeSclaudio 			if (tls_config_ticket_autorekey(config) == -1)
15447c43cfeSclaudio 				return (NULL);
15547c43cfeSclaudio 		}
15647c43cfeSclaudio 	}
15747c43cfeSclaudio 	for (i = 0; i < TLS_NUM_TICKETS; i++) {
15847c43cfeSclaudio 		struct tls_ticket_key *tk = &config->ticket_keys[i];
15947c43cfeSclaudio 		if (now - config->session_lifetime > tk->time)
16047c43cfeSclaudio 			continue;
16147c43cfeSclaudio 		if (keyname == NULL || timingsafe_memcmp(keyname,
16247c43cfeSclaudio 		    tk->key_name, sizeof(tk->key_name)) == 0) {
16347c43cfeSclaudio 			key = tk;
16447c43cfeSclaudio 			break;
16547c43cfeSclaudio 		}
16647c43cfeSclaudio 	}
16747c43cfeSclaudio 	return (key);
16847c43cfeSclaudio }
16947c43cfeSclaudio 
17047c43cfeSclaudio static int
tls_server_ticket_cb(SSL * ssl,unsigned char * keyname,unsigned char * iv,EVP_CIPHER_CTX * ctx,HMAC_CTX * hctx,int mode)17147c43cfeSclaudio tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
17247c43cfeSclaudio     EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int mode)
17347c43cfeSclaudio {
17447c43cfeSclaudio 	struct tls_ticket_key *key;
17547c43cfeSclaudio 	struct tls *tls_ctx;
17647c43cfeSclaudio 
17747c43cfeSclaudio 	if ((tls_ctx = SSL_get_app_data(ssl)) == NULL)
17847c43cfeSclaudio 		return (-1);
17947c43cfeSclaudio 
18047c43cfeSclaudio 	if (mode == 1) {
18147c43cfeSclaudio 		/* create new session */
18247c43cfeSclaudio 		key = tls_server_ticket_key(tls_ctx->config, NULL);
18347c43cfeSclaudio 		if (key == NULL) {
1847a756d37Sjoshua 			tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
1857a756d37Sjoshua 			    "no valid ticket key found");
18647c43cfeSclaudio 			return (-1);
18747c43cfeSclaudio 		}
18847c43cfeSclaudio 
18947c43cfeSclaudio 		memcpy(keyname, key->key_name, sizeof(key->key_name));
19047c43cfeSclaudio 		arc4random_buf(iv, EVP_MAX_IV_LENGTH);
191bcc534f9Sinoguchi 		if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
192bcc534f9Sinoguchi 		    key->aes_key, iv)) {
1937a756d37Sjoshua 			tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
1947a756d37Sjoshua 			    "failed to init encrypt");
195bcc534f9Sinoguchi 			return (-1);
196bcc534f9Sinoguchi 		}
197bcc534f9Sinoguchi 		if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
198bcc534f9Sinoguchi 		    EVP_sha256(), NULL)) {
1997a756d37Sjoshua 			tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
2007a756d37Sjoshua 			    "failed to init hmac");
201bcc534f9Sinoguchi 			return (-1);
202bcc534f9Sinoguchi 		}
20347c43cfeSclaudio 		return (0);
20447c43cfeSclaudio 	} else {
20547c43cfeSclaudio 		/* get key by name */
20647c43cfeSclaudio 		key = tls_server_ticket_key(tls_ctx->config, keyname);
20747c43cfeSclaudio 		if (key == NULL)
20847c43cfeSclaudio 			return (0);
20947c43cfeSclaudio 
210bcc534f9Sinoguchi 		if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
211bcc534f9Sinoguchi 		    key->aes_key, iv)) {
2127a756d37Sjoshua 			tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
2137a756d37Sjoshua 			    "failed to init decrypt");
214bcc534f9Sinoguchi 			return (-1);
215bcc534f9Sinoguchi 		}
216bcc534f9Sinoguchi 		if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
217bcc534f9Sinoguchi 		    EVP_sha256(), NULL)) {
2187a756d37Sjoshua 			tls_set_errorx(tls_ctx, TLS_ERROR_UNKNOWN,
2197a756d37Sjoshua 			    "failed to init hmac");
220bcc534f9Sinoguchi 			return (-1);
221bcc534f9Sinoguchi 		}
22247c43cfeSclaudio 
22347c43cfeSclaudio 		/* time to renew the ticket? is it the primary key? */
22447c43cfeSclaudio 		if (key != &tls_ctx->config->ticket_keys[0])
22547c43cfeSclaudio 			return (2);
22647c43cfeSclaudio 		return (1);
22747c43cfeSclaudio 	}
22847c43cfeSclaudio }
22947c43cfeSclaudio 
230f89edc01Sjsing static int
tls_configure_server_ssl(struct tls * ctx,SSL_CTX ** ssl_ctx,struct tls_keypair * keypair)231991d42a1Sjsing tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
232991d42a1Sjsing     struct tls_keypair *keypair)
233b600beedSjsing {
234991d42a1Sjsing 	SSL_CTX_free(*ssl_ctx);
235991d42a1Sjsing 
236991d42a1Sjsing 	if ((*ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
2377a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl context failure");
238b600beedSjsing 		goto err;
239b600beedSjsing 	}
240b600beedSjsing 
241f61da50dSjsing 	SSL_CTX_set_options(*ssl_ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
242f61da50dSjsing 
243f89edc01Sjsing 	if (SSL_CTX_set_tlsext_servername_callback(*ssl_ctx,
244f89edc01Sjsing 	    tls_servername_cb) != 1) {
2457a756d37Sjoshua 		tls_set_error(ctx, TLS_ERROR_UNKNOWN,
2467a756d37Sjoshua 		    "failed to set servername callback");
247f89edc01Sjsing 		goto err;
248f89edc01Sjsing 	}
249f89edc01Sjsing 	if (SSL_CTX_set_tlsext_servername_arg(*ssl_ctx, ctx) != 1) {
2507a756d37Sjoshua 		tls_set_error(ctx, TLS_ERROR_UNKNOWN,
2517a756d37Sjoshua 		    "failed to set servername callback arg");
252f89edc01Sjsing 		goto err;
253f89edc01Sjsing 	}
254f89edc01Sjsing 
255991d42a1Sjsing 	if (tls_configure_ssl(ctx, *ssl_ctx) != 0)
256b600beedSjsing 		goto err;
257991d42a1Sjsing 	if (tls_configure_ssl_keypair(ctx, *ssl_ctx, keypair, 1) != 0)
258b600beedSjsing 		goto err;
25951f3bd3dSbeck 	if (ctx->config->verify_client != 0) {
26051f3bd3dSbeck 		int verify = SSL_VERIFY_PEER;
26151f3bd3dSbeck 		if (ctx->config->verify_client == 1)
26251f3bd3dSbeck 			verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
263991d42a1Sjsing 		if (tls_configure_ssl_verify(ctx, *ssl_ctx, verify) == -1)
26451f3bd3dSbeck 			goto err;
26551f3bd3dSbeck 	}
266b600beedSjsing 
267183da8c6Sjsing 	if (ctx->config->alpn != NULL)
268991d42a1Sjsing 		SSL_CTX_set_alpn_select_cb(*ssl_ctx, tls_server_alpn_cb,
269183da8c6Sjsing 		    ctx);
270183da8c6Sjsing 
2719e5deb48Sjsing 	if (ctx->config->dheparams == -1)
272991d42a1Sjsing 		SSL_CTX_set_dh_auto(*ssl_ctx, 1);
2739e5deb48Sjsing 	else if (ctx->config->dheparams == 1024)
274991d42a1Sjsing 		SSL_CTX_set_dh_auto(*ssl_ctx, 2);
2759e5deb48Sjsing 
2764896de1eSjsing 	if (ctx->config->ecdhecurves != NULL) {
277991d42a1Sjsing 		SSL_CTX_set_ecdh_auto(*ssl_ctx, 1);
2784896de1eSjsing 		if (SSL_CTX_set1_groups(*ssl_ctx, ctx->config->ecdhecurves,
2794896de1eSjsing 		    ctx->config->ecdhecurves_len) != 1) {
2807a756d37Sjoshua 			tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
2817a756d37Sjoshua 			    "failed to set ecdhe curves");
282b600beedSjsing 			goto err;
283b600beedSjsing 		}
284b600beedSjsing 	}
285b600beedSjsing 
286c57e6ec0Sjsing 	if (ctx->config->ciphers_server == 1)
287991d42a1Sjsing 		SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
288c57e6ec0Sjsing 
2892279ffc3Sbeck 	if (SSL_CTX_set_tlsext_status_cb(*ssl_ctx, tls_ocsp_stapling_cb) != 1) {
2907a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
2917a756d37Sjoshua 		    "failed to add OCSP stapling callback");
292668bec95Sbeck 		goto err;
293668bec95Sbeck 	}
294668bec95Sbeck 
29547c43cfeSclaudio 	if (ctx->config->session_lifetime > 0) {
29647c43cfeSclaudio 		/* set the session lifetime and enable tickets */
29747c43cfeSclaudio 		SSL_CTX_set_timeout(*ssl_ctx, ctx->config->session_lifetime);
29847c43cfeSclaudio 		SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET);
29947c43cfeSclaudio 		if (!SSL_CTX_set_tlsext_ticket_key_cb(*ssl_ctx,
30047c43cfeSclaudio 		    tls_server_ticket_cb)) {
3017a756d37Sjoshua 			tls_set_error(ctx, TLS_ERROR_UNKNOWN,
30247c43cfeSclaudio 			    "failed to set the TLS ticket callback");
30347c43cfeSclaudio 			goto err;
30447c43cfeSclaudio 		}
30547c43cfeSclaudio 	}
30647c43cfeSclaudio 
30747c43cfeSclaudio 	if (SSL_CTX_set_session_id_context(*ssl_ctx, ctx->config->session_id,
30847c43cfeSclaudio 	    sizeof(ctx->config->session_id)) != 1) {
3097a756d37Sjoshua 		tls_set_error(ctx, TLS_ERROR_UNKNOWN,
3107a756d37Sjoshua 		    "failed to set session id context");
31131413d7eSreyk 		goto err;
31231413d7eSreyk 	}
31331413d7eSreyk 
314b600beedSjsing 	return (0);
315b600beedSjsing 
316b600beedSjsing   err:
317991d42a1Sjsing 	SSL_CTX_free(*ssl_ctx);
318991d42a1Sjsing 	*ssl_ctx = NULL;
319991d42a1Sjsing 
320991d42a1Sjsing 	return (-1);
321991d42a1Sjsing }
322991d42a1Sjsing 
323f89edc01Sjsing static int
tls_configure_server_sni(struct tls * ctx)324f89edc01Sjsing tls_configure_server_sni(struct tls *ctx)
325f89edc01Sjsing {
326f89edc01Sjsing 	struct tls_sni_ctx **sni_ctx;
327f89edc01Sjsing 	struct tls_keypair *kp;
328f89edc01Sjsing 
329f89edc01Sjsing 	if (ctx->config->keypair->next == NULL)
330f89edc01Sjsing 		return (0);
331f89edc01Sjsing 
332f89edc01Sjsing 	/* Set up additional SSL contexts for SNI. */
333f89edc01Sjsing 	sni_ctx = &ctx->sni_ctx;
334f89edc01Sjsing 	for (kp = ctx->config->keypair->next; kp != NULL; kp = kp->next) {
335f89edc01Sjsing 		if ((*sni_ctx = tls_sni_ctx_new()) == NULL) {
3367a756d37Sjoshua 			tls_set_errorx(ctx, TLS_ERROR_OUT_OF_MEMORY, "out of memory");
337f89edc01Sjsing 			goto err;
338f89edc01Sjsing 		}
3399ee433b9Sjsing 		(*sni_ctx)->keypair = kp;
340f89edc01Sjsing 		if (tls_configure_server_ssl(ctx, &(*sni_ctx)->ssl_ctx, kp) == -1)
341f89edc01Sjsing 			goto err;
342f89edc01Sjsing 		if (tls_keypair_load_cert(kp, &ctx->error,
343f89edc01Sjsing 		    &(*sni_ctx)->ssl_cert) == -1)
344f89edc01Sjsing 			goto err;
345f89edc01Sjsing 		sni_ctx = &(*sni_ctx)->next;
346f89edc01Sjsing 	}
347f89edc01Sjsing 
348f89edc01Sjsing 	return (0);
349f89edc01Sjsing 
350f89edc01Sjsing  err:
351f89edc01Sjsing 	return (-1);
352f89edc01Sjsing }
353f89edc01Sjsing 
354991d42a1Sjsing int
tls_configure_server(struct tls * ctx)355991d42a1Sjsing tls_configure_server(struct tls *ctx)
356991d42a1Sjsing {
357991d42a1Sjsing 	if (tls_configure_server_ssl(ctx, &ctx->ssl_ctx,
358991d42a1Sjsing 	    ctx->config->keypair) == -1)
359991d42a1Sjsing 		goto err;
360f89edc01Sjsing 	if (tls_configure_server_sni(ctx) == -1)
361f89edc01Sjsing 		goto err;
362991d42a1Sjsing 
363991d42a1Sjsing 	return (0);
364991d42a1Sjsing 
365991d42a1Sjsing  err:
366b600beedSjsing 	return (-1);
367b600beedSjsing }
368b600beedSjsing 
369ed19021fSbcook static struct tls *
tls_accept_common(struct tls * ctx)3702233a86cSjsing tls_accept_common(struct tls *ctx)
371b600beedSjsing {
372e2b71c11Sjsing 	struct tls *conn_ctx = NULL;
373b600beedSjsing 
374b600beedSjsing 	if ((ctx->flags & TLS_SERVER) == 0) {
375*40ae7d6bSjoshua 		tls_set_errorx(ctx, TLS_ERROR_INVALID_CONTEXT,
376*40ae7d6bSjoshua 		    "not a server context");
377b600beedSjsing 		goto err;
378b600beedSjsing 	}
379b600beedSjsing 
380b600beedSjsing 	if ((conn_ctx = tls_server_conn(ctx)) == NULL) {
3817a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
3827a756d37Sjoshua 		    "connection context failure");
383b600beedSjsing 		goto err;
384b600beedSjsing 	}
385b600beedSjsing 
386b600beedSjsing 	if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
3877a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, "ssl failure");
388b600beedSjsing 		goto err;
389b600beedSjsing 	}
390ed19021fSbcook 
3918c73da28Sjsing 	if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) {
3927a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
3937a756d37Sjoshua 		    "ssl application data failure");
3948c73da28Sjsing 		goto err;
3958c73da28Sjsing 	}
396ed19021fSbcook 
397ed19021fSbcook 	return conn_ctx;
398ed19021fSbcook 
399ed19021fSbcook  err:
400ed19021fSbcook 	tls_free(conn_ctx);
401ed19021fSbcook 
402ed19021fSbcook 	return (NULL);
403ed19021fSbcook }
404ed19021fSbcook 
405ed19021fSbcook int
tls_accept_socket(struct tls * ctx,struct tls ** cctx,int s)406777595f3Sjsing tls_accept_socket(struct tls *ctx, struct tls **cctx, int s)
407ed19021fSbcook {
408777595f3Sjsing 	return (tls_accept_fds(ctx, cctx, s, s));
409ed19021fSbcook }
410ed19021fSbcook 
411ed19021fSbcook int
tls_accept_fds(struct tls * ctx,struct tls ** cctx,int fd_read,int fd_write)412ed19021fSbcook tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write)
413ed19021fSbcook {
414ed19021fSbcook 	struct tls *conn_ctx;
415ed19021fSbcook 
4162233a86cSjsing 	if ((conn_ctx = tls_accept_common(ctx)) == NULL)
417ed19021fSbcook 		goto err;
418ed19021fSbcook 
419e1e4dea2Sjsing 	if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 ||
420e1e4dea2Sjsing 	    SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) {
4217a756d37Sjoshua 		tls_set_errorx(ctx, TLS_ERROR_UNKNOWN,
4227a756d37Sjoshua 		    "ssl file descriptor failure");
423b600beedSjsing 		goto err;
424b600beedSjsing 	}
425b600beedSjsing 
426e2b71c11Sjsing 	*cctx = conn_ctx;
427b600beedSjsing 
428b600beedSjsing 	return (0);
429b600beedSjsing  err:
430e2b71c11Sjsing 	tls_free(conn_ctx);
431ed19021fSbcook 	*cctx = NULL;
432e2b71c11Sjsing 
433ed19021fSbcook 	return (-1);
434ed19021fSbcook }
435ed19021fSbcook 
436ed19021fSbcook int
tls_accept_cbs(struct tls * ctx,struct tls ** cctx,tls_read_cb read_cb,tls_write_cb write_cb,void * cb_arg)437ed19021fSbcook tls_accept_cbs(struct tls *ctx, struct tls **cctx,
438ed19021fSbcook     tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg)
439ed19021fSbcook {
440ed19021fSbcook 	struct tls *conn_ctx;
441ed19021fSbcook 
4422233a86cSjsing 	if ((conn_ctx = tls_accept_common(ctx)) == NULL)
443ed19021fSbcook 		goto err;
444ed19021fSbcook 
44559bda8beSjsing 	if (tls_set_cbs(conn_ctx, read_cb, write_cb, cb_arg) != 0)
446ed19021fSbcook 		goto err;
447ed19021fSbcook 
448ed19021fSbcook 	*cctx = conn_ctx;
449ed19021fSbcook 
450ed19021fSbcook 	return (0);
451ed19021fSbcook  err:
452ed19021fSbcook 	tls_free(conn_ctx);
453e2b71c11Sjsing 	*cctx = NULL;
454e2b71c11Sjsing 
455b600beedSjsing 	return (-1);
456b600beedSjsing }
457e1e4dea2Sjsing 
458e1e4dea2Sjsing int
tls_handshake_server(struct tls * ctx)459e2b71c11Sjsing tls_handshake_server(struct tls *ctx)
460e1e4dea2Sjsing {
461e2b71c11Sjsing 	int ssl_ret;
462e2b71c11Sjsing 	int rv = -1;
463e2b71c11Sjsing 
464e2b71c11Sjsing 	if ((ctx->flags & TLS_SERVER_CONN) == 0) {
465*40ae7d6bSjoshua 		tls_set_errorx(ctx, TLS_ERROR_INVALID_CONTEXT,
4667a756d37Sjoshua 		    "not a server connection context");
467e2b71c11Sjsing 		goto err;
468e2b71c11Sjsing 	}
469e2b71c11Sjsing 
4705a752462Sjsing 	ctx->state |= TLS_SSL_NEEDS_SHUTDOWN;
4715a752462Sjsing 
4729ba095aaSjsing 	ERR_clear_error();
473e2b71c11Sjsing 	if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) {
474e2b71c11Sjsing 		rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake");
475e2b71c11Sjsing 		goto err;
476e2b71c11Sjsing 	}
477e2b71c11Sjsing 
478e2b71c11Sjsing 	ctx->state |= TLS_HANDSHAKE_COMPLETE;
479521d38f2Sbeck 	rv = 0;
480e2b71c11Sjsing 
481e2b71c11Sjsing  err:
482e2b71c11Sjsing 	return (rv);
483e1e4dea2Sjsing }
484