Re: [openssl.org #2909] Wildcard support for certificate matching (plus fixes)

2012-11-19 Thread Florian Weimer

On 11/18/2012 04:16 PM, Stephen Henson via RT wrote:

I have also added a manual page.  The test case does not have full
coverage, but it is better than nothing.



Many thanks for the patch. I've applied it with a few minor changes. Let
me know if I broke anything.


Thanks for showing me the concise way for setting GENERAL_NAMEs.

I've adjusted the test case to cover the new return values 
(v3nametest.patch).  It shouldn't matter from a testing point of view, 
but I think it's important to show the correct error checking.


The IDNA filter for wildcards was incomplete, and I couldn't find this 
in any standard, so I suggest removing it (idna.patch).


--
Florian Weimer / Red Hat Product Security Team
commit 373bf51bb3a64f4d91241752be7178104d0de28b
Author: Florian Weimer 
Date:   Mon Nov 19 11:04:56 2012 +0100

Adjust v3nametest.c return value checking to API

diff --git a/crypto/x509v3/v3nametest.c b/crypto/x509v3/v3nametest.c
index 5bf1201..c1d5ff3 100644
--- a/crypto/x509v3/v3nametest.c
+++ b/crypto/x509v3/v3nametest.c
@@ -273,28 +273,38 @@ static void run_cert(X509 *crt, const char *nameincert,
 		ret = X509_check_host(crt, (const unsigned char *)name,
   namelen, 0);
 		match = -1;
-		if (fn->host)
+		if (ret < 0)
 			{
-			if (ret && !samename)
+			fprintf(stderr, "internal error in X509_check_host");
+			++errors;
+			}
+		else if (fn->host)
+			{
+			if (ret == 1 && !samename)
 match = 1;
-			if (!ret && samename)
+			if (ret == 0 && samename)
 match = 0;
 			}
-		else if (ret)
+		else if (ret == 1)
 			match = 1;
 		check_message(fn, "host", nameincert, match, *pname);
 
 		ret = X509_check_host(crt, (const unsigned char *)name,
   namelen, X509_CHECK_FLAG_NO_WILDCARDS);
 		match = -1;
-		if (fn->host)
+		if (ret < 0)
 			{
-			if (ret && !samename)
+			fprintf(stderr, "internal error in X509_check_host");
+			++errors;
+			}
+		else if (fn->host)
+			{
+			if (ret == 1 && !samename)
 match = 1;
-			if (!ret && samename)
+			if (ret == 0 && samename)
 match = 0;
 			}
-		else if (ret)
+		else if (ret == 1)
 			match = 1;
 		check_message(fn, "host-no-wildcards",
 			  nameincert, match, *pname);
commit b399db5b4a31dd13ebc2ee114501c4ee20b748f2
Author: Florian Weimer 
Date:   Mon Nov 19 11:32:38 2012 +0100

X509_check_host: remove IDNA wildcard block

I couldn't find this in any standard, and the check was incomplete
anyway.

diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index ffd9f0d..de43c2f 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -719,12 +719,7 @@ static const unsigned char *wildcard_find_star(const unsigned char *pattern,
 static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
 			  const unsigned char *subject, size_t subject_len)
 	{
-	const unsigned char *star;
-	/* Do not match IDNA names. */
-	if (subject_len >=4 && memcmp(subject, "xn--", 4) == 0)
-		star = NULL;
-	else
-		star = wildcard_find_star(pattern, pattern_len);
+	const unsigned char *star = wildcard_find_star(pattern, pattern_len);
 	if (star == NULL)
 		return equal_nocase(pattern, pattern_len,
 subject, subject_len);
diff --git a/crypto/x509v3/v3nametest.c b/crypto/x509v3/v3nametest.c
index c1d5ff3..aa0d29c 100644
--- a/crypto/x509v3/v3nametest.c
+++ b/crypto/x509v3/v3nametest.c
@@ -24,6 +24,7 @@ static const char *const exceptions[] =
 	"set CN: host: [*.example.com] matches [a.example.com]",
 	"set CN: host: [*.example.com] matches [b.example.com]",
 	"set CN: host: [*.example.com] matches [www.example.com]",
+	"set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
 	"set CN: host: [test.*.example.com] does not match [test.*.example.com]",
 	"set CN: host: [test.*.example.com] matches [test.www.example.com]",
 	"set CN: host: [*.www.example.com] does not match [*.www.example.com]",
@@ -36,6 +37,7 @@ static const char *const exceptions[] =
 	"set dnsName: host: [*.example.com] does not match [*.example.com]",
 	"set dnsName: host: [*.example.com] matches [a.example.com]",
 	"set dnsName: host: [*.example.com] matches [b.example.com]",
+	"set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
 	"set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
 	"set dnsName: host: [*.www.example.com] does not match [*.www.example.com]",
 	"set dnsName: host: [test.*.example.com] matches [test.www.example.com]",


[openssl.org #2909] Wildcard support for certificate matching (plus fixes)

2012-11-18 Thread Stephen Henson via RT
> [openssl-dev@openssl.org - Wed Nov 07 20:23:31 2012]:
> 
> Hi,
> 
> the attached patch implements wildcard matching and introduces the 
> X509_CHECK_FLAG_NO_WILDCARDS flag to disable it if necessary.
> 
> In addition, it implements case-insensitive comparison of host names and 
> email address domain parts, as required by RFC 5280.  Domain names and 
> email addresses which contain NUL characters are now rejected, to cope 
> with some mis-issued certificates.
> 
> I have also added a manual page.  The test case does not have full 
> coverage, but it is better than nothing.
> 

Many thanks for the patch. I've applied it with a few minor changes. Let
me know if I broke anything.

> It might make sense to change the API so that 0 means success, 1 match 
> failure, and -1 an internal error.  Right now, it is not possible to 
> tell match failures and internal errors apart.
> 

Agreed. I changed it to return -1 for internal error and -2 for
malformed IP address parameter.

Steve.
-- 
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org