Re: libtls: ALPN support

2016-07-28 Thread Bob Beck
Adds no new files, and I've seen it before..

ok beck@ - get it in and we'll sort  it out in tree if anything further is
needed.


On Wed, Jul 27, 2016 at 10:59 AM, Joel Sing  wrote:

> The following diff adds ALPN support to libtls via:
>
> tls_config_set_alpn() - set the ALPN protocols supported by this
> client/server
> tls_conn_alpn_selected() - get the ALPN protocol selected for this
> connection
>
> ok?
>
> Index: tls.c
> ===
> RCS file: /cvs/src/lib/libtls/tls.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 tls.c
> --- tls.c   7 Jul 2016 14:09:03 -   1.41
> +++ tls.c   27 Jul 2016 16:57:06 -
> @@ -310,6 +310,14 @@ tls_configure_ssl(struct tls *ctx)
> if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0)
> SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
>
> +   if (ctx->config->alpn != NULL) {
> +   if (SSL_CTX_set_alpn_protos(ctx->ssl_ctx,
> ctx->config->alpn,
> +   ctx->config->alpn_len) != 0) {
> +   tls_set_errorx(ctx, "failed to set alpn");
> +   goto err;
> +   }
> +   }
> +
> if (ctx->config->ciphers != NULL) {
> if (SSL_CTX_set_cipher_list(ctx->ssl_ctx,
> ctx->config->ciphers) != 1) {
> Index: tls.h
> ===
> RCS file: /cvs/src/lib/libtls/tls.h,v
> retrieving revision 1.29
> diff -u -p -r1.29 tls.h
> --- tls.h   27 May 2016 14:21:24 -  1.29
> +++ tls.h   27 Jul 2016 16:57:06 -
> @@ -52,6 +52,7 @@ const char *tls_error(struct tls *_ctx);
>  struct tls_config *tls_config_new(void);
>  void tls_config_free(struct tls_config *_config);
>
> +int tls_config_set_alpn(struct tls_config *_config, const char *_alpn);
>  int tls_config_set_ca_file(struct tls_config *_config, const char
> *_ca_file);
>  int tls_config_set_ca_path(struct tls_config *_config, const char
> *_ca_path);
>  int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca,
> @@ -116,8 +117,9 @@ const char *tls_peer_cert_subject(struct
>  time_t tls_peer_cert_notbefore(struct tls *_ctx);
>  time_t tls_peer_cert_notafter(struct tls *_ctx);
>
> -const char *tls_conn_version(struct tls *_ctx);
> +const char *tls_conn_alpn_selected(struct tls *_ctx);
>  const char *tls_conn_cipher(struct tls *_ctx);
> +const char *tls_conn_version(struct tls *_ctx);
>
>  uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password);
>
> Index: tls_config.c
> ===
> RCS file: /cvs/src/lib/libtls/tls_config.c,v
> retrieving revision 1.22
> diff -u -p -r1.22 tls_config.c
> --- tls_config.c13 Jul 2016 16:30:48 -  1.22
> +++ tls_config.c27 Jul 2016 16:57:06 -
> @@ -166,6 +166,7 @@ tls_config_free(struct tls_config *confi
>
> free(config->error.msg);
>
> +   free(config->alpn);
> free((char *)config->ca_file);
> free((char *)config->ca_mem);
> free((char *)config->ca_path);
> @@ -247,6 +248,72 @@ tls_config_parse_protocols(uint32_t *pro
> free(s);
>
> 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(, ",")) != 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([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 

libtls: ALPN support

2016-07-27 Thread Joel Sing
The following diff adds ALPN support to libtls via:

tls_config_set_alpn() - set the ALPN protocols supported by this client/server
tls_conn_alpn_selected() - get the ALPN protocol selected for this connection

ok?

Index: tls.c
===
RCS file: /cvs/src/lib/libtls/tls.c,v
retrieving revision 1.41
diff -u -p -r1.41 tls.c
--- tls.c   7 Jul 2016 14:09:03 -   1.41
+++ tls.c   27 Jul 2016 16:57:06 -
@@ -310,6 +310,14 @@ tls_configure_ssl(struct tls *ctx)
if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0)
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
 
+   if (ctx->config->alpn != NULL) {
+   if (SSL_CTX_set_alpn_protos(ctx->ssl_ctx, ctx->config->alpn,
+   ctx->config->alpn_len) != 0) {
+   tls_set_errorx(ctx, "failed to set alpn");
+   goto err;
+   }
+   }
+
if (ctx->config->ciphers != NULL) {
if (SSL_CTX_set_cipher_list(ctx->ssl_ctx,
ctx->config->ciphers) != 1) {
Index: tls.h
===
RCS file: /cvs/src/lib/libtls/tls.h,v
retrieving revision 1.29
diff -u -p -r1.29 tls.h
--- tls.h   27 May 2016 14:21:24 -  1.29
+++ tls.h   27 Jul 2016 16:57:06 -
@@ -52,6 +52,7 @@ const char *tls_error(struct tls *_ctx);
 struct tls_config *tls_config_new(void);
 void tls_config_free(struct tls_config *_config);
 
+int tls_config_set_alpn(struct tls_config *_config, const char *_alpn);
 int tls_config_set_ca_file(struct tls_config *_config, const char *_ca_file);
 int tls_config_set_ca_path(struct tls_config *_config, const char *_ca_path);
 int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca,
@@ -116,8 +117,9 @@ const char *tls_peer_cert_subject(struct
 time_t tls_peer_cert_notbefore(struct tls *_ctx);
 time_t tls_peer_cert_notafter(struct tls *_ctx);
 
-const char *tls_conn_version(struct tls *_ctx);
+const char *tls_conn_alpn_selected(struct tls *_ctx);
 const char *tls_conn_cipher(struct tls *_ctx);
+const char *tls_conn_version(struct tls *_ctx);
 
 uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password);
 
Index: tls_config.c
===
RCS file: /cvs/src/lib/libtls/tls_config.c,v
retrieving revision 1.22
diff -u -p -r1.22 tls_config.c
--- tls_config.c13 Jul 2016 16:30:48 -  1.22
+++ tls_config.c27 Jul 2016 16:57:06 -
@@ -166,6 +166,7 @@ tls_config_free(struct tls_config *confi
 
free(config->error.msg);
 
+   free(config->alpn);
free((char *)config->ca_file);
free((char *)config->ca_mem);
free((char *)config->ca_path);
@@ -247,6 +248,72 @@ tls_config_parse_protocols(uint32_t *pro
free(s);
 
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(, ",")) != 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([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, >alpn,
+   >alpn_len);
 }
 
 int
Index: tls_conninfo.c
===
RCS file: /cvs/src/lib/libtls/tls_conninfo.c,v
retrieving revision 1.5
diff -u -p -r1.5 tls_conninfo.c
--- tls_conninfo.c  7 Oct 2015 23:33:38 -   1.5
+++ tls_conninfo.c  27 Jul 2016 16:57:06 -
@@ -150,6 +150,26 @@ tls_get_peer_cert_times(struct tls *ctx,
return (rv);
 }