Package: libapache2-mod-gnutls
Version: 0.5.10-1.1
Followup-For: Bug #578663

This bug still exists in current stable and unstable packages. I have
analyzed the problem and found that the authentication hook
(mgs_hook_authz) failed to consider the server's client verify mode,
even if the verify mode was unset in the directory configuration. As a
result, invalid certificates were ignored and clients could connect and
receive data as long as they presented any certificate whatsoever. The
logs show that the certificate was recognized as invalid, but the
request is still served.

[debug] gnutls_hooks.c(1181): [client 127.0.0.1] GnuTLS: A Chain of 1
certificate(s) was provided for validation
[debug] gnutls_hooks.c(1236): [client 127.0.0.1] GnuTLS: Verifying list
of  1 certificate(s)
[info] [client 127.0.0.1] GnuTLS: Could not find Signer for Peer Certificate
[info] [client 127.0.0.1] GnuTLS: Peer Certificate is invalid.

The attached patch applies to the version in stable, commit
5a8a32bbfb8a83fe6358c5c31c443325a7775fc2 in my git repository [1] should
work for the unstable version. Functionally, they are identical, but
apparently indentation changed between the two versions.

Since this bug makes required TLS client auth effectively worthless, I
consider it a security issue.

[1]
https://github.com/airtower-luna/mod_gnutls/commit/5a8a32bbfb8a83fe6358c5c31c443325a7775fc2

-- System Information:
Debian Release: 7.8
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libapache2-mod-gnutls depends on:
ii  libapr-memcache0  0.7.0-1
ii  libc6             2.13-38+deb7u7
ii  libgnutls26       2.12.20-8+deb7u2

libapache2-mod-gnutls recommends no packages.

libapache2-mod-gnutls suggests no packages.

-- Configuration Files:
/etc/apache2/sites-available/default-tls changed [not included]

-- no debconf information
From 5a8a32bbfb8a83fe6358c5c31c443325a7775fc2 Mon Sep 17 00:00:00 2001
From: Thomas Klute <thomas2.kl...@uni-dortmund.de>
Date: Thu, 5 Feb 2015 14:48:45 +0100
Subject: [PATCH] TLS Client auth: Check server verify mode if unset for dir

The authentication hook (mgs_hook_authz) failed to consider the server's
client verify mode, even if the verify mode was unset in the directory
configuration. As a result, invalid certificates were ignored and
clients could connect and receive data as long as they presented any
certificate whatsoever. Logs showed that authorization was granted
despite the certificate being invalid (timestamps removed for
readability):

[:debug] [pid 10806:tid 140242057148160] gnutls_hooks.c(1198): [client ::1:40992] GnuTLS: Verifying list of 1 certificate(s) via method 'cartel'
[:info] [pid 10806:tid 140242057148160] [client ::1:40992] GnuTLS: Could not find Signer for Peer Certificate
[:info] [pid 10806:tid 140242057148160] [client ::1:40992] GnuTLS: Peer Certificate is invalid.
[authz_core:debug] [pid 10806:tid 140242057148160] mod_authz_core.c(835): [client ::1:40992] AH01628: authorization result: granted (no directives)

This commit adds a check for undefined verify mode in the directory
configuration and applies the server wide configuration in that case.
---
 src/gnutls_hooks.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Index: mod-gnutls-0.5.10/src/gnutls_hooks.c
===================================================================
--- mod-gnutls-0.5.10.orig/src/gnutls_hooks.c	2011-07-08 23:29:46.000000000 +0200
+++ mod-gnutls-0.5.10/src/gnutls_hooks.c	2015-02-17 15:37:15.173845398 +0100
@@ -909,9 +909,12 @@
 			return DECLINED;
 		}
 		rv = mgs_cert_verify(r, ctxt);
-		if (rv != DECLINED &&
-		    (rv != HTTP_FORBIDDEN ||
-		     dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
+		if (rv != DECLINED
+		    && (rv != HTTP_FORBIDDEN
+			|| dc->client_verify_mode == GNUTLS_CERT_REQUIRE
+			|| (dc->client_verify_mode == -1
+			    && ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUIRE)))
+		{
 			return rv;
 		}
 	}

Reply via email to