From 46e49260b35a2a39bbb92f44ceb598ab2db94d6a Mon Sep 17 00:00:00 2001
From: Laurent Bercot
+ You can wildcard the first level of a SNI domain: you can point +to a valid certificate for foo.example.com for all +values of foo via a variable called CERTFILE:*.example.com +(and have the corresponding KEYFILE:*.example.com). Only the +first level can be wildcarded, and this does not work for top-level +domains (you cannot hold a certificate for *.com). Note: if you are +using a shell to handle your environment variables, be careful to +properly quote them so that it does not attempt to expand the asterisks. +
+If you are using client certificates, s6-tlsd-io also requires either one of the following variables to be set: diff --git a/src/sbearssl/sbearssl_sni_policy_vtable.c b/src/sbearssl/sbearssl_sni_policy_vtable.c index 0f3de6e..a1d878a 100644 --- a/src/sbearssl/sbearssl_sni_policy_vtable.c +++ b/src/sbearssl/sbearssl_sni_policy_vtable.c @@ -49,14 +49,36 @@ static int choose (br_ssl_server_policy_class const **pctx, br_ssl_server_contex sbearssl_sni_policy_node *node ; char const *servername = br_ssl_engine_get_server_name(&sc->eng) ; - /* Get the node corresponding to the ServerName sent by the client. "" for no SNI. */ + /* + Get the node corresponding to the ServerName sent by the client. + If servername is foo.bar.baz, try: + 1. foo.bar.baz + 2. *.bar.baz (don't do this for TLDs, we don't want *.com) + 3. empty string (i.e. default certificate) + If no SNI, only try the empty string. + */ { - uint32_t n ; - if (!avltree_search(&pol->map, servername, &n)) + uint32_t n = avltree_totalsize(&pol->map) ; + if (servername) { - if (!servername[0]) return 0 ; - if (!avltree_search(&pol->map, "", &n)) return 0 ; + if (!avltree_search(&pol->map, servername, &n)) + { + char const *sub1 = strchr(servername, '.') ; + if (sub1 && sub1[1]) + { + char const *sub2 = strchr(sub1 + 1, '.') ; + if (sub2 && sub2[1]) + { + size_t len = strlen(sub1) ; + char tmp[len + 2] ; + tmp[0] = '*' ; + memcpy(tmp + 1, sub1, len + 1) ; + avltree_search(&pol->map, tmp, &n) ; + } + } + } } + if (n == avltree_totalsize(&pol->map) && !avltree_search(&pol->map, "", &n)) return 0 ; avltree_free(&pol->map) ; node = genalloc_s(sbearssl_sni_policy_node, &pol->mapga) + n ; } -- cgit v1.2.3