From 6c9b08ce2679fccb224dd02afd9221ed28623f9b Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Fri, 30 Oct 2009 18:48:16 +0000
Subject: [PATCH] In case of certificate verification failures include failure
 reason into the error message (openssl only)

---
 libraries/libldap/ldap-tls.h |  2 +-
 libraries/libldap/tls2.c     |  4 ++--
 libraries/libldap/tls_g.c    |  2 +-
 libraries/libldap/tls_m.c    |  2 +-
 libraries/libldap/tls_o.c    | 15 +++++++++++++--
 5 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/libraries/libldap/ldap-tls.h b/libraries/libldap/ldap-tls.h
index 0200cc20b9..dd730f672b 100644
--- a/libraries/libldap/ldap-tls.h
+++ b/libraries/libldap/ldap-tls.h
@@ -37,7 +37,7 @@ typedef tls_session *(TI_session_new)(tls_ctx *ctx, int is_server);
 typedef int (TI_session_connect)(LDAP *ld, tls_session *s);
 typedef int (TI_session_accept)(tls_session *s);
 typedef int (TI_session_upflags)(Sockbuf *sb, tls_session *s, int rc);
-typedef char *(TI_session_errmsg)(int rc, char *buf, size_t len );
+typedef char *(TI_session_errmsg)(tls_session *s, int rc, char *buf, size_t len );
 typedef int (TI_session_dn)(tls_session *sess, struct berval *dn);
 typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
 typedef int (TI_session_strength)(tls_session *sess);
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 3c440e9e51..ac555b9c3a 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -376,7 +376,7 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
 			return 1;
 		}
 
-		msg = tls_imp->ti_session_errmsg( err, buf, sizeof(buf) );
+		msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
 		if ( msg ) {
 			if ( ld->ld_error ) {
 				LDAP_FREE( ld->ld_error );
@@ -438,7 +438,7 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
 
 		if ( DebugTest( LDAP_DEBUG_ANY ) ) {
 			char buf[256], *msg;
-			msg = tls_imp->ti_session_errmsg( err, buf, sizeof(buf) );
+			msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
 			Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
 				msg ? msg : "(unknown)", 0, 0 );
 		}
diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c
index 9313bfbf7c..16fa7cab25 100644
--- a/libraries/libldap/tls_g.c
+++ b/libraries/libldap/tls_g.c
@@ -525,7 +525,7 @@ tlsg_session_upflags( Sockbuf *sb, tls_session *session, int rc )
 }
 
 static char *
-tlsg_session_errmsg( int rc, char *buf, size_t len )
+tlsg_session_errmsg( tls_session *sess, int rc, char *buf, size_t len )
 {
 	return (char *)gnutls_strerror( rc );
 }
diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
index b62aa0e746..918c67cb6a 100644
--- a/libraries/libldap/tls_m.c
+++ b/libraries/libldap/tls_m.c
@@ -2013,7 +2013,7 @@ tlsm_session_upflags( Sockbuf *sb, tls_session *session, int rc )
 }
 
 static char *
-tlsm_session_errmsg( int rc, char *buf, size_t len )
+tlsm_session_errmsg( tls_session *sess, int rc, char *buf, size_t len )
 {
 	int i;
 
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index 6707e29153..4d08272a21 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -398,11 +398,22 @@ tlso_session_upflags( Sockbuf *sb, tls_session *sess, int rc )
 }
 
 static char *
-tlso_session_errmsg( int rc, char *buf, size_t len )
+tlso_session_errmsg( tls_session *sess, int rc, char *buf, size_t len )
 {
+	char err[256] = "";
+	const char *certerr=NULL;
+	tlso_session *s = (tlso_session *)sess;
+
 	rc = ERR_peek_error();
 	if ( rc ) {
-		ERR_error_string_n( rc, buf, len );
+		ERR_error_string_n( rc, err, sizeof(err) );
+		if ( ( ERR_GET_LIB(rc) == ERR_LIB_SSL ) && 
+				( ERR_GET_REASON(rc) == SSL_R_CERTIFICATE_VERIFY_FAILED ) ) {
+			int certrc = SSL_get_verify_result(s);
+			certerr = (char *)X509_verify_cert_error_string(certrc);
+		}
+		snprintf(buf, len, "%s%s%s%s", err, certerr ? " (" :"", 
+				certerr ? certerr : "", certerr ?  ")" : "" );
 		return buf;
 	}
 	return NULL;
-- 
GitLab