mrc0mmand / rpms / openldap

Forked from rpms/openldap 3 years ago
Clone

Blame SOURCES/openldap-nss-ciphersuite-handle-masks-correctly.patch

d198f9
fix: openldap ciphersuite parsing code handles masks incorrectly
d198f9
d198f9
Author: Matus Honek <mhonek@redhat.com>
d198f9
Original-Author: Martin Poole <mpoole@redhat.com>
d198f9
Resolves: #1231522
d198f9
Related: #1238322
d198f9
d198f9
diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
d198f9
--- a/libraries/libldap/tls_m.c
d198f9
+++ b/libraries/libldap/tls_m.c
d198f9
@@ -215,7 +215,6 @@ typedef struct {
d198f9
 /* cipher attributes  */
d198f9
 #define SSL_kRSA        0x00000001L
d198f9
 #define SSL_aRSA        0x00000002L
d198f9
-#define SSL_RSA         (SSL_kRSA|SSL_aRSA)
d198f9
 #define SSL_aDSA        0x00000004L
d198f9
 #define SSL_DSA         SSL_aDSA
d198f9
 #define SSL_eNULL       0x00000008L
a3e6a8
@@ -225,19 +224,27 @@ typedef struct {
d198f9
 #define SSL_RC2         0x00000080L
d198f9
 #define SSL_AES128      0x00000100L
d198f9
 #define SSL_AES256      0x00000200L
d198f9
-#define SSL_AES         (SSL_AES128|SSL_AES256)
d198f9
 #define SSL_MD5         0x00000400L
d198f9
 #define SSL_SHA1        0x00000800L
d198f9
 #define SSL_kEDH        0x00001000L
d198f9
 #define SSL_CAMELLIA128 0x00002000L
d198f9
 #define SSL_CAMELLIA256 0x00004000L
d198f9
-#define SSL_CAMELLIA    (SSL_CAMELLIA128|SSL_CAMELLIA256)
d198f9
 #define SSL_SEED        0x00008000L
d198f9
 #define SSL_kECDH       0x00010000L
d198f9
 #define SSL_kECDHE      0x00020000L
d198f9
 #define SSL_aECDSA      0x00040000L
d198f9
 #define SSL_SHA256	0x00080000L
d198f9
 #define SSL_SHA384	0x00100000L
d198f9
+#define SSL_kEECDH  0x00200000L
d198f9
+#define SSL_AESGCM  0x00400000L
d198f9
+#define SSL_AEAD    0x00800000L
a3e6a8
+#define SSL_CHACHA20POLY1305 0x02000000L
d198f9
+
d198f9
+/* cipher attributes non-unique - do not use for definitions */
d198f9
+#define SSL_RSA         0x00000001L
d198f9
+#define SSL_AES         0x00000002L
d198f9
+#define SSL_CAMELLIA    0x00000004L
d198f9
+#define SSL_ECDH        0x00000008L
d198f9
 
d198f9
 /* cipher strength */
d198f9
 #define SSL_NULL      0x00000001L
d198f9
@@ -247,6 +253,9 @@ typedef struct {
d198f9
 #define SSL_MEDIUM    0x00000010L
d198f9
 #define SSL_HIGH      0x00000020L
d198f9
 
d198f9
+/* cipher strengths non-unique - do not use for definitions */
d198f9
+#define SSL_EXPORT    0x00000001L
d198f9
+
d198f9
 #define SSL2  0x00000001L
d198f9
 #define SSL3  0x00000002L
d198f9
 /* OpenSSL treats SSL3 and TLSv1 the same */
d198f9
@@ -609,10 +618,12 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 		while ((*cipher) && (isspace(*cipher)))
d198f9
 			++cipher;
d198f9
 
d198f9
-		action = 1;
d198f9
 		switch(*cipher) {
d198f9
-		case '+': /* Add something */
d198f9
-			action = 1;
d198f9
+		case '+': /* Do nothig. NSS does not support ordering. */
d198f9
+			Debug( LDAP_DEBUG_ARGS,
d198f9
+			       "TLS: warning: parsing cipher string: ordering is not supported by NSS.\n",
d198f9
+			       0, 0, 0 );
d198f9
+			action = 2;
d198f9
 			cipher++;
d198f9
 			break;
d198f9
 		case '-': /* Subtract something */
d198f9
@@ -623,8 +634,8 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 			action = -1;
d198f9
 			cipher++;
d198f9
 			break;
d198f9
-		default:
d198f9
-			/* do nothing */
d198f9
+		default: /* Add something */
d198f9
+			action = 1;
d198f9
 			break;
d198f9
 		}
d198f9
 
95f81a
@@ -654,7 +665,10 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 			}
d198f9
 		} else {
d198f9
 			int mask = 0;
d198f9
+			int multi_mask = 0;
95f81a
+			int negative_mask = 0;
d198f9
 			int strength = 0;
d198f9
+			int multi_strength = 0;
d198f9
 			int protocol = 0;
d198f9
 			char *c;
d198f9
 
95f81a
@@ -665,16 +678,21 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 					*c++ = '\0';
d198f9
 				}
d198f9
 
d198f9
-				if (!strcmp(cipher, "RSA")) {
d198f9
-					mask |= SSL_RSA;
d198f9
+				if ((!strcmp(cipher, "RSA")) || (!strcmp(cipher, "kRSA"))) {
d198f9
+					mask |= SSL_kRSA;
95f81a
+				} else if (!strcmp(cipher, "aRSA")) {
95f81a
+					mask |= SSL_aRSA;
95f81a
+					negative_mask |= SSL_kECDH;
d198f9
 				} else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) {
d198f9
 					mask |= SSL_eNULL;
d198f9
 				} else if (!strcmp(cipher, "AES128")) {
d198f9
 					mask |= SSL_AES128;
d198f9
 				} else if (!strcmp(cipher, "AES256")) {
d198f9
 					mask |= SSL_AES256;
d198f9
+				} else if (!strcmp(cipher, "AESGCM")) {
d198f9
+					mask |= SSL_AESGCM;
d198f9
 				} else if (!strcmp(cipher, "AES")) {
d198f9
-					mask |= SSL_AES;
d198f9
+					multi_mask |= SSL_AES;
d198f9
 				} else if (!strcmp(cipher, "3DES")) {
d198f9
 					mask |= SSL_3DES;
d198f9
 				} else if (!strcmp(cipher, "DES")) {
a3e6a8
@@ -685,28 +705,45 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 					mask |= SSL_RC2;
d198f9
 				} else if (!strcmp(cipher, "MD5")) {
d198f9
 					mask |= SSL_MD5;
d198f9
-				} else if ((!strcmp(cipher, "SHA")) || (!strcmp(cipher, "SHA1"))) {
d198f9
-					mask |= SSL_SHA1;
d198f9
 				} else if (!strcmp(cipher, "SHA256")) {
d198f9
 					mask |= SSL_SHA256;
d198f9
+				} else if (!strcmp(cipher, "SHA384")) {
d198f9
+					mask |= SSL_SHA384;
d198f9
+				} else if ((!strcmp(cipher, "SHA")) || (!strcmp(cipher, "SHA1"))) {
d198f9
+					mask |= SSL_SHA1;
95f81a
-				} else if (!strcmp(cipher, "EDH")) {
95f81a
+				} else if ((!strcmp(cipher, "EDH")) || (!strcmp(cipher, "DH"))) {
d198f9
 					mask |= SSL_kEDH;
d198f9
-				} else if (!strcmp(cipher, "DSS")) {
d198f9
+				} else if ((!strcmp(cipher, "DSS")) || (!strcmp(cipher, "aDSS"))) {
d198f9
 					mask |= SSL_aDSA;
d198f9
 				} else if (!strcmp(cipher, "CAMELLIA128")) {
d198f9
 					mask |= SSL_CAMELLIA128;
d198f9
 				} else if (!strcmp(cipher, "CAMELLIA256")) {
d198f9
 					mask |= SSL_CAMELLIA256;
d198f9
 				} else if (!strcmp(cipher, "CAMELLIA")) {
d198f9
-					mask |= SSL_CAMELLIA;
d198f9
+					multi_mask |= SSL_CAMELLIA;
d198f9
 				} else if (!strcmp(cipher, "SEED")) {
d198f9
 					mask |= SSL_SEED;
d198f9
-				} else if (!strcmp(cipher, "ECDH")) {
d198f9
+				} else if (!strcmp(cipher, "kECDHe")) {
d198f9
+					mask |= SSL_kECDH|SSL_aECDSA;
d198f9
+				} else if (!strcmp(cipher, "kECDHr")) {
d198f9
+					mask |= SSL_kECDH|SSL_aRSA;
d198f9
+				} else if (!strcmp(cipher, "kECDH")) {
95f81a
+					mask |= SSL_kECDH;
d198f9
+				} else if (!strcmp(cipher, "aECDH")) {
d198f9
 					mask |= SSL_kECDH;
d198f9
+				} else if (!strcmp(cipher, "EECDH")) {
d198f9
+					mask |= SSL_kECDHE;
d198f9
+				} else if (!strcmp(cipher, "kEECDH")) {
d198f9
+					mask |= SSL_kECDHE;
d198f9
 				} else if (!strcmp(cipher, "ECDHE")) {
d198f9
 					mask |= SSL_kECDHE;
d198f9
-				} else if (!strcmp(cipher, "ECDSA")) {
d198f9
+				} else if (!strcmp(cipher, "ECDH")) {
d198f9
+					multi_mask |= SSL_ECDH;
d198f9
+				} else if ((!strcmp(cipher, "ECDSA")) || (!strcmp(cipher, "aECDSA"))) {
d198f9
 					mask |= SSL_aECDSA;
95f81a
+					negative_mask |= SSL_kECDH;
a3e6a8
+				} else if (!strcmp(cipher, "CHACHA20POLY1305")) {
a3e6a8
+					mask |= SSL_CHACHA20POLY1305;
d198f9
 				} else if (!strcmp(cipher, "SSLv2")) {
d198f9
 					protocol |= SSL2;
95f81a
 				} else if (!strcmp(cipher, "SSLv3")) {
d198f9
@@ -721,12 +756,12 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 					strength |= SSL_MEDIUM;
d198f9
 				} else if (!strcmp(cipher, "LOW")) {
d198f9
 					strength |= SSL_LOW;
d198f9
-				} else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
d198f9
-					strength |= SSL_EXPORT40|SSL_EXPORT56;
d198f9
 				} else if (!strcmp(cipher, "EXPORT40")) {
d198f9
 					strength |= SSL_EXPORT40;
d198f9
 				} else if (!strcmp(cipher, "EXPORT56")) {
d198f9
 					strength |= SSL_EXPORT56;
d198f9
+				} else if ((!strcmp(cipher, "EXPORT")) || (!strcmp(cipher, "EXP"))) {
d198f9
+					multi_strength |= SSL_EXPORT;
d198f9
 				}
