diff options
author | reyk <> | 2015-02-07 23:25:37 +0000 |
---|---|---|
committer | reyk <> | 2015-02-07 23:25:37 +0000 |
commit | 66c5af83b4df3fc9df8b20fbc3eb60a6696e84f3 (patch) | |
tree | ab6a1fbb8cc7e259680a1a2f04cba6b09a58b79b | |
parent | 7e2dc80f61d80ca43ec37c4500834784e3e22dae (diff) | |
download | openbsd-66c5af83b4df3fc9df8b20fbc3eb60a6696e84f3.tar.gz openbsd-66c5af83b4df3fc9df8b20fbc3eb60a6696e84f3.tar.bz2 openbsd-66c5af83b4df3fc9df8b20fbc3eb60a6696e84f3.zip |
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@
-rw-r--r-- | src/lib/libtls/tls.h | 4 | ||||
-rw-r--r-- | src/lib/libtls/tls_util.c | 90 |
2 files changed, 92 insertions, 2 deletions
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 @@ | |||
1 | /* $OpenBSD: tls.h,v 1.4 2015/02/07 06:19:26 jsing Exp $ */ | 1 | /* $OpenBSD: tls.h,v 1.5 2015/02/07 23:25:37 reyk Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -76,4 +76,6 @@ int tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen); | |||
76 | int tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen); | 76 | int tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen); |
77 | int tls_close(struct tls *ctx); | 77 | int tls_close(struct tls *ctx); |
78 | 78 | ||
79 | uint8_t *tls_load_file(const char *file, size_t *len, char *password); | ||
80 | |||
79 | #endif /* HEADER_TLS_H */ | 81 | #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 @@ | |||
1 | /* $OpenBSD: tls_util.c,v 1.1 2014/10/31 13:46:17 jsing Exp $ */ | 1 | /* $OpenBSD: tls_util.c,v 1.2 2015/02/07 23:25:37 reyk Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -15,8 +16,13 @@ | |||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | 17 | */ |
17 | 18 | ||
19 | #include <sys/stat.h> | ||
20 | |||
18 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <unistd.h> | ||
23 | #include <fcntl.h> | ||
19 | 24 | ||
25 | #include "tls.h" | ||
20 | #include "tls_internal.h" | 26 | #include "tls_internal.h" |
21 | 27 | ||
22 | /* | 28 | /* |
@@ -79,3 +85,85 @@ done: | |||
79 | 85 | ||
80 | return (rv); | 86 | return (rv); |
81 | } | 87 | } |
88 | |||
89 | static int | ||
90 | tls_password_cb(char *buf, int size, int rwflag, void *u) | ||
91 | { | ||
92 | size_t len; | ||
93 | if (u == NULL) { | ||
94 | memset(buf, 0, size); | ||
95 | return (0); | ||
96 | } | ||
97 | if ((len = strlcpy(buf, u, size)) >= (size_t)size) | ||
98 | return (0); | ||
99 | return (len); | ||
100 | } | ||
101 | |||
102 | uint8_t * | ||
103 | tls_load_file(const char *name, size_t *len, char *password) | ||
104 | { | ||
105 | FILE *fp; | ||
106 | EVP_PKEY *key = NULL; | ||
107 | BIO *bio = NULL; | ||
108 | char *data, *buf = NULL; | ||
109 | struct stat st; | ||
110 | size_t size; | ||
111 | int fd = -1; | ||
112 | |||
113 | *len = 0; | ||
114 | |||
115 | if ((fd = open(name, O_RDONLY)) == -1) | ||
116 | return (NULL); | ||
117 | |||
118 | /* Just load the file into memory without decryption */ | ||
119 | if (password == NULL) { | ||
120 | if (fstat(fd, &st) != 0) | ||
121 | goto fail; | ||
122 | size = (size_t)st.st_size; | ||
123 | if ((buf = calloc(1, size + 1)) == NULL) | ||
124 | goto fail; | ||
125 | if (read(fd, buf, size) != size) | ||
126 | goto fail; | ||
127 | close(fd); | ||
128 | goto done; | ||
129 | } | ||
130 | |||
131 | /* Or read the (possibly) encrypted key from file */ | ||
132 | if ((fp = fdopen(fd, "r")) == NULL) | ||
133 | goto fail; | ||
134 | fd = -1; | ||
135 | |||
136 | key = PEM_read_PrivateKey(fp, NULL, tls_password_cb, password); | ||
137 | fclose(fp); | ||
138 | if (key == NULL) | ||
139 | goto fail; | ||
140 | |||
141 | /* Write unencrypted key to memory buffer */ | ||
142 | if ((bio = BIO_new(BIO_s_mem())) == NULL) | ||
143 | goto fail; | ||
144 | if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) | ||
145 | goto fail; | ||
146 | if ((size = BIO_get_mem_data(bio, &data)) <= 0) | ||
147 | goto fail; | ||
148 | if ((buf = calloc(1, size)) == NULL) | ||
149 | goto fail; | ||
150 | memcpy(buf, data, size); | ||
151 | |||
152 | BIO_free_all(bio); | ||
153 | EVP_PKEY_free(key); | ||
154 | |||
155 | done: | ||
156 | *len = size; | ||
157 | return (buf); | ||
158 | |||
159 | fail: | ||
160 | free(buf); | ||
161 | if (fd != -1) | ||
162 | close(fd); | ||
163 | if (bio != NULL) | ||
164 | BIO_free_all(bio); | ||
165 | if (key != NULL) | ||
166 | EVP_PKEY_free(key); | ||
167 | |||
168 | return (NULL); | ||
169 | } | ||