diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libtls/tls.c | 52 | ||||
| -rw-r--r-- | src/lib/libtls/tls_config.c | 81 | ||||
| -rw-r--r-- | src/lib/libtls/tls_internal.h | 9 |
3 files changed, 98 insertions, 44 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 4d4910d128..429881dbb3 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls.c,v 1.44 2016/08/12 15:10:59 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.45 2016/08/13 13:05:51 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -216,9 +216,7 @@ tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 216 | 216 | ||
| 217 | if (!required && | 217 | if (!required && |
| 218 | keypair->cert_mem == NULL && | 218 | keypair->cert_mem == NULL && |
| 219 | keypair->key_mem == NULL && | 219 | keypair->key_mem == NULL) |
| 220 | keypair->cert_file == NULL && | ||
| 221 | keypair->key_file == NULL) | ||
| 222 | return(0); | 220 | return(0); |
| 223 | 221 | ||
| 224 | if (keypair->cert_mem != NULL) { | 222 | if (keypair->cert_mem != NULL) { |
| @@ -260,21 +258,6 @@ tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 260 | pkey = NULL; | 258 | pkey = NULL; |
| 261 | } | 259 | } |
| 262 | 260 | ||
| 263 | if (keypair->cert_file != NULL) { | ||
| 264 | if (SSL_CTX_use_certificate_chain_file(ssl_ctx, | ||
| 265 | keypair->cert_file) != 1) { | ||
| 266 | tls_set_errorx(ctx, "failed to load certificate file"); | ||
| 267 | goto err; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | if (keypair->key_file != NULL) { | ||
| 271 | if (SSL_CTX_use_PrivateKey_file(ssl_ctx, | ||
| 272 | keypair->key_file, SSL_FILETYPE_PEM) != 1) { | ||
| 273 | tls_set_errorx(ctx, "failed to load private key file"); | ||
| 274 | goto err; | ||
| 275 | } | ||
| 276 | } | ||
| 277 | |||
| 278 | if (SSL_CTX_check_private_key(ssl_ctx) != 1) { | 261 | if (SSL_CTX_check_private_key(ssl_ctx) != 1) { |
| 279 | tls_set_errorx(ctx, "private/public key mismatch"); | 262 | tls_set_errorx(ctx, "private/public key mismatch"); |
| 280 | goto err; | 263 | goto err; |
| @@ -340,31 +323,46 @@ tls_configure_ssl(struct tls *ctx) | |||
| 340 | int | 323 | int |
| 341 | tls_configure_ssl_verify(struct tls *ctx, int verify) | 324 | tls_configure_ssl_verify(struct tls *ctx, int verify) |
| 342 | { | 325 | { |
| 326 | size_t ca_len = ctx->config->ca_len; | ||
| 327 | char *ca_mem = ctx->config->ca_mem; | ||
| 328 | char *ca_free = NULL; | ||
| 329 | |||
| 343 | SSL_CTX_set_verify(ctx->ssl_ctx, verify, NULL); | 330 | SSL_CTX_set_verify(ctx->ssl_ctx, verify, NULL); |
| 344 | 331 | ||
| 345 | if (ctx->config->ca_mem != NULL) { | 332 | /* If no CA has been specified, attempt to load the default. */ |
| 346 | /* XXX do this in set. */ | 333 | if (ctx->config->ca_mem == NULL && ctx->config->ca_path == NULL) { |
| 347 | if (ctx->config->ca_len > INT_MAX) { | 334 | if (tls_config_load_file(&ctx->error, "CA", _PATH_SSL_CA_FILE, |
| 335 | &ca_mem, &ca_len) != 0) | ||
| 336 | goto err; | ||
| 337 | ca_free = ca_mem; | ||
| 338 | } | ||
| 339 | |||
| 340 | if (ca_mem != NULL) { | ||
| 341 | if (ca_len > INT_MAX) { | ||
| 348 | tls_set_errorx(ctx, "ca too long"); | 342 | tls_set_errorx(ctx, "ca too long"); |
| 349 | goto err; | 343 | goto err; |
| 350 | } | 344 | } |
| 351 | if (SSL_CTX_load_verify_mem(ctx->ssl_ctx, | 345 | if (SSL_CTX_load_verify_mem(ctx->ssl_ctx, ca_mem, |
| 352 | ctx->config->ca_mem, ctx->config->ca_len) != 1) { | 346 | ca_len) != 1) { |
| 353 | tls_set_errorx(ctx, "ssl verify memory setup failure"); | 347 | tls_set_errorx(ctx, "ssl verify memory setup failure"); |
| 354 | goto err; | 348 | goto err; |
| 355 | } | 349 | } |
| 356 | } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, | 350 | } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, NULL, |
| 357 | ctx->config->ca_file, ctx->config->ca_path) != 1) { | 351 | ctx->config->ca_path) != 1) { |
| 358 | tls_set_errorx(ctx, "ssl verify setup failure"); | 352 | tls_set_errorx(ctx, "ssl verify locations failure"); |
| 359 | goto err; | 353 | goto err; |
| 360 | } | 354 | } |
| 361 | if (ctx->config->verify_depth >= 0) | 355 | if (ctx->config->verify_depth >= 0) |
| 362 | SSL_CTX_set_verify_depth(ctx->ssl_ctx, | 356 | SSL_CTX_set_verify_depth(ctx->ssl_ctx, |
| 363 | ctx->config->verify_depth); | 357 | ctx->config->verify_depth); |
| 364 | 358 | ||
| 359 | free(ca_free); | ||
| 360 | |||
| 365 | return (0); | 361 | return (0); |
| 366 | 362 | ||
| 367 | err: | 363 | err: |
| 364 | free(ca_free); | ||
| 365 | |||
| 368 | return (-1); | 366 | return (-1); |
| 369 | } | 367 | } |
| 370 | 368 | ||
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index e690b9ee76..cd2a04cdd6 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.25 2016/08/12 15:10:59 jsing Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.26 2016/08/13 13:05:51 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -15,9 +15,13 @@ | |||
| 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 | 17 | ||
| 18 | #include <sys/stat.h> | ||
| 19 | |||
| 18 | #include <ctype.h> | 20 | #include <ctype.h> |
| 19 | #include <errno.h> | 21 | #include <errno.h> |
| 22 | #include <fcntl.h> | ||
| 20 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| 24 | #include <unistd.h> | ||
| 21 | 25 | ||
| 22 | #include <tls.h> | 26 | #include <tls.h> |
| 23 | #include "tls_internal.h" | 27 | #include "tls_internal.h" |
| @@ -64,9 +68,11 @@ tls_keypair_new() | |||
| 64 | } | 68 | } |
| 65 | 69 | ||
| 66 | static int | 70 | static int |
| 67 | tls_keypair_set_cert_file(struct tls_keypair *keypair, const char *cert_file) | 71 | tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, |
| 72 | const char *cert_file) | ||
| 68 | { | 73 | { |
| 69 | return set_string(&keypair->cert_file, cert_file); | 74 | return tls_config_load_file(error, "certificate", cert_file, |
| 75 | &keypair->cert_mem, &keypair->cert_len); | ||
| 70 | } | 76 | } |
| 71 | 77 | ||
| 72 | static int | 78 | static int |
| @@ -77,9 +83,13 @@ tls_keypair_set_cert_mem(struct tls_keypair *keypair, const uint8_t *cert, | |||
| 77 | } | 83 | } |
| 78 | 84 | ||
| 79 | static int | 85 | static int |
| 80 | tls_keypair_set_key_file(struct tls_keypair *keypair, const char *key_file) | 86 | tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error, |
| 87 | const char *key_file) | ||
| 81 | { | 88 | { |
| 82 | return set_string(&keypair->key_file, key_file); | 89 | if (keypair->key_mem != NULL) |
| 90 | explicit_bzero(keypair->key_mem, keypair->key_len); | ||
| 91 | return tls_config_load_file(error, "key", key_file, | ||
| 92 | &keypair->key_mem, &keypair->key_len); | ||
| 83 | } | 93 | } |
| 84 | 94 | ||
| 85 | static int | 95 | static int |
| @@ -106,14 +116,59 @@ tls_keypair_free(struct tls_keypair *keypair) | |||
| 106 | 116 | ||
| 107 | tls_keypair_clear(keypair); | 117 | tls_keypair_clear(keypair); |
| 108 | 118 | ||
| 109 | free((char *)keypair->cert_file); | ||
| 110 | free(keypair->cert_mem); | 119 | free(keypair->cert_mem); |
| 111 | free((char *)keypair->key_file); | ||
| 112 | free(keypair->key_mem); | 120 | free(keypair->key_mem); |
| 113 | 121 | ||
| 114 | free(keypair); | 122 | free(keypair); |
| 115 | } | 123 | } |
| 116 | 124 | ||
| 125 | int | ||
| 126 | tls_config_load_file(struct tls_error *error, const char *filetype, | ||
| 127 | const char *filename, char **buf, size_t *len) | ||
| 128 | { | ||
| 129 | struct stat st; | ||
| 130 | int fd = -1; | ||
| 131 | |||
| 132 | free(*buf); | ||
| 133 | *buf = NULL; | ||
| 134 | *len = 0; | ||
| 135 | |||
| 136 | if ((fd = open(filename, O_RDONLY)) == -1) { | ||
| 137 | tls_error_set(error, "failed to open %s file '%s'", | ||
| 138 | filetype, filename); | ||
| 139 | goto fail; | ||
| 140 | } | ||
| 141 | if (fstat(fd, &st) != 0) { | ||
| 142 | tls_error_set(error, "failed to stat %s file '%s'", | ||
| 143 | filetype, filename); | ||
| 144 | goto fail; | ||
| 145 | } | ||
| 146 | *len = (size_t)st.st_size; | ||
| 147 | if ((*buf = malloc(*len)) == NULL) { | ||
| 148 | tls_error_set(error, "failed to allocate buffer for " | ||
| 149 | "%s file", filetype); | ||
| 150 | goto fail; | ||
| 151 | } | ||
| 152 | if (read(fd, *buf, *len) != *len) { | ||
| 153 | tls_error_set(error, "failed to read %s file '%s'", | ||
| 154 | filetype, filename); | ||
| 155 | goto fail; | ||
| 156 | } | ||
| 157 | close(fd); | ||
| 158 | return 0; | ||
| 159 | |||
| 160 | fail: | ||
| 161 | if (fd != -1) | ||
| 162 | close(fd); | ||
| 163 | if (*buf != NULL) | ||
| 164 | explicit_bzero(*buf, *len); | ||
| 165 | free(*buf); | ||
| 166 | *buf = NULL; | ||
| 167 | *len = 0; | ||
| 168 | |||
| 169 | return -1; | ||
| 170 | } | ||
| 171 | |||
| 117 | struct tls_config * | 172 | struct tls_config * |
| 118 | tls_config_new(void) | 173 | tls_config_new(void) |
| 119 | { | 174 | { |
| @@ -128,8 +183,6 @@ tls_config_new(void) | |||
| 128 | /* | 183 | /* |
| 129 | * Default configuration. | 184 | * Default configuration. |
| 130 | */ | 185 | */ |
| 131 | if (tls_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0) | ||
| 132 | goto err; | ||
| 133 | if (tls_config_set_dheparams(config, "none") != 0) | 186 | if (tls_config_set_dheparams(config, "none") != 0) |
| 134 | goto err; | 187 | goto err; |
| 135 | if (tls_config_set_ecdhecurve(config, "auto") != 0) | 188 | if (tls_config_set_ecdhecurve(config, "auto") != 0) |
| @@ -167,7 +220,6 @@ tls_config_free(struct tls_config *config) | |||
| 167 | free(config->error.msg); | 220 | free(config->error.msg); |
| 168 | 221 | ||
| 169 | free(config->alpn); | 222 | free(config->alpn); |
| 170 | free((char *)config->ca_file); | ||
| 171 | free((char *)config->ca_mem); | 223 | free((char *)config->ca_mem); |
| 172 | free((char *)config->ca_path); | 224 | free((char *)config->ca_path); |
| 173 | free((char *)config->ciphers); | 225 | free((char *)config->ciphers); |
| @@ -319,7 +371,8 @@ tls_config_set_alpn(struct tls_config *config, const char *alpn) | |||
| 319 | int | 371 | int |
| 320 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) | 372 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) |
| 321 | { | 373 | { |
| 322 | return set_string(&config->ca_file, ca_file); | 374 | return tls_config_load_file(&config->error, "CA", ca_file, |
| 375 | &config->ca_mem, &config->ca_len); | ||
| 323 | } | 376 | } |
| 324 | 377 | ||
| 325 | int | 378 | int |
| @@ -337,7 +390,8 @@ tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) | |||
| 337 | int | 390 | int |
| 338 | tls_config_set_cert_file(struct tls_config *config, const char *cert_file) | 391 | tls_config_set_cert_file(struct tls_config *config, const char *cert_file) |
| 339 | { | 392 | { |
| 340 | return tls_keypair_set_cert_file(config->keypair, cert_file); | 393 | return tls_keypair_set_cert_file(config->keypair, &config->error, |
| 394 | cert_file); | ||
| 341 | } | 395 | } |
| 342 | 396 | ||
| 343 | int | 397 | int |
| @@ -424,7 +478,8 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *name) | |||
| 424 | int | 478 | int |
| 425 | tls_config_set_key_file(struct tls_config *config, const char *key_file) | 479 | tls_config_set_key_file(struct tls_config *config, const char *key_file) |
| 426 | { | 480 | { |
| 427 | return tls_keypair_set_key_file(config->keypair, key_file); | 481 | return tls_keypair_set_key_file(config->keypair, &config->error, |
| 482 | key_file); | ||
| 428 | } | 483 | } |
| 429 | 484 | ||
| 430 | int | 485 | int |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index 1ef95adb08..fa972bbadf 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.35 2016/08/12 15:10:59 jsing Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.36 2016/08/13 13:05:51 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> |
| @@ -44,10 +44,8 @@ struct tls_error { | |||
| 44 | struct tls_keypair { | 44 | struct tls_keypair { |
| 45 | struct tls_keypair *next; | 45 | struct tls_keypair *next; |
| 46 | 46 | ||
| 47 | const char *cert_file; | ||
| 48 | char *cert_mem; | 47 | char *cert_mem; |
| 49 | size_t cert_len; | 48 | size_t cert_len; |
| 50 | const char *key_file; | ||
| 51 | char *key_mem; | 49 | char *key_mem; |
| 52 | size_t key_len; | 50 | size_t key_len; |
| 53 | }; | 51 | }; |
| @@ -57,7 +55,6 @@ struct tls_config { | |||
| 57 | 55 | ||
| 58 | char *alpn; | 56 | char *alpn; |
| 59 | size_t alpn_len; | 57 | size_t alpn_len; |
| 60 | const char *ca_file; | ||
| 61 | const char *ca_path; | 58 | const char *ca_path; |
| 62 | char *ca_mem; | 59 | char *ca_mem; |
| 63 | size_t ca_len; | 60 | size_t ca_len; |
| @@ -120,8 +117,12 @@ int tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 120 | int tls_configure_server(struct tls *ctx); | 117 | int tls_configure_server(struct tls *ctx); |
| 121 | int tls_configure_ssl(struct tls *ctx); | 118 | int tls_configure_ssl(struct tls *ctx); |
| 122 | int tls_configure_ssl_verify(struct tls *ctx, int verify); | 119 | int tls_configure_ssl_verify(struct tls *ctx, int verify); |
| 120 | |||
| 123 | int tls_handshake_client(struct tls *ctx); | 121 | int tls_handshake_client(struct tls *ctx); |
| 124 | int tls_handshake_server(struct tls *ctx); | 122 | int tls_handshake_server(struct tls *ctx); |
| 123 | |||
| 124 | int tls_config_load_file(struct tls_error *error, const char *filetype, | ||
| 125 | const char *filename, char **buf, size_t *len); | ||
| 125 | int tls_host_port(const char *hostport, char **host, char **port); | 126 | int tls_host_port(const char *hostport, char **host, char **port); |
| 126 | 127 | ||
| 127 | int tls_error_set(struct tls_error *error, const char *fmt, ...) | 128 | int tls_error_set(struct tls_error *error, const char *fmt, ...) |