d198f9
 
d198f9
 				if (c)
95f81a
@@ -734,23 +769,39 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum])
d198f9
 
d198f9
 			} /* while */
d198f9
 
d198f9
+			/* NSS does not support ordering */
d198f9
+			if (action == 2)
d198f9
+			  continue;
d198f9
+
d198f9
 			/* If we have a mask, apply it. If not then perhaps they provided
d198f9
 			 * a specific cipher to enable.
d198f9
+			 * if more than one mask is provided then AND logic applies (to match openssl)
d198f9
 			 */
d198f9
-			if (mask || strength || protocol) {
95f81a
+			if (mask || negative_mask || multi_mask || strength || multi_strength || protocol) {
d198f9
 				for (i=0; i
d198f9
-					if (((ciphers_def[i].attr & mask) ||
d198f9
-						 (ciphers_def[i].strength & strength) ||
d198f9
-						 (ciphers_def[i].version & protocol)) &&
d198f9
-						(cipher_list[i] != -1)) {
d198f9
-						/* Enable the NULL ciphers only if explicity
d198f9
-						 * requested */
d198f9
-						if (ciphers_def[i].attr & SSL_eNULL) {
d198f9
-							if (mask & SSL_eNULL)
d198f9
-								cipher_list[i] = action;
d198f9
-						} else
d198f9
-							cipher_list[i] = action;
d198f9
-					}
d198f9
+					if ( cipher_list[i] == -1 )
d198f9
+						continue;
d198f9
+					if ( mask != (ciphers_def[i].attr & mask) )
d198f9
+						continue;
d198f9
+					if ( strength != (ciphers_def[i].strength & strength) )
d198f9
+						continue;
d198f9
+					if ( protocol != (ciphers_def[i].version & protocol) )
d198f9
+						continue;
d198f9
+					if ((multi_mask & SSL_AES) &&
d198f9
+					    !(ciphers_def[i].attr & (SSL_AES128|SSL_AES256|SSL_AESGCM)))
d198f9
+						continue;
d198f9
+					if ((multi_mask & SSL_ECDH) &&
d198f9
+					    !(ciphers_def[i].attr & (SSL_kECDH|SSL_kECDHE)))
d198f9
+						continue;
d198f9
+					if ((multi_mask & SSL_CAMELLIA) &&
d198f9
+					    !(ciphers_def[i].attr & (SSL_CAMELLIA128|SSL_CAMELLIA256)))
d198f9
+						continue;
d198f9
+					if ((multi_strength & SSL_EXPORT) &&
d198f9
+					    !(ciphers_def[i].strength & (SSL_EXPORT40|SSL_EXPORT56)))
d198f9
+						continue;
95f81a
+					if ( negative_mask & ciphers_def[i].attr )
95f81a
+						continue;
d198f9
+					cipher_list[i] = action;
d198f9
 				}
d198f9
 			} else {
d198f9
 				for (i=0; i