summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libtls/tls_server.c')
-rw-r--r--src/lib/libtls/tls_server.c134
1 files changed, 133 insertions, 1 deletions
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