andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From a7470fb5cd822c87dcba450021ee534c75f3eaa6 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Tue, 6 Jan 2015 16:23:35 -0800
dc8c34
Subject: [PATCH 293/305] Ticket #47928 - Disable SSL v3, by default
dc8c34
 [389-ds-base-1.2.11 only]
dc8c34
dc8c34
Description:
dc8c34
[fedse.c]
dc8c34
  By default, nsSSL3 is set to off and nsTLS1 is on in cn=encryption,cn=config.
dc8c34
[ssl.c]
dc8c34
  Back-ported SSLVersionRange from the master branch, but no new range
dc8c34
  parameter support in the config.  If nsSSL3 is explicitely set to
dc8c34
  on, SSL_LIBRARY_VERSION_3_0 is set to the minimum ssl version.
dc8c34
  Otherwise, SSL_LIBRARY_VERSION_TLS_1_0 becomes the minimum version.
dc8c34
  The max available version is set to the maximum ssl version.
dc8c34
dc8c34
  On this version, there is no way to disable TLS1.0 and enable TLS1.1
dc8c34
  and newer.  If nsTLS1 is on, all TLS1.X are enabled.
dc8c34
dc8c34
Note: This patch covers Ticket #605 - support TLS 1.1, as well.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47928
dc8c34
(cherry picked from commit 17fc03cf1101135b99234f17efd3eb746626be1a)
dc8c34
---
dc8c34
 ldap/servers/slapd/fedse.c |   3 +-
dc8c34
 ldap/servers/slapd/ssl.c   | 150 ++++++++++++++++++++++++++++++++++++++++-----
dc8c34
 2 files changed, 136 insertions(+), 17 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
dc8c34
index dbfba16..f8c95ce 100644
dc8c34
--- a/ldap/servers/slapd/fedse.c
dc8c34
+++ b/ldap/servers/slapd/fedse.c
dc8c34
@@ -107,7 +107,8 @@ static const char *internal_entries[] =
dc8c34
 	"nsSSLSessionTimeout:0\n"
dc8c34
 	"nsSSLClientAuth:allowed\n"
dc8c34
 	"nsSSL2:off\n"
dc8c34
-	"nsSSL3:off\n",
dc8c34
+	"nsSSL3:off\n"
dc8c34
+	"nsTLS1:on\n",
dc8c34
 
dc8c34
     "dn:cn=monitor\n"
dc8c34
     "objectclass:top\n"
dc8c34
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
dc8c34
index bbadf93..23fa620 100644
dc8c34
--- a/ldap/servers/slapd/ssl.c
dc8c34
+++ b/ldap/servers/slapd/ssl.c
dc8c34
@@ -79,6 +79,24 @@
dc8c34
 #define MAXPATHLEN 1024
dc8c34
 #endif
dc8c34
 
dc8c34
+#if NSS_VMAJOR * 100 + NSS_VMINOR >= 315
dc8c34
+/* TLS1.2 is defined in RFC5246. */
dc8c34
+#define NSS_TLS12 1
dc8c34
+#elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314
dc8c34
+/* TLS1.1 is defined in RFC4346. */
dc8c34
+#define NSS_TLS11 1
dc8c34
+#else
dc8c34
+#define NSS_TLS10 1
dc8c34
+#endif
dc8c34
+
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
+static SSLVersionRange enabledNSSVersions;
dc8c34
+static SSLVersionRange slapdNSSVersions;
dc8c34
+#endif
dc8c34
+
dc8c34
+/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */
dc8c34
+#define VERSION_STR_LENGTH 64
dc8c34
+
dc8c34
 extern char* slapd_SSL3ciphers;
dc8c34
 extern symbol_t supported_ciphers[];
dc8c34
 
dc8c34
@@ -165,6 +183,12 @@ static cipherstruct _conf_ciphers[] = {
dc8c34
     /*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */
dc8c34
     {"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
dc8c34
     {"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
dc8c34
+#if defined(NSS_TLS12)
dc8c34
+    /* New in NSS 3.15 */
dc8c34
+    {"tls_rsa_aes_128_gcm_sha",             "TLS_RSA_WITH_AES_128_GCM_SHA256"},
dc8c34
+    {"tls_dhe_rsa_aes_128_gcm_sha",         "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
dc8c34
+    {"tls_dhe_dss_aes_128_gcm_sha",         NULL}, /* not available */
dc8c34
+#endif
dc8c34
     {NULL, NULL, 0}
dc8c34
 };
dc8c34
 
dc8c34
@@ -524,6 +548,54 @@ warn_if_no_key_file(const char *dir, int no_log)
dc8c34
     return ret;
dc8c34
 }
dc8c34
 
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
+/* 
dc8c34
+ * If non NULL buf and positive bufsize is given,
dc8c34
+ * the memory is used to store the version string.
dc8c34
+ * Otherwise, the memory for the string is allocated.
dc8c34
+ * The latter case, caller is responsible to free it.
dc8c34
+ */
dc8c34
+char *
dc8c34
+slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize)
dc8c34
+{
dc8c34
+    char *vstr = buf;
dc8c34
+    if (vnum >= SSL_LIBRARY_VERSION_3_0) {
dc8c34
+        if (vnum == SSL_LIBRARY_VERSION_3_0) { /* SSL3 */
dc8c34
+            if (buf && bufsize) { 
dc8c34
+                PR_snprintf(buf, bufsize, "SSL3"); 
dc8c34
+            } else { 
dc8c34
+                vstr = slapi_ch_smprintf("SSL3"); 
dc8c34
+            } 
dc8c34
+        } else { /* TLS v X.Y */
dc8c34
+            const char *TLSFMT = "TLS%d.%d";
dc8c34
+            int minor_offset = 0; /* e.g. 0x0401 -> TLS v 2.1, not 2.0 */
dc8c34
+
dc8c34
+            if ((vnum & SSL_LIBRARY_VERSION_3_0) == SSL_LIBRARY_VERSION_3_0) {
dc8c34
+                minor_offset = 1; /* e.g. 0x0301 -> TLS v 1.0, not 1.1 */
dc8c34
+            }
dc8c34
+            if (buf && bufsize) { 
dc8c34
+                PR_snprintf(buf, bufsize, TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset); 
dc8c34
+            } else { 
dc8c34
+                vstr = slapi_ch_smprintf(TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset); 
dc8c34
+            }
dc8c34
+        }
dc8c34
+    } else if (vnum == SSL_LIBRARY_VERSION_2) { /* SSL2 */
dc8c34
+        if (buf && bufsize) {
dc8c34
+            PR_snprintf(buf, bufsize, "SSL2");
dc8c34
+        } else {
dc8c34
+            vstr = slapi_ch_smprintf("SSL2");
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+        if (buf && bufsize) {
dc8c34
+            PR_snprintf(buf, bufsize, "Unknown SSL version: 0x%x", vnum); 
dc8c34
+        } else {
dc8c34
+            vstr = slapi_ch_smprintf("Unknown SSL version: 0x%x", vnum);
dc8c34
+        }
dc8c34
+    }
dc8c34
+    return vstr;
dc8c34
+}
dc8c34
+#endif
dc8c34
+
dc8c34
 /*
dc8c34
  * slapd_nss_init() is always called from main(), even if we do not
dc8c34
  * plan to listen on a secure port.  If config_available is 0, the
dc8c34
@@ -548,6 +620,17 @@ slapd_nss_init(int init_ssl, int config_available)
dc8c34
 	char *certdb_file_name = NULL;
dc8c34
 	char *keydb_file_name = NULL;
dc8c34
 	char *secmoddb_file_name = NULL;
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
+	char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
dc8c34
+	/* Get the range of the supported SSL version */
dc8c34
+	SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
dc8c34
+	
dc8c34
+	(void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
dc8c34
+	(void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
dc8c34
+	slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization",
dc8c34
+	                "supported range by NSS: min: %s, max: %s\n",
dc8c34
+	                emin, emax);
dc8c34
+#endif
dc8c34
 
dc8c34
 	/* set in slapd_bootstrap_config,
dc8c34
 	   thus certdir is available even if config_available is false */
dc8c34
@@ -879,9 +962,13 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
dc8c34
     char* tmpDir;
dc8c34
     Slapi_Entry *e = NULL;
dc8c34
     PRBool enableSSL2 = PR_FALSE;
dc8c34
-    PRBool enableSSL3 = PR_TRUE;
dc8c34
+    PRBool enableSSL3 = PR_FALSE;
dc8c34
     PRBool enableTLS1 = PR_TRUE;
dc8c34
     PRBool fipsMode = PR_FALSE;
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
+    PRUint16 NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
dc8c34
+    PRUint16 NSSVersionMax = enabledNSSVersions.max;
dc8c34
+#endif
dc8c34
 
dc8c34
     /* turn off the PKCS11 pin interactive mode */
dc8c34
 #ifndef _WIN32
dc8c34
@@ -1226,23 +1313,54 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
dc8c34
         }
dc8c34
         slapi_ch_free_string( &val );
dc8c34
     }
dc8c34
-    sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
dc8c34
-    if (sslStatus != SECSuccess) {
dc8c34
-        errorCode = PR_GetError();
dc8c34
-        slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
dc8c34
-               "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
dc8c34
-               enableSSL3 ? "enable" : "disable",
dc8c34
-               errorCode, slapd_pr_strerror(errorCode));
dc8c34
-    }
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
+    if (NSSVersionMin > 0) {
dc8c34
+        char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
dc8c34
+        /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
dc8c34
+        if (enableTLS1) {
dc8c34
+            NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
dc8c34
+        }
dc8c34
+        if (enableSSL3) {
dc8c34
+            NSSVersionMin = SSL_LIBRARY_VERSION_3_0;
dc8c34
+        }
dc8c34
+        slapdNSSVersions.min = NSSVersionMin;
dc8c34
+        slapdNSSVersions.max = NSSVersionMax;
dc8c34
+        (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
dc8c34
+        (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
dc8c34
+        slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
dc8c34
+                        "Configured SSL version range: min: %s, max: %s\n",
dc8c34
+                        mymin, mymax);
dc8c34
+        sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions);
dc8c34
+        if (sslStatus == SECSuccess) {
dc8c34
+            /* Set the restricted value to the cn=encryption entry */
dc8c34
+        } else {
dc8c34
+            slapd_SSL_error("SSL Initialization 2: "
dc8c34
+                            "Failed to set SSL range: min: %s, max: %s\n",
dc8c34
+                            mymin, mymax);
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+#endif
dc8c34
+        /* deprecated code */
dc8c34
+        sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
dc8c34
+        if (sslStatus != SECSuccess) {
dc8c34
+            errorCode = PR_GetError();
dc8c34
+            slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
dc8c34
+                   "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
dc8c34
+                   enableSSL3 ? "enable" : "disable",
dc8c34
+                   errorCode, slapd_pr_strerror(errorCode));
dc8c34
+        }
dc8c34
 
dc8c34
-    sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
dc8c34
-    if (sslStatus != SECSuccess) {
dc8c34
-        errorCode = PR_GetError();
dc8c34
-        slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
dc8c34
-               "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
dc8c34
-               enableTLS1 ? "enable" : "disable",
dc8c34
-               errorCode, slapd_pr_strerror(errorCode));
dc8c34
+        sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
dc8c34
+        if (sslStatus != SECSuccess) {
dc8c34
+            errorCode = PR_GetError();
dc8c34
+            slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
dc8c34
+                   "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
dc8c34
+                   enableTLS1 ? "enable" : "disable",
dc8c34
+                   errorCode, slapd_pr_strerror(errorCode));
dc8c34
+        }
dc8c34
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
dc8c34
     }
dc8c34
+#endif
dc8c34
     freeConfigEntry( &e );
dc8c34
 
dc8c34
     if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) {
dc8c34
-- 
dc8c34
1.9.3
dc8c34