diff options
author | jsing <> | 2016-04-28 16:48:44 +0000 |
---|---|---|
committer | jsing <> | 2016-04-28 16:48:44 +0000 |
commit | 2666540eb58ec0e76b541248bed9d159e6a2ccea (patch) | |
tree | 2228658d31ed91575cce8bbc0cc1f0394cb96787 /src | |
parent | 8da506fe86ae4114f94c896522d4bf388c1bfded (diff) | |
download | openbsd-2666540eb58ec0e76b541248bed9d159e6a2ccea.tar.gz openbsd-2666540eb58ec0e76b541248bed9d159e6a2ccea.tar.bz2 openbsd-2666540eb58ec0e76b541248bed9d159e6a2ccea.zip |
Rework the error handling in libtls so that we can associate errors with
both configuration and contexts. This allows us to propagate errors that
occur during configuration, rather than either just failing with no reason
or delaying the failure until it can be propagated via the tls context.
Also provide a tls_config_error() function for retrieving the last error
from a tls_config *.
ok bcook@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libtls/tls.c | 59 | ||||
-rw-r--r-- | src/lib/libtls/tls.h | 3 | ||||
-rw-r--r-- | src/lib/libtls/tls_config.c | 18 | ||||
-rw-r--r-- | src/lib/libtls/tls_init.3 | 15 | ||||
-rw-r--r-- | src/lib/libtls/tls_internal.h | 23 |
5 files changed, 90 insertions, 28 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 5ca555027f..661aa6ad0a 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.35 2016/01/18 16:15:14 bcook Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.36 2016/04/28 16:48:44 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -58,17 +58,18 @@ tls_init(void) | |||
58 | const char * | 58 | const char * |
59 | tls_error(struct tls *ctx) | 59 | tls_error(struct tls *ctx) |
60 | { | 60 | { |
61 | return ctx->errmsg; | 61 | return ctx->error.msg; |
62 | } | 62 | } |
63 | 63 | ||
64 | static int | 64 | static int |
65 | tls_set_verror(struct tls *ctx, int errnum, const char *fmt, va_list ap) | 65 | tls_set_verror(struct tls_error *error, int errnum, const char *fmt, va_list ap) |
66 | { | 66 | { |
67 | char *errmsg = NULL; | 67 | char *errmsg = NULL; |
68 | int rv = -1; | 68 | int rv = -1; |
69 | 69 | ||
70 | free(ctx->errmsg); | 70 | free(error->msg); |
71 | ctx->errmsg = NULL; | 71 | error->msg = NULL; |
72 | error->num = errnum; | ||
72 | 73 | ||
73 | if (vasprintf(&errmsg, fmt, ap) == -1) { | 74 | if (vasprintf(&errmsg, fmt, ap) == -1) { |
74 | errmsg = NULL; | 75 | errmsg = NULL; |
@@ -76,12 +77,12 @@ tls_set_verror(struct tls *ctx, int errnum, const char *fmt, va_list ap) | |||
76 | } | 77 | } |
77 | 78 | ||
78 | if (errnum == -1) { | 79 | if (errnum == -1) { |
79 | ctx->errmsg = errmsg; | 80 | error->msg = errmsg; |
80 | return (0); | 81 | return (0); |
81 | } | 82 | } |
82 | 83 | ||
83 | if (asprintf(&ctx->errmsg, "%s: %s", errmsg, strerror(errnum)) == -1) { | 84 | if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) { |
84 | ctx->errmsg = NULL; | 85 | error->msg = NULL; |
85 | goto err; | 86 | goto err; |
86 | } | 87 | } |
87 | rv = 0; | 88 | rv = 0; |
@@ -93,15 +94,43 @@ tls_set_verror(struct tls *ctx, int errnum, const char *fmt, va_list ap) | |||
93 | } | 94 | } |
94 | 95 | ||
95 | int | 96 | int |
96 | tls_set_error(struct tls *ctx, const char *fmt, ...) | 97 | tls_set_config_error(struct tls_config *config, const char *fmt, ...) |
98 | { | ||
99 | va_list ap; | ||
100 | int errnum, rv; | ||
101 | |||
102 | errnum = errno; | ||
103 | |||
104 | va_start(ap, fmt); | ||
105 | rv = tls_set_verror(&config->error, errnum, fmt, ap); | ||
106 | va_end(ap); | ||
107 | |||
108 | return (rv); | ||
109 | } | ||
110 | |||
111 | int | ||
112 | tls_set_config_errorx(struct tls_config *config, const char *fmt, ...) | ||
97 | { | 113 | { |
98 | va_list ap; | 114 | va_list ap; |
99 | int rv; | 115 | int rv; |
100 | 116 | ||
101 | ctx->errnum = errno; | 117 | va_start(ap, fmt); |
118 | rv = tls_set_verror(&config->error, -1, fmt, ap); | ||
119 | va_end(ap); | ||
120 | |||
121 | return (rv); | ||
122 | } | ||
123 | |||
124 | int | ||
125 | tls_set_error(struct tls *ctx, const char *fmt, ...) | ||
126 | { | ||
127 | va_list ap; | ||
128 | int errnum, rv; | ||
129 | |||
130 | errnum = errno; | ||
102 | 131 | ||
103 | va_start(ap, fmt); | 132 | va_start(ap, fmt); |
104 | rv = tls_set_verror(ctx, ctx->errnum, fmt, ap); | 133 | rv = tls_set_verror(&ctx->error, errnum, fmt, ap); |
105 | va_end(ap); | 134 | va_end(ap); |
106 | 135 | ||
107 | return (rv); | 136 | return (rv); |
@@ -114,7 +143,7 @@ tls_set_errorx(struct tls *ctx, const char *fmt, ...) | |||
114 | int rv; | 143 | int rv; |
115 | 144 | ||
116 | va_start(ap, fmt); | 145 | va_start(ap, fmt); |
117 | rv = tls_set_verror(ctx, -1, fmt, ap); | 146 | rv = tls_set_verror(&ctx->error, -1, fmt, ap); |
118 | va_end(ap); | 147 | va_end(ap); |
119 | 148 | ||
120 | return (rv); | 149 | return (rv); |
@@ -328,9 +357,9 @@ tls_reset(struct tls *ctx) | |||
328 | free(ctx->servername); | 357 | free(ctx->servername); |
329 | ctx->servername = NULL; | 358 | ctx->servername = NULL; |
330 | 359 | ||
331 | free(ctx->errmsg); | 360 | free(ctx->error.msg); |
332 | ctx->errmsg = NULL; | 361 | ctx->error.msg = NULL; |
333 | ctx->errnum = 0; | 362 | ctx->error.num = -1; |
334 | 363 | ||
335 | tls_free_conninfo(ctx->conninfo); | 364 | tls_free_conninfo(ctx->conninfo); |
336 | free(ctx->conninfo); | 365 | free(ctx->conninfo); |
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h index e5c31ed581..da229d1fee 100644 --- a/src/lib/libtls/tls.h +++ b/src/lib/libtls/tls.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.h,v 1.26 2015/10/07 23:33:38 beck Exp $ */ | 1 | /* $OpenBSD: tls.h,v 1.27 2016/04/28 16:48:44 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -46,6 +46,7 @@ struct tls_config; | |||
46 | 46 | ||
47 | int tls_init(void); | 47 | int tls_init(void); |
48 | 48 | ||
49 | const char *tls_config_error(struct tls_config *_config); | ||
49 | const char *tls_error(struct tls *_ctx); | 50 | const char *tls_error(struct tls *_ctx); |
50 | 51 | ||
51 | struct tls_config *tls_config_new(void); | 52 | struct tls_config *tls_config_new(void); |
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 5ab2379628..9c2b5810f6 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_config.c,v 1.14 2015/09/29 10:17:04 deraadt Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.15 2016/04/28 16:48:44 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -99,6 +99,8 @@ tls_config_free(struct tls_config *config) | |||
99 | 99 | ||
100 | tls_config_clear_keys(config); | 100 | tls_config_clear_keys(config); |
101 | 101 | ||
102 | free(config->error.msg); | ||
103 | |||
102 | free((char *)config->ca_file); | 104 | free((char *)config->ca_file); |
103 | free((char *)config->ca_path); | 105 | free((char *)config->ca_path); |
104 | free((char *)config->cert_file); | 106 | free((char *)config->cert_file); |
@@ -110,6 +112,12 @@ tls_config_free(struct tls_config *config) | |||
110 | free(config); | 112 | free(config); |
111 | } | 113 | } |
112 | 114 | ||
115 | const char * | ||
116 | tls_config_error(struct tls_config *config) | ||
117 | { | ||
118 | return config->error.msg; | ||
119 | } | ||
120 | |||
113 | void | 121 | void |
114 | tls_config_clear_keys(struct tls_config *config) | 122 | tls_config_clear_keys(struct tls_config *config) |
115 | { | 123 | { |
@@ -232,8 +240,10 @@ tls_config_set_dheparams(struct tls_config *config, const char *params) | |||
232 | keylen = -1; | 240 | keylen = -1; |
233 | else if (strcasecmp(params, "legacy") == 0) | 241 | else if (strcasecmp(params, "legacy") == 0) |
234 | keylen = 1024; | 242 | keylen = 1024; |
235 | else | 243 | else { |
244 | tls_set_config_errorx(config, "invalid dhe param '%s'", params); | ||
236 | return (-1); | 245 | return (-1); |
246 | } | ||
237 | 247 | ||
238 | config->dheparams = keylen; | 248 | config->dheparams = keylen; |
239 | 249 | ||
@@ -249,8 +259,10 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *name) | |||
249 | nid = NID_undef; | 259 | nid = NID_undef; |
250 | else if (strcasecmp(name, "auto") == 0) | 260 | else if (strcasecmp(name, "auto") == 0) |
251 | nid = -1; | 261 | nid = -1; |
252 | else if ((nid = OBJ_txt2nid(name)) == NID_undef) | 262 | else if ((nid = OBJ_txt2nid(name)) == NID_undef) { |
263 | tls_set_config_errorx(config, "invalid ecdhe curve '%s'", name); | ||
253 | return (-1); | 264 | return (-1); |
265 | } | ||
254 | 266 | ||
255 | config->ecdhecurve = nid; | 267 | config->ecdhecurve = nid; |
256 | 268 | ||
diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3 index d5acc59cdc..48662e0868 100644 --- a/src/lib/libtls/tls_init.3 +++ b/src/lib/libtls/tls_init.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: tls_init.3,v 1.56 2016/04/24 12:16:36 jmc Exp $ | 1 | .\" $OpenBSD: tls_init.3,v 1.57 2016/04/28 16:48:44 jsing Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> | 3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> |
4 | .\" | 4 | .\" |
@@ -14,11 +14,12 @@ | |||
14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 14 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | .\" | 16 | .\" |
17 | .Dd $Mdocdate: April 24 2016 $ | 17 | .Dd $Mdocdate: April 28 2016 $ |
18 | .Dt TLS_INIT 3 | 18 | .Dt TLS_INIT 3 |
19 | .Os | 19 | .Os |
20 | .Sh NAME | 20 | .Sh NAME |
21 | .Nm tls_init , | 21 | .Nm tls_init , |
22 | .Nm tls_config_error , | ||
22 | .Nm tls_error , | 23 | .Nm tls_error , |
23 | .Nm tls_config_new , | 24 | .Nm tls_config_new , |
24 | .Nm tls_config_free , | 25 | .Nm tls_config_free , |
@@ -75,8 +76,10 @@ | |||
75 | .Ft "int" | 76 | .Ft "int" |
76 | .Fn tls_init "void" | 77 | .Fn tls_init "void" |
77 | .Ft "const char *" | 78 | .Ft "const char *" |
78 | .Fn tls_error "struct tls *ctx" | 79 | .Fn tls_config_error "struct tls *config" |
79 | .Ft "struct tls_config *" | 80 | .Ft "struct tls_config *" |
81 | .Fn tls_error "struct tls *ctx" | ||
82 | .Ft "const char *" | ||
80 | .Fn tls_config_new "void" | 83 | .Fn tls_config_new "void" |
81 | .Ft "void" | 84 | .Ft "void" |
82 | .Fn tls_config_free "struct tls_config *config" | 85 | .Fn tls_config_free "struct tls_config *config" |
@@ -668,9 +671,11 @@ while (len > 0) { | |||
668 | .Ed | 671 | .Ed |
669 | .Sh ERRORS | 672 | .Sh ERRORS |
670 | The | 673 | The |
674 | .Fn tls_config_error | ||
675 | and | ||
671 | .Fn tls_error | 676 | .Fn tls_error |
672 | function may be used to retrieve a string containing more information | 677 | functions may be used to retrieve a string containing more information |
673 | about the most recent error. | 678 | about the most recent error relating to a configuration or context. |
674 | .\" .Sh SEE ALSO | 679 | .\" .Sh SEE ALSO |
675 | .Sh HISTORY | 680 | .Sh HISTORY |
676 | The | 681 | The |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index b203b5662e..21bf2b4613 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.26 2015/10/07 23:33:38 beck Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.27 2016/04/28 16:48:44 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> |
@@ -34,7 +34,14 @@ union tls_addr { | |||
34 | struct in6_addr ip6; | 34 | struct in6_addr ip6; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | struct tls_error { | ||
38 | char *msg; | ||
39 | int num; | ||
40 | }; | ||
41 | |||
37 | struct tls_config { | 42 | struct tls_config { |
43 | struct tls_error error; | ||
44 | |||
38 | const char *ca_file; | 45 | const char *ca_file; |
39 | const char *ca_path; | 46 | const char *ca_path; |
40 | char *ca_mem; | 47 | char *ca_mem; |
@@ -78,12 +85,11 @@ struct tls_conninfo { | |||
78 | 85 | ||
79 | struct tls { | 86 | struct tls { |
80 | struct tls_config *config; | 87 | struct tls_config *config; |
88 | struct tls_error error; | ||
89 | |||
81 | uint32_t flags; | 90 | uint32_t flags; |
82 | uint32_t state; | 91 | uint32_t state; |
83 | 92 | ||
84 | char *errmsg; | ||
85 | int errnum; | ||
86 | |||
87 | char *servername; | 93 | char *servername; |
88 | int socket; | 94 | int socket; |
89 | 95 | ||
@@ -104,14 +110,23 @@ int tls_configure_ssl_verify(struct tls *ctx, int verify); | |||
104 | int tls_handshake_client(struct tls *ctx); | 110 | int tls_handshake_client(struct tls *ctx); |
105 | int tls_handshake_server(struct tls *ctx); | 111 | int tls_handshake_server(struct tls *ctx); |
106 | int tls_host_port(const char *hostport, char **host, char **port); | 112 | int tls_host_port(const char *hostport, char **host, char **port); |
113 | |||
114 | int tls_set_config_error(struct tls_config *cfg, const char *fmt, ...) | ||
115 | __attribute__((__format__ (printf, 2, 3))) | ||
116 | __attribute__((__nonnull__ (2))); | ||
117 | int tls_set_config_errorx(struct tls_config *cfg, const char *fmt, ...) | ||
118 | __attribute__((__format__ (printf, 2, 3))) | ||
119 | __attribute__((__nonnull__ (2))); | ||
107 | int tls_set_error(struct tls *ctx, const char *fmt, ...) | 120 | int tls_set_error(struct tls *ctx, const char *fmt, ...) |
108 | __attribute__((__format__ (printf, 2, 3))) | 121 | __attribute__((__format__ (printf, 2, 3))) |
109 | __attribute__((__nonnull__ (2))); | 122 | __attribute__((__nonnull__ (2))); |
110 | int tls_set_errorx(struct tls *ctx, const char *fmt, ...) | 123 | int tls_set_errorx(struct tls *ctx, const char *fmt, ...) |
111 | __attribute__((__format__ (printf, 2, 3))) | 124 | __attribute__((__format__ (printf, 2, 3))) |
112 | __attribute__((__nonnull__ (2))); | 125 | __attribute__((__nonnull__ (2))); |
126 | |||
113 | int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, | 127 | int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, |
114 | const char *prefix); | 128 | const char *prefix); |
129 | |||
115 | int tls_get_conninfo(struct tls *ctx); | 130 | int tls_get_conninfo(struct tls *ctx); |
116 | void tls_free_conninfo(struct tls_conninfo *conninfo); | 131 | void tls_free_conninfo(struct tls_conninfo *conninfo); |
117 | 132 | ||