diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2016-08-13 13:05:52 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2016-08-13 13:05:52 +0000 |
commit | b908002fe2494be1995704916d6c886d6aeec47d (patch) | |
tree | 5c04e25b8ce5a719e8dba129da6011b87333223c /lib/libtls/tls_config.c | |
parent | 2a1ee9d6efb1941e56c6aebf198aea5df7277cce (diff) |
Load CA, certificate and key files into memory when the appropriate
tls_config_set_*_file() function is called. This allows us to immediately
propagate useful error messages, play more nicely with privsep/pledge and
have a single code path. Instead of always loading the default CA when
tls_config_new() is called, defer and only load the default CA when
tls_configure() is invoked, if a CA has not already been specified.
ok beck@ bluhm@
Diffstat (limited to 'lib/libtls/tls_config.c')
-rw-r--r-- | lib/libtls/tls_config.c | 81 |
1 files changed, 68 insertions, 13 deletions
diff --git a/lib/libtls/tls_config.c b/lib/libtls/tls_config.c index e690b9ee760..cd2a04cdd6b 100644 --- a/lib/libtls/tls_config.c +++ b/lib/libtls/tls_config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_config.c,v 1.25 2016/08/12 15:10:59 jsing Exp $ */ +/* $OpenBSD: tls_config.c,v 1.26 2016/08/13 13:05:51 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * @@ -15,9 +15,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/stat.h> + #include <ctype.h> #include <errno.h> +#include <fcntl.h> #include <stdlib.h> +#include <unistd.h> #include <tls.h> #include "tls_internal.h" @@ -64,9 +68,11 @@ tls_keypair_new() } static int -tls_keypair_set_cert_file(struct tls_keypair *keypair, const char *cert_file) +tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, + const char *cert_file) { - return set_string(&keypair->cert_file, cert_file); + return tls_config_load_file(error, "certificate", cert_file, + &keypair->cert_mem, &keypair->cert_len); } static int @@ -77,9 +83,13 @@ tls_keypair_set_cert_mem(struct tls_keypair *keypair, const uint8_t *cert, } static int -tls_keypair_set_key_file(struct tls_keypair *keypair, const char *key_file) +tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error, + const char *key_file) { - return set_string(&keypair->key_file, key_file); + if (keypair->key_mem != NULL) + explicit_bzero(keypair->key_mem, keypair->key_len); + return tls_config_load_file(error, "key", key_file, + &keypair->key_mem, &keypair->key_len); } static int @@ -106,14 +116,59 @@ tls_keypair_free(struct tls_keypair *keypair) tls_keypair_clear(keypair); - free((char *)keypair->cert_file); free(keypair->cert_mem); - free((char *)keypair->key_file); free(keypair->key_mem); free(keypair); } +int +tls_config_load_file(struct tls_error *error, const char *filetype, + const char *filename, char **buf, size_t *len) +{ + struct stat st; + int fd = -1; + + free(*buf); + *buf = NULL; + *len = 0; + + if ((fd = open(filename, O_RDONLY)) == -1) { + tls_error_set(error, "failed to open %s file '%s'", + filetype, filename); + goto fail; + } + if (fstat(fd, &st) != 0) { + tls_error_set(error, "failed to stat %s file '%s'", + filetype, filename); + goto fail; + } + *len = (size_t)st.st_size; + if ((*buf = malloc(*len)) == NULL) { + tls_error_set(error, "failed to allocate buffer for " + "%s file", filetype); + goto fail; + } + if (read(fd, *buf, *len) != *len) { + tls_error_set(error, "failed to read %s file '%s'", + filetype, filename); + goto fail; + } + close(fd); + return 0; + + fail: + if (fd != -1) + close(fd); + if (*buf != NULL) + explicit_bzero(*buf, *len); + free(*buf); + *buf = NULL; + *len = 0; + + return -1; +} + struct tls_config * tls_config_new(void) { @@ -128,8 +183,6 @@ tls_config_new(void) /* * Default configuration. */ - if (tls_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0) - goto err; if (tls_config_set_dheparams(config, "none") != 0) goto err; if (tls_config_set_ecdhecurve(config, "auto") != 0) @@ -167,7 +220,6 @@ tls_config_free(struct tls_config *config) free(config->error.msg); free(config->alpn); - free((char *)config->ca_file); free((char *)config->ca_mem); free((char *)config->ca_path); free((char *)config->ciphers); @@ -319,7 +371,8 @@ tls_config_set_alpn(struct tls_config *config, const char *alpn) int tls_config_set_ca_file(struct tls_config *config, const char *ca_file) { - return set_string(&config->ca_file, ca_file); + return tls_config_load_file(&config->error, "CA", ca_file, + &config->ca_mem, &config->ca_len); } int @@ -337,7 +390,8 @@ tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) int tls_config_set_cert_file(struct tls_config *config, const char *cert_file) { - return tls_keypair_set_cert_file(config->keypair, cert_file); + return tls_keypair_set_cert_file(config->keypair, &config->error, + cert_file); } int @@ -424,7 +478,8 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *name) int tls_config_set_key_file(struct tls_config *config, const char *key_file) { - return tls_keypair_set_key_file(config->keypair, key_file); + return tls_keypair_set_key_file(config->keypair, &config->error, + key_file); } int |