diff options
author | jsing <> | 2016-07-06 16:16:36 +0000 |
---|---|---|
committer | jsing <> | 2016-07-06 16:16:36 +0000 |
commit | c6881b696b1fa5d3e6966b53235e4c76d0574048 (patch) | |
tree | dd36a8def4c5396baa868a5a3d3d3fa3785f19dd /src | |
parent | c6b61bddec1634e2d244575d39a9e88063218f88 (diff) | |
download | openbsd-c6881b696b1fa5d3e6966b53235e4c76d0574048.tar.gz openbsd-c6881b696b1fa5d3e6966b53235e4c76d0574048.tar.bz2 openbsd-c6881b696b1fa5d3e6966b53235e4c76d0574048.zip |
Always load CA, key and certificate files at the time the configuration
function is called. This simplifies code and results in a single memory
based code path being used to provide data to libssl. Errors that occur
when accessing the specified file are now detected and propagated
immediately. Since the file access now occurs when the configuration
function is called, we now play nicely with privsep/pledge.
ok beck@ bluhm@ doug@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libtls/tls.c | 23 | ||||
-rw-r--r-- | src/lib/libtls/tls_config.c | 79 | ||||
-rw-r--r-- | src/lib/libtls/tls_internal.h | 5 |
3 files changed, 72 insertions, 35 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 783d320a9d..e0464ec8b1 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.39 2016/07/06 02:32:57 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.40 2016/07/06 16:16:36 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -216,9 +216,7 @@ tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
216 | 216 | ||
217 | if (!required && | 217 | if (!required && |
218 | keypair->cert_mem == NULL && | 218 | keypair->cert_mem == NULL && |
219 | keypair->key_mem == NULL && | 219 | keypair->key_mem == NULL) |
220 | keypair->cert_file == NULL && | ||
221 | keypair->key_file == NULL) | ||
222 | return(0); | 220 | return(0); |
223 | 221 | ||
224 | if (keypair->cert_mem != NULL) { | 222 | if (keypair->cert_mem != NULL) { |
@@ -260,21 +258,6 @@ tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
260 | pkey = NULL; | 258 | pkey = NULL; |
261 | } | 259 | } |
262 | 260 | ||
263 | if (keypair->cert_file != NULL) { | ||
264 | if (SSL_CTX_use_certificate_chain_file(ssl_ctx, | ||
265 | keypair->cert_file) != 1) { | ||
266 | tls_set_errorx(ctx, "failed to load certificate file"); | ||
267 | goto err; | ||
268 | } | ||
269 | } | ||
270 | if (keypair->key_file != NULL) { | ||
271 | if (SSL_CTX_use_PrivateKey_file(ssl_ctx, | ||
272 | keypair->key_file, SSL_FILETYPE_PEM) != 1) { | ||
273 | tls_set_errorx(ctx, "failed to load private key file"); | ||
274 | goto err; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | if (SSL_CTX_check_private_key(ssl_ctx) != 1) { | 261 | if (SSL_CTX_check_private_key(ssl_ctx) != 1) { |
279 | tls_set_errorx(ctx, "private/public key mismatch"); | 262 | tls_set_errorx(ctx, "private/public key mismatch"); |
280 | goto err; | 263 | goto err; |
@@ -346,7 +329,7 @@ tls_configure_ssl_verify(struct tls *ctx, int verify) | |||
346 | goto err; | 329 | goto err; |
347 | } | 330 | } |
348 | } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, | 331 | } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, |
349 | ctx->config->ca_file, ctx->config->ca_path) != 1) { | 332 | NULL, ctx->config->ca_path) != 1) { |
350 | tls_set_errorx(ctx, "ssl verify setup failure"); | 333 | tls_set_errorx(ctx, "ssl verify setup failure"); |
351 | goto err; | 334 | goto err; |
352 | } | 335 | } |
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 8f73a5a45b..cfd054b024 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_config.c,v 1.18 2016/05/27 14:38:40 jsing Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.19 2016/07/06 16:16:36 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -15,9 +15,13 @@ | |||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <sys/stat.h> | ||
19 | |||
18 | #include <ctype.h> | 20 | #include <ctype.h> |
19 | #include <errno.h> | 21 | #include <errno.h> |
22 | #include <fcntl.h> | ||
20 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <unistd.h> | ||
21 | 25 | ||
22 | #include <tls.h> | 26 | #include <tls.h> |
23 | #include "tls_internal.h" | 27 | #include "tls_internal.h" |
@@ -57,6 +61,53 @@ set_mem(char **dest, size_t *destlen, const void *src, size_t srclen) | |||
57 | return 0; | 61 | return 0; |
58 | } | 62 | } |
59 | 63 | ||
64 | static int | ||
65 | load_file(struct tls_error *error, const char *filetype, const char *filename, | ||
66 | char **buf, size_t *len) | ||
67 | { | ||
68 | struct stat st; | ||
69 | int fd = -1; | ||
70 | |||
71 | free(*buf); | ||
72 | *buf = NULL; | ||
73 | *len = 0; | ||
74 | |||
75 | if ((fd = open(filename, O_RDONLY)) == -1) { | ||
76 | tls_error_set(error, "failed to open %s file '%s'", | ||
77 | filetype, filename); | ||
78 | goto fail; | ||
79 | } | ||
80 | if (fstat(fd, &st) != 0) { | ||
81 | tls_error_set(error, "failed to stat %s file '%s'", | ||
82 | filetype, filename); | ||
83 | goto fail; | ||
84 | } | ||
85 | *len = (size_t)st.st_size; | ||
86 | if ((*buf = malloc(*len)) == NULL) { | ||
87 | tls_error_set(error, "failed to allocate buffer for " | ||
88 | "%s file '%s'", filetype, filename); | ||
89 | goto fail; | ||
90 | } | ||
91 | if (read(fd, *buf, *len) != *len) { | ||
92 | tls_error_set(error, "failed to read %s file '%s'", | ||
93 | filetype, filename); | ||
94 | goto fail; | ||
95 | } | ||
96 | close(fd); | ||
97 | return 0; | ||
98 | |||
99 | fail: | ||
100 | if (fd != -1) | ||
101 | close(fd); | ||
102 | if (*buf != NULL) | ||
103 | explicit_bzero(*buf, *len); | ||
104 | free(*buf); | ||
105 | *buf = NULL; | ||
106 | *len = 0; | ||
107 | |||
108 | return -1; | ||
109 | } | ||
110 | |||
60 | static struct tls_keypair * | 111 | static struct tls_keypair * |
61 | tls_keypair_new() | 112 | tls_keypair_new() |
62 | { | 113 | { |
@@ -64,9 +115,11 @@ tls_keypair_new() | |||
64 | } | 115 | } |
65 | 116 | ||
66 | static int | 117 | static int |
67 | tls_keypair_set_cert_file(struct tls_keypair *keypair, const char *cert_file) | 118 | tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, |
119 | const char *cert_file) | ||
68 | { | 120 | { |
69 | return set_string(&keypair->cert_file, cert_file); | 121 | return load_file(error, "certificate", cert_file, &keypair->cert_mem, |
122 | &keypair->cert_len); | ||
70 | } | 123 | } |
71 | 124 | ||
72 | static int | 125 | static int |
@@ -77,9 +130,13 @@ tls_keypair_set_cert_mem(struct tls_keypair *keypair, const uint8_t *cert, | |||
77 | } | 130 | } |
78 | 131 | ||
79 | static int | 132 | static int |
80 | tls_keypair_set_key_file(struct tls_keypair *keypair, const char *key_file) | 133 | tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error, |
134 | const char *key_file) | ||
81 | { | 135 | { |
82 | return set_string(&keypair->key_file, key_file); | 136 | if (keypair->key_mem != NULL) |
137 | explicit_bzero(keypair->key_mem, keypair->key_len); | ||
138 | return load_file(error, "key", key_file, &keypair->key_mem, | ||
139 | &keypair->key_len); | ||
83 | } | 140 | } |
84 | 141 | ||
85 | static int | 142 | static int |
@@ -106,9 +163,7 @@ tls_keypair_free(struct tls_keypair *keypair) | |||
106 | 163 | ||
107 | tls_keypair_clear(keypair); | 164 | tls_keypair_clear(keypair); |
108 | 165 | ||
109 | free((char *)keypair->cert_file); | ||
110 | free(keypair->cert_mem); | 166 | free(keypair->cert_mem); |
111 | free((char *)keypair->key_file); | ||
112 | free(keypair->key_mem); | 167 | free(keypair->key_mem); |
113 | 168 | ||
114 | free(keypair); | 169 | free(keypair); |
@@ -166,7 +221,6 @@ tls_config_free(struct tls_config *config) | |||
166 | 221 | ||
167 | free(config->error.msg); | 222 | free(config->error.msg); |
168 | 223 | ||
169 | free((char *)config->ca_file); | ||
170 | free((char *)config->ca_mem); | 224 | free((char *)config->ca_mem); |
171 | free((char *)config->ca_path); | 225 | free((char *)config->ca_path); |
172 | free((char *)config->ciphers); | 226 | free((char *)config->ciphers); |
@@ -252,7 +306,8 @@ tls_config_parse_protocols(uint32_t *protocols, const char *protostr) | |||
252 | int | 306 | int |
253 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) | 307 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) |
254 | { | 308 | { |
255 | return set_string(&config->ca_file, ca_file); | 309 | return load_file(&config->error, "CA", ca_file, &config->ca_mem, |
310 | &config->ca_len); | ||
256 | } | 311 | } |
257 | 312 | ||
258 | int | 313 | int |
@@ -270,7 +325,8 @@ tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) | |||
270 | int | 325 | int |
271 | tls_config_set_cert_file(struct tls_config *config, const char *cert_file) | 326 | tls_config_set_cert_file(struct tls_config *config, const char *cert_file) |
272 | { | 327 | { |
273 | return tls_keypair_set_cert_file(config->keypair, cert_file); | 328 | return tls_keypair_set_cert_file(config->keypair, &config->error, |
329 | cert_file); | ||
274 | } | 330 | } |
275 | 331 | ||
276 | int | 332 | int |
@@ -337,7 +393,8 @@ tls_config_set_ecdhecurve(struct tls_config *config, const char *name) | |||
337 | int | 393 | int |
338 | tls_config_set_key_file(struct tls_config *config, const char *key_file) | 394 | tls_config_set_key_file(struct tls_config *config, const char *key_file) |
339 | { | 395 | { |
340 | return tls_keypair_set_key_file(config->keypair, key_file); | 396 | return tls_keypair_set_key_file(config->keypair, &config->error, |
397 | key_file); | ||
341 | } | 398 | } |
342 | 399 | ||
343 | int | 400 | int |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index 745fb40c76..b7a1530c96 100644 --- a/src/lib/libtls/tls_internal.h +++ b/src/lib/libtls/tls_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_internal.h,v 1.29 2016/05/27 14:38:40 jsing Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.30 2016/07/06 16:16:36 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> | 3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> |
4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
@@ -42,10 +42,8 @@ struct tls_error { | |||
42 | struct tls_keypair { | 42 | struct tls_keypair { |
43 | struct tls_keypair *next; | 43 | struct tls_keypair *next; |
44 | 44 | ||
45 | const char *cert_file; | ||
46 | char *cert_mem; | 45 | char *cert_mem; |
47 | size_t cert_len; | 46 | size_t cert_len; |
48 | const char *key_file; | ||
49 | char *key_mem; | 47 | char *key_mem; |
50 | size_t key_len; | 48 | size_t key_len; |
51 | }; | 49 | }; |
@@ -53,7 +51,6 @@ struct tls_keypair { | |||
53 | struct tls_config { | 51 | struct tls_config { |
54 | struct tls_error error; | 52 | struct tls_error error; |
55 | 53 | ||
56 | const char *ca_file; | ||
57 | const char *ca_path; | 54 | const char *ca_path; |
58 | char *ca_mem; | 55 | char *ca_mem; |
59 | size_t ca_len; | 56 | size_t ca_len; |