sem_init.3: Mark up SEM_VALUE_MAX.
[dragonfly.git] / crypto / libressl / tls / tls_server.c
blob58dbb60513ddbe09b3c0301f46254654dec32db8
1 /* $OpenBSD: tls_server.c,v 1.18 2015/09/29 10:17:04 deraadt Exp $ */
2 /*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
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.
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.
18 #include <openssl/ec.h>
19 #include <openssl/err.h>
20 #include <openssl/ssl.h>
22 #include <tls.h>
23 #include "tls_internal.h"
25 struct tls *
26 tls_server(void)
28 struct tls *ctx;
30 if ((ctx = tls_new()) == NULL)
31 return (NULL);
33 ctx->flags |= TLS_SERVER;
35 return (ctx);
38 struct tls *
39 tls_server_conn(struct tls *ctx)
41 struct tls *conn_ctx;
43 if ((conn_ctx = tls_new()) == NULL)
44 return (NULL);
46 conn_ctx->flags |= TLS_SERVER_CONN;
48 return (conn_ctx);
51 int
52 tls_configure_server(struct tls *ctx)
54 EC_KEY *ecdh_key;
55 unsigned char sid[SSL_MAX_SSL_SESSION_ID_LENGTH];
57 if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
58 tls_set_errorx(ctx, "ssl context failure");
59 goto err;
62 if (tls_configure_ssl(ctx) != 0)
63 goto err;
64 if (tls_configure_keypair(ctx, ctx->ssl_ctx, ctx->config->keypair, 1) != 0)
65 goto err;
66 if (ctx->config->verify_client != 0) {
67 int verify = SSL_VERIFY_PEER;
68 if (ctx->config->verify_client == 1)
69 verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
70 if (tls_configure_ssl_verify(ctx, verify) == -1)
71 goto err;
74 if (ctx->config->dheparams == -1)
75 SSL_CTX_set_dh_auto(ctx->ssl_ctx, 1);
76 else if (ctx->config->dheparams == 1024)
77 SSL_CTX_set_dh_auto(ctx->ssl_ctx, 2);
79 if (ctx->config->ecdhecurve == -1) {
80 SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1);
81 } else if (ctx->config->ecdhecurve != NID_undef) {
82 if ((ecdh_key = EC_KEY_new_by_curve_name(
83 ctx->config->ecdhecurve)) == NULL) {
84 tls_set_errorx(ctx, "failed to set ECDHE curve");
85 goto err;
87 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
88 SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ecdh_key);
89 EC_KEY_free(ecdh_key);
92 if (ctx->config->ciphers_server == 1)
93 SSL_CTX_set_options(ctx->ssl_ctx,
94 SSL_OP_CIPHER_SERVER_PREFERENCE);
97 * Set session ID context to a random value. We don't support
98 * persistent caching of sessions so it is OK to set a temporary
99 * session ID context that is valid during run time.
101 arc4random_buf(sid, sizeof(sid));
102 if (!SSL_CTX_set_session_id_context(ctx->ssl_ctx, sid, sizeof(sid))) {
103 tls_set_errorx(ctx, "failed to set session id context");
104 goto err;
107 return (0);
109 err:
110 return (-1);
114 tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket)
116 return (tls_accept_fds(ctx, cctx, socket, socket));
120 tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write)
122 struct tls *conn_ctx = NULL;
124 if ((ctx->flags & TLS_SERVER) == 0) {
125 tls_set_errorx(ctx, "not a server context");
126 goto err;
129 if ((conn_ctx = tls_server_conn(ctx)) == NULL) {
130 tls_set_errorx(ctx, "connection context failure");
131 goto err;
134 if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
135 tls_set_errorx(ctx, "ssl failure");
136 goto err;
138 if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) {
139 tls_set_errorx(ctx, "ssl application data failure");
140 goto err;
142 if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 ||
143 SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) {
144 tls_set_errorx(ctx, "ssl file descriptor failure");
145 goto err;
148 *cctx = conn_ctx;
150 return (0);
152 err:
153 tls_free(conn_ctx);
155 *cctx = NULL;
157 return (-1);
161 tls_handshake_server(struct tls *ctx)
163 int ssl_ret;
164 int rv = -1;
166 if ((ctx->flags & TLS_SERVER_CONN) == 0) {
167 tls_set_errorx(ctx, "not a server connection context");
168 goto err;
171 ERR_clear_error();
172 if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) {
173 rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake");
174 goto err;
177 ctx->state |= TLS_HANDSHAKE_COMPLETE;
178 rv = 0;
180 err:
181 return (rv);