spichugi / rpms / openldap

Forked from rpms/openldap 3 years ago
Clone
Blob Blame History Raw
Update MozNSS OpenSSL-like parsing code

Author: Matus Honek <mhonek@redhat.com>
PreviousAuthor: Jan Vcelak <jvcelak@redhat.com>

diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
--- a/libraries/libldap/tls_m.c
+++ b/libraries/libldap/tls_m.c
@@ -617,10 +617,12 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 		while ((*cipher) && (isspace(*cipher)))
 			++cipher;
 
-		action = 1;
 		switch(*cipher) {
-		case '+': /* Add something */
-			action = 1;
+		case '+': /* Do nothig. NSS does not support ordering. */
+			Debug( LDAP_DEBUG_ARGS,
+			       "TLS: warning: parsing cipher string: ordering is not supported by NSS.\n",
+			       0, 0, 0 );
+			action = 2;
 			cipher++;
 			break;
 		case '-': /* Subtract something */
@@ -631,8 +633,8 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 			action = -1;
 			cipher++;
 			break;
-		default:
-			/* do nothing */
+		default: /* Add something */
+			action = 1;
 			break;
 		}
 
@@ -666,7 +668,10 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 			}
 		} else {
 			int mask = 0;
+			int multi_mask = 0;
+			int negative_mask = 0;
 			int strength = 0;
+			int multi_strength = 0;
 			int protocol = 0;
 			char *c;
 
@@ -677,12 +682,21 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 					*c++ = '\0';
 				}
 
-				if (!strcmp(cipher, "RSA")) {
-					mask |= SSL_RSA;
+				if ((!strcmp(cipher, "RSA")) || (!strcmp(cipher, "kRSA"))) {
+					mask |= SSL_kRSA;
+				} else if (!strcmp(cipher, "aRSA")) {
+					mask |= SSL_aRSA;
+					negative_mask |= SSL_kECDH;
 				} else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) {
 					mask |= SSL_eNULL;
+				} else if (!strcmp(cipher, "AES128")) {
+					mask |= SSL_AES128;
+				} else if (!strcmp(cipher, "AES256")) {
+					mask |= SSL_AES256;
+				} else if (!strcmp(cipher, "AESGCM")) {
+					mask |= SSL_AESGCM;
 				} else if (!strcmp(cipher, "AES")) {
-					mask |= SSL_AES;
+					multi_mask |= SSL_AES;
 				} else if (!strcmp(cipher, "3DES")) {
 					mask |= SSL_3DES;
 				} else if (!strcmp(cipher, "DES")) {
@@ -693,26 +707,69 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 					mask |= SSL_RC2;
 				} else if (!strcmp(cipher, "MD5")) {
 					mask |= SSL_MD5;
+				} else if (!strcmp(cipher, "SHA256")) {
+					mask |= SSL_SHA256;
+				} else if (!strcmp(cipher, "SHA384")) {
+					mask |= SSL_SHA384;
 				} else if ((!strcmp(cipher, "SHA")) || (!strcmp(cipher, "SHA1"))) {
 					mask |= SSL_SHA1;
+				} else if ((!strcmp(cipher, "EDH")) || (!strcmp(cipher, "DH"))) {
+					mask |= SSL_kEDH;
+				} else if ((!strcmp(cipher, "DSS")) || (!strcmp(cipher, "aDSS"))) {
+					mask |= SSL_aDSA;
+				} else if (!strcmp(cipher, "CAMELLIA128")) {
+					mask |= SSL_CAMELLIA128;
+				} else if (!strcmp(cipher, "CAMELLIA256")) {
+					mask |= SSL_CAMELLIA256;
+				} else if (!strcmp(cipher, "CAMELLIA")) {
+					multi_mask |= SSL_CAMELLIA;
+				} else if (!strcmp(cipher, "SEED")) {
+					mask |= SSL_SEED;
+				} else if (!strcmp(cipher, "kECDHe")) {
+					mask |= SSL_kECDH|SSL_aECDSA;
+				} else if (!strcmp(cipher, "kECDHr")) {
+					mask |= SSL_kECDH|SSL_aRSA;
+				} else if (!strcmp(cipher, "kECDH")) {
+					mask |= SSL_kECDH;
+				} else if (!strcmp(cipher, "aECDH")) {
+					mask |= SSL_kECDH;
+				} else if (!strcmp(cipher, "EECDH")) {
+					mask |= SSL_kECDHE;
+				} else if (!strcmp(cipher, "kEECDH")) {
+					mask |= SSL_kECDHE;
+				} else if (!strcmp(cipher, "ECDHE")) {
+					mask |= SSL_kECDHE;
+				} else if (!strcmp(cipher, "ECDH")) {
+					multi_mask |= SSL_ECDH;
+				} else if ((!strcmp(cipher, "ECDSA")) || (!strcmp(cipher, "aECDSA"))) {
+					mask |= SSL_aECDSA;
+					negative_mask |= SSL_kECDH;
+				} else if (!strcmp(cipher, "PSK")) {
+					mask |= SSL_aPSK;
+				} else if (!strcmp(cipher, "CHACHA20POLY1305")) {
+					mask |= SSL_CHACHA20POLY1305;
 				} else if (!strcmp(cipher, "SSLv2")) {
 					protocol |= SSL2;
 				} else if (!strcmp(cipher, "SSLv3")) {
 					protocol |= SSL3;
 				} else if (!strcmp(cipher, "TLSv1")) {
 					protocol |= TLS1;
+				} else if (!strcmp(cipher, "TLSv1.2")) {
+					protocol |= TLS1_2;
+				} else if (!strcmp(cipher, "TLSv1.3")) {
+					protocol |= TLS1_3;
 				} else if (!strcmp(cipher, "HIGH")) {
 					strength |= SSL_HIGH;
 				} else if (!strcmp(cipher, "MEDIUM")) {
 					strength |= SSL_MEDIUM;
 				} else if (!strcmp(cipher, "LOW")) {
 					strength |= SSL_LOW;
-				} else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
-					strength |= SSL_EXPORT40|SSL_EXPORT56;
 				} else if (!strcmp(cipher, "EXPORT40")) {
 					strength |= SSL_EXPORT40;
 				} else if (!strcmp(cipher, "EXPORT56")) {
 					strength |= SSL_EXPORT56;
+				} else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
+					multi_strength |= SSL_EXPORT;
 				}
 
 				if (c)
@@ -720,23 +775,39 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
 
 			} /* while */
 
+			/* NSS does not support ordering */
+			if (action == 2)
+			  continue;
+
 			/* If we have a mask, apply it. If not then perhaps they provided
 			 * a specific cipher to enable.
+			 * if more than one mask is provided then AND logic applies (to match openssl)
 			 */
-			if (mask || strength || protocol) {
+			if (mask || negative_mask || multi_mask || strength || multi_strength || protocol) {
 				for (i=0; i<ciphernum; i++) {
-					if (((ciphers_def[i].attr & mask) ||
-						 (ciphers_def[i].strength & strength) ||
-						 (ciphers_def[i].version & protocol)) &&
-						(cipher_list[i] != -1)) {
-						/* Enable the NULL ciphers only if explicity
-						 * requested */
-						if (ciphers_def[i].attr & SSL_eNULL) {
-							if (mask & SSL_eNULL)
-								cipher_list[i] = action;
-						} else
-							cipher_list[i] = action;
-					}
+					if ( cipher_list[i] == -1 )
+						continue;
+					if ( mask != (ciphers_def[i].attr & mask) )
+						continue;
+					if ( strength != (ciphers_def[i].strength & strength) )
+						continue;
+					if ( protocol != (ciphers_def[i].version & protocol) )
+						continue;
+					if ((multi_mask & SSL_AES) &&
+					    !(ciphers_def[i].attr & (SSL_AES128|SSL_AES256|SSL_AESGCM)))
+						continue;
+					if ((multi_mask & SSL_ECDH) &&
+					    !(ciphers_def[i].attr & (SSL_kECDH|SSL_kECDHE)))
+						continue;
+					if ((multi_mask & SSL_CAMELLIA) &&
+					    !(ciphers_def[i].attr & (SSL_CAMELLIA128|SSL_CAMELLIA256)))
+						continue;
+					if ((multi_strength & SSL_EXPORT) &&
+					    !(ciphers_def[i].strength & (SSL_EXPORT40|SSL_EXPORT56)))
+						continue;
+					if ( negative_mask & ciphers_def[i].attr )
+						continue;
+					cipher_list[i] = action;
 				}
 			} else {
 				for (i=0; i<ciphernum; i++) {