diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2016-11-03 10:05:33 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2016-11-03 10:05:33 +0000 |
commit | 0e8805b379f487a342717c36a9c78d923c5bbaa6 (patch) | |
tree | acf9ff175bf8f776762d8edfed3c1e6199b078eb /lib/libtls | |
parent | aab80535ba59293c70a008640d9626eb8234c379 (diff) |
Only set an error from libssl related code, if an error has not already
been set by libtls code. This avoids the situation where a libtls callback
has set an error, only to have it replaced by a less useful libssl based
error.
ok beck@
Diffstat (limited to 'lib/libtls')
-rw-r--r-- | lib/libtls/tls.c | 47 | ||||
-rw-r--r-- | lib/libtls/tls_internal.h | 7 |
2 files changed, 47 insertions, 7 deletions
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c index cccdb00531a..6893e95b083 100644 --- a/lib/libtls/tls.c +++ b/lib/libtls/tls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.c,v 1.50 2016/11/02 15:18:42 beck Exp $ */ +/* $OpenBSD: tls.c,v 1.51 2016/11/03 10:05:32 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -61,15 +61,25 @@ tls_error(struct tls *ctx) return ctx->error.msg; } +void +tls_error_clear(struct tls_error *error) +{ + free(error->msg); + error->msg = NULL; + error->num = 0; + error->tls = 0; +} + static int tls_error_vset(struct tls_error *error, int errnum, const char *fmt, va_list ap) { char *errmsg = NULL; int rv = -1; - free(error->msg); - error->msg = NULL; + tls_error_clear(error); + error->num = errnum; + error->tls = 1; if (vasprintf(&errmsg, fmt, ap) == -1) { errmsg = NULL; @@ -177,6 +187,23 @@ tls_set_errorx(struct tls *ctx, const char *fmt, ...) return (rv); } +int +tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int rv; + + /* Only set an error if a more specific one does not already exist. */ + if (ctx->error.tls != 0) + return (0); + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + struct tls_sni_ctx * tls_sni_ctx_new(void) { @@ -464,21 +491,21 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) } else if (ssl_ret == -1) { errstr = strerror(errno); } - tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); + tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr); return (-1); case SSL_ERROR_SSL: if ((err = ERR_peek_error()) != 0) { errstr = ERR_error_string(err, NULL); } - tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); + tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr); return (-1); case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_ACCEPT: case SSL_ERROR_WANT_X509_LOOKUP: default: - tls_set_errorx(ctx, "%s failed (%i)", prefix, ssl_err); + tls_set_ssl_errorx(ctx, "%s failed (%i)", prefix, ssl_err); return (-1); } } @@ -488,6 +515,8 @@ tls_handshake(struct tls *ctx) { int rv = -1; + tls_error_clear(&ctx->error); + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { tls_set_errorx(ctx, "invalid operation for context"); goto out; @@ -517,6 +546,8 @@ tls_read(struct tls *ctx, void *buf, size_t buflen) ssize_t rv = -1; int ssl_ret; + tls_error_clear(&ctx->error); + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { if ((rv = tls_handshake(ctx)) != 0) goto out; @@ -546,6 +577,8 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen) ssize_t rv = -1; int ssl_ret; + tls_error_clear(&ctx->error); + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { if ((rv = tls_handshake(ctx)) != 0) goto out; @@ -575,6 +608,8 @@ tls_close(struct tls *ctx) int ssl_ret; int rv = 0; + tls_error_clear(&ctx->error); + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { tls_set_errorx(ctx, "invalid operation for context"); rv = -1; diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index df35db37f2e..fde4066f7cc 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.44 2016/11/02 15:18:42 beck Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.45 2016/11/03 10:05:32 jsing Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> @@ -39,6 +39,7 @@ union tls_addr { struct tls_error { char *msg; int num; + int tls; }; struct tls_keypair { @@ -174,6 +175,7 @@ int tls_host_port(const char *hostport, char **host, char **port); int tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg); +void tls_error_clear(struct tls_error *error); int tls_error_set(struct tls_error *error, const char *fmt, ...) __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2))); @@ -192,6 +194,9 @@ int tls_set_error(struct tls *ctx, const char *fmt, ...) int tls_set_errorx(struct tls *ctx, const char *fmt, ...) __attribute__((__format__ (printf, 2, 3))) __attribute__((__nonnull__ (2))); +int tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix); |