Re: libtls: ALPN support
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(&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_
libtls: ALPN support
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(&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 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,