summaryrefslogtreecommitdiff
path: root/lib/libtls
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2015-02-07 23:25:38 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2015-02-07 23:25:38 +0000
commit62ead7fa7f7602db6d1dc73457d2308bf1e51fa3 (patch)
tree7afecf9dc1b777992374710114807996c14fa988 /lib/libtls
parent1f9e69e498f3b613e2f5d3f04824a51fa69248a5 (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.h4
-rw-r--r--lib/libtls/tls_util.c90
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);
+}