diff options
Diffstat (limited to 'src/lib/libtls/tls_config.c')
-rw-r--r-- | src/lib/libtls/tls_config.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 43f06b0063..640a69e783 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.22 2016/07/13 16:30:48 jsing Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.23 2016/08/01 17:32:19 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -166,6 +166,7 @@ tls_config_free(struct tls_config *config) | |||
166 | 166 | ||
167 | free(config->error.msg); | 167 | free(config->error.msg); |
168 | 168 | ||
169 | free(config->alpn); | ||
169 | free((char *)config->ca_file); | 170 | free((char *)config->ca_file); |
170 | free((char *)config->ca_mem); | 171 | free((char *)config->ca_mem); |
171 | free((char *)config->ca_path); | 172 | free((char *)config->ca_path); |
@@ -249,6 +250,73 @@ tls_config_parse_protocols(uint32_t *protocols, const char *protostr) | |||
249 | return (0); | 250 | return (0); |
250 | } | 251 | } |
251 | 252 | ||
253 | static int | ||
254 | tls_config_parse_alpn(struct tls_config *config, const char *alpn, | ||
255 | char **alpn_data, size_t *alpn_len) | ||
256 | { | ||
257 | size_t buf_len, i, len; | ||
258 | char *buf = NULL; | ||
259 | char *s = NULL; | ||
260 | char *p, *q; | ||
261 | |||
262 | free(*alpn_data); | ||
263 | *alpn_data = NULL; | ||
264 | *alpn_len = 0; | ||
265 | |||
266 | if ((buf_len = strlen(alpn) + 1) > 65535) { | ||
267 | tls_config_set_errorx(config, "alpn too large"); | ||
268 | goto err; | ||
269 | } | ||
270 | |||
271 | if ((buf = malloc(buf_len)) == NULL) { | ||
272 | tls_config_set_errorx(config, "out of memory"); | ||
273 | goto err; | ||
274 | } | ||
275 | |||
276 | if ((s = strdup(alpn)) == NULL) { | ||
277 | tls_config_set_errorx(config, "out of memory"); | ||
278 | goto err; | ||
279 | } | ||
280 | |||
281 | i = 0; | ||
282 | q = s; | ||
283 | while ((p = strsep(&q, ",")) != NULL) { | ||
284 | if ((len = strlen(p)) == 0) { | ||
285 | tls_config_set_errorx(config, | ||
286 | "alpn protocol with zero length"); | ||
287 | goto err; | ||
288 | } | ||
289 | if (len > 255) { | ||
290 | tls_config_set_errorx(config, | ||
291 | "alpn protocol too long"); | ||
292 | goto err; | ||
293 | } | ||
294 | buf[i++] = len & 0xff; | ||
295 | memcpy(&buf[i], p, len); | ||
296 | i += len; | ||
297 | } | ||
298 | |||
299 | free(s); | ||
300 | |||
301 | *alpn_data = buf; | ||
302 | *alpn_len = buf_len; | ||
303 | |||
304 | return (0); | ||
305 | |||
306 | err: | ||
307 | free(buf); | ||
308 | free(s); | ||
309 | |||
310 | return (-1); | ||
311 | } | ||
312 | |||
313 | int | ||
314 | tls_config_set_alpn(struct tls_config *config, const char *alpn) | ||
315 | { | ||
316 | return tls_config_parse_alpn(config, alpn, &config->alpn, | ||
317 | &config->alpn_len); | ||
318 | } | ||
319 | |||
252 | int | 320 | int |
253 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) | 321 | tls_config_set_ca_file(struct tls_config *config, const char *ca_file) |
254 | { | 322 | { |