diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2015-09-14 12:29:17 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2015-09-14 12:29:17 +0000 |
commit | fddb2664a7cfd52519d99e70d9ece29dbe30ecf5 (patch) | |
tree | 973a6633046210689bcb00754764a5c18a7c23d2 /lib/libtls | |
parent | e7064847bafe6bbfabcccc0cb5aef9170f6452eb (diff) |
Expose EOF without close-notify via tls_close().
Make tls_read(3)/tls_write(3) follow read(2)/write(2) like semantics and
return 0 on EOF with and without close-notify. However, if we saw an EOF
from the underlying file descriptors without getting a close-notify, save
this and make it visible when tls_close(3) is called. This keeps the
semantics we want, but makes it possible to detect truncation at higher
layers, if necessary.
ok beck@ guenther@
Diffstat (limited to 'lib/libtls')
-rw-r--r-- | lib/libtls/tls.c | 15 | ||||
-rw-r--r-- | lib/libtls/tls_internal.h | 5 |
2 files changed, 14 insertions, 6 deletions
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c index cb2833cb54c..236ed9185b8 100644 --- a/lib/libtls/tls.c +++ b/lib/libtls/tls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.c,v 1.30 2015/09/14 12:20:40 jsing Exp $ */ +/* $OpenBSD: tls.c,v 1.31 2015/09/14 12:29:16 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -352,7 +352,8 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) if ((err = ERR_peek_error()) != 0) { errstr = ERR_error_string(err, NULL); } else if (ssl_ret == 0) { - errstr = "EOF"; + ctx->state |= TLS_EOF_NO_CLOSE_NOTIFY; + return (0); } else if (ssl_ret == -1) { errstr = strerror(errno); } @@ -421,7 +422,7 @@ tls_read(struct tls *ctx, void *buf, size_t buflen) } ERR_clear_error(); - if ((ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen)) >= 0) { + if ((ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen)) > 0) { rv = (ssize_t)ssl_ret; goto out; } @@ -450,7 +451,7 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen) } ERR_clear_error(); - if ((ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen)) >= 0) { + if ((ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen)) > 0) { rv = (ssize_t)ssl_ret; goto out; } @@ -501,6 +502,12 @@ tls_close(struct tls *ctx) } ctx->socket = -1; } + + if ((ctx->state & TLS_EOF_NO_CLOSE_NOTIFY) != 0) { + tls_set_errorx(ctx, "EOF without close notify"); + rv = -1; + } + out: /* Prevent callers from performing incorrect error handling */ errno = 0; diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index d7878a75e32..320f1fbfaa0 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.22 2015/09/13 10:32:46 beck Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.23 2015/09/14 12:29:16 jsing Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> @@ -62,7 +62,8 @@ struct tls_conninfo { #define TLS_SERVER (1 << 1) #define TLS_SERVER_CONN (1 << 2) -#define TLS_HANDSHAKE_COMPLETE (1 << 0) +#define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) +#define TLS_HANDSHAKE_COMPLETE (1 << 1) struct tls { struct tls_config *config; |