From 66c5af83b4df3fc9df8b20fbc3eb60a6696e84f3 Mon Sep 17 00:00:00 2001 From: reyk <> Date: Sat, 7 Feb 2015 23:25:37 +0000 Subject: Add tls_load_file() as a helper to load certificates or encrypted keys into memory. This can be used for tls_config_set_ca_mem(), tls_config_set_cert_mem() or tls_config_set_key_mem(). With input from jsing@, tedu@ and henning@ OK tedu@ --- src/lib/libtls/tls.h | 4 ++- src/lib/libtls/tls_util.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h index 20e5b46901..bd1eed559b 100644 --- a/src/lib/libtls/tls.h +++ b/src/lib/libtls/tls.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.h,v 1.4 2015/02/07 06:19:26 jsing Exp $ */ +/* $OpenBSD: tls.h,v 1.5 2015/02/07 23:25:37 reyk Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -76,4 +76,6 @@ int tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen); int tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen); int tls_close(struct tls *ctx); +uint8_t *tls_load_file(const char *file, size_t *len, char *password); + #endif /* HEADER_TLS_H */ diff --git a/src/lib/libtls/tls_util.c b/src/lib/libtls/tls_util.c index 2adfb674b8..a7b9faabbe 100644 --- a/src/lib/libtls/tls_util.c +++ b/src/lib/libtls/tls_util.c @@ -1,6 +1,7 @@ -/* $OpenBSD: tls_util.c,v 1.1 2014/10/31 13:46:17 jsing Exp $ */ +/* $OpenBSD: tls_util.c,v 1.2 2015/02/07 23:25:37 reyk Exp $ */ /* * Copyright (c) 2014 Joel Sing + * Copyright (c) 2015 Reyk Floeter * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,8 +16,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include +#include +#include +#include "tls.h" #include "tls_internal.h" /* @@ -79,3 +85,85 @@ done: return (rv); } + +static int +tls_password_cb(char *buf, int size, int rwflag, void *u) +{ + size_t len; + if (u == NULL) { + memset(buf, 0, size); + return (0); + } + if ((len = strlcpy(buf, u, size)) >= (size_t)size) + return (0); + return (len); +} + +uint8_t * +tls_load_file(const char *name, size_t *len, char *password) +{ + FILE *fp; + EVP_PKEY *key = NULL; + BIO *bio = NULL; + char *data, *buf = NULL; + struct stat st; + size_t size; + int fd = -1; + + *len = 0; + + if ((fd = open(name, O_RDONLY)) == -1) + return (NULL); + + /* Just load the file into memory without decryption */ + if (password == NULL) { + if (fstat(fd, &st) != 0) + goto fail; + size = (size_t)st.st_size; + if ((buf = calloc(1, size + 1)) == NULL) + goto fail; + if (read(fd, buf, size) != size) + goto fail; + close(fd); + goto done; + } + + /* Or read the (possibly) encrypted key from file */ + if ((fp = fdopen(fd, "r")) == NULL) + goto fail; + fd = -1; + + key = PEM_read_PrivateKey(fp, NULL, tls_password_cb, password); + fclose(fp); + if (key == NULL) + goto fail; + + /* Write unencrypted key to memory buffer */ + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto fail; + if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) + goto fail; + if ((size = BIO_get_mem_data(bio, &data)) <= 0) + goto fail; + if ((buf = calloc(1, size)) == NULL) + goto fail; + memcpy(buf, data, size); + + BIO_free_all(bio); + EVP_PKEY_free(key); + + done: + *len = size; + return (buf); + + fail: + free(buf); + if (fd != -1) + close(fd); + if (bio != NULL) + BIO_free_all(bio); + if (key != NULL) + EVP_PKEY_free(key); + + return (NULL); +} -- cgit v1.2.3-55-g6feb