From da1f7191999fe0c4c24d3fa9b6831dd1323fabf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=BA=C5=A1=20Hon=C4=9Bk?= Date: Thu, 26 Jan 2017 15:09:10 +0100 Subject: [PATCH] NSS: fix incorrect multi-keyword parsing and support new ones - add multi_mask, negative_mask, and multi_strength + some keywords may describe multiple cipher suite parameters at once - fix masks decision tree + all masks have to fit the cipher suite to include it - correct 'action' evaluation + plus sign means ordering (which NSS does not support) + no sign presence means adding implicitly - extend keywords for new future ciphers Backporting: #1372349 Resolves: #1243517 --- openldap-nss-cipher-attributes.patch | 64 +++++++++ openldap-nss-ciphers-parsing.patch | 205 +++++++++++++++++++++++++++ openldap.spec | 11 +- 3 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 openldap-nss-cipher-attributes.patch create mode 100644 openldap-nss-ciphers-parsing.patch diff --git a/openldap-nss-cipher-attributes.patch b/openldap-nss-cipher-attributes.patch new file mode 100644 index 0000000..e51f1ea --- /dev/null +++ b/openldap-nss-cipher-attributes.patch @@ -0,0 +1,64 @@ +Update MozNSS cipher attributes definitions + +Author: Matus Honek +PreviousAuthor: Jan Vcelak + +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 +@@ -210,27 +210,37 @@ typedef struct { + /* cipher attributes */ + #define SSL_kRSA 0x00000001L + #define SSL_aRSA 0x00000002L +-#define SSL_RSA (SSL_kRSA|SSL_aRSA) + #define SSL_aDSA 0x00000004L + #define SSL_DSA SSL_aDSA + #define SSL_eNULL 0x00000008L + #define SSL_DES 0x00000010L + #define SSL_3DES 0x00000020L + #define SSL_RC4 0x00000040L + #define SSL_RC2 0x00000080L + #define SSL_AES128 0x00000100L + #define SSL_AES256 0x00000200L +-#define SSL_AES (SSL_AES128|SSL_AES256) + #define SSL_MD5 0x00000400L + #define SSL_SHA1 0x00000800L + #define SSL_kEDH 0x00001000L + #define SSL_CAMELLIA128 0x00002000L + #define SSL_CAMELLIA256 0x00004000L +-#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + #define SSL_SEED 0x00008000L + #define SSL_kECDH 0x00010000L + #define SSL_kECDHE 0x00020000L + #define SSL_aECDSA 0x00040000L ++#define SSL_SHA256 0x00080000L ++#define SSL_SHA384 0x00100000L ++#define SSL_kEECDH 0x00200000L ++#define SSL_AESGCM 0x00400000L ++#define SSL_AEAD 0x00800000L ++#define SSL_aPSK 0x01000000L ++#define SSL_CHACHA20POLY1305 0x02000000L ++ ++/* cipher attributes non-unique - do not use for definitions */ ++#define SSL_RSA 0x00000001L ++#define SSL_AES 0x00000002L ++#define SSL_CAMELLIA 0x00000004L ++#define SSL_ECDH 0x00000008L + + /* cipher strength */ + #define SSL_NULL 0x00000001L +@@ -237,10 +251,14 @@ typedef struct { + #define SSL_MEDIUM 0x00000010L + #define SSL_HIGH 0x00000020L + ++/* cipher strengths non-unique - do not use for definitions */ ++#define SSL_EXPORT 0x00000001L ++ + #define SSL2 0x00000001L + #define SSL3 0x00000002L + /* OpenSSL treats SSL3 and TLSv1 the same */ + #define TLS1 SSL3 ++#define TLS1_2 0x00000004L + + /* Cipher translation */ + static cipher_properties ciphers_def[] = { diff --git a/openldap-nss-ciphers-parsing.patch b/openldap-nss-ciphers-parsing.patch new file mode 100644 index 0000000..8b7c4e5 --- /dev/null +++ b/openldap-nss-ciphers-parsing.patch @@ -0,0 +1,205 @@ +Update MozNSS OpenSSL-like parsing code + +Author: Matus Honek +PreviousAuthor: Jan Vcelak + +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 +@@ -597,10 +597,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 */ +@@ -611,8 +613,8 @@ nss_parse_ciphers(const char *cipherstr, int cipher_list[ciphernum]) + action = -1; + cipher++; + break; +- default: +- /* do nothing */ ++ default: /* Add something */ ++ action = 1; + break; + } + +@@ -646,7 +648,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; + +@@ -657,16 +662,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")) { +@@ -673,44 +687,67 @@ 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")) { +- mask |= SSL_kEDH; +- } else if (!strcmp(cipher, "DSS")) { +- mask |= SSL_aDSA; ++ } 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")) { +- mask |= SSL_CAMELLIA; ++ multi_mask |= SSL_CAMELLIA; + } else if (!strcmp(cipher, "SEED")) { + mask |= SSL_SEED; +- } else if (!strcmp(cipher, "ECDH")) { +- mask |= SSL_kECDH; +- } else if (!strcmp(cipher, "ECDHE")) { +- mask |= SSL_kECDHE; +- } else if (!strcmp(cipher, "ECDSA")) { +- mask |= SSL_aECDSA; ++ } 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, "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) +@@ -700,23 +751,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 - 2.4.44-5 +- NSS: fix: incorrect multi-keyword parsing and support new ones (#1243517) + * Mon Jan 23 2017 Matus Honek - 2.4.44-4 - fix previous commit (#1375432)