From f485acaf23d445c9711277d979dca46f32a61e32 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Fri, 12 Jul 2019 16:08:46 +0200 Subject: [PATCH] Make SNI lookup case-insensitive Fixes #301 --- src/hitch.c | 29 ++++++++++++++++++++----- src/hitch.h | 1 + src/tests/test05-multiple-listen-SNI.sh | 3 +++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/hitch.c b/src/hitch.c index da7cacdf..bbea696f 100644 --- a/src/hitch.c +++ b/src/hitch.c @@ -716,12 +716,12 @@ static int sni_match(const sni_name *sn, const char *srvname) { if (!sn->is_wildcard) - return (strcasecmp(srvname, sn->servername) == 0); + return (strcasecmp(srvname, sn->sni_key) == 0); else { char *s = strchr(srvname, '.'); if (s == NULL) return (0); - return (strcasecmp(s, sn->servername + 1) == 0); + return (strcasecmp(s, sn->sni_key + 1) == 0); } } @@ -769,6 +769,22 @@ sni_try_lookup(SSL *ssl, const char *sni_key, const struct sni_name_s *sn_tab) return (1); } +char * +sni_build_key(const char *servername) +{ + char *key, *c; + + if (servername == NULL) + return (NULL); + + AN(servername); + key = strdup(servername); + + for (c = key; *c != '\0'; c++) + *c = tolower(*c); + return (key); +} + /* * Switch the context of the current SSL object to the most appropriate one * based on the SNI header @@ -791,7 +807,7 @@ sni_switch_ctx(SSL *ssl, int *al, void *data) if (servername == NULL) return (SSL_TLSEXT_ERR_NOACK); - sni_key = strdup(servername); + sni_key = sni_build_key(servername); AN(sni_key); if (fr != NULL) { @@ -839,6 +855,7 @@ sctx_free(sslctx *sc, sni_name **sn_tab) if (sn_tab != NULL) HASH_DEL(*sn_tab, sn); free(sn->servername); + free(sn->sni_key); FREE_OBJ(sn); } @@ -1078,9 +1095,10 @@ insert_sni_names(sslctx *sc, sni_name **sn_tab) VTAILQ_FOREACH(sn, &sc->sni_list, list) { CHECK_OBJ_NOTNULL(sn, SNI_NAME_MAGIC); - key = sn->servername; + key = sn->sni_key; + AN(key); if (sn->is_wildcard) - key = sn->servername + 1; + key = sn->sni_key + 1; HASH_FIND_STR(*sn_tab, key, sn2); if (sn2 != NULL) { ERR("Warning: SNI name '%s' from '%s' overridden" @@ -1116,6 +1134,7 @@ load_cert_ctx(sslctx *so) (unsigned char **)&sn->servername, asn1_str); \ sn->is_wildcard = \ (strstr(sn->servername, "*.") == sn->servername); \ + sn->sni_key = sni_build_key(sn->servername); \ sn->sctx = so; \ VTAILQ_INSERT_TAIL(&so->sni_list, sn, list); \ } while (0) diff --git a/src/hitch.h b/src/hitch.h index f9055f72..1771416f 100644 --- a/src/hitch.h +++ b/src/hitch.h @@ -97,6 +97,7 @@ typedef struct sni_name_s { unsigned magic; #define SNI_NAME_MAGIC 0xb0626581 char *servername; + char *sni_key; sslctx *sctx; int is_wildcard; VTAILQ_ENTRY(sni_name_s) list; diff --git a/src/tests/test05-multiple-listen-SNI.sh b/src/tests/test05-multiple-listen-SNI.sh index 2449b3f3..245158f6 100755 --- a/src/tests/test05-multiple-listen-SNI.sh +++ b/src/tests/test05-multiple-listen-SNI.sh @@ -42,3 +42,6 @@ subj_name_eq "default.example.com" cfg-no-sni.dump s_client -servername site1.example.com >cfg-sni.dump subj_name_eq "site1.example.com" cfg-sni.dump + +s_client -servername SITE1.EXAMPLE.COM >cfg-sni-upper.dump +subj_name_eq "site1.example.com" cfg-sni-upper.dump