summaryrefslogtreecommitdiff
path: root/lib/libtls/tls_config.c
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2016-08-13 13:05:52 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2016-08-13 13:05:52 +0000
commitb908002fe2494be1995704916d6c886d6aeec47d (patch)
tree5c04e25b8ce5a719e8dba129da6011b87333223c /lib/libtls/tls_config.c
parent2a1ee9d6efb1941e56c6aebf198aea5df7277cce (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.c81
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