summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjca <jca@openbsd.org>2014-10-06 11:53:18 +0000
committerjca <jca@openbsd.org>2014-10-06 11:53:18 +0000
commitc0fbe72cd20830e15900b107e889b2e273ba6f78 (patch)
treeeac06b2a107929c0d33e0e0ee642ae70e46517c3
parentAmend previous commit to unbreak TLS cert validation when using a proxy. (diff)
downloadwireguard-openbsd-c0fbe72cd20830e15900b107e889b2e273ba6f78.tar.xz
wireguard-openbsd-c0fbe72cd20830e15900b107e889b2e273ba6f78.zip
If we have to match against a wildcard in a cert, verify that it contains
at least a domain label before the tld, as in *.example.org. Suggested by Richard Moore (rich@kde) ok tedu@
-rw-r--r--lib/libressl/ressl_verify.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/lib/libressl/ressl_verify.c b/lib/libressl/ressl_verify.c
index 9dfadedfb84..9511ad2ff23 100644
--- a/lib/libressl/ressl_verify.c
+++ b/lib/libressl/ressl_verify.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ressl_verify.c,v 1.3 2014/08/05 12:46:16 jsing Exp $ */
+/* $OpenBSD: ressl_verify.c,v 1.4 2014/10/06 11:53:18 jca Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
*
@@ -33,17 +33,37 @@ int ressl_check_common_name(X509 *cert, const char *host);
int
ressl_match_hostname(const char *cert_hostname, const char *hostname)
{
- const char *cert_domain, *domain;
+ const char *cert_domain, *domain, *next_dot;
if (strcasecmp(cert_hostname, hostname) == 0)
return 0;
/* Wildcard match? */
if (cert_hostname[0] == '*') {
+ /*
+ * Valid wildcards:
+ * - "*.domain.tld"
+ * - "*.sub.domain.tld"
+ * - etc.
+ * Reject "*.tld".
+ * No attempt to prevent the use of eg. "*.co.uk".
+ */
cert_domain = &cert_hostname[1];
+ /* Disallow "*" */
+ if (cert_domain[0] == '\0')
+ return -1;
+ /* Disallow "*foo" */
if (cert_domain[0] != '.')
return -1;
- if (strlen(cert_domain) == 1)
+ /* Disallow "*.." */
+ if (cert_domain[1] == '.')
+ return -1;
+ next_dot = strchr(&cert_domain[1], '.');
+ /* Disallow "*.bar" */
+ if (next_dot == NULL)
+ return -1;
+ /* Disallow "*.bar.." */
+ if (next_dot[1] == '.')
return -1;
domain = strchr(hostname, '.');