1 /* $OpenBSD: tls_server.c,v 1.18 2015/09/29 10:17:04 deraadt Exp $ */
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>
23 #include "tls_internal.h"
30 if ((ctx
= tls_new()) == NULL
)
33 ctx
->flags
|= TLS_SERVER
;
39 tls_server_conn(struct tls
*ctx
)
43 if ((conn_ctx
= tls_new()) == NULL
)
46 conn_ctx
->flags
|= TLS_SERVER_CONN
;
52 tls_configure_server(struct tls
*ctx
)
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");
62 if (tls_configure_ssl(ctx
) != 0)
64 if (tls_configure_keypair(ctx
, ctx
->ssl_ctx
, ctx
->config
->keypair
, 1) != 0)
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)
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");
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");
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");
129 if ((conn_ctx
= tls_server_conn(ctx
)) == NULL
) {
130 tls_set_errorx(ctx
, "connection context failure");
134 if ((conn_ctx
->ssl_conn
= SSL_new(ctx
->ssl_ctx
)) == NULL
) {
135 tls_set_errorx(ctx
, "ssl failure");
138 if (SSL_set_app_data(conn_ctx
->ssl_conn
, conn_ctx
) != 1) {
139 tls_set_errorx(ctx
, "ssl application data failure");
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");
161 tls_handshake_server(struct tls
*ctx
)
166 if ((ctx
->flags
& TLS_SERVER_CONN
) == 0) {
167 tls_set_errorx(ctx
, "not a server connection context");
172 if ((ssl_ret
= SSL_accept(ctx
->ssl_conn
)) != 1) {
173 rv
= tls_ssl_error(ctx
, ctx
->ssl_conn
, ssl_ret
, "handshake");
177 ctx
->state
|= TLS_HANDSHAKE_COMPLETE
;