summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libtls/tls.c28
-rw-r--r--src/lib/libtls/tls_internal.h15
-rw-r--r--src/lib/libtls/tls_server.c134
3 files changed, 174 insertions, 3 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index bf0e1f769f..df610fe238 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.c,v 1.46 2016/08/15 14:04:23 jsing Exp $ */ 1/* $OpenBSD: tls.c,v 1.47 2016/08/22 14:51:37 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -177,6 +177,24 @@ tls_set_errorx(struct tls *ctx, const char *fmt, ...)
177 return (rv); 177 return (rv);
178} 178}
179 179
180struct tls_sni_ctx *
181tls_sni_ctx_new(void)
182{
183 return (calloc(1, sizeof(struct tls_sni_ctx)));
184}
185
186void
187tls_sni_ctx_free(struct tls_sni_ctx *sni_ctx)
188{
189 if (sni_ctx == NULL)
190 return;
191
192 SSL_CTX_free(sni_ctx->ssl_ctx);
193 X509_free(sni_ctx->ssl_cert);
194
195 free(sni_ctx);
196}
197
180struct tls * 198struct tls *
181tls_new(void) 199tls_new(void)
182{ 200{
@@ -376,6 +394,8 @@ tls_free(struct tls *ctx)
376void 394void
377tls_reset(struct tls *ctx) 395tls_reset(struct tls *ctx)
378{ 396{
397 struct tls_sni_ctx *sni, *nsni;
398
379 SSL_CTX_free(ctx->ssl_ctx); 399 SSL_CTX_free(ctx->ssl_ctx);
380 SSL_free(ctx->ssl_conn); 400 SSL_free(ctx->ssl_conn);
381 X509_free(ctx->ssl_peer_cert); 401 X509_free(ctx->ssl_peer_cert);
@@ -397,6 +417,12 @@ tls_reset(struct tls *ctx)
397 tls_free_conninfo(ctx->conninfo); 417 tls_free_conninfo(ctx->conninfo);
398 free(ctx->conninfo); 418 free(ctx->conninfo);
399 ctx->conninfo = NULL; 419 ctx->conninfo = NULL;
420
421 for (sni = ctx->sni_ctx; sni != NULL; sni = nsni) {
422 nsni = sni->next;
423 tls_sni_ctx_free(sni);
424 }
425 ctx->sni_ctx = NULL;
400} 426}
401 427
402int 428int
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index bbd231e00e..428e29c857 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.39 2016/08/15 15:44:58 jsing Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.40 2016/08/22 14:51:37 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>
@@ -91,6 +91,13 @@ struct tls_conninfo {
91#define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) 91#define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0)
92#define TLS_HANDSHAKE_COMPLETE (1 << 1) 92#define TLS_HANDSHAKE_COMPLETE (1 << 1)
93 93
94struct tls_sni_ctx {
95 struct tls_sni_ctx *next;
96
97 SSL_CTX *ssl_ctx;
98 X509 *ssl_cert;
99};
100
94struct tls { 101struct tls {
95 struct tls_config *config; 102 struct tls_config *config;
96 struct tls_error error; 103 struct tls_error error;
@@ -103,11 +110,17 @@ struct tls {
103 110
104 SSL *ssl_conn; 111 SSL *ssl_conn;
105 SSL_CTX *ssl_ctx; 112 SSL_CTX *ssl_ctx;
113
114 struct tls_sni_ctx *sni_ctx;
115
106 X509 *ssl_peer_cert; 116 X509 *ssl_peer_cert;
107 117
108 struct tls_conninfo *conninfo; 118 struct tls_conninfo *conninfo;
109}; 119};
110 120
121struct tls_sni_ctx *tls_sni_ctx_new(void);
122void tls_sni_ctx_free(struct tls_sni_ctx *sni_ctx);
123
111struct tls *tls_new(void); 124struct tls *tls_new(void);
112struct tls *tls_server_conn(struct tls *ctx); 125struct tls *tls_server_conn(struct tls *ctx);
113 126
diff --git a/src/lib/libtls/tls_server.c b/src/lib/libtls/tls_server.c
index 40096ae99f..044678c705 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.24 2016/08/18 15:52:03 jsing Exp $ */ 1/* $OpenBSD: tls_server.c,v 1.25 2016/08/22 14:51:37 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -15,6 +15,10 @@
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 17
18#include <sys/socket.h>
19
20#include <arpa/inet.h>
21
18#include <openssl/ec.h> 22#include <openssl/ec.h>
19#include <openssl/err.h> 23#include <openssl/err.h>
20#include <openssl/ssl.h> 24#include <openssl/ssl.h>
@@ -63,6 +67,92 @@ tls_server_alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
63} 67}
64 68
65static int 69static int
70tls_servername_cb(SSL *ssl, int *al, void *arg)
71{
72 struct tls *ctx = (struct tls *)arg;
73 struct tls_sni_ctx *sni_ctx;
74 union tls_addr addrbuf;
75 struct tls *conn_ctx;
76 const char *name;
77
78 if ((conn_ctx = SSL_get_app_data(ssl)) == NULL)
79 goto err;
80
81 if ((name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) == NULL) {
82 /*
83 * The servername callback gets called even when there is no
84 * TLS servername extension provided by the client. Sigh!
85 */
86 return (SSL_TLSEXT_ERR_NOACK);
87 }
88
89 /* Per RFC 6066 section 3: ensure that name is not an IP literal. */
90 if (inet_pton(AF_INET, name, &addrbuf) == 1 ||
91 inet_pton(AF_INET6, name, &addrbuf) == 1)
92 goto err;
93
94 free((char *)conn_ctx->servername);
95 if ((conn_ctx->servername = strdup(name)) == NULL)
96 goto err;
97
98 /* Find appropriate SSL context for requested servername. */
99 for (sni_ctx = ctx->sni_ctx; sni_ctx != NULL; sni_ctx = sni_ctx->next) {
100 if (tls_check_name(ctx, sni_ctx->ssl_cert, name) == 0) {
101 SSL_set_SSL_CTX(conn_ctx->ssl_conn, sni_ctx->ssl_ctx);
102 return (SSL_TLSEXT_ERR_OK);
103 }
104 }
105
106 /* No match, use the existing context/certificate. */
107 return (SSL_TLSEXT_ERR_OK);
108
109 err:
110 /*
111 * There is no way to tell libssl that an internal failure occurred.
112 * The only option we have is to return a fatal alert.
113 */
114 *al = TLS1_AD_INTERNAL_ERROR;
115 return (SSL_TLSEXT_ERR_ALERT_FATAL);
116}
117
118static int
119tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
120 X509 **cert)
121{
122 char *errstr = "unknown";
123 BIO *cert_bio = NULL;
124 int ssl_err;
125
126 X509_free(*cert);
127 *cert = NULL;
128
129 if (keypair->cert_mem == NULL) {
130 tls_error_set(error, "keypair has no certificate");
131 goto err;
132 }
133 if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem,
134 keypair->cert_len)) == NULL) {
135 tls_error_set(error, "failed to create certificate bio");
136 goto err;
137 }
138 if ((*cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL)) == NULL) {
139 if ((ssl_err = ERR_peek_error()) != 0)
140 errstr = ERR_error_string(ssl_err, NULL);
141 tls_error_set(error, "failed to load certificate: %s", errstr);
142 goto err;
143 }
144
145 BIO_free(cert_bio);
146
147 return (0);
148
149 err:
150 BIO_free(cert_bio);
151
152 return (-1);
153}
154
155static int
66tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, 156tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
67 struct tls_keypair *keypair) 157 struct tls_keypair *keypair)
68{ 158{
@@ -76,6 +166,16 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
76 goto err; 166 goto err;
77 } 167 }
78 168
169 if (SSL_CTX_set_tlsext_servername_callback(*ssl_ctx,
170 tls_servername_cb) != 1) {
171 tls_set_error(ctx, "failed to set servername callback");
172 goto err;
173 }
174 if (SSL_CTX_set_tlsext_servername_arg(*ssl_ctx, ctx) != 1) {
175 tls_set_error(ctx, "failed to set servername callback arg");
176 goto err;
177 }
178
79 if (tls_configure_ssl(ctx, *ssl_ctx) != 0) 179 if (tls_configure_ssl(ctx, *ssl_ctx) != 0)
80 goto err; 180 goto err;
81 if (tls_configure_ssl_keypair(ctx, *ssl_ctx, keypair, 1) != 0) 181 if (tls_configure_ssl_keypair(ctx, *ssl_ctx, keypair, 1) != 0)
@@ -134,12 +234,44 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx,
134 return (-1); 234 return (-1);
135} 235}
136 236
237static int
238tls_configure_server_sni(struct tls *ctx)
239{
240 struct tls_sni_ctx **sni_ctx;
241 struct tls_keypair *kp;
242
243 if (ctx->config->keypair->next == NULL)
244 return (0);
245
246 /* Set up additional SSL contexts for SNI. */
247 sni_ctx = &ctx->sni_ctx;
248 for (kp = ctx->config->keypair->next; kp != NULL; kp = kp->next) {
249 if ((*sni_ctx = tls_sni_ctx_new()) == NULL) {
250 tls_set_errorx(ctx, "out of memory");
251 goto err;
252 }
253 if (tls_configure_server_ssl(ctx, &(*sni_ctx)->ssl_ctx, kp) == -1)
254 goto err;
255 if (tls_keypair_load_cert(kp, &ctx->error,
256 &(*sni_ctx)->ssl_cert) == -1)
257 goto err;
258 sni_ctx = &(*sni_ctx)->next;
259 }
260
261 return (0);
262
263 err:
264 return (-1);
265}
266
137int 267int
138tls_configure_server(struct tls *ctx) 268tls_configure_server(struct tls *ctx)
139{ 269{
140 if (tls_configure_server_ssl(ctx, &ctx->ssl_ctx, 270 if (tls_configure_server_ssl(ctx, &ctx->ssl_ctx,
141 ctx->config->keypair) == -1) 271 ctx->config->keypair) == -1)
142 goto err; 272 goto err;
273 if (tls_configure_server_sni(ctx) == -1)
274 goto err;
143 275
144 return (0); 276 return (0);
145 277