ldap/schema/01core389.ldif | 4
ldap/servers/slapd/ssl.c | 407 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 385 insertions(+), 26 deletions(-)
New commits:
commit 88d4beccb9d9f7bb89f5e24c47828d7516ba7ca8
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Dec 3 11:49:03 2013 -0800
Ticket #605 - support TLS 1.1
Description:
NSS 3.14 deprecates the current way to configure SSL versions:
SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3|SSL_ENABLE_TLS, True|False)
Instead, it introduces new range APIs to provide more detailed SSL
version control by using SSL_VersionRangeSet(pr_sock, NSSVersions).
The NSSVersions has 2 fields "min" and "max", which take the minimum
and maximum SSL versions.
By default, slapd_ssl_init2 sets the default supported range by NSS,
which is min: SSL3 and max: TLS1.2. This patch adds 2 config params
sslVersionMin and sslVersionMax to cn=encryption,cn=config to provide
the ability to control the values.
Both takes: ssl3 or tls1.?. If the range is not supported by the
NSS or conflicts with the current params nsSSL3 and nsTLS1, it'd be
adjusted.
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index b9baae7..7b27685 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -120,6 +120,8 @@ attributeTypes: ( nsKeyfile-oid NAME 'nsKeyfile' DESC 'Netscape defined attribut
attributeTypes: ( nsSSL2-oid NAME 'nsSSL2' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSL3-oid NAME 'nsSSL3' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsTLS1-oid NAME 'nsTLS1' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( sslVersionMin-oid NAME 'sslVersionMin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( sslVersionMax-oid NAME 'sslVersionMax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLClientAuth-oid NAME 'nsSSLClientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLSessionTimeout-oid NAME 'nsSSLSessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSL3SessionTimeout-oid NAME 'nsSSL3SessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
@@ -169,7 +171,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC
objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY ( nsSaslMapPriority ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' )
-objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' )
+objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' )
objectClasses: ( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $ nsSSLPersonalityssl $ nsSSLActivation ) X-ORIGIN 'Netscape' )
objectClasses: ( 2.16.840.1.113730.3.2.327 NAME 'rootDNPluginConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( rootdn-open-time $ rootdn-close-time $ rootdn-days-allowed $ rootdn-allow-host $ rootdn-deny-host $ rootdn-allow-ip $ rootdn-deny-ip ) X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 61809aa..7b9bf2a 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -54,6 +54,7 @@
#include <io.h>
#endif
+#include <stdio.h>
#include <sys/param.h>
#include <ssl.h>
#include <nss.h>
@@ -81,6 +82,7 @@
extern char* slapd_SSL3ciphers;
extern symbol_t supported_ciphers[];
+static SSLVersionRange enabledNSSVersions;
/* dongle_file_name is set in slapd_nss_init when we set the path for the
key, cert, and secmod files - the dongle file must be in the same directory
@@ -141,10 +143,9 @@ static cipherstruct _conf_ciphers[] = {
{"TLS","rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, /* ditto */
{"TLS","tls_rsa_export1024_with_des_cbc_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
{"TLS","rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, /* ditto */
- {"SSL3","fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
- {"SSL3","fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
- {"SSL3","fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
-
+ {"SSL3","fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, /* deprecated */
+ {"SSL3","fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, /* deprecated */
+ {"SSL3","fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, /* deprecated */
/*{"SSL3","dhe_dss_40_sha", SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA}, */
{"SSL3","dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA},
@@ -165,6 +166,11 @@ static cipherstruct _conf_ciphers[] = {
/*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */
{"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
{"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
+ /* New in NSS 3.14 */
+ {"TLS","tls_rsa_aes_128_gcm_sha", TLS_RSA_WITH_AES_128_GCM_SHA256},
+ {"TLS","tls_dhe_rsa_aes_128_gcm_sha", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ {"TLS","tls_dhe_dss_aes_128_gcm_sha", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+
{NULL, NULL, 0}
};
@@ -517,6 +523,121 @@ warn_if_no_key_file(const char *dir, int no_log)
return ret;
}
+typedef struct _nss_version_list {
+ PRUint16 vnum;
+ char* vname;
+} NSSVersion_list;
+NSSVersion_list _NSSVersion_list[] =
+{
+ {SSL_LIBRARY_VERSION_2, "SSL2"},
+ {SSL_LIBRARY_VERSION_3_0, "SSL3"},
+ {SSL_LIBRARY_VERSION_TLS_1_0, "TLS1.0"},
+ {SSL_LIBRARY_VERSION_TLS_1_1, "TLS1.1"},
+ {SSL_LIBRARY_VERSION_TLS_1_2, "TLS1.2"},
+ {0, "unknown"}
+};
+
+static char *
+getNSSVersion_str(PRUint16 vnum)
+{
+ NSSVersion_list *nvlp = NULL;
+ char *vstr = "none";
+ if (vnum) {
+ for (nvlp = _NSSVersion_list; nvlp && nvlp->vnum; nvlp++) {
+ if (nvlp->vnum == vnum) {
+ vstr = nvlp->vname;
+ break;
+ }
+ }
+ }
+ return vstr;
+}
+
+/* restrict SSLVersionRange with the existing SSL config params (nsSSL3, nsTLS1) */
+static void
+restrict_SSLVersionRange(SSLVersionRange *sslversion, PRBool enableSSL3, PRBool enableTLS1)
+{
+ int rc = 0;
+ if (enableSSL3) {
+ if (enableTLS1) {
+ /* no restriction */
+ ;
+ } else {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsTLS1. "
+ "Ignoring nsTLS1: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ rc = 1;
+ } else if (sslversion->min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsTLS1. "
+ "Ignoring nsTLS1: off\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ rc = 1;
+ } else if (sslversion->max < SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server enabled nsSSL3. "
+ "Ignoring max: %s\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max),
+ getNSSVersion_str(sslversion->max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else {
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ }
+ }
+ } else {
+ if (enableTLS1) {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3. ",
+ "Ignoring nsSSL3: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else if (sslversion->max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3. "
+ "Ignoring nsSSL3: off\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else if (sslversion->min < SSL_LIBRARY_VERSION_TLS_1_0) {
+ sslversion->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ } else {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3 and nsTLS1. "
+ "Ignoring nsSSL3: off and nsTLS1: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ rc = 1;
+ }
+ }
+ if (0 == rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "SSL version range: min: %s, max: %s\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ }
+}
+
/*
* slapd_nss_init() is always called from main(), even if we do not
* plan to listen on a secure port. If config_available is 0, the
@@ -541,6 +662,13 @@ slapd_nss_init(int init_ssl, int config_available)
char *certdb_file_name = NULL;
char *keydb_file_name = NULL;
char *secmoddb_file_name = NULL;
+ /* Get the range of the supported SSL version */
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
+
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "supported range: min: %s, max: %s\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
/* set in slapd_bootstrap_config,
thus certdir is available even if config_available is false */
@@ -854,8 +982,196 @@ slapd_ssl_init() {
}
+/*
+ * val: sslVersionMin/Max value set in cn=encription,cn=config (INPUT)
+ * rval: Corresponding value to set SSLVersionRange (OUTPUT)
+ * ismin: True if val is sslVersionMin value
+ */
+#define SSLSTR "ssl"
+#define SSLLEN (sizeof(SSLSTR) - 1)
+#define TLSSTR "tls"
+#define TLSLEN (sizeof(TLSSTR) - 1)
+static int
+set_NSS_version(char *val, PRUint16 *rval, int ismin)
+{
+ char *vp, *endp;
+ int vnum;
-int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
+ if (NULL == rval) {
+ return 1;
+ }
+ if (!strncasecmp(val, SSLSTR, SSLLEN)) { /* ssl# */
+ vp = val + SSLLEN;
+ vnum = strtol(vp, &endp, 10);
+ if (2 == vnum) {
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_2) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_2;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_2) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_2;
+ }
+ }
+ } else if (3 == vnum) {
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_3_0;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_3_0) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_3_0;
+ }
+ }
+ } else {
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ } else if (!strncasecmp(val, TLSSTR, TLSLEN)) { /* tls# */
+ float tlsv;
+ vp = val + TLSLEN;
+ sscanf(vp, "%4f", &tlsv);
+ if (tlsv < 1.1) { /* TLS1.0 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ }
+ } else if (tlsv < 1.2) { /* TLS1.1 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
+ }
+ }
+ } else if (tlsv < 1.3) { /* TLS1.2 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
+ }
+ }
+ } else { /* TLS newer than 1.2 */
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is out of the range of the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is out of the range of the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ } else {
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ return 0;
+}
+#undef SSLSTR
+#undef SSLLEN
+#undef TLSSTR
+#undef TLSLEN
+
+int
+slapd_ssl_init2(PRFileDesc **fd, int startTLS)
{
PRFileDesc *pr_sock, *sock = (*fd);
PRErrorCode errorCode;
@@ -875,13 +1191,15 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
PRBool enableSSL3 = PR_TRUE;
PRBool enableTLS1 = PR_TRUE;
PRBool fipsMode = PR_FALSE;
+ PRUint16 NSSVersionMin = enabledNSSVersions.min;
+ PRUint16 NSSVersionMax = enabledNSSVersions.max;
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
SVRCOREStdPinObj *StdPinObj;
if (svrcore_setup()) {
- return 1;
+ return 1;
}
StdPinObj = (SVRCOREStdPinObj *)SVRCORE_GetRegisteredPinObj();
@@ -1083,7 +1401,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
slapd_pk11_DestroyPrivateKey(key);
key = NULL;
}
- slapi_ch_free((void **) &personality);
+ slapi_ch_free((void **) &personality);
if (SECSuccess != rv) {
freeConfigEntry( &e );
continue;
@@ -1108,7 +1426,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
"slapd_ssl_init2", "tmp dir = %s\n", tmpDir);
rv = SSL_ConfigServerSessionIDCache(0, stimeout, stimeout, tmpDir);
- slapi_ch_free_string(&tmpDir);
+ slapi_ch_free_string(&tmpDir);
if (rv) {
errorCode = PR_GetError();
if (errorCode == ENOSPC) {
@@ -1172,7 +1490,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
default_val = "allowed";
break;
}
- val = default_val;
+ val = default_val;
}
if( config_set_SSLclientAuth( "nssslclientauth", val, errorbuf,
CONFIG_APPLY ) != LDAP_SUCCESS ) {
@@ -1184,7 +1502,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
val, errorbuf, errorCode, slapd_pr_strerror(errorCode));
}
if (val != default_val) {
- slapi_ch_free_string(&val);
+ slapi_ch_free_string(&val);
}
if ( e != NULL ) {
@@ -1218,23 +1536,62 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
}
}
slapi_ch_free_string( &val );
+ val = slapi_entry_attr_get_charptr( e, "sslVersionMin" );
+ if ( val ) {
+ (void)set_NSS_version(val, &NSSVersionMin, 1);
+ }
+ slapi_ch_free_string( &val );
+ val = slapi_entry_attr_get_charptr( e, "sslVersionMax" );
+ if ( val ) {
+ (void)set_NSS_version(val, &NSSVersionMax, 0);
+ }
+ slapi_ch_free_string( &val );
+ if (NSSVersionMin > NSSVersionMax) {
+ slapd_SSL_warn("Security Initialization: The min value of NSS version range "
+ "\"%s\" is greater than the max value \"%s\"; "
+ "the default range \"%s\" - \"%s\" is used.\n",
+ getNSSVersion_str(NSSVersionMin),
+ getNSSVersion_str(NSSVersionMax),
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ NSSVersionMin = enabledNSSVersions.min;
+ NSSVersionMax = enabledNSSVersions.max;
+ }
}
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableSSL3 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
- }
+ if (NSSVersionMin > 0) {
+ /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
+ SSLVersionRange myNSSVersions;
+ myNSSVersions.min = NSSVersionMin;
+ myNSSVersions.max = NSSVersionMax;
+ restrict_SSLVersionRange(&myNSSVersions, enableSSL3, enableTLS1);
+ SSL_VersionRangeSet(pr_sock, &myNSSVersions);
+ if (sslStatus == SECSuccess) {
+ /* Set the restricted value to the cn=encryption entry */
+ } else {
+ slapd_SSL_error("SSL Initialization 2: "
+ "Failed to set SSL range: min: %s, max: %s\n",
+ getNSSVersion_str(myNSSVersions.min),
+ getNSSVersion_str(myNSSVersions.max));
+ }
+ } else {
+ /* deprecated code */
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableSSL3 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableTLS1 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableTLS1 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
}
freeConfigEntry( &e );