diff mbox

[v2] OpenSSL: Accept certificates marked for both server and client use

Message ID alpine.DEB.2.02.1402150527020.43540@department-of-alchemy.MIT.EDU
State Superseded
Headers show

Commit Message

Anders Kaseorg Feb. 15, 2014, 10:28 a.m. UTC
Commit 51e3eafb68e15e78e98ca955704be8a6c3a7b304 was too strict in
forbidding certificates marked for client use.  For example, this
broke the MIT SECURE wireless network.  The extended key usage is a
_list_ of allowed uses, and rather than checking that client use is
not in the list, we should check that server use is in the list.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
---
(Change from v1: accept XKU_ANYEKU.)

 src/crypto/tls.h         |  2 +-
 src/crypto/tls_openssl.c | 10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

Comments

Anders Kaseorg Feb. 15, 2014, 10:46 a.m. UTC | #1
On Sat, 15 Feb 2014, Anders Kaseorg wrote:
> (Change from v1: accept XKU_ANYEKU.)

Argh, it always has to be more complicated: XKU_ANYEKU is new in OpenSSL 
1.1.x Git and not yet in any released version of OpenSSL.  So the only 
correct thing I think we can do is put #ifdef XKU_ANYEKU around the entire 
check, causing it to be skipped for OpenSSL versions that aren’t from the 
future.

Does that sound reasonable?

Anders
diff mbox

Patch

diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 287fd33..3f07600 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -42,7 +42,7 @@  enum tls_fail_reason {
 	TLS_FAIL_BAD_CERTIFICATE = 7,
 	TLS_FAIL_SERVER_CHAIN_PROBE = 8,
 	TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9,
-	TLS_FAIL_SERVER_USED_CLIENT_CERT = 10
+	TLS_FAIL_NON_SERVER_KEY_USAGE = 10,
 };
 
 union tls_event_data {
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index d025ae0..a935e4b 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -1479,11 +1479,13 @@  static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
 
 	if (!conn->server && err_cert && preverify_ok && depth == 0 &&
 	    (err_cert->ex_flags & EXFLAG_XKUSAGE) &&
-	    (err_cert->ex_xkusage & XKU_SSL_CLIENT)) {
-		wpa_printf(MSG_WARNING, "TLS: Server used client certificate");
+	    !(err_cert->ex_xkusage & (XKU_SSL_SERVER | XKU_ANYEKU))) {
+		wpa_printf(MSG_WARNING, "TLS: Server certificate marked for "
+			   "non-server key usage");
 		openssl_tls_fail_event(conn, err_cert, err, depth, buf,
-				       "Server used client certificate",
-				       TLS_FAIL_SERVER_USED_CLIENT_CERT);
+				       "Server certificate marked for "
+				       "non-server key usage",
+				       TLS_FAIL_NON_SERVER_KEY_USAGE);
 		preverify_ok = 0;
 	}