diff options
| author | jsing <> | 2015-08-27 15:26:50 +0000 |
|---|---|---|
| committer | jsing <> | 2015-08-27 15:26:50 +0000 |
| commit | d621690a38473c22a65b4be34c24680f5148cd42 (patch) | |
| tree | d2c2a8c6fc1b8da3c4117997a97ab03f0ac74f21 /src/lib/libtls/tls.c | |
| parent | ec56fcd75da47203f2a92e4a7ac2df5ec3da32be (diff) | |
| download | openbsd-d621690a38473c22a65b4be34c24680f5148cd42.tar.gz openbsd-d621690a38473c22a65b4be34c24680f5148cd42.tar.bz2 openbsd-d621690a38473c22a65b4be34c24680f5148cd42.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 | ||
