diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2015-02-07 23:25:38 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2015-02-07 23:25:38 +0000 |
commit | 62ead7fa7f7602db6d1dc73457d2308bf1e51fa3 (patch) | |
tree | 7afecf9dc1b777992374710114807996c14fa988 /lib/libtls | |
parent | 1f9e69e498f3b613e2f5d3f04824a51fa69248a5 (diff) |
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@
Diffstat (limited to 'lib/libtls')
-rw-r--r-- | lib/libtls/tls.h | 4 | ||||
-rw-r--r-- | lib/libtls/tls_util.c | 90 |
2 files changed, 92 insertions, 2 deletions
diff --git a/lib/libtls/tls.h b/lib/libtls/tls.h index 20e5b469019..bd1eed559b6 100644 --- a/lib/libtls/tls.h +++ b/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 <jsing@openbsd.org> * @@ -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/lib/libtls/tls_util.c b/lib/libtls/tls_util.c index 2adfb674b8f..a7b9faabbea 100644 --- a/lib/libtls/tls_util.c +++ b/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 <jsing@openbsd.org> + * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> * * 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 <sys/stat.h> + #include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#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); +} |