summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls.c
diff options
context:
space:
mode:
authorjsing <>2015-08-27 15:26:50 +0000
committerjsing <>2015-08-27 15:26:50 +0000
commit4cf0ea2d0621bc7128cf6a7cb3ed6a178f835617 (patch)
treed2c2a8c6fc1b8da3c4117997a97ab03f0ac74f21 /src/lib/libtls/tls.c
parent9385a1fd21f3850678c58b5cc8702c3a54b91ead (diff)
downloadopenbsd-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.c87
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
61static int
62tls_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
87err:
88 free(errmsg);
89
90 return (rv);
91}
92
61int 93int
62tls_set_error(struct tls *ctx, char *fmt, ...) 94tls_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
108int
109tls_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
243int 286int
@@ -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