diff options
author | jsing <> | 2015-08-27 15:26:50 +0000 |
---|---|---|
committer | jsing <> | 2015-08-27 15:26:50 +0000 |
commit | 4cf0ea2d0621bc7128cf6a7cb3ed6a178f835617 (patch) | |
tree | d2c2a8c6fc1b8da3c4117997a97ab03f0ac74f21 /src/lib/libtls/tls.c | |
parent | 9385a1fd21f3850678c58b5cc8702c3a54b91ead (diff) | |
download | openbsd-4cf0ea2d0621bc7128cf6a7cb3ed6a178f835617.tar.gz openbsd-4cf0ea2d0621bc7128cf6a7cb3ed6a178f835617.tar.bz2 openbsd-4cf0ea2d0621bc7128cf6a7cb3ed6a178f835617.zip |
Improve libtls error messages.
The tls_set_error() function previously stored the errno but did nothing
with it. Change tls_set_error() to append the strerror(3) of the stored
errno so that we include useful information regarding failures.
Provide a tls_set_errorx() function that does not store the errno or
include strerror(3) in the error message. Call this function instead of
tls_set_error() for errors where the errno value has no useful meaning.
With feedback from and ok doug@
Diffstat (limited to 'src/lib/libtls/tls.c')
-rw-r--r-- | src/lib/libtls/tls.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index c79191ee15..445933d176 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.14 2015/08/27 14:34:46 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.15 2015/08/27 15:26:49 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,18 +58,61 @@ tls_error(struct tls *ctx) | |||
58 | return ctx->errmsg; | 58 | return ctx->errmsg; |
59 | } | 59 | } |
60 | 60 | ||
61 | static int | ||
62 | tls_set_verror(struct tls *ctx, int errnum, const char *fmt, va_list ap) | ||
63 | { | ||
64 | char *errmsg = NULL; | ||
65 | int rv = -1; | ||
66 | |||
67 | free(ctx->errmsg); | ||
68 | ctx->errmsg = NULL; | ||
69 | |||
70 | if (vasprintf(&errmsg, fmt, ap) == -1) { | ||
71 | errmsg = NULL; | ||
72 | goto err; | ||
73 | } | ||
74 | |||
75 | if (errnum == -1) { | ||
76 | ctx->errmsg = errmsg; | ||
77 | return (0); | ||
78 | } | ||
79 | |||
80 | if (asprintf(&ctx->errmsg, "%s: %s", errmsg, strerror(errnum)) == -1) { | ||
81 | ctx->errmsg = NULL; | ||
82 | goto err; | ||
83 | } | ||
84 | |||
85 | rv = 0; | ||
86 | |||
87 | err: | ||
88 | free(errmsg); | ||
89 | |||
90 | return (rv); | ||
91 | } | ||
92 | |||
61 | int | 93 | int |
62 | tls_set_error(struct tls *ctx, char *fmt, ...) | 94 | tls_set_error(struct tls *ctx, const char *fmt, ...) |
63 | { | 95 | { |
64 | va_list ap; | 96 | va_list ap; |
65 | int rv; | 97 | int rv; |
66 | 98 | ||
67 | ctx->err = errno; | 99 | ctx->errnum = errno; |
68 | free(ctx->errmsg); | 100 | |
69 | ctx->errmsg = NULL; | 101 | va_start(ap, fmt); |
102 | rv = tls_set_verror(ctx, ctx->errnum, fmt, ap); | ||
103 | va_end(ap); | ||
104 | |||
105 | return (rv); | ||
106 | } | ||
107 | |||
108 | int | ||
109 | tls_set_errorx(struct tls *ctx, const char *fmt, ...) | ||
110 | { | ||
111 | va_list ap; | ||
112 | int rv; | ||
70 | 113 | ||
71 | va_start(ap, fmt); | 114 | va_start(ap, fmt); |
72 | rv = vasprintf(&ctx->errmsg, fmt, ap); | 115 | rv = tls_set_verror(ctx, -1, fmt, ap); |
73 | va_end(ap); | 116 | va_end(ap); |
74 | 117 | ||
75 | return (rv); | 118 | return (rv); |
@@ -113,35 +156,35 @@ tls_configure_keypair(struct tls *ctx) | |||
113 | 156 | ||
114 | if (ctx->config->cert_mem != NULL) { | 157 | if (ctx->config->cert_mem != NULL) { |
115 | if (ctx->config->cert_len > INT_MAX) { | 158 | if (ctx->config->cert_len > INT_MAX) { |
116 | tls_set_error(ctx, "certificate too long"); | 159 | tls_set_errorx(ctx, "certificate too long"); |
117 | goto err; | 160 | goto err; |
118 | } | 161 | } |
119 | 162 | ||
120 | if (SSL_CTX_use_certificate_chain_mem(ctx->ssl_ctx, | 163 | if (SSL_CTX_use_certificate_chain_mem(ctx->ssl_ctx, |
121 | ctx->config->cert_mem, ctx->config->cert_len) != 1) { | 164 | ctx->config->cert_mem, ctx->config->cert_len) != 1) { |
122 | tls_set_error(ctx, "failed to load certificate"); | 165 | tls_set_errorx(ctx, "failed to load certificate"); |
123 | goto err; | 166 | goto err; |
124 | } | 167 | } |
125 | cert = NULL; | 168 | cert = NULL; |
126 | } | 169 | } |
127 | if (ctx->config->key_mem != NULL) { | 170 | if (ctx->config->key_mem != NULL) { |
128 | if (ctx->config->key_len > INT_MAX) { | 171 | if (ctx->config->key_len > INT_MAX) { |
129 | tls_set_error(ctx, "key too long"); | 172 | tls_set_errorx(ctx, "key too long"); |
130 | goto err; | 173 | goto err; |
131 | } | 174 | } |
132 | 175 | ||
133 | if ((bio = BIO_new_mem_buf(ctx->config->key_mem, | 176 | if ((bio = BIO_new_mem_buf(ctx->config->key_mem, |
134 | ctx->config->key_len)) == NULL) { | 177 | ctx->config->key_len)) == NULL) { |
135 | tls_set_error(ctx, "failed to create buffer"); | 178 | tls_set_errorx(ctx, "failed to create buffer"); |
136 | goto err; | 179 | goto err; |
137 | } | 180 | } |
138 | if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, | 181 | if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, |
139 | NULL)) == NULL) { | 182 | NULL)) == NULL) { |
140 | tls_set_error(ctx, "failed to read private key"); | 183 | tls_set_errorx(ctx, "failed to read private key"); |
141 | goto err; | 184 | goto err; |
142 | } | 185 | } |
143 | if (SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey) != 1) { | 186 | if (SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey) != 1) { |
144 | tls_set_error(ctx, "failed to load private key"); | 187 | tls_set_errorx(ctx, "failed to load private key"); |
145 | goto err; | 188 | goto err; |
146 | } | 189 | } |
147 | BIO_free(bio); | 190 | BIO_free(bio); |
@@ -153,20 +196,20 @@ tls_configure_keypair(struct tls *ctx) | |||
153 | if (ctx->config->cert_file != NULL) { | 196 | if (ctx->config->cert_file != NULL) { |
154 | if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, | 197 | if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, |
155 | ctx->config->cert_file) != 1) { | 198 | ctx->config->cert_file) != 1) { |
156 | tls_set_error(ctx, "failed to load certificate file"); | 199 | tls_set_errorx(ctx, "failed to load certificate file"); |
157 | goto err; | 200 | goto err; |
158 | } | 201 | } |
159 | } | 202 | } |
160 | if (ctx->config->key_file != NULL) { | 203 | if (ctx->config->key_file != NULL) { |
161 | if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, | 204 | if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, |
162 | ctx->config->key_file, SSL_FILETYPE_PEM) != 1) { | 205 | ctx->config->key_file, SSL_FILETYPE_PEM) != 1) { |
163 | tls_set_error(ctx, "failed to load private key file"); | 206 | tls_set_errorx(ctx, "failed to load private key file"); |
164 | goto err; | 207 | goto err; |
165 | } | 208 | } |
166 | } | 209 | } |
167 | 210 | ||
168 | if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) { | 211 | if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) { |
169 | tls_set_error(ctx, "private/public key mismatch"); | 212 | tls_set_errorx(ctx, "private/public key mismatch"); |
170 | goto err; | 213 | goto err; |
171 | } | 214 | } |
172 | 215 | ||
@@ -203,7 +246,7 @@ tls_configure_ssl(struct tls *ctx) | |||
203 | if (ctx->config->ciphers != NULL) { | 246 | if (ctx->config->ciphers != NULL) { |
204 | if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, | 247 | if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, |
205 | ctx->config->ciphers) != 1) { | 248 | ctx->config->ciphers) != 1) { |
206 | tls_set_error(ctx, "failed to set ciphers"); | 249 | tls_set_errorx(ctx, "failed to set ciphers"); |
207 | goto err; | 250 | goto err; |
208 | } | 251 | } |
209 | } | 252 | } |
@@ -235,9 +278,9 @@ tls_reset(struct tls *ctx) | |||
235 | ctx->socket = -1; | 278 | ctx->socket = -1; |
236 | ctx->state = 0; | 279 | ctx->state = 0; |
237 | 280 | ||
238 | ctx->err = 0; | ||
239 | free(ctx->errmsg); | 281 | free(ctx->errmsg); |
240 | ctx->errmsg = NULL; | 282 | ctx->errmsg = NULL; |
283 | ctx->errnum = 0; | ||
241 | } | 284 | } |
242 | 285 | ||
243 | int | 286 | int |
@@ -267,21 +310,21 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) | |||
267 | } else if (ssl_ret == -1) { | 310 | } else if (ssl_ret == -1) { |
268 | errstr = strerror(errno); | 311 | errstr = strerror(errno); |
269 | } | 312 | } |
270 | tls_set_error(ctx, "%s failed: %s", prefix, errstr); | 313 | tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); |
271 | return (-1); | 314 | return (-1); |
272 | 315 | ||
273 | case SSL_ERROR_SSL: | 316 | case SSL_ERROR_SSL: |
274 | if ((err = ERR_peek_error()) != 0) { | 317 | if ((err = ERR_peek_error()) != 0) { |
275 | errstr = ERR_error_string(err, NULL); | 318 | errstr = ERR_error_string(err, NULL); |
276 | } | 319 | } |
277 | tls_set_error(ctx, "%s failed: %s", prefix, errstr); | 320 | tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); |
278 | return (-1); | 321 | return (-1); |
279 | 322 | ||
280 | case SSL_ERROR_WANT_CONNECT: | 323 | case SSL_ERROR_WANT_CONNECT: |
281 | case SSL_ERROR_WANT_ACCEPT: | 324 | case SSL_ERROR_WANT_ACCEPT: |
282 | case SSL_ERROR_WANT_X509_LOOKUP: | 325 | case SSL_ERROR_WANT_X509_LOOKUP: |
283 | default: | 326 | default: |
284 | tls_set_error(ctx, "%s failed (%i)", prefix, ssl_err); | 327 | tls_set_errorx(ctx, "%s failed (%i)", prefix, ssl_err); |
285 | return (-1); | 328 | return (-1); |
286 | } | 329 | } |
287 | } | 330 | } |
@@ -294,7 +337,7 @@ tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen) | |||
294 | *outlen = 0; | 337 | *outlen = 0; |
295 | 338 | ||
296 | if (buflen > INT_MAX) { | 339 | if (buflen > INT_MAX) { |
297 | tls_set_error(ctx, "buflen too long"); | 340 | tls_set_errorx(ctx, "buflen too long"); |
298 | return (-1); | 341 | return (-1); |
299 | } | 342 | } |
300 | 343 | ||
@@ -315,7 +358,7 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen) | |||
315 | *outlen = 0; | 358 | *outlen = 0; |
316 | 359 | ||
317 | if (buflen > INT_MAX) { | 360 | if (buflen > INT_MAX) { |
318 | tls_set_error(ctx, "buflen too long"); | 361 | tls_set_errorx(ctx, "buflen too long"); |
319 | return (-1); | 362 | return (-1); |
320 | } | 363 | } |
321 | 364 | ||