diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libtls/tls_util.c | 90 |
1 files changed, 89 insertions, 1 deletions
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 | } | ||