Provide an API that enables server side SNI support - add the ability to
authorjsing <jsing@openbsd.org>
Mon, 22 Aug 2016 14:55:59 +0000 (14:55 +0000)
committerjsing <jsing@openbsd.org>
Mon, 22 Aug 2016 14:55:59 +0000 (14:55 +0000)
provide additional keypairs (via tls_config_add_keypair_{file,mem}()) and
allow the server to determine what servername the client requested (via
tls_conn_servername()).

ok beck@

lib/libtls/tls.h
lib/libtls/tls_config.c
lib/libtls/tls_conninfo.c
lib/libtls/tls_init.3
lib/libtls/tls_internal.h

index 13df43f..7a68c3d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.33 2016/08/12 15:10:59 jsing Exp $ */
+/* $OpenBSD: tls.h,v 1.34 2016/08/22 14:55:59 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -52,6 +52,11 @@ 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_add_keypair_file(struct tls_config *_config,
+    const char *_cert_file, const char *_key_file);
+int tls_config_add_keypair_mem(struct tls_config *_config, const uint8_t *_cert,
+    size_t _cert_len, const uint8_t *_key, size_t _key_len);
+
 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);
@@ -119,6 +124,7 @@ time_t      tls_peer_cert_notafter(struct tls *_ctx);
 
 const char *tls_conn_alpn_selected(struct tls *_ctx);
 const char *tls_conn_cipher(struct tls *_ctx);
+const char *tls_conn_servername(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 0d52704..c07621a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.27 2016/08/13 13:15:53 jsing Exp $ */
+/* $OpenBSD: tls_config.c,v 1.28 2016/08/22 14:55:59 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -227,6 +227,18 @@ tls_config_free(struct tls_config *config)
        free(config);
 }
 
+static void
+tls_config_keypair_add(struct tls_config *config, struct tls_keypair *keypair)
+{
+       struct tls_keypair *kp;
+
+       kp = config->keypair;
+       while (kp->next != NULL)
+               kp = kp->next;
+
+       kp->next = keypair;
+}
+
 const char *
 tls_config_error(struct tls_config *config)
 {
@@ -369,6 +381,50 @@ tls_config_set_alpn(struct tls_config *config, const char *alpn)
            &config->alpn_len);
 }
 
+int
+tls_config_add_keypair_file(struct tls_config *config,
+    const char *cert_file, const char *key_file)
+{
+       struct tls_keypair *keypair;
+
+       if ((keypair = tls_keypair_new()) == NULL)
+               return (-1);
+       if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
+               goto err;
+       if (tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
+               goto err;
+
+       tls_config_keypair_add(config, keypair);
+
+       return (0);
+
+ err:
+       tls_keypair_free(keypair);
+       return (-1);
+}
+
+int
+tls_config_add_keypair_mem(struct tls_config *config, const uint8_t *cert,
+    size_t cert_len, const uint8_t *key, size_t key_len)
+{
+       struct tls_keypair *keypair;
+
+       if ((keypair = tls_keypair_new()) == NULL)
+               return (-1);
+       if (tls_keypair_set_cert_mem(keypair, cert, cert_len) != 0)
+               goto err;
+       if (tls_keypair_set_key_mem(keypair, key, key_len) != 0)
+               goto err;
+
+       tls_config_keypair_add(config, keypair);
+
+       return (0);
+
+ err:
+       tls_keypair_free(keypair);
+       return (-1);
+}
+
 int
 tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
 {
index 523b279..281af79 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_conninfo.c,v 1.9 2016/08/15 14:47:41 jsing Exp $ */
+/* $OpenBSD: tls_conninfo.c,v 1.10 2016/08/22 14:55:59 jsing Exp $ */
 /*
  * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
  * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -199,6 +199,11 @@ tls_get_conninfo(struct tls *ctx)
                goto err;
        if (tls_conninfo_alpn_proto(ctx) == -1)
                goto err;
+       if (ctx->servername != NULL) {
+               if ((ctx->conninfo->servername =
+                   strdup(ctx->servername)) == NULL)
+                       goto err;
+       }
 
        return (0);
 err:
@@ -241,6 +246,14 @@ tls_conn_cipher(struct tls *ctx)
        return (ctx->conninfo->cipher);
 }
 
+const char *
+tls_conn_servername(struct tls *ctx)
+{
+       if (ctx->conninfo == NULL)
+               return (NULL);
+       return (ctx->conninfo->servername);
+}
 const char *
 tls_conn_version(struct tls *ctx)
 {
index cd98450..4d73674 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tls_init.3,v 1.66 2016/08/18 15:43:12 jsing Exp $
+.\" $OpenBSD: tls_init.3,v 1.67 2016/08/22 14:55:59 jsing Exp $
 .\"
 .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 18 2016 $
+.Dd $Mdocdate: August 22 2016 $
 .Dt TLS_INIT 3
 .Os
 .Sh NAME
@@ -24,6 +24,8 @@
 .Nm tls_config_new ,
 .Nm tls_config_free ,
 .Nm tls_config_parse_protocols ,
+.Nm tls_config_add_keypair_file ,
+.Nm tls_config_add_keypair_mem ,
 .Nm tls_config_set_alpn ,
 .Nm tls_config_set_ca_file ,
 .Nm tls_config_set_ca_path ,
@@ -57,6 +59,7 @@
 .Nm tls_peer_cert_notafter ,
 .Nm tls_conn_alpn_selected ,
 .Nm tls_conn_cipher ,
+.Nm tls_conn_servername ,
 .Nm tls_conn_version ,
 .Nm tls_load_file ,
 .Nm tls_client ,
 .Ft "int"
 .Fn tls_config_parse_protocols "uint32_t *protocols" "const char *protostr"
 .Ft "int"
+.Fn tls_config_add_keypair_file "struct tls_config *config" "const char *cert_file" "const char *key_file"
+.Ft "int"
+.Fn tls_config_add_keypair_mem "struct tls_config *config" "const uint8_t *cert" "size_t cert_len" "const uint8_t *key" "size_t key_len"
+.Ft "int"
 .Fn tls_config_set_alpn "struct tls_config *config" "const char *alpn"
 .Ft "int"
 .Fn tls_config_set_ca_file "struct tls_config *config" "const char *ca_file"
 .Ft "const char *"
 .Fn tls_conn_cipher "struct tls *ctx"
 .Ft "const char *"
+.Fn tls_conn_servername "struct tls *ctx"
+.Ft "const char *"
 .Fn tls_conn_version "struct tls *ctx"
 .Ft "uint8_t *"
 .Fn tls_load_file "const char *file" "size_t *len" "char *password"
@@ -301,6 +310,16 @@ The following functions modify a configuration by setting parameters (the
 configuration options may only apply to clients, to servers or to both):
 .Bl -bullet -offset four
 .It
+.Fn tls_config_add_keypair_file
+adds an additional public certificate and private key from the specified files,
+used as an alternative certificate for Server Name Indication.
+.Em (Server)
+.It
+.Fn tls_config_set_keypair_mem
+adds an additional public certificate and private key from memory,
+used as an alternative certificate for Server Name Indication.
+.Em (Server)
+.It
 .Fn tls_config_set_alpn
 sets the ALPN protocols that are supported.
 The alpn string is a comma separated list of protocols, in order of preference.
@@ -445,6 +464,12 @@ connected to
 .Ar ctx .
 .Em (Server and client)
 .It
+.Fn tls_conn_servername
+returns a string corresponding to the servername that the client connected to
+.Ar ctx
+requested by sending a TLS Server Name Indication extension.
+.Em (Server)
+.It
 .Fn tls_conn_version
 returns a string corresponding to a TLS version negotiated with the peer
 connected to
index 428e29c..3fcc7a0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.40 2016/08/22 14:51:37 jsing Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.41 2016/08/22 14:55:59 jsing Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -74,6 +74,7 @@ struct tls_config {
 struct tls_conninfo {
        char *alpn;
        char *cipher;
+       char *servername;
        char *version;
 
        char *hash;