From f7415644a66ca9d04e5e06312a163e677032b695 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Thu, 10 Sep 2015 10:14:21 +0000 Subject: Split tls_handshake() out from tls_accept/tls_connect. By doing this the tls_accept/tls_connect functions can be guaranteed to succeed or fail and will no longer return TLS_READ_AGAIN/TLS_WRITE_AGAIN. This also resolves the semantics of tls_accept_*. The tls_handshake() function now does I/O and can return TLS_READ_AGAIN/TLS_WRITE_AGAIN. Calls to tls_read() and tls_write() will trigger the handshake if it has not already completed, meaning that in many cases existing code will continue to work. Discussed over many coffees at l2k15. ok beck@ bluhm@ --- src/lib/libtls/tls_server.c | 76 +++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'src/lib/libtls/tls_server.c') diff --git a/src/lib/libtls/tls_server.c b/src/lib/libtls/tls_server.c index a3cee09596..3dfd29ac19 100644 --- a/src/lib/libtls/tls_server.c +++ b/src/lib/libtls/tls_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_server.c,v 1.14 2015/09/10 09:10:42 jsing Exp $ */ +/* $OpenBSD: tls_server.c,v 1.15 2015/09/10 10:14:20 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -109,55 +109,71 @@ tls_configure_server(struct tls *ctx) return (-1); } +int +tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) +{ + return (tls_accept_fds(ctx, cctx, socket, socket)); +} + int tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write) { - struct tls *conn_ctx = *cctx; - int ret, err; + struct tls *conn_ctx = NULL; if ((ctx->flags & TLS_SERVER) == 0) { tls_set_errorx(ctx, "not a server context"); goto err; } - if (conn_ctx == NULL) { - if ((conn_ctx = tls_server_conn(ctx)) == NULL) { - tls_set_errorx(ctx, "connection context failure"); - goto err; - } - *cctx = conn_ctx; - - if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { - tls_set_errorx(ctx, "ssl failure"); - goto err; - } - if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { - tls_set_errorx(ctx, "ssl application data failure"); - goto err; - } - if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || - SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { - tls_set_errorx(ctx, "ssl file descriptor failure"); - goto err; - } + if ((conn_ctx = tls_server_conn(ctx)) == NULL) { + tls_set_errorx(ctx, "connection context failure"); + goto err; } - if ((ret = SSL_accept(conn_ctx->ssl_conn)) != 1) { - err = tls_ssl_error(ctx, conn_ctx->ssl_conn, ret, "accept"); - if (err == TLS_READ_AGAIN || err == TLS_WRITE_AGAIN) { - return (err); - } + if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { + tls_set_errorx(ctx, "ssl failure"); + goto err; + } + if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { + tls_set_errorx(ctx, "ssl application data failure"); + goto err; + } + if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { + tls_set_errorx(ctx, "ssl file descriptor failure"); goto err; } + *cctx = conn_ctx; + return (0); err: + tls_free(conn_ctx); + + *cctx = NULL; + return (-1); } int -tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) +tls_handshake_server(struct tls *ctx) { - return (tls_accept_fds(ctx, cctx, socket, socket)); + int ssl_ret; + int rv = -1; + + if ((ctx->flags & TLS_SERVER_CONN) == 0) { + tls_set_errorx(ctx, "not a server connection context"); + goto err; + } + + if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); + goto err; + } + + ctx->state |= TLS_HANDSHAKE_COMPLETE; + + err: + return (rv); } -- cgit v1.2.3-55-g6feb