From 5802b7206a96d5d55ba7408d05151a1887b21d28 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Fri, 12 Aug 2016 15:10:59 +0000 Subject: Add ALPN support to libtls. ok beck@ doug@ --- src/lib/libtls/tls_config.c | 69 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'src/lib/libtls/tls_config.c') diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 63054ab1e9..e690b9ee76 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_config.c,v 1.24 2016/08/02 07:47:11 jsing Exp $ */ +/* $OpenBSD: tls_config.c,v 1.25 2016/08/12 15:10:59 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -166,6 +166,7 @@ tls_config_free(struct tls_config *config) free(config->error.msg); + free(config->alpn); free((char *)config->ca_file); free((char *)config->ca_mem); free((char *)config->ca_path); @@ -249,6 +250,72 @@ tls_config_parse_protocols(uint32_t *protocols, const char *protostr) return (0); } +static int +tls_config_parse_alpn(struct tls_config *config, const char *alpn, + char **alpn_data, size_t *alpn_len) +{ + size_t buf_len, i, len; + char *buf = NULL; + char *s = NULL; + char *p, *q; + + if ((buf_len = strlen(alpn) + 1) > 65535) { + tls_config_set_errorx(config, "alpn too large"); + goto err; + } + + if ((buf = malloc(buf_len)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + if ((s = strdup(alpn)) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto err; + } + + i = 0; + q = s; + while ((p = strsep(&q, ",")) != NULL) { + if ((len = strlen(p)) == 0) { + tls_config_set_errorx(config, + "alpn protocol with zero length"); + goto err; + } + if (len > 255) { + tls_config_set_errorx(config, + "alpn protocol too long"); + goto err; + } + buf[i++] = len & 0xff; + memcpy(&buf[i], p, len); + i += len; + } + + free(s); + + *alpn_data = buf; + *alpn_len = buf_len; + + return (0); + + err: + free(buf); + free(s); + + *alpn_data = NULL; + *alpn_len = 0; + + return (-1); +} + +int +tls_config_set_alpn(struct tls_config *config, const char *alpn) +{ + return tls_config_parse_alpn(config, alpn, &config->alpn, + &config->alpn_len); +} + int tls_config_set_ca_file(struct tls_config *config, const char *ca_file) { -- cgit v1.2.3-55-g6feb