Verify certificates in GnuTLS code. Fixes LM-107. Patch by Sjoerd Simons.
authorDafydd Harries <daf@rhydd.org>
Wed, 05 Sep 2007 16:03:24 +0100
changeset 273 6be9056c1fb3
parent 272 00c0890d19c0
child 274 c32a7011e435
Verify certificates in GnuTLS code. Fixes LM-107. Patch by Sjoerd Simons.
loudmouth/lm-ssl-gnutls.c
--- a/loudmouth/lm-ssl-gnutls.c	Wed Sep 05 16:00:09 2007 +0100
+++ b/loudmouth/lm-ssl-gnutls.c	Wed Sep 05 16:03:24 2007 +0100
@@ -31,11 +31,13 @@
 
 #include <gnutls/x509.h>
 
+#define CA_PEM_FILE "/etc/ssl/certs/ca-certificates.crt"
+
 struct _LmSSL {
 	LmSSLBase base;
 
-	gnutls_session                        gnutls_session;
-	gnutls_certificate_client_credentials gnutls_xcred;
+	gnutls_session                 gnutls_session;
+	gnutls_certificate_credentials gnutls_xcred;
 };
 
 static gboolean       ssl_verify_certificate    (LmSSL       *ssl,
@@ -45,16 +47,33 @@
 ssl_verify_certificate (LmSSL *ssl, const gchar *server)
 {
 	LmSSLBase *base;
-	int        status;
+	unsigned int        status;
+	int rc;
 
 	base = LM_SSL_BASE (ssl);
 
 	/* This verification function uses the trusted CAs in the credentials
 	 * structure. So you must have installed one or more CA certificates.
 	 */
-	status = gnutls_certificate_verify_peers (ssl->gnutls_session);
+	rc = gnutls_certificate_verify_peers2 (ssl->gnutls_session, &status);
+
+	if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
+		if (base->func (ssl,
+			       LM_SSL_STATUS_NO_CERT_FOUND,
+			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
+			return FALSE;
+		}
+	}
 
-	if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
+	if (rc != 0) {
+		if (base->func (ssl,
+			       LM_SSL_STATUS_GENERIC_ERROR,
+			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
+			return FALSE;
+		}
+	}
+
+	if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
 		if (base->func (ssl,
 			       LM_SSL_STATUS_NO_CERT_FOUND,
 			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
@@ -100,8 +119,8 @@
 
 		gnutls_x509_crt_init (&cert);
 
-		if (!gnutls_x509_crt_import (cert, &cert_list[0],
-					     GNUTLS_X509_FMT_DER)) {
+		if (gnutls_x509_crt_import (cert, &cert_list[0],
+					     GNUTLS_X509_FMT_DER) != 0) {
 			if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, 
 					base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
 				return FALSE;
@@ -165,6 +184,9 @@
 {
 	gnutls_global_init ();
 	gnutls_certificate_allocate_credentials (&ssl->gnutls_xcred);
+	gnutls_certificate_set_x509_trust_file(ssl->gnutls_xcred,
+					       CA_PEM_FILE,
+					       GNUTLS_X509_FMT_PEM);
 }
 
 gboolean