Hi everyone.
We at SUSE had a problem using TigerVNC in our newer FIPS-compliant environment. I am attaching a patch to fix this problem.
As part of establishing a secure connection, TigerVNC generates Diffie-Hellman parameters to use for creating a shared key. This was the way to do it before GnuTLS 3.6.0.
The problem is that generating DH parameters is no longer allowed in
FIPS mode. Any attempt to securely connect to a TigerVNC server fails in
a FIPS system.
GnuTLS 3.6.0 has deprecated Diffie-Hellman parameter generation. Instead, GnuTLS now defaults to using parameters from RFC-7919, which would solve our problem.
Fortunately for us the solution is simple: remove from TigerVNC the code that generates DH parameters.
Thank you, and I hope you find this helpful.
--Jason
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
index d5ef47e6..2111bae6 100644
--- a/common/rfb/SSecurityTLS.cxx
+++ b/common/rfb/SSecurityTLS.cxx
@@ -37,8 +37,6 @@
#include <rdr/TLSOutStream.h>
#include <gnutls/x509.h>
-#define DH_BITS 1024 /* XXX This should be configurable! */
-
using namespace rfb;
StringParameter SSecurityTLS::X509_CertFile
@@ -50,7 +48,7 @@ StringParameter SSecurityTLS::X509_KeyFile
static LogWriter vlog("TLS");
SSecurityTLS::SSecurityTLS(SConnection* sc, bool _anon)
- : SSecurity(sc), session(NULL), dh_params(NULL), anon_cred(NULL),
+ : SSecurity(sc), session(NULL), anon_cred(NULL),
cert_cred(NULL), anon(_anon), tlsis(NULL), tlsos(NULL),
rawis(NULL), rawos(NULL)
{
@@ -70,11 +68,6 @@ void SSecurityTLS::shutdown()
}
}
- if (dh_params) {
- gnutls_dh_params_deinit(dh_params);
- dh_params = 0;
- }
-
if (anon_cred) {
gnutls_anon_free_server_credentials(anon_cred);
anon_cred = 0;
@@ -198,18 +191,10 @@ void SSecurityTLS::setParams(gnutls_session_t session)
throw AuthFailureException("gnutls_set_priority_direct failed");
}
- if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS)
- throw AuthFailureException("gnutls_dh_params_init failed");
-
- if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS)
- throw AuthFailureException("gnutls_dh_params_generate2 failed");
-
if (anon) {
if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_anon_allocate_server_credentials failed");
- gnutls_anon_set_server_dh_params(anon_cred, dh_params);
-
if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred)
!= GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_credentials_set failed");
@@ -220,8 +205,6 @@ void SSecurityTLS::setParams(gnutls_session_t session)
if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_certificate_allocate_credentials failed");
- gnutls_certificate_set_dh_params(cert_cred, dh_params);
-
switch (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, GNUTLS_X509_FMT_PEM)) {
case GNUTLS_E_SUCCESS:
break;
diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h
index dd89bb49..fe9fe673 100644
--- a/common/rfb/SSecurityTLS.h
+++ b/common/rfb/SSecurityTLS.h
@@ -55,7 +55,6 @@ namespace rfb {
private:
gnutls_session_t session;
- gnutls_dh_params_t dh_params;
gnutls_anon_server_credentials_t anon_cred;
gnutls_certificate_credentials_t cert_cred;
char *keyfile, *certfile;