summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libtls/tls.c10
-rw-r--r--src/lib/libtls/tls.h8
-rw-r--r--src/lib/libtls/tls_config.c69
-rw-r--r--src/lib/libtls/tls_conninfo.c35
-rw-r--r--src/lib/libtls/tls_init.336
-rw-r--r--src/lib/libtls/tls_internal.h6
-rw-r--r--src/lib/libtls/tls_server.c20
7 files changed, 168 insertions, 16 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index ddf847d390..4d4910d128 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.c,v 1.43 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls.c,v 1.44 2016/08/12 15:10:59 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -310,6 +310,14 @@ tls_configure_ssl(struct tls *ctx)
310 if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0) 310 if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0)
311 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2); 311 SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
312 312
313 if (ctx->config->alpn != NULL) {
314 if (SSL_CTX_set_alpn_protos(ctx->ssl_ctx, ctx->config->alpn,
315 ctx->config->alpn_len) != 0) {
316 tls_set_errorx(ctx, "failed to set alpn");
317 goto err;
318 }
319 }
320
313 if (ctx->config->ciphers != NULL) { 321 if (ctx->config->ciphers != NULL) {
314 if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, 322 if (SSL_CTX_set_cipher_list(ctx->ssl_ctx,
315 ctx->config->ciphers) != 1) { 323 ctx->config->ciphers) != 1) {
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h
index 1497319611..13df43f046 100644
--- a/src/lib/libtls/tls.h
+++ b/src/lib/libtls/tls.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.h,v 1.32 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls.h,v 1.33 2016/08/12 15:10:59 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -27,7 +27,7 @@ extern "C" {
27#include <stddef.h> 27#include <stddef.h>
28#include <stdint.h> 28#include <stdint.h>
29 29
30#define TLS_API 20160801 30#define TLS_API 20160812
31 31
32#define TLS_PROTOCOL_TLSv1_0 (1 << 1) 32#define TLS_PROTOCOL_TLSv1_0 (1 << 1)
33#define TLS_PROTOCOL_TLSv1_1 (1 << 2) 33#define TLS_PROTOCOL_TLSv1_1 (1 << 2)
@@ -52,6 +52,7 @@ const char *tls_error(struct tls *_ctx);
52struct tls_config *tls_config_new(void); 52struct tls_config *tls_config_new(void);
53void tls_config_free(struct tls_config *_config); 53void tls_config_free(struct tls_config *_config);
54 54
55int tls_config_set_alpn(struct tls_config *_config, const char *_alpn);
55int tls_config_set_ca_file(struct tls_config *_config, const char *_ca_file); 56int tls_config_set_ca_file(struct tls_config *_config, const char *_ca_file);
56int tls_config_set_ca_path(struct tls_config *_config, const char *_ca_path); 57int tls_config_set_ca_path(struct tls_config *_config, const char *_ca_path);
57int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca, 58int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca,
@@ -116,8 +117,9 @@ const char *tls_peer_cert_subject(struct tls *_ctx);
116time_t tls_peer_cert_notbefore(struct tls *_ctx); 117time_t tls_peer_cert_notbefore(struct tls *_ctx);
117time_t tls_peer_cert_notafter(struct tls *_ctx); 118time_t tls_peer_cert_notafter(struct tls *_ctx);
118 119
119const char *tls_conn_version(struct tls *_ctx); 120const char *tls_conn_alpn_selected(struct tls *_ctx);
120const char *tls_conn_cipher(struct tls *_ctx); 121const char *tls_conn_cipher(struct tls *_ctx);
122const char *tls_conn_version(struct tls *_ctx);
121 123
122uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password); 124uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password);
123 125
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 @@
1/* $OpenBSD: tls_config.c,v 1.24 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls_config.c,v 1.25 2016/08/12 15:10:59 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,72 @@ tls_config_parse_protocols(uint32_t *protocols, const char *protostr)
249 return (0); 250 return (0);
250} 251}
251 252
253static int
254tls_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 if ((buf_len = strlen(alpn) + 1) > 65535) {
263 tls_config_set_errorx(config, "alpn too large");
264 goto err;
265 }
266
267 if ((buf = malloc(buf_len)) == NULL) {
268 tls_config_set_errorx(config, "out of memory");
269 goto err;
270 }
271
272 if ((s = strdup(alpn)) == NULL) {
273 tls_config_set_errorx(config, "out of memory");
274 goto err;
275 }
276
277 i = 0;
278 q = s;
279 while ((p = strsep(&q, ",")) != NULL) {
280 if ((len = strlen(p)) == 0) {
281 tls_config_set_errorx(config,
282 "alpn protocol with zero length");
283 goto err;
284 }
285 if (len > 255) {
286 tls_config_set_errorx(config,
287 "alpn protocol too long");
288 goto err;
289 }
290 buf[i++] = len & 0xff;
291 memcpy(&buf[i], p, len);
292 i += len;
293 }
294
295 free(s);
296
297 *alpn_data = buf;
298 *alpn_len = buf_len;
299
300 return (0);
301
302 err:
303 free(buf);
304 free(s);
305
306 *alpn_data = NULL;
307 *alpn_len = 0;
308
309 return (-1);
310}
311
312int
313tls_config_set_alpn(struct tls_config *config, const char *alpn)
314{
315 return tls_config_parse_alpn(config, alpn, &config->alpn,
316 &config->alpn_len);
317}
318
252int 319int
253tls_config_set_ca_file(struct tls_config *config, const char *ca_file) 320tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
254{ 321{
diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c
index 6caf655536..7888c919b0 100644
--- a/src/lib/libtls/tls_conninfo.c
+++ b/src/lib/libtls/tls_conninfo.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_conninfo.c,v 1.7 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls_conninfo.c,v 1.8 2016/08/12 15:10:59 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -150,6 +150,26 @@ tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, time_t *notafter)
150 return (rv); 150 return (rv);
151} 151}
152 152
153static int
154tls_conninfo_alpn_proto(struct tls *ctx)
155{
156 const unsigned char *p;
157 unsigned int len;
158
159 free(ctx->conninfo->alpn);
160 ctx->conninfo->alpn = NULL;
161
162 SSL_get0_alpn_selected(ctx->ssl_conn, &p, &len);
163 if (len > 0) {
164 if ((ctx->conninfo->alpn = malloc(len + 1)) == NULL)
165 return (-1);
166 memcpy(ctx->conninfo->alpn, p, len);
167 ctx->conninfo->alpn[len] = '\0';
168 }
169
170 return (0);
171}
172
153int 173int
154tls_get_conninfo(struct tls *ctx) { 174tls_get_conninfo(struct tls *ctx) {
155 const char * tmp; 175 const char * tmp;
@@ -175,6 +195,9 @@ tls_get_conninfo(struct tls *ctx) {
175 ctx->conninfo->cipher = strdup(tmp); 195 ctx->conninfo->cipher = strdup(tmp);
176 if (ctx->conninfo->cipher == NULL) 196 if (ctx->conninfo->cipher == NULL)
177 goto err; 197 goto err;
198 if (tls_conninfo_alpn_proto(ctx) == -1)
199 goto err;
200
178 return (0); 201 return (0);
179err: 202err:
180 tls_free_conninfo(ctx->conninfo); 203 tls_free_conninfo(ctx->conninfo);
@@ -184,6 +207,8 @@ err:
184void 207void
185tls_free_conninfo(struct tls_conninfo *conninfo) { 208tls_free_conninfo(struct tls_conninfo *conninfo) {
186 if (conninfo != NULL) { 209 if (conninfo != NULL) {
210 free(conninfo->alpn);
211 conninfo->alpn = NULL;
187 free(conninfo->hash); 212 free(conninfo->hash);
188 conninfo->hash = NULL; 213 conninfo->hash = NULL;
189 free(conninfo->subject); 214 free(conninfo->subject);
@@ -198,6 +223,14 @@ tls_free_conninfo(struct tls_conninfo *conninfo) {
198} 223}
199 224
200const char * 225const char *
226tls_conn_alpn_selected(struct tls *ctx)
227{
228 if (ctx->conninfo == NULL)
229 return (NULL);
230 return (ctx->conninfo->alpn);
231}
232
233const char *
201tls_conn_cipher(struct tls *ctx) 234tls_conn_cipher(struct tls *ctx)
202{ 235{
203 if (ctx->conninfo == NULL) 236 if (ctx->conninfo == NULL)
diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3
index 6ba2cb28be..e7f10ef556 100644
--- a/src/lib/libtls/tls_init.3
+++ b/src/lib/libtls/tls_init.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: tls_init.3,v 1.64 2016/08/02 07:47:11 jsing Exp $ 1.\" $OpenBSD: tls_init.3,v 1.65 2016/08/12 15:10:59 jsing Exp $
2.\" 2.\"
3.\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> 3.\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
4.\" 4.\"
@@ -14,7 +14,7 @@
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
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.Dd $Mdocdate: August 2 2016 $ 17.Dd $Mdocdate: August 12 2016 $
18.Dt TLS_INIT 3 18.Dt TLS_INIT 3
19.Os 19.Os
20.Sh NAME 20.Sh NAME
@@ -24,6 +24,7 @@
24.Nm tls_config_new , 24.Nm tls_config_new ,
25.Nm tls_config_free , 25.Nm tls_config_free ,
26.Nm tls_config_parse_protocols , 26.Nm tls_config_parse_protocols ,
27.Nm tls_config_set_alpn ,
27.Nm tls_config_set_ca_file , 28.Nm tls_config_set_ca_file ,
28.Nm tls_config_set_ca_path , 29.Nm tls_config_set_ca_path ,
29.Nm tls_config_set_ca_mem , 30.Nm tls_config_set_ca_mem ,
@@ -54,8 +55,9 @@
54.Nm tls_peer_cert_hash , 55.Nm tls_peer_cert_hash ,
55.Nm tls_peer_cert_notbefore , 56.Nm tls_peer_cert_notbefore ,
56.Nm tls_peer_cert_notafter , 57.Nm tls_peer_cert_notafter ,
57.Nm tls_conn_version , 58.Nm tls_conn_alpn_selected ,
58.Nm tls_conn_cipher , 59.Nm tls_conn_cipher ,
60.Nm tls_conn_version ,
59.Nm tls_load_file , 61.Nm tls_load_file ,
60.Nm tls_client , 62.Nm tls_client ,
61.Nm tls_server , 63.Nm tls_server ,
@@ -88,6 +90,8 @@
88.Ft "int" 90.Ft "int"
89.Fn tls_config_parse_protocols "uint32_t *protocols" "const char *protostr" 91.Fn tls_config_parse_protocols "uint32_t *protocols" "const char *protostr"
90.Ft "int" 92.Ft "int"
93.Fn tls_config_set_alpn "struct tls_config *config" "const char *alpn"
94.Ft "int"
91.Fn tls_config_set_ca_file "struct tls_config *config" "const char *ca_file" 95.Fn tls_config_set_ca_file "struct tls_config *config" "const char *ca_file"
92.Ft "int" 96.Ft "int"
93.Fn tls_config_set_ca_path "struct tls_config *config" "const char *ca_path" 97.Fn tls_config_set_ca_path "struct tls_config *config" "const char *ca_path"
@@ -148,9 +152,11 @@
148.Ft "time_t" 152.Ft "time_t"
149.Fn tls_peer_cert_notafter "struct tls *ctx" 153.Fn tls_peer_cert_notafter "struct tls *ctx"
150.Ft "const char *" 154.Ft "const char *"
151.Fn tls_conn_version "struct tls *ctx" 155.Fn tls_conn_alpn_selected "struct tls *ctx"
152.Ft "const char *" 156.Ft "const char *"
153.Fn tls_conn_cipher "struct tls *ctx" 157.Fn tls_conn_cipher "struct tls *ctx"
158.Ft "const char *"
159.Fn tls_conn_version "struct tls *ctx"
154.Ft "uint8_t *" 160.Ft "uint8_t *"
155.Fn tls_load_file "const char *file" "size_t *len" "char *password" 161.Fn tls_load_file "const char *file" "size_t *len" "char *password"
156.Ft "struct tls *" 162.Ft "struct tls *"
@@ -295,6 +301,11 @@ The following functions modify a configuration by setting parameters.
295Configuration options may apply to only clients or only servers or both. 301Configuration options may apply to only clients or only servers or both.
296.Bl -bullet -offset four 302.Bl -bullet -offset four
297.It 303.It
304.Fn tls_config_set_alpn
305sets the ALPN protocols that are supported.
306The alpn string is a comma separated list of protocols, in order of preference.
307.Em (Client and Server)
308.It
298.Fn tls_config_set_ca_file 309.Fn tls_config_set_ca_file
299sets the filename used to load a file 310sets the filename used to load a file
300containing the root certificates. 311containing the root certificates.
@@ -480,13 +491,14 @@ the peer certificate from
480will only succeed after the handshake is complete. 491will only succeed after the handshake is complete.
481.Em (Server and client) 492.Em (Server and client)
482.It 493.It
483.Fn tls_conn_version 494.Fn tls_conn_alpn_selected
484returns a string 495returns a string that specifies the ALPN protocol selected for use with the peer
485corresponding to a TLS version negotiated with the peer
486connected to 496connected to
487.Ar ctx . 497.Ar ctx .
488.Fn tls_conn_version 498If no protocol was selected then NULL is returned.
499.Fn tls_conn_alpn_selected
489will only succeed after the handshake is complete. 500will only succeed after the handshake is complete.
501.Em (Server and Client)
490.It 502.It
491.Fn tls_conn_cipher 503.Fn tls_conn_cipher
492returns a string 504returns a string
@@ -497,6 +509,14 @@ connected to
497will only succeed after the handshake is complete. 509will only succeed after the handshake is complete.
498.Em (Server and client) 510.Em (Server and client)
499.It 511.It
512.Fn tls_conn_version
513returns a string
514corresponding to a TLS version negotiated with the peer
515connected to
516.Ar ctx .
517.Fn tls_conn_version
518will only succeed after the handshake is complete.
519.It
500.Fn tls_load_file 520.Fn tls_load_file
501loads a certificate or key from disk into memory to be loaded with 521loads a certificate or key from disk into memory to be loaded with
502.Fn tls_config_set_ca_mem , 522.Fn tls_config_set_ca_mem ,
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index be5d659e68..1ef95adb08 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.34 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.35 2016/08/12 15:10:59 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>
@@ -55,6 +55,8 @@ struct tls_keypair {
55struct tls_config { 55struct tls_config {
56 struct tls_error error; 56 struct tls_error error;
57 57
58 char *alpn;
59 size_t alpn_len;
58 const char *ca_file; 60 const char *ca_file;
59 const char *ca_path; 61 const char *ca_path;
60 char *ca_mem; 62 char *ca_mem;
@@ -73,6 +75,7 @@ struct tls_config {
73}; 75};
74 76
75struct tls_conninfo { 77struct tls_conninfo {
78 char *alpn;
76 char *issuer; 79 char *issuer;
77 char *subject; 80 char *subject;
78 char *hash; 81 char *hash;
@@ -104,6 +107,7 @@ struct tls {
104 SSL *ssl_conn; 107 SSL *ssl_conn;
105 SSL_CTX *ssl_ctx; 108 SSL_CTX *ssl_ctx;
106 X509 *ssl_peer_cert; 109 X509 *ssl_peer_cert;
110
107 struct tls_conninfo *conninfo; 111 struct tls_conninfo *conninfo;
108}; 112};
109 113
diff --git a/src/lib/libtls/tls_server.c b/src/lib/libtls/tls_server.c
index bba15aae7e..690af32eaf 100644
--- a/src/lib/libtls/tls_server.c
+++ b/src/lib/libtls/tls_server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_server.c,v 1.21 2016/08/02 07:47:11 jsing Exp $ */ 1/* $OpenBSD: tls_server.c,v 1.22 2016/08/12 15:10:59 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -48,6 +48,20 @@ tls_server_conn(struct tls *ctx)
48 return (conn_ctx); 48 return (conn_ctx);
49} 49}
50 50
51static int
52tls_server_alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
53 const unsigned char *in, unsigned int inlen, void *arg)
54{
55 struct tls *ctx = arg;
56
57 if (SSL_select_next_proto((unsigned char**)out, outlen,
58 ctx->config->alpn, ctx->config->alpn_len, in, inlen) ==
59 OPENSSL_NPN_NEGOTIATED)
60 return (SSL_TLSEXT_ERR_OK);
61
62 return (SSL_TLSEXT_ERR_NOACK);
63}
64
51int 65int
52tls_configure_server(struct tls *ctx) 66tls_configure_server(struct tls *ctx)
53{ 67{
@@ -71,6 +85,10 @@ tls_configure_server(struct tls *ctx)
71 goto err; 85 goto err;
72 } 86 }
73 87
88 if (ctx->config->alpn != NULL)
89 SSL_CTX_set_alpn_select_cb(ctx->ssl_ctx, tls_server_alpn_cb,
90 ctx);
91
74 if (ctx->config->dheparams == -1) 92 if (ctx->config->dheparams == -1)
75 SSL_CTX_set_dh_auto(ctx->ssl_ctx, 1); 93 SSL_CTX_set_dh_auto(ctx->ssl_ctx, 1);
76 else if (ctx->config->dheparams == 1024) 94 else if (ctx->config->dheparams == 1024)