summaryrefslogtreecommitdiff
path: root/lib/libtls
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2016-11-03 10:05:33 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2016-11-03 10:05:33 +0000
commit0e8805b379f487a342717c36a9c78d923c5bbaa6 (patch)
treeacf9ff175bf8f776762d8edfed3c1e6199b078eb /lib/libtls
parentaab80535ba59293c70a008640d9626eb8234c379 (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.c47
-rw-r--r--lib/libtls/tls_internal.h7
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);