summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2016-11-03 10:05:32 +0000
committerjsing <>2016-11-03 10:05:32 +0000
commitc8f23a73c54fa03e5487282a15314fd81bdcef57 (patch)
treebd289b4e8ede05ba1e2074b7be3604ce3c1e12b8 /src
parent05264184755e9ad926b368969ae307f8b4784f6e (diff)
downloadopenbsd-c8f23a73c54fa03e5487282a15314fd81bdcef57.tar.gz
openbsd-c8f23a73c54fa03e5487282a15314fd81bdcef57.tar.bz2
openbsd-c8f23a73c54fa03e5487282a15314fd81bdcef57.zip
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 'src')
-rw-r--r--src/lib/libtls/tls.c47
-rw-r--r--src/lib/libtls/tls_internal.h7
2 files changed, 47 insertions, 7 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index cccdb00531..6893e95b08 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.c,v 1.50 2016/11/02 15:18:42 beck Exp $ */ 1/* $OpenBSD: tls.c,v 1.51 2016/11/03 10:05:32 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -61,15 +61,25 @@ tls_error(struct tls *ctx)
61 return ctx->error.msg; 61 return ctx->error.msg;
62} 62}
63 63
64void
65tls_error_clear(struct tls_error *error)
66{
67 free(error->msg);
68 error->msg = NULL;
69 error->num = 0;
70 error->tls = 0;
71}
72
64static int 73static int
65tls_error_vset(struct tls_error *error, int errnum, const char *fmt, va_list ap) 74tls_error_vset(struct tls_error *error, int errnum, const char *fmt, va_list ap)
66{ 75{
67 char *errmsg = NULL; 76 char *errmsg = NULL;
68 int rv = -1; 77 int rv = -1;
69 78
70 free(error->msg); 79 tls_error_clear(error);
71 error->msg = NULL; 80
72 error->num = errnum; 81 error->num = errnum;
82 error->tls = 1;
73 83
74 if (vasprintf(&errmsg, fmt, ap) == -1) { 84 if (vasprintf(&errmsg, fmt, ap) == -1) {
75 errmsg = NULL; 85 errmsg = NULL;
@@ -177,6 +187,23 @@ tls_set_errorx(struct tls *ctx, const char *fmt, ...)
177 return (rv); 187 return (rv);
178} 188}
179 189
190int
191tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...)
192{
193 va_list ap;
194 int rv;
195
196 /* Only set an error if a more specific one does not already exist. */
197 if (ctx->error.tls != 0)
198 return (0);
199
200 va_start(ap, fmt);
201 rv = tls_error_vset(&ctx->error, -1, fmt, ap);
202 va_end(ap);
203
204 return (rv);
205}
206
180struct tls_sni_ctx * 207struct tls_sni_ctx *
181tls_sni_ctx_new(void) 208tls_sni_ctx_new(void)
182{ 209{
@@ -464,21 +491,21 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix)
464 } else if (ssl_ret == -1) { 491 } else if (ssl_ret == -1) {
465 errstr = strerror(errno); 492 errstr = strerror(errno);
466 } 493 }
467 tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); 494 tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr);
468 return (-1); 495 return (-1);
469 496
470 case SSL_ERROR_SSL: 497 case SSL_ERROR_SSL:
471 if ((err = ERR_peek_error()) != 0) { 498 if ((err = ERR_peek_error()) != 0) {
472 errstr = ERR_error_string(err, NULL); 499 errstr = ERR_error_string(err, NULL);
473 } 500 }
474 tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); 501 tls_set_ssl_errorx(ctx, "%s failed: %s", prefix, errstr);
475 return (-1); 502 return (-1);
476 503
477 case SSL_ERROR_WANT_CONNECT: 504 case SSL_ERROR_WANT_CONNECT:
478 case SSL_ERROR_WANT_ACCEPT: 505 case SSL_ERROR_WANT_ACCEPT:
479 case SSL_ERROR_WANT_X509_LOOKUP: 506 case SSL_ERROR_WANT_X509_LOOKUP:
480 default: 507 default:
481 tls_set_errorx(ctx, "%s failed (%i)", prefix, ssl_err); 508 tls_set_ssl_errorx(ctx, "%s failed (%i)", prefix, ssl_err);
482 return (-1); 509 return (-1);
483 } 510 }
484} 511}
@@ -488,6 +515,8 @@ tls_handshake(struct tls *ctx)
488{ 515{
489 int rv = -1; 516 int rv = -1;
490 517
518 tls_error_clear(&ctx->error);
519
491 if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { 520 if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) {
492 tls_set_errorx(ctx, "invalid operation for context"); 521 tls_set_errorx(ctx, "invalid operation for context");
493 goto out; 522 goto out;
@@ -517,6 +546,8 @@ tls_read(struct tls *ctx, void *buf, size_t buflen)
517 ssize_t rv = -1; 546 ssize_t rv = -1;
518 int ssl_ret; 547 int ssl_ret;
519 548
549 tls_error_clear(&ctx->error);
550
520 if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { 551 if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) {
521 if ((rv = tls_handshake(ctx)) != 0) 552 if ((rv = tls_handshake(ctx)) != 0)
522 goto out; 553 goto out;
@@ -546,6 +577,8 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen)
546 ssize_t rv = -1; 577 ssize_t rv = -1;
547 int ssl_ret; 578 int ssl_ret;
548 579
580 tls_error_clear(&ctx->error);
581
549 if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { 582 if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) {
550 if ((rv = tls_handshake(ctx)) != 0) 583 if ((rv = tls_handshake(ctx)) != 0)
551 goto out; 584 goto out;
@@ -575,6 +608,8 @@ tls_close(struct tls *ctx)
575 int ssl_ret; 608 int ssl_ret;
576 int rv = 0; 609 int rv = 0;
577 610
611 tls_error_clear(&ctx->error);
612
578 if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { 613 if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) {
579 tls_set_errorx(ctx, "invalid operation for context"); 614 tls_set_errorx(ctx, "invalid operation for context");
580 rv = -1; 615 rv = -1;
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index df35db37f2..fde4066f7c 100644
--- a/src/lib/libtls/tls_internal.h
+++ b/src/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_internal.h,v 1.44 2016/11/02 15:18:42 beck Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.45 2016/11/03 10:05:32 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> 3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -39,6 +39,7 @@ union tls_addr {
39struct tls_error { 39struct tls_error {
40 char *msg; 40 char *msg;
41 int num; 41 int num;
42 int tls;
42}; 43};
43 44
44struct tls_keypair { 45struct tls_keypair {
@@ -174,6 +175,7 @@ int tls_host_port(const char *hostport, char **host, char **port);
174int tls_set_cbs(struct tls *ctx, 175int tls_set_cbs(struct tls *ctx,
175 tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg); 176 tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg);
176 177
178void tls_error_clear(struct tls_error *error);
177int tls_error_set(struct tls_error *error, const char *fmt, ...) 179int tls_error_set(struct tls_error *error, const char *fmt, ...)
178 __attribute__((__format__ (printf, 2, 3))) 180 __attribute__((__format__ (printf, 2, 3)))
179 __attribute__((__nonnull__ (2))); 181 __attribute__((__nonnull__ (2)));
@@ -192,6 +194,9 @@ int tls_set_error(struct tls *ctx, const char *fmt, ...)
192int tls_set_errorx(struct tls *ctx, const char *fmt, ...) 194int tls_set_errorx(struct tls *ctx, const char *fmt, ...)
193 __attribute__((__format__ (printf, 2, 3))) 195 __attribute__((__format__ (printf, 2, 3)))
194 __attribute__((__nonnull__ (2))); 196 __attribute__((__nonnull__ (2)));
197int tls_set_ssl_errorx(struct tls *ctx, const char *fmt, ...)
198 __attribute__((__format__ (printf, 2, 3)))
199 __attribute__((__nonnull__ (2)));
195 200
196int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, 201int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret,
197 const char *prefix); 202 const char *prefix);