diff --git a/.gitignore b/.gitignore index 5d073c3..b764056 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/mod_nss-1.0.11.tar.gz +SOURCES/mod_nss-1.0.14.tar.gz diff --git a/.mod_nss.metadata b/.mod_nss.metadata index f5f9120..9e97382 100644 --- a/.mod_nss.metadata +++ b/.mod_nss.metadata @@ -1 +1 @@ -2ab3b3a684fffe4ed86b6950bc10896dcb48d229 SOURCES/mod_nss-1.0.11.tar.gz +a439ff97312a3b88dc86ad779134a0e4f5d492f5 SOURCES/mod_nss-1.0.14.tar.gz diff --git a/SOURCES/mod_nss-brewtest.patch b/SOURCES/mod_nss-brewtest.patch new file mode 100644 index 0000000..0764aa9 --- /dev/null +++ b/SOURCES/mod_nss-brewtest.patch @@ -0,0 +1,83 @@ +From 9736af2af69bd7fc924bb30a4849f55bd6d497cf Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 23 May 2016 18:34:36 -0400 +Subject: [PATCH] Disable SNI and proxy tests, AES128 cipher test + +The SNI tests rely on a tweaked /etc/hosts that points multiple +hostnames to one. + +The proxy test requires Internet access + +The python client isn't returning the re-negotiated cipher +which causes the AES128 to report a failure. Drop the test. +--- + test/suite1.tmpl | 6 ------ + test/test.py | 28 ---------------------------- + 2 files changed, 34 deletions(-) + +diff --git a/test/suite1.tmpl b/test/suite1.tmpl +index 2c09a89..291e173 100644 +--- a/test/suite1.tmpl ++++ b/test/suite1.tmpl +@@ -45,12 +45,6 @@ CoreDumpDirectory $SERVER_ROOT + NSSCipherSuite RC4-SHA + + +- +- # In openssl equivalent of AES:-ECDH:-ADH:-PSK:-DH +- # In NSS equivalent of AES:-ECDH +- NSSCipherSuite AES+RSA +- +- + + NSSCipherSuite +dhe_rsa_aes_128_sha + +diff --git a/test/test.py b/test/test.py +index 866e388..4fdb59a 100644 +--- a/test/test.py ++++ b/test/test.py +@@ -60,13 +60,6 @@ class test_suite1(Declarative): + ), + + dict( +- desc='SSL AES128-SHA cipher check', +- request=('/index.html', {}), +- expected=200, +- cipher='AES128-SHA', +- ), +- +- dict( + desc='Default protocol check', + request=('/', {}), + expected=200, +@@ -271,27 +264,6 @@ class test_suite1(Declarative): + expected=requests.exceptions.SSLError(), + ), + +- dict( +- desc='Basic reverse proxy request', +- request=('/google/', {}), +- expected=200, +- ), +- +- dict( +- desc='SNI request when SNI is disabled', +- request=('/index.html', +- {'host': 'www1.example.com', 'port': 8000} +- ), +- expected=requests.exceptions.SSLError(), +- expected_str='doesn\'t match', +- ), +- +- dict( +- desc='Reverse proxy request when SNI is disabled', +- request=('/proxy/index.html', {}), +- expected=400, +- ), +- + ] + + if ENABLE_SERVER_DHE: +-- +2.5.5 + diff --git a/SOURCES/mod_nss-certdb-permissions.patch b/SOURCES/mod_nss-certdb-permissions.patch new file mode 100644 index 0000000..806fd4c --- /dev/null +++ b/SOURCES/mod_nss-certdb-permissions.patch @@ -0,0 +1,89 @@ +From 7c08aa9b0aa10f4d13e7317c9a7353399188dba4 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Wed, 21 Sep 2016 13:45:25 -0400 +Subject: [PATCH] Enhance checking on NSS database permissions to include + directory + +Previously I was checking the NSS database files for readability +but not the database directory itself. Since it starts as root if +the directory permissions didn't allow read by the Apache user but +the files themselves did then startup would continue but blow +up due to the inability to chdir into the directory. + +BZ #1312583 +--- + nss_engine_init.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +diff --git a/nss_engine_init.c b/nss_engine_init.c +index cd71989..03ac644 100644 +--- a/nss_engine_init.c ++++ b/nss_engine_init.c +@@ -51,8 +51,7 @@ static char *version_components[] = { + NULL + }; + +-/* See if a uid or gid can read a file at a given path. Ignore world +- * read permissions. ++/* See if a uid or gid can read a file at a given path. + * + * Return 0 on failure or file doesn't exist + * Return 1 on success +@@ -65,14 +64,14 @@ static int check_path(uid_t uid, gid_t gid, char *filepath, apr_pool_t *p) + if ((rv = apr_stat(&finfo, filepath, APR_FINFO_PROT | APR_FINFO_OWNER, + p)) == APR_SUCCESS) { + if (((uid == finfo.user) && +- ((finfo.protection & APR_FPROT_UREAD))) || ++ (finfo.protection & APR_FPROT_UREAD)) || + ((gid == finfo.group) && +- ((finfo.protection & APR_FPROT_GREAD))) ++ (finfo.protection & APR_FPROT_GREAD)) || ++ (finfo.protection & APR_FPROT_WREAD) + ) + { + return 1; + } +- return 0; + } + return 0; + } +@@ -158,6 +157,11 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) + } + } + ++ if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) ++ dbdir = (char *)mc->pCertificateDatabase + 4; ++ else ++ dbdir = (char *)mc->pCertificateDatabase; ++ + /* Assuming everything is ok so far, check the cert database permissions + * for the server user before Apache starts forking. We die now or + * get stuck in an endless loop not able to read the NSS database. +@@ -172,6 +176,13 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) + "Checking permissions for user %s: uid %d gid %d", + mc->user, pw->pw_uid, pw->pw_gid); + ++ if (!(check_path(pw->pw_uid, pw->pw_gid, dbdir, p))) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, ++ "Server user %s lacks read access to NSS " ++ "database directory %s.", mc->user, dbdir); ++ nss_die(); ++ } ++ + if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) { + apr_snprintf(filepath, 1024, "%s/key4.db", + mc->pCertificateDatabase+4); +@@ -231,10 +242,6 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) + else + return; + } +- if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) +- dbdir = (char *)mc->pCertificateDatabase + 4; +- else +- dbdir = (char *)mc->pCertificateDatabase; + if (chdir(dbdir) != 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, + "Unable to change directory to %s", mc->pCertificateDatabase); +-- +2.5.5 + diff --git a/SOURCES/mod_nss-cipher-logical_and.patch b/SOURCES/mod_nss-cipher-logical_and.patch deleted file mode 100644 index 643d5d4..0000000 --- a/SOURCES/mod_nss-cipher-logical_and.patch +++ /dev/null @@ -1,875 +0,0 @@ -From 63eb1f4c6ef8c1bb68afbfc5fba8762d50c1a0a8 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Wed, 17 Jun 2015 11:12:40 -0400 -Subject: [PATCH] Fix logical AND support in OpenSSL cipher compatibility - -The + operator didn't perform properly at all. It is supposed -to be used either for logical AND to combine two cipher suites -or to move ciphers to the end of the list. Given that NSS -doesn't support cipher ordering + is a no-op in this case. - -Also add in a slew of missing aliases: kRSA, aRSA, EDH, -ECDH, kECDHe, kECDHr, kEECDH, aECDH, aNULL, AESGCM, AES128, -AES256, CAMELLIA, CAMELLIA128, CAMELLIA256. - -Fix the definition of TLSv1.2. - -Define some ciphers as unimplemented in NSS. - -Renumber the mask/protocol/strength values to ensure uniqueness. - -Replace the existing cipher test to one that compares the output -of the NSS-generated cipher string with the openssl generated -string. There are a lot of restrictions on the openssl string -since so much isn't either implemented or needed for mod_nss. - -Add a new openssl-compatible cipher request test to the server -tests. ---- - nss_engine_cipher.c | 196 +++++++++++++++++++++++++++++++------- - nss_engine_cipher.h | 61 ++++++------ - test/createinstance.sh | 1 + - test/suite1.tmpl | 6 ++ - test/test.py | 6 ++ - test/test_cipher.py | 254 ++++++++++++++++++++++++++++++++----------------- - test_cipher.c | 32 +++++-- - 7 files changed, 401 insertions(+), 155 deletions(-) - -diff --git a/nss_engine_cipher.c b/nss_engine_cipher.c -index 9110d57..37ef338 100644 ---- a/nss_engine_cipher.c -+++ b/nss_engine_cipher.c -@@ -29,10 +29,11 @@ cipher_properties ciphers_def[ciphernum] = - {"rsa_rc4_128_md5", TLS_RSA_WITH_RC4_128_MD5, "RC4-MD5", SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5, SSLV3, SSL_MEDIUM, 128, 128}, - {"rsa_rc4_128_sha", TLS_RSA_WITH_RC4_128_SHA, "RC4-SHA", SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA1, SSLV3, SSL_MEDIUM, 128, 128}, - {"rsa_rc2_40_md5", TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "EXP-RC2-CBC-MD5", SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5, SSLV3, SSL_EXPORT40, 40, 128}, -+ /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA not implemented 0x0008 */ - {"rsa_des_sha", TLS_RSA_WITH_DES_CBC_SHA, "DES-CBC-SHA", SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1, SSLV3, SSL_LOW, 56, 56}, -- {"rsa_3des_sha", TLS_RSA_WITH_3DES_EDE_CBC_SHA, "DES-CBC3-SHA", SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA1, SSLV3, SSL_HIGH, 112, 168}, -+ {"rsa_3des_sha", TLS_RSA_WITH_3DES_EDE_CBC_SHA, "DES-CBC3-SHA", SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA1, SSLV3, SSL_HIGH, 168, 168}, - {"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, "AES128-SHA", SSL_kRSA|SSL_aRSA|SSL_AES128|SSL_SHA1, TLSV1, SSL_HIGH, 128, 128}, -- {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, "AES256-SHA256", SSL_kRSA|SSL_aRSA|SSL_AES256|SSL_SHA1, TLSV1, SSL_HIGH, 256, 256}, -+ {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, "AES256-SHA", SSL_kRSA|SSL_aRSA|SSL_AES256|SSL_SHA1, TLSV1, SSL_HIGH, 256, 256}, - {"null_sha_256", TLS_RSA_WITH_NULL_SHA256, "NULL-SHA256", SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_SHA256, TLSV1_2, SSL_STRONG_NONE, 0, 0}, - {"aes_128_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256, "AES128-SHA256", SSL_kRSA|SSL_aRSA|SSL_AES128|SSL_SHA256, TLSV1_2, SSL_HIGH, 128, 128}, - {"aes_256_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256, "AES256-SHA256", SSL_kRSA|SSL_aRSA|SSL_AES256|SSL_SHA256, TLSV1_2, SSL_HIGH, 256, 256}, -@@ -73,9 +74,25 @@ cipher_properties ciphers_def[ciphernum] = - {"ecdhe_rsa_aes_128_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "ECDHE-RSA-AES128-SHA256", SSL_kEECDH|SSL_aRSA|SSL_AES128|SSL_SHA256, TLSV1_2, SSL_HIGH, 128, 128}, - {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "ECDHE-ECDSA-AES128-GCM-SHA256", SSL_kEECDH|SSL_aECDSA|SSL_AES128GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 128, 128}, - {"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "ECDHE-RSA-AES128-GCM-SHA256", SSL_kEECDH|SSL_aRSA|SSL_AES128GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 128, 128}, -+ /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 is not implemented */ -+ /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 is not implemented */ -+ /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 is not implemented */ -+ /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 is not implemented */ - #endif - }; - -+ -+/* Some ciphers are optionally enabled in OpenSSL. For safety sake assume -+ * they are not available. -+ */ -+static int skip_ciphers = 4; -+static int ciphers_not_in_openssl[] = { -+ SSL_RSA_FIPS_WITH_DES_CBC_SHA, -+ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, -+ TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, -+ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, -+}; -+ - static int parse_nss_ciphers(server_rec *s, char *ciphers, PRBool cipher_list[ciphernum]); - static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_list[ciphernum]); - -@@ -107,19 +124,48 @@ int nss_parse_ciphers(server_rec *s, char *ciphers, PRBool cipher_list[ciphernum - rv = parse_nss_ciphers(s, ciphers, cipher_list); - } else { - rv = parse_openssl_ciphers(s, ciphers, cipher_list); -- if (0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2)) { -+ if (rv == 0 && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2)) { - rv = parse_nss_ciphers(s, ciphers, cipher_list); - } - } -+ if (0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2)) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, -+ "no cipher match"); -+ } - - return rv; - } - - -+/* Given a set of ciphers perform a given action on the indexed value. -+ * -+ * This is needed because the + action doesn't do anything in the NSS -+ * context. In OpenSSL it will re-order the cipher list. -+ */ -+static int set_cipher_value(PRBool cipher_list[ciphernum], int index, int action) -+{ -+ int i; -+ -+ for (i = 0; i < skip_ciphers; i++) { -+ if (ciphers_def[index].num == ciphers_not_in_openssl[i]) { -+ cipher_list[index] = -1; -+ return; -+ } -+ } -+ -+ if (cipher_list[index] == -1) /* cipher is disabled */ -+ return; -+ else -+ cipher_list[index] = action; -+} -+ -+ - static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_list[ciphernum]) - { - char * cipher; - int i, action; -+ PRBool merge = PR_FALSE; -+ PRBool found = PR_FALSE; - - cipher = ciphers; - while (ciphers && (strlen(ciphers))) -@@ -127,12 +173,12 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - while ((*cipher) && (isspace(*cipher))) - ++cipher; - -- action = 1; -+ action = 1; /* default to enable */ - switch(*cipher) - { - case '+': /* Add something */ -- action = 1; -- cipher++; -+ /* Cipher ordering is not supported in NSS */ -+ return 0; - break; - case '-': /* Subtract something */ - action = 0; -@@ -149,34 +195,58 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - - if ((ciphers = strchr(cipher, ':'))) { - *ciphers++ = '\0'; -+ merge = PR_FALSE; -+ found = PR_FALSE; - } - - if (!strcmp(cipher, "ALL")) { -+ found = PR_TRUE; - for (i=0; i - -+ -+ # In openssl equivalent of AES:-ECDH:-ADH:-PSK:-DH -+ # In NSS equivalent of AES:-ECDH -+ NSSCipherSuite AES+RSA -+ -+ - - NSSOptions +StdEnvVars +CompatEnvVars +ExportCertData - NSSVerifyClient require -diff --git a/test/test.py b/test/test.py -index ee8d95b..23e093c 100644 ---- a/test/test.py -+++ b/test/test.py -@@ -69,6 +69,12 @@ class test_suite1(Declarative): - ), - - dict( -+ desc='server-side OpenSSL-style AES cipher check', -+ request=('/openssl_aes_cipher/', {'ciphers': 'AES128-SHA'}), -+ expected=200, -+ ), -+ -+ dict( - desc='Basic client auth, no certificate', - request=('/acl/aclS01.html', {}), - expected=requests.exceptions.SSLError(), -diff --git a/test/test_cipher.py b/test/test_cipher.py -index 55989bd..a91f411 100644 ---- a/test/test_cipher.py -+++ b/test/test_cipher.py -@@ -10,9 +10,50 @@ WITH_ECC=47 - cwd = os.getcwd() - srcdir = os.path.dirname(cwd) - exe = "%s/test_cipher" % srcdir -+openssl = "/usr/bin/openssl" - - ciphernum = 0 - -+CIPHERS_NOT_IN_NSS = ['ECDH-RSA-AES128-SHA256', -+ 'ECDH-ECDSA-AES128-GCM-SHA256', -+ 'ECDH-ECDSA-AES128-SHA256', -+ 'ECDH-RSA-AES128-GCM-SHA256', -+ 'EXP-DES-CBC-SHA', -+] -+ -+def assert_equal_openssl(nss_ciphers, ossl_ciphers): -+ (nss, err, rc) = run([exe, "--o", nss_ciphers]) -+ assert rc == 0 -+ (ossl, err, rc) = run([openssl, "ciphers", ossl_ciphers]) -+ assert rc == 0 -+ -+ nss_list = nss.strip().split(':') -+ nss_list.sort() -+ -+ ossl_list = ossl.strip().split(':') -+ ossl_list = list(set(ossl_list)) -+ ossl_list.sort() -+ -+ # NSS doesn't support the SHA-384 ciphers, remove them from the OpenSSL -+ # output. -+ t = list() -+ for o in ossl_list: -+ if 'SHA384' in o: -+ continue -+ if o in CIPHERS_NOT_IN_NSS: -+ continue -+ t.append(o) -+ ossl_list = t -+ -+ if len(nss_list) > len(ossl_list): -+ diff = set(nss_list) - set(ossl_list) -+ elif len(ossl_list) > len(nss_list): -+ diff = set(ossl_list) - set(nss_list) -+ else: -+ diff = '' -+ -+ assert nss_list == ossl_list, '%r != %r. Difference %r' % (':'.join(nss_list), ':'.join(ossl_list), diff) -+ - class test_ciphers(object): - @classmethod - def setUpClass(cls): -@@ -20,131 +61,172 @@ class test_ciphers(object): - assert rc == 0 - cls.ciphernum = int(out) - -+ def test_RSA(self): -+ assert_equal_openssl("RSA", "RSA:-SSLv2:-SEED:-IDEA") -+ -+ def test_kRSA(self): -+ assert_equal_openssl("kRSA", "kRSA:-SSLv2:-SEED:-IDEA") -+ -+ def test_aRSA(self): -+ assert_equal_openssl("aRSA", "aRSA:-SSLv2:-SEED:-IDEA:-DH") -+ -+ def test_EDH(self): -+ # No DH ciphers supported yet -+ (out, err, rc) = run([exe, "EDH"]) -+ assert rc == 1 -+ - def test_RC4(self): -- (out, err, rc) = run([exe, "RC4"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc4_56_sha') -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc4_56_sha, ecdh_ecdsa_rc4_128_sha, ecdhe_ecdsa_rc4_128_sha, ecdh_rsa_128_sha, ecdhe_rsa_rc4_128_sha, ecdh_anon_rc4_128sha') -+ assert_equal_openssl("RC4", "RC4:-KRB5:-PSK:-ADH") -+ -+ def test_RC2(self): -+ assert_equal_openssl("RC2", "RC2:-SSLv2:-KRB5") - - def test_AES(self): -- (out, err, rc) = run([exe, "AES"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_aes_128_sha, rsa_aes_256_sha, aes_128_sha_256, aes_256_sha_256, rsa_aes_128_gcm_sha_256') -- else: -- assert_equal(out, 'rsa_aes_128_sha, rsa_aes_256_sha, aes_128_sha_256, aes_256_sha_256, rsa_aes_128_gcm_sha_256, ecdh_ecdsa_rc4_128_sha, ecdh_ecdsa_3des_sha, ecdh_ecdsa_aes_128_sha, ecdh_ecdsa_aes_256_sha, ecdhe_ecdsa_rc4_128_sha, ecdhe_ecdsa_3des_sha, ecdhe_ecdsa_aes_128_sha, ecdhe_ecdsa_aes_256_sha, ecdh_rsa_128_sha, ecdh_rsa_3des_sha, ecdh_rsa_aes_128_sha, ecdh_rsa_aes_256_sha, ecdhe_rsa_aes_128_sha, ecdhe_rsa_aes_256_sha, ecdh_anon_aes_128_sha, ecdh_anon_aes_256_sha, ecdhe_ecdsa_aes_128_sha_256, ecdhe_rsa_aes_128_sha_256, ecdhe_ecdsa_aes_128_gcm_sha_256, ecdhe_rsa_aes_128_gcm_sha_256') -+ assert_equal_openssl("AES", "AES:-PSK:-ADH:-DSS:-DH") - -+ def test_AESGCM(self): -+ assert_equal_openssl("AESGCM", "AESGCM:-PSK:-ADH:-DSS:-DH") -+ -+ def test_AES128(self): -+ assert_equal_openssl("AES128", "AES128:-PSK:-ADH:-DSS:-DH") -+ -+ def test_AES256(self): -+ assert_equal_openssl("AES256", "AES256:-PSK:-ADH:-DSS:-DH") -+ -+ def test_CAMELLIA(self): -+ assert_equal_openssl("CAMELLIA", "CAMELLIA:-DH") -+ -+ def test_CAMELLIA128(self): -+ assert_equal_openssl("CAMELLIA128", "CAMELLIA128:-DH") -+ -+ def test_CAMELLIA256(self): -+ assert_equal_openssl("CAMELLIA256", "CAMELLIA256:-DH") -+ -+ def test_3DES(self): -+ assert_equal_openssl("3DES", "3DES:-SSLv2:-PSK:-KRB5:-DH") -+ -+ def test_DES(self): -+ assert_equal_openssl("DES", "DES:-SSLv2:-KRB5:-DH") - - def test_ALL(self): -- (out, err, rc) = run([exe, "ALL"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, aes_128_sha_256, aes_256_sha_256, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, rsa_aes_128_gcm_sha_256' -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, aes_128_sha_256, aes_256_sha_256, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, rsa_aes_128_gcm_sha_256, fips_3des_sha, fips_des_sha, ecdh_ecdsa_rc4_128_sha, ecdh_ecdsa_3des_sha, ecdh_ecdsa_aes_128_sha, ecdh_ecdsa_aes_256_sha, ecdhe_ecdsa_rc4_128_sha, ecdhe_ecdsa_3des_sha, ecdhe_ecdsa_aes_128_sha, ecdhe_ecdsa_aes_256_sha, ecdh_rsa_128_sha, ecdh_rsa_3des_sha, ecdh_rsa_aes_128_sha, ecdh_rsa_aes_256_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdhe_rsa_aes_128_sha, ecdhe_rsa_aes_256_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha, ecdh_anon_aes_128_sha, ecdh_anon_aes_256_sha, ecdhe_ecdsa_aes_128_sha_256, ecdhe_rsa_aes_128_sha_256, ecdhe_ecdsa_aes_128_gcm_sha_256, ecdhe_rsa_aes_128_gcm_sha_256') -+ assert_equal_openssl("ALL", "ALL:-SSLv2:-KRB5:-ADH:-DH:-DSS:-PSK:-SEED:-IDEA") - - def test_ALL_no_AES(self): -- (out, err, rc) = run([exe, "ALL:-AES"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha') -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha') -+ assert_equal_openssl("ALL:-AES", "ALL:-AES:-SSLv2:-KRB5:-ADH:-DH:-DSS:-PSK:-SEED:-IDEA") -+ -+ def test_COMPLEMENTOFALL(self): -+ assert_equal_openssl("COMPLEMENTOFALL", "COMPLEMENTOFALL") -+ -+ # skipping DEFAULT as we use the NSS defaults -+ # skipping COMPLEMENTOFDEFAULT as these are all ADH ciphers - - def test_SSLv3(self): -- (out, err, rc) = run([exe, "SSLv3"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha') -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha, ecdh_ecdsa_rc4_128_sha, ecdh_ecdsa_3des_sha, ecdh_ecdsa_aes_128_sha, ecdh_ecdsa_aes_256_sha, ecdhe_ecdsa_rc4_128_sha, ecdhe_ecdsa_3des_sha, ecdhe_ecdsa_aes_128_sha, ecdhe_ecdsa_aes_256_sha, ecdh_rsa_128_sha, ecdh_rsa_3des_sha, ecdh_rsa_aes_128_sha, ecdh_rsa_aes_256_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdhe_rsa_aes_128_sha, ecdhe_rsa_aes_256_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha, ecdh_anon_aes_128_sha, ecdh_anon_aes_256_sha') -+ assert_equal_openssl("SSLv3", "SSLv3:-KRB5:-PSK:-ADH:-EDH:-SEED:-IDEA") - - def test_SSLv3_equals_TLSv1(self): -- (out, err, rc) = run([exe, "SSLv3"]) -- (out2, err2, rc2) = run([exe, "TLSv1"]) -+ (nss, err, rc) = run([exe, "--o", "SSLv3"]) -+ (nss2, err, rc2) = run([exe, "--o", "TLSv1"]) - assert rc == 0 - assert rc2 == 0 -- assert_equal(out, out2) -+ assert_equal(nss, nss2) - - def test_TLSv12(self): -- if self.ciphernum < WITH_ECC: -- raise nose.SkipTest('ECC disabled') -- (out, err, rc) = run([exe, "TLSv12"]) -- assert rc == 0 -- assert_equal(out, 'aes_128_sha_256, aes_256_sha_256, rsa_aes_128_gcm_sha_256, ecdhe_ecdsa_aes_128_sha_256, ecdhe_rsa_aes_128_sha_256, ecdhe_ecdsa_aes_128_gcm_sha_256, ecdhe_rsa_aes_128_gcm_sha_256') -+ assert_equal_openssl("TLSv1.2", "TLSv1.2:TLSv1.2:-ADH:-DH:-DSS") - - def test_NULL(self): -- (out, err, rc) = run([exe, "NULL"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_null_md5, rsa_null_sha, null_sha_256') -- else: -- assert_equal(out, 'rsa_null_md5, rsa_null_sha, null_sha_256, ecdh_ecdsa_null_sha, ecdhe_ecdsa_null_sha, ecdh_rsa_null_sha, ecdhe_rsa_null, ecdh_anon_null_sha') -+ assert_equal_openssl("NULL", "NULL") - - def test_nss_rsa_rc4_128(self): -+ # Test NSS cipher parsing - (out, err, rc) = run([exe, "+rsa_rc4_128_md5,+rsa_rc4_128_sha"]) - assert rc == 0 - assert_equal(out, 'rsa_rc4_128_md5, rsa_rc4_128_sha') - -- def test_openssl_cipher(self): -- (out, err, rc) = run([exe, "DES-CBC3-SHA"]) -- assert rc == 0 -- assert_equal(out, 'rsa_3des_sha') -+ def test_EXP(self): -+ assert_equal_openssl("EXP", "EXP:-SSLv2:-DH:-KRB5") - -- def test_openssl_cipherlist(self): -- (out, err, rc) = run([exe, "DES-CBC3-SHA:RC4-SHA"]) -- assert rc == 0 -- assert_equal(out, 'rsa_rc4_128_sha, rsa_3des_sha') -+ def test_EXPORT(self): -+ assert_equal_openssl("EXPORT", "EXPORT:-SSLv2:-DH:-KRB5") - -- def test_EXP(self): -- (out, err, rc) = run([exe, "EXP"]) -- assert rc == 0 -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc2_40_md5, rsa_des_56_sha, rsa_rc4_56_sha') -+ def test_EXPORT40(self): -+ assert_equal_openssl("EXPORT40", "EXPORT40:-SSLv2:-ADH:-DH:-KRB5") - - def test_MD5(self): -- (out, err, rc) = run([exe, "MD5"]) -- assert rc == 0 -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc2_40_md5') -+ assert_equal_openssl("MD5", "MD5:-SSLv2:-DH:-KRB5") - - def test_SHA(self): -- (out, err, rc) = run([exe, "SHA"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_128_sha, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha') -- else: -- assert_equal(out, 'rsa_rc4_128_sha, rsa_des_sha, rsa_3des_sha, rsa_aes_128_sha, rsa_aes_256_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha, ecdh_ecdsa_rc4_128_sha, ecdh_ecdsa_3des_sha, ecdh_ecdsa_aes_128_sha, ecdh_ecdsa_aes_256_sha, ecdhe_ecdsa_rc4_128_sha, ecdhe_ecdsa_3des_sha, ecdhe_ecdsa_aes_128_sha, ecdhe_ecdsa_aes_256_sha, ecdh_rsa_128_sha, ecdh_rsa_3des_sha, ecdh_rsa_aes_128_sha, ecdh_rsa_aes_256_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdhe_rsa_aes_128_sha, ecdhe_rsa_aes_256_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha, ecdh_anon_aes_128_sha, ecdh_anon_aes_256_sha') -+ assert_equal_openssl("SHA", "SHA:-SSLv2:-DH:-KRB5:-PSK:-IDEA:-SEED") -+ -+ def test_HIGH(self): -+ assert_equal_openssl("HIGH", "HIGH:-SSLv2:-DH:-ADH:-KRB5:-PSK") -+ -+ def test_MEDIUM(self): -+ assert_equal_openssl("MEDIUM", "MEDIUM:-SSLv2:-ADH:-KRB5:-PSK:-SEED:-IDEA") -+ -+ def test_LOW(self): -+ assert_equal_openssl("LOW", "LOW:-SSLv2:-DH:-ADH:-KRB5") - - def test_SHA256(self): -- (out, err, rc) = run([exe, "SHA256"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'aes_128_sha_256, aes_256_sha_256') -- else: -- assert_equal(out, 'aes_128_sha_256, aes_256_sha_256, ecdhe_ecdsa_aes_128_sha_256, ecdhe_rsa_aes_128_sha_256') -+ assert_equal_openssl("SHA256", "SHA256:-ADH:-DSS:-DH") - - def test_SHA_MD5_minus_AES(self): -- (out, err, rc) = run([exe, "SHA:MD5:-AES"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha') -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha') -+ assert_equal_openssl("SHA:MD5:-AES", "SHA:MD5:-AES:-SSLv2:-DH:-DSS:-KRB5:-SEED:-PSK:-IDEA") - -- def test_SHA_MD5_not_AES_HIGH(self): -- (out, err, rc) = run([exe, "!AES:SHA:MD5"]) -- assert rc == 0 -- if self.ciphernum < WITH_ECC: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha') -- else: -- assert_equal(out, 'rsa_rc4_40_md5, rsa_rc4_128_md5, rsa_rc4_128_sha, rsa_rc2_40_md5, rsa_des_sha, rsa_3des_sha, camelia_128_sha, rsa_des_56_sha, rsa_rc4_56_sha, camelia_256_sha, fips_3des_sha, fips_des_sha, ecdhe_rsa_rc4_128_sha, ecdhe_rsa_3des_sha, ecdh_anon_rc4_128sha, ecdh_anon_3des_sha') -+ def test_SHA_MD5_not_AES(self): -+ assert_equal_openssl("!AES:SHA:MD5", "!AES:SHA:MD5:-SSLv2:-DH:-KRB5:-DSS:-SEED:-PSK:-IDEA") -+ -+ def test_aECDH(self): -+ assert_equal_openssl("aECDH", "aECDH") -+ -+ def test_kECDHe(self): -+ assert_equal_openssl("kECDHe", "kECDHe") -+ -+ def test_kECDHr(self): -+ assert_equal_openssl("kECDHr", "kECDHr") -+ -+ def test_kEECDH(self): -+ assert_equal_openssl("kEECDH", "kEECDH") -+ -+ def test_ECDH(self): -+ assert_equal_openssl("ECDH", "ECDH") -+ -+ def test_AES_no_ECDH(self): -+ assert_equal_openssl("AES:-ECDH", "AES:-ECDH:-ADH:-PSK:-DH") -+ assert_equal_openssl("AES+RSA", "AES+RSA") -+ -+ def test_logical_and_3DES_RSA(self): -+ assert_equal_openssl("3DES+RSA", "3DES+RSA:-SSLv2") -+ -+ def test_logical_and_RSA_RC4(self): -+ assert_equal_openssl("RSA+RC4", "RSA+RC4:-SSLv2") -+ -+ def test_logical_and_ECDH_SHA(self): -+ assert_equal_openssl("ECDH+SHA", "ECDH+SHA") -+ -+ def test_logical_and_RSA_RC4_no_SHA(self): -+ assert_equal_openssl("RSA+RC4:!SHA", "RSA+RC4:-SSLv2:!SHA") -+ -+ def test_additive_RSA_RC4(self): -+ assert_equal_openssl("RSA:+RC4", "RSA:+RC4:-SSLv2:-SEED:-IDEA") -+ -+ def test_negative_plus_RSA_MD5(self): -+ assert_equal_openssl("-RC2:RSA+MD5", "-RC2:RSA+MD5:-SSLv2") - - def test_nss_subtraction(self): - (out, err, rc) = run([exe, "+rsa_rc4_128_md5,+rsa_rc4_128_sha,-rsa_rc4_128_md5"]) - assert rc == 0 - assert_equal(out, 'rsa_rc4_128_sha') - -+ def test_openssl_cipher(self): -+ (out, err, rc) = run([exe, "DES-CBC3-SHA"]) -+ assert rc == 0 -+ assert_equal(out, 'rsa_3des_sha') -+ -+ def test_openssl_cipherlist(self): -+ (out, err, rc) = run([exe, "DES-CBC3-SHA:RC4-SHA"]) -+ assert rc == 0 -+ assert_equal(out, 'rsa_rc4_128_sha, rsa_3des_sha') -+ - # As long as at least one is valid, things are ok - def test_nss_unknown(self): - (out, err, rc) = run([exe, "+rsa_rc4_128_md5,+unknown"]) -@@ -156,7 +238,9 @@ class test_ciphers(object): - assert rc == 0 - assert_equal(out, 'aes_128_sha_256') - -+ def test_openssl_single_cipher(self): -+ assert_equal_openssl("RC4-SHA", "RC4-SHA") -+ - def test_invalid_format(self): - (out, err, rc) = run([exe, "none"]) - assert rc == 1 -- assert_equal(err, 'nss_engine_cipher.c:292, invalid cipher string none. Format is +cipher1,-cipher2...Unable to parse cipher list') -diff --git a/test_cipher.c b/test_cipher.c -index 91d112b..86a88d6 100644 ---- a/test_cipher.c -+++ b/test_cipher.c -@@ -40,7 +40,7 @@ int ap_log_error_(const char *fn, int line, int module_index, - - va_start(args, fmt); - vsprintf(out, fmt, args); -- fprintf(stderr,"%s:%d, %s", fn, line, out); -+ fprintf(stderr,"%s:%d, %s\n", fn, line, out); - va_end(args); - - return 0; -@@ -53,10 +53,11 @@ int main(int argc, char ** argv) - int rv=0; - int i; - char *ciphers; -+ PRBool openssl_output = PR_FALSE; - PRBool ciphers_list[ciphernum]; - -- if (argc != 2) { -- fprintf(stderr, "Usage: test_cipher [--count] \n"); -+ if (argc != 2 && argc != 3) { -+ fprintf(stderr, "Usage: test_cipher [--count] [--o] \n"); - exit(1); - } - -@@ -70,9 +71,14 @@ int main(int argc, char ** argv) - ciphers_list[i] = PR_FALSE; - } - -- ciphers = strdup(argv[1]); -+ i = 1; /* index of ciphers */ -+ if (!strcmp(argv[1], "--o")) { -+ openssl_output = PR_TRUE; -+ i = 2; -+ } -+ -+ ciphers = strdup(argv[i]); - if (nss_parse_ciphers(NULL, ciphers, ciphers_list) < 0) { -- fprintf(stderr, "Unable to parse cipher list\n"); - rv = 1; - } - free(ciphers); -@@ -85,12 +91,22 @@ int main(int argc, char ** argv) - for (i = 0; i < ciphernum; i++) - { - if (ciphers_list[i] == 1) { -- strncat(output, ciphers_def[i].name, sizeof(output)); -- strncat(output, ", ", sizeof(output)); -+ if (openssl_output) { -+ strncat(output, ciphers_def[i].openssl_name, sizeof(output)); -+ strncat(output, ":", sizeof(output)); -+ } else { -+ strncat(output, ciphers_def[i].name, sizeof(output)); -+ strncat(output, ", ", sizeof(output)); -+ } - } - } -- output[strlen(output) - 2] = '\0'; -+ if (openssl_output) -+ output[strlen(output) - 1] = '\0'; -+ else -+ output[strlen(output) - 2] = '\0'; - fprintf(stdout, "%s\n", output); -+ } else { -+ fprintf(stdout, "Unable to parse cipher list\n"); - } - - return rv; --- -1.9.3 - diff --git a/SOURCES/mod_nss-cipher-set.patch b/SOURCES/mod_nss-cipher-set.patch deleted file mode 100644 index ed0c606..0000000 --- a/SOURCES/mod_nss-cipher-set.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -u --recursive mod_nss-1.0.11/nss_engine_init.c mod_nss-1.0.11.test/nss_engine_init.c ---- mod_nss-1.0.11/nss_engine_init.c 2014-12-02 13:59:03.000000000 -0500 -+++ mod_nss-1.0.11.test/nss_engine_init.c 2015-08-27 13:13:25.531530206 -0400 -@@ -977,7 +977,7 @@ - - /* Finally actually enable the selected ciphers */ - for (i=0; imodel, ciphers_def[i].num, cipher_state[i]); -+ SSL_CipherPrefSet(mctx->model, ciphers_def[i].num, cipher_state[i] == 1 ? PR_TRUE : PR_FALSE); - } - } - diff --git a/SOURCES/mod_nss-clean-semaphore.patch b/SOURCES/mod_nss-clean-semaphore.patch new file mode 100644 index 0000000..0c2676a --- /dev/null +++ b/SOURCES/mod_nss-clean-semaphore.patch @@ -0,0 +1,102 @@ +From 985d17d57cfd5a36bfdecc891e9331210ea38ee4 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 8 Aug 2016 10:12:01 -0400 +Subject: [PATCH] Fix semaphore leak in nss_pcache + +On shutdown Apache was sending a SIGTERM which caused the helper +to be killed rather than shutting down gracefully, resulting in +a leak of the semaphone lock in nss_pcache. + +Catch that signal and shut down gracefully instead. + +Resolves: #1364560 + +--- + nss_pcache.c | 43 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/nss_pcache.c b/nss_pcache.c +index a8b15f7..5e98adb 100644 +--- a/nss_pcache.c ++++ b/nss_pcache.c +@@ -95,6 +95,37 @@ struct Node + + /* global variables */ + Node *pinList = NULL; ++int semid = 0; ++PRFileDesc *in = NULL; ++PRFileDesc *out = NULL; ++ ++void cleanup() { ++ union semun semarg; ++ ++ freeList(pinList); ++ pinList = NULL; ++ ++ if (in) { ++ PR_Close(in); ++ in = NULL; ++ } ++ ++ if (NSS_IsInitialized()) { ++ NSS_Shutdown(); ++ } ++ ++ /* Remove the semaphore used for locking here. This is because this ++ * program only goes away when Apache shuts down so we don't have to ++ * worry about reloads. ++ */ ++ semctl(semid, 0, IPC_RMID, semarg); ++} ++ ++void signalhandler(int signo) { ++ if (signo == SIGTERM) { ++ cleanup(); ++ } ++} + + /* + * CreatePk11PinStore +@@ -308,8 +339,6 @@ Pk11StoreGetPin(char **out, Pk11PinStore *store) + int main(int argc, char ** argv) + { + SECStatus rv; +- PRFileDesc *in; +- PRFileDesc *out; + PRPollDesc pd; + PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; + char buf[1024]; +@@ -318,7 +347,6 @@ int main(int argc, char ** argv) + char * tokenName; + char * tokenpw; + int fipsmode = 0; +- int semid = 0; + union semun semarg; + + if (argc < 4 || argc > 5) { +@@ -327,6 +355,7 @@ int main(int argc, char ** argv) + } + + signal(SIGHUP, SIG_IGN); ++ signal(SIGTERM, signalhandler); + + semid = strtol(argv[1], NULL, 10); + +@@ -459,13 +488,7 @@ int main(int argc, char ** argv) + } + } + } +- freeList(pinList); +- PR_Close(in); +- /* Remove the semaphore used for locking here. This is because this +- * program only goes away when Apache shuts down so we don't have to +- * worry about reloads. +- */ +- semctl(semid, 0, IPC_RMID, semarg); ++ cleanup(); + return 0; + } + +-- +1.8.3.1 + diff --git a/SOURCES/mod_nss-default-null.patch b/SOURCES/mod_nss-default-null.patch deleted file mode 100644 index 98fd43e..0000000 --- a/SOURCES/mod_nss-default-null.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 1aaffff1a658c5b9d5a5e09d4c6ab0a7ed4e1a50 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Mon, 21 Sep 2015 15:41:24 -0400 -Subject: [PATCH] The OpenSSL DEFAULT cipher macro shouldn't enable NULL - ciphers - ---- - nss_engine_cipher.c | 13 +++++++++++++ - test/test_cipher.py | 8 ++++++++ - 2 files changed, 21 insertions(+) - -diff --git a/nss_engine_cipher.c b/nss_engine_cipher.c -index 012e269..45b8836 100644 ---- a/nss_engine_cipher.c -+++ b/nss_engine_cipher.c -@@ -164,6 +164,7 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - int i, action; - PRBool merge = PR_FALSE; - PRBool found = PR_FALSE; -+ PRBool first = PR_TRUE; - - cipher = ciphers; - while (ciphers && (strlen(ciphers))) -@@ -210,11 +211,22 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - set_cipher_value(cipher_list, i, action); - } - } else if (!strcmp(cipher, "DEFAULT")) { -+ /* In OpenSSL the default cipher list is -+ * ALL:!aNULL:!eNULL:!SSLv2 -+ * So we need to disable all the NULL ciphers too. -+ */ -+ int mask = SSL_aNULL | SSL_eNULL; -+ PRBool enabled; - found = PR_TRUE; - for (i=0; i < ciphernum; i++) { - if (cipher_list[i] != -1) - SSL_CipherPrefGetDefault(ciphers_def[i].num, - &cipher_list[i]); -+ if (PR_TRUE == first) { -+ if (ciphers_def[i].attr & mask) { -+ set_cipher_value(cipher_list, i, -1); -+ } -+ } - } - } else if (!strcmp(cipher, "COMPLEMENTOFDEFAULT")) { - found = PR_TRUE; -@@ -374,6 +386,7 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - } - } /* while */ - if (PR_TRUE == merge) { -+ first = PR_FALSE; - /* Merge the candidate list into the cipher list */ - for (i=0; i +Date: Tue, 17 May 2016 14:02:24 -0400 +Subject: [PATCH] Work around missing ndg-httpsclient breaking import of + pyopenssl + +--- + test/test_request.py | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/test/test_request.py b/test/test_request.py +index 5d2a525..254b31c 100644 +--- a/test/test_request.py ++++ b/test/test_request.py +@@ -8,8 +8,13 @@ import logging + import socket + from requests.packages.urllib3.util import get_host + from requests.packages.urllib3.util.timeout import Timeout +-from requests.packages.urllib3.contrib import pyopenssl + from requests.packages.urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool, VerifiedHTTPSConnection ++try: ++ from requests.packages.urllib3.contrib.pyopenssl import DEFAULT_SSL_CIPHER_LIST ++except ImportError: ++ DEFAULT_SSL_CIPHER_LIST = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:" + \ ++ "ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:" + \ ++ "!aNULL:!MD5:!DSS" + + # Don't bend over backwards for ssl support, assume it is there. + import ssl +@@ -33,7 +38,7 @@ except ImportError: + # Other older python we use the urllib3 bundled copy + from urllib3.packages.ssl_match_hostname import match_hostname, CertificateError + +-SAVE_DEFAULT_SSL_CIPHER_LIST = pyopenssl.DEFAULT_SSL_CIPHER_LIST ++SAVE_DEFAULT_SSL_CIPHER_LIST = DEFAULT_SSL_CIPHER_LIST + + log = logging.getLogger(__name__) + +@@ -141,9 +146,9 @@ class MyVerifiedHTTPSConnection(VerifiedHTTPSConnection): + def connect(self): + if self.sni: + if self.ciphers: +- pyopenssl.DEFAULT_SSL_CIPHER_LIST = self.ciphers ++ DEFAULT_SSL_CIPHER_LIST = self.ciphers + else: +- pyopenssl.DEFAULT_SSL_CIPHER_LIST = SAVE_DEFAULT_SSL_CIPHER_LIST ++ DEFAULT_SSL_CIPHER_LIST = SAVE_DEFAULT_SSL_CIPHER_LIST + return super(MyVerifiedHTTPSConnection, self).connect() + + # Add certificate verification +-- +2.5.5 + diff --git a/SOURCES/mod_nss-doc-changes.patch b/SOURCES/mod_nss-doc-changes.patch deleted file mode 100644 index 5a38f36..0000000 --- a/SOURCES/mod_nss-doc-changes.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 3537472b0a55c72fb5dea022ff3be7abddab055a Mon Sep 17 00:00:00 2001 -From: Matthew Harmsen -Date: Tue, 28 Jul 2015 14:17:57 -0600 -Subject: [PATCH] doc changes - -- Bugzilla Bug #1066236 - mod_nss: documentation formatting fixes [rhel-7.1] ---- - docs/mod_nss.html | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/docs/mod_nss.html b/docs/mod_nss.html -index 2d349b6..19d8fef 100644 ---- a/docs/mod_nss.html -+++ b/docs/mod_nss.html -@@ -398,7 +398,7 @@ Deprecated.
-
- NSSSession3CacheTimeout
-

--Specifies the number of seconds SSL 3 sessions are cached.
-+Specifies the number of seconds SSLv3 sessions are cached.
-
- The valid range is 5 - 86400 seconds. A setting outside the valid - range is silently constrained.
-@@ -453,7 +453,7 @@ Example
-
- Enables or disables FIPS 140 mode. This replaces the standard - internal PKCS#11 module with a FIPS-enabled one. It also forces the --enabled protocols to TLSv1.2, TLSv1.1 and TLS v1.0 and disables all ciphers -+enabled protocols to TLSv1.2, TLSv1.1 and TLSv1.0 and disables all ciphers - but the FIPS ones. You may still select which ciphers you would like - limited to those that are FIPS-certified. Any non-FIPS that are - included in the NSSCipherSuite entry are automatically disabled. -@@ -881,8 +881,8 @@ and the maximum allowed protocols based upon these entries allowing for the - inclusion of every protocol in-between. For example, if only SSLv3 and TLSv1.1 - are specified, SSLv3, TLSv1.0, and TLSv1.1 will all be allowed, as NSS utilizes - protocol ranges to accept all protocols inclusively --(TLS 1.1 -> TLS 1.0 -> SSL 3.0), and does not allow exclusion of any protocols --in the middle of a range (e. g. - TLS 1.0).
-+(TLSv1.1 -> TLSv1.0 -> SSLv3.0), and does not allow exclusion of any protocols -+in the middle of a range (e. g. - TLSv1.0).
-
- Finally, NSS will always automatically negotiate the use of the strongest - possible protocol that has been specified which is acceptable to both sides of -@@ -1505,9 +1505,10 @@ certutil: certificate is valid
- -

Why is SSLv2 disabled?

- All major browsers (Firefox, Internet Explorer, Mozilla, Netscape, Opera, and --Safari) support SSL 3 and TLS so there is no need for a web server to support --SSL 2. There are some known attacks against SSL 2 that are handled by SSL --3/TLS. SSL2 also doesn't support useful features like client authentication. -+Safari) support SSLv3 and TLS so there is no need for a web server to support -+SSLv2. There are some known attacks against SSLv2 that are handled by -+SSLv3/TLS. SSLv2 also doesn't support useful features like client -+authentication. -
- -

Frequently Asked Questions

--- -1.8.3.1 - diff --git a/SOURCES/mod_nss-eecdh_cipher.patch b/SOURCES/mod_nss-eecdh_cipher.patch deleted file mode 100644 index 7776be8..0000000 --- a/SOURCES/mod_nss-eecdh_cipher.patch +++ /dev/null @@ -1,117 +0,0 @@ -From a199da277582152086eb06267dd31932f03a0b8e Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Mon, 21 Sep 2015 18:34:12 -0400 -Subject: [PATCH] Implement EECDH, kECDH, AECDH, ECDSA and aECDSA cipher macros - -Also add test for AESGCM ---- - nss_engine_cipher.c | 28 ++++++++++++++++++++++++++++ - test/test_cipher.py | 18 ++++++++++++++++++ - 2 files changed, 46 insertions(+) - -diff --git a/nss_engine_cipher.c b/nss_engine_cipher.c -index 45b8836..bede228 100644 ---- a/nss_engine_cipher.c -+++ b/nss_engine_cipher.c -@@ -237,6 +237,8 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - "Cipher ordering is not supported in NSS"); - return -1; - } else { -+ int amask = 0; -+ int amaskaction = 0; - int mask = 0; - int strength = 0; - int protocol = 0; -@@ -251,6 +253,8 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - - c = cipher; - while (c && (strlen(c))) { -+ amask = 0; -+ amaskaction = 0; - mask = 0; - strength = 0; - protocol = 0; -@@ -276,6 +280,16 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - #endif - } else if (!strcmp(cipher, "ECDH")) { - mask |= SSL_ECDH; -+ } else if (!strcmp(cipher, "EECDH")) { -+ mask |= SSL_kEECDH; -+ amask = SSL_aNULL; -+ amaskaction = 1; /* filter anonymous out */ -+ } else if (!strcmp(cipher, "AECDH")) { -+ mask |= SSL_kEECDH; -+ amask = SSL_aNULL; /* require anonymous */ -+ amaskaction = 0; /* keep these */ -+ } else if (!strcmp(cipher, "kECDH")) { -+ mask |= SSL_kECDHe | SSL_kECDHr; - } else if (!strcmp(cipher, "kECDHe")) { - mask |= SSL_kECDHe; - } else if (!strcmp(cipher, "kECDHr")) { -@@ -284,6 +298,10 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - mask |= SSL_kEECDH; - } else if (!strcmp(cipher, "aECDH")) { - mask |= SSL_aECDH; -+ } else if (!strcmp(cipher, "ECDSA")) { -+ mask |= SSL_aECDSA; -+ } else if (!strcmp(cipher, "aECDSA")) { -+ mask |= SSL_aECDSA; - } else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) { - mask |= SSL_eNULL; - } else if (!strcmp(cipher, "aNULL")) { -@@ -352,6 +370,16 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis - (ciphers_def[i].strength & strength) || - (ciphers_def[i].version & protocol)) && - (cipher_list[i] != -1)) { -+ if (amask != 0) { -+ PRBool match = PR_FALSE; -+ if (ciphers_def[i].attr & amask) { -+ match = PR_TRUE; -+ } -+ if (amaskaction && match) -+ continue; -+ if (!amaskaction && !match) -+ continue; -+ } - #if 0 - /* Enable the NULL ciphers only if explicity - * requested */ -diff --git a/test/test_cipher.py b/test/test_cipher.py -index af9d7eb..3f1f344 100644 ---- a/test/test_cipher.py -+++ b/test/test_cipher.py -@@ -183,6 +183,9 @@ class test_ciphers(object): - def test_aECDH(self): - assert_equal_openssl("aECDH", "aECDH") - -+ def test_kECDH(self): -+ assert_equal_openssl("kECDH", "kECDH") -+ - def test_kECDHe(self): - assert_equal_openssl("kECDHe", "kECDHe") - -@@ -192,6 +195,21 @@ class test_ciphers(object): - def test_kEECDH(self): - assert_equal_openssl("kEECDH", "kEECDH") - -+ def test_AECDH(self): -+ assert_equal_openssl("AECDH", "AECDH") -+ -+ def test_EECDH(self): -+ assert_equal_openssl("EECDH", "EECDH") -+ -+ def test_ECDSA(self): -+ assert_equal_openssl("ECDSA", "ECDSA") -+ -+ def test_aECDSA(self): -+ assert_equal_openssl("aECDSA", "aECDSA") -+ -+ def test_AESGCM(self): -+ assert_equal_openssl("AESGCM", "AESGCM:-DH") -+ - def test_ECDH(self): - assert_equal_openssl("ECDH", "ECDH") - --- -1.9.3 - diff --git a/SOURCES/mod_nss-gencert.patch b/SOURCES/mod_nss-gencert.patch index a993e2d..6a8bbde 100644 --- a/SOURCES/mod_nss-gencert.patch +++ b/SOURCES/mod_nss-gencert.patch @@ -1,6 +1,6 @@ -From 2d99bb694029f06d3bb7810922e755c57229b951 Mon Sep 17 00:00:00 2001 +From 4908fdb78aaf4434e4519fe0809383dc69778823 Mon Sep 17 00:00:00 2001 From: Rob Crittenden -Date: Tue, 2 Dec 2014 11:34:23 -0500 +Date: Tue, 17 May 2016 11:34:06 -0400 Subject: [PATCH] Modify gencert to create a password-less database --- @@ -8,16 +8,20 @@ Subject: [PATCH] Modify gencert to create a password-less database 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gencert.in b/gencert.in -index ffccaab..1808f42 100755 +index 0fd1c67..659a9fc 100755 --- a/gencert.in +++ b/gencert.in -@@ -85,12 +85,11 @@ fi - - DBDIR=$1 +@@ -115,7 +115,7 @@ done + echo "TEST = $TEST" + echo "SNI = $SNI" -echo "httptest" > $DEST/pw.txt +echo -e "\n" > $DEST/pw.txt + function generate_server_sni_cert { + hostname=$1 +@@ -172,8 +172,7 @@ function generate_server_sni_cert { + echo "" echo "#####################################################################" -echo "Generating new server certificate and key database. The password" @@ -26,7 +30,7 @@ index ffccaab..1808f42 100755 echo "#####################################################################" $CERTUTIL -N -d $DBDIR -f $DEST/pw.txt -@@ -207,8 +206,4 @@ echo "#####################################################################" +@@ -328,8 +327,4 @@ echo "#####################################################################" rm $DEST/pw.txt rm $DEST/noise @@ -36,5 +40,5 @@ index ffccaab..1808f42 100755 - exit 0 -- -1.9.3 +2.5.5 diff --git a/SOURCES/mod_nss-makecheck.patch b/SOURCES/mod_nss-makecheck.patch deleted file mode 100644 index 1f78465..0000000 --- a/SOURCES/mod_nss-makecheck.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff -up --recursive mod_nss-1.0.11/Makefile.am mod_nss-1.0.11.test/Makefile.am ---- mod_nss-1.0.11/Makefile.am 2015-09-21 16:41:05.789937357 -0400 -+++ mod_nss-1.0.11.test/Makefile.am 2015-09-21 16:42:38.112473063 -0400 -@@ -103,12 +103,6 @@ check: - cd test; \ - rm -rf work; \ - nosetests -v test_cipher.py; \ -- ./setup.sh; \ -- nosetests -v test.py; \ -- sleep 5; \ -- rm -rf work; \ -- ./setup.sh sql:; \ -- DBPREFIX=sql: nosetests -v test.py; \ - cd .. - - .PHONY: all test clean -diff -up --recursive mod_nss-1.0.11/test/test_request.py mod_nss-1.0.11.test/test/test_request.py ---- mod_nss-1.0.11/test/test_request.py 2014-12-02 13:59:03.000000000 -0500 -+++ mod_nss-1.0.11.test/test/test_request.py 2015-09-21 16:42:25.563672095 -0400 -@@ -4,8 +4,8 @@ - import socket - import requests - import urlparse --from urllib3.util import get_host --from urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool -+from requests.packages.urllib3.util import get_host -+from requests.packages.urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool - import logging - - # Don't bend over backwards for ssl support, assume it is there. -@@ -107,6 +107,9 @@ class MyVerifiedHTTPSConnection(HTTPSCon - ca_certs = None - client_cipher = None - -+ # A gross oversimplification but we aren't testing this -+ is_verified = True -+ - def set_cert(self, key_file=None, cert_file=None, - cert_reqs='CERT_NONE', ca_certs=None): - ssl_req_scheme = { diff --git a/SOURCES/mod_nss-parallel-build.patch b/SOURCES/mod_nss-parallel-build.patch deleted file mode 100644 index e6abd76..0000000 --- a/SOURCES/mod_nss-parallel-build.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index 6bbbc45..4978ff3 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -7,8 +7,7 @@ bin_PROGRAMS = nss_pcache test_cipher - - nss_pcache_SOURCES = nss_pcache.c - --test_cipher_SOURCES = test_cipher.c --test_cipher_LDADD = .libs/nss_engine_cipher.o -+test_cipher_SOURCES = test_cipher.c nss_engine_cipher.c - test_cipher_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(EXTRA_CPPFLAGS) - - man8_MANS = \ diff --git a/SOURCES/mod_nss-remove-r-user-from-hook-fixup.patch b/SOURCES/mod_nss-remove-r-user-from-hook-fixup.patch new file mode 100644 index 0000000..41dda9f --- /dev/null +++ b/SOURCES/mod_nss-remove-r-user-from-hook-fixup.patch @@ -0,0 +1,21 @@ +diff -rupN mod_nss-1.0.14.orig/nss_engine_kernel.c mod_nss-1.0.14/nss_engine_kernel.c +--- mod_nss-1.0.14.orig/nss_engine_kernel.c 2016-04-15 12:27:59.000000000 -0600 ++++ mod_nss-1.0.14/nss_engine_kernel.c 2016-06-27 13:18:09.571283114 -0600 +@@ -953,17 +953,6 @@ int nss_hook_Fixup(request_rec *r) + } + + /* +- * Set r->user if requested +- */ +- if (dc->szUserName) { +- val = nss_var_lookup(r->pool, r->server, r->connection, +- r, (char *)dc->szUserName); +- if (val && val[0]) { +- r->user = val; +- } +- } +- +- /* + * Annotate the SSI/CGI environment with standard SSL information + */ + /* the always present HTTPS (=HTTP over SSL) flag! */ diff --git a/SOURCES/mod_nss-sha384_cipher.patch b/SOURCES/mod_nss-sha384_cipher.patch deleted file mode 100644 index 8a74d18..0000000 --- a/SOURCES/mod_nss-sha384_cipher.patch +++ /dev/null @@ -1,85 +0,0 @@ -diff -up --recursive mod_nss-1.0.11/nss_engine_cipher.c mod_nss-1.0.11.cipher/nss_engine_cipher.c ---- mod_nss-1.0.11/nss_engine_cipher.c 2015-09-22 10:08:46.977756724 -0400 -+++ mod_nss-1.0.11.cipher/nss_engine_cipher.c 2015-09-22 13:50:49.320055436 -0400 -@@ -42,6 +42,7 @@ cipher_properties ciphers_def[ciphernum] - {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, "EXP1024-RC4-SHA", SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA1, TLSV1, SSL_EXPORT56, 56, 128}, - {"camelia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "CAMELLIA256-SHA", SSL_kRSA|SSL_aRSA|SSL_CAMELLIA256|SSL_SHA1, TLSV1, SSL_HIGH, 256, 256}, - {"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256, "AES128-GCM-SHA256", SSL_kRSA|SSL_aRSA|SSL_AES128GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 128, 128}, -+ {"rsa_aes_256_gcm_sha_384", TLS_RSA_WITH_AES_256_GCM_SHA384, "AES256-GCM-SHA384", SSL_kRSA|SSL_aRSA|SSL_AES256GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 256, 256}, - {"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "FIPS-DES-CBC3-SHA", SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA1, SSLV3, SSL_HIGH, 112, 168}, - {"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA, "FIPS-DES-CBC-SHA", SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1, SSLV3, SSL_LOW, 56, 56}, - #ifdef NSS_ENABLE_ECC -@@ -73,6 +74,10 @@ cipher_properties ciphers_def[ciphernum] - {"ecdhe_ecdsa_aes_128_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "ECDHE-ECDSA-AES128-SHA256", SSL_kEECDH|SSL_aECDSA|SSL_AES128|SSL_SHA256, TLSV1_2, SSL_HIGH, 128, 128}, - {"ecdhe_rsa_aes_128_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "ECDHE-RSA-AES128-SHA256", SSL_kEECDH|SSL_aRSA|SSL_AES128|SSL_SHA256, TLSV1_2, SSL_HIGH, 128, 128}, - {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "ECDHE-ECDSA-AES128-GCM-SHA256", SSL_kEECDH|SSL_aECDSA|SSL_AES128GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 128, 128}, -+ {"ecdhe_ecdsa_aes_256_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "ECDHE-ECDSA-AES256-SHA384", SSL_kEECDH|SSL_aECDSA|SSL_AES256|SSL_SHA384, TLSV1_2, SSL_HIGH, 256, 256}, -+ {"ecdhe_rsa_aes_256_sha_384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "ECDHE-RSA-AES256-SHA384", SSL_kEECDH|SSL_aRSA|SSL_AES256|SSL_SHA384, TLSV1_2, SSL_HIGH, 256, 256}, -+ {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "ECDHE-ECDSA-AES256-GCM-SHA384", SSL_kEECDH|SSL_aECDSA|SSL_AES256GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 256, 256}, -+ {"ecdhe_rsa_aes_256_gcm_sha_384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "ECDHE-RSA-AES256-GCM-SHA384", SSL_kEECDH|SSL_aRSA|SSL_AES256GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 256, 256}, - {"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "ECDHE-RSA-AES128-GCM-SHA256", SSL_kEECDH|SSL_aRSA|SSL_AES128GCM|SSL_AEAD, TLSV1_2, SSL_HIGH, 128, 128}, - /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 is not implemented */ - /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 is not implemented */ -@@ -323,6 +328,8 @@ static int parse_openssl_ciphers(server_ - mask |= SSL_SHA1; - } else if (!strcmp(cipher, "SHA256")) { - mask |= SSL_SHA256; -+ } else if (!strcmp(cipher, "SHA384")) { -+ mask |= SSL_SHA384; - } else if (!strcmp(cipher, "SSLv2")) { - /* no-op */ - } else if (!strcmp(cipher, "SSLv3")) { -diff -up --recursive mod_nss-1.0.11/nss_engine_cipher.h mod_nss-1.0.11.cipher/nss_engine_cipher.h ---- mod_nss-1.0.11/nss_engine_cipher.h 2015-09-22 10:08:13.915509295 -0400 -+++ mod_nss-1.0.11.cipher/nss_engine_cipher.h 2015-09-22 13:45:18.838532130 -0400 -@@ -70,7 +70,8 @@ typedef struct - #define SSL_AES128GCM 0x04000000L - #define SSL_AES256GCM 0x08000000L - #define SSL_SHA256 0x10000000L --#define SSL_AEAD 0x20000000L -+#define SSL_SHA384 0x20000000L -+#define SSL_AEAD 0x40000000L - - #define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) - #define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) -@@ -83,9 +84,9 @@ typedef struct - - /* the table itself is defined in nss_engine_cipher.c */ - #ifdef NSS_ENABLE_ECC --#define ciphernum 49 -+#define ciphernum 54 - #else --#define ciphernum 20 -+#define ciphernum 21 - #endif - - /* function prototypes */ -diff -up --recursive mod_nss-1.0.11/test/test_cipher.py mod_nss-1.0.11.cipher/test/test_cipher.py ---- mod_nss-1.0.11/test/test_cipher.py 2015-09-22 10:08:46.977756724 -0400 -+++ mod_nss-1.0.11.cipher/test/test_cipher.py 2015-09-22 13:50:05.214717202 -0400 -@@ -19,6 +19,10 @@ CIPHERS_NOT_IN_NSS = ['ECDH-RSA-AES128-S - 'ECDH-ECDSA-AES128-SHA256', - 'ECDH-RSA-AES128-GCM-SHA256', - 'EXP-DES-CBC-SHA', -+ 'ECDH-RSA-AES256-GCM-SHA384', -+ 'ECDH-ECDSA-AES256-SHA384', -+ 'ECDH-RSA-AES256-SHA384', -+ 'ECDH-ECDSA-AES256-GCM-SHA384', - ] - - def assert_equal_openssl(nss_ciphers, ossl_ciphers): -@@ -34,12 +38,10 @@ def assert_equal_openssl(nss_ciphers, os - ossl_list = list(set(ossl_list)) - ossl_list.sort() - -- # NSS doesn't support the SHA-384 ciphers, remove them from the OpenSSL -- # output. -+ # NSS doesn't support the all the same ciphers as OpenSSL. Remove -+ # the ones we know about from the OpenSSL output. - t = list() - for o in ossl_list: -- if 'SHA384' in o: -- continue - if o in CIPHERS_NOT_IN_NSS: - continue - t.append(o) diff --git a/SOURCES/mod_nss-test-cipherlist.patch b/SOURCES/mod_nss-test-cipherlist.patch new file mode 100644 index 0000000..2a5f76e --- /dev/null +++ b/SOURCES/mod_nss-test-cipherlist.patch @@ -0,0 +1,37 @@ +From 6bf887340626e35e0497deaf246a9f034d8fe8ee Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 23 May 2016 17:21:11 -0400 +Subject: [PATCH] Add back export and low-security ciphers + +These are disabled in OpenSSL 1.02g but are still enabled in +the version in RHEL 7. +--- + test/test_cipher.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/test/test_cipher.py b/test/test_cipher.py +index 1cce9e4..8b12f26 100644 +--- a/test/test_cipher.py ++++ b/test/test_cipher.py +@@ -40,7 +40,7 @@ if ENABLE_SERVER_DHE == 0: + OPENSSL_CIPHERS_IGNORE += ':-DH' + + def assert_equal_openssl(ciphers): +- nss_ciphers = ciphers + ":-EXP:-LOW" ++ nss_ciphers = ciphers + ossl_ciphers = ciphers + OPENSSL_CIPHERS_IGNORE + (nss, err, rc) = run([exe, "--o", nss_ciphers]) + assert rc == 0 +@@ -270,8 +270,7 @@ class test_ciphers(object): + assert_no_NULL("DEFAULT:aRSA") + + def test_SYSTEM_DEFAULT(self): +- # I've added in !DHE here which differs from F-23 default +- assert_equal_openssl("!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES:!DHE") ++ assert_equal_openssl("!SSLv2:kEECDH:kRSA:kEDH:kPSK:DH:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES") + + def test_cipher_reorder(self): + # re-ordering now allowed but shouldn't blow up either +-- +2.5.5 + diff --git a/SPECS/mod_nss.spec b/SPECS/mod_nss.spec index ed2c7ad..2de3a7c 100644 --- a/SPECS/mod_nss.spec +++ b/SPECS/mod_nss.spec @@ -5,8 +5,8 @@ %{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn 2>/dev/null || echo 0-0)}} Name: mod_nss -Version: 1.0.11 -Release: 6%{?dist} +Version: 1.0.14 +Release: 7%{?dist} Summary: SSL/TLS module for the Apache HTTP server Group: System Environment/Daemons License: ASL 2.0 @@ -23,6 +23,7 @@ BuildRequires: libtool BuildRequires: openssl BuildRequires: python-nose BuildRequires: python-requests +BuildRequires: python-urllib3 Requires: httpd-mmn = %{_httpd_mmn} Requires(post): httpd, nss-tools Requires: nss%{?_isa} >= 3.19.1 @@ -35,19 +36,18 @@ Requires: %{_libdir}/libnssckbi.so Patch1: mod_nss-conf.patch # Generate a password-less NSS database Patch2: mod_nss-gencert.patch -Patch3: mod_nss-parallel-build.patch -Patch4: mod_nss-doc-changes.patch -Patch5: mod_nss-cipher-logical_and.patch -# Disable some of the in-tree tests because TPS fails -Patch6: mod_nss-makecheck.patch -# Only enable a cipher if is the magic number 1 -Patch7: mod_nss-cipher-set.patch -# Don't enable NULL ciphers for DEFAULT:aRSA -Patch8: mod_nss-default-null.patch -# Add openssl cipher macro EECDH -Patch9: mod_nss-eecdh_cipher.patch -# Add two new SHA384 ciphers in NSS -Patch10: mod_nss-sha384_cipher.patch +# Set DEFAULT_SSL_CIPHER_LIST manually if pyopenssl can't be imported +Patch3: mod_nss-defaultcipherlist.patch +# Match the available ciphers in RHEL OpenSSL so tests pass +Patch4: mod_nss-test-cipherlist.patch +# Disable and fix tests to work inside of brew +Patch5: mod_nss-brewtest.patch +# Remove setting 'r->user' in nss_hook_Fixup() +Patch6: mod_nss-remove-r-user-from-hook-fixup.patch +# Cleanup nss_pcache semaphore on shutdown +Patch7: mod_nss-clean-semaphore.patch +# Check certificate database directory permissions +Patch8: mod_nss-certdb-permissions.patch %description The mod_nss module provides strong cryptography for the Apache Web @@ -59,14 +59,12 @@ security library. %setup -q %patch1 -p1 -b .conf %patch2 -p1 -b .gencert -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 +%patch3 -p1 -b .defaultcipherlist +%patch4 -p1 -b .testcipherlist +%patch5 -p1 -b .brewtest +%patch6 -p1 -b .remove_r_user +%patch7 -p1 -b .semaphore +%patch8 -p1 -b .permissions # Touch expression parser sources to prevent regenerating it touch nss_expr_*.[chyl] @@ -131,7 +129,7 @@ install -m 755 nss_pcache $RPM_BUILD_ROOT%{_libexecdir}/ # ln -s %{_libexecdir}/nss_pcache $RPM_BUILD_ROOT%{_sbindir}/nss_pcache install -m 755 gencert $RPM_BUILD_ROOT%{_sbindir}/ -ln -s ../../../%{_libdir}/libnssckbi.so $RPM_BUILD_ROOT%{_sysconfdir}/httpd/alias/ +ln -s %{_libdir}/libnssckbi.so $RPM_BUILD_ROOT%{_sysconfdir}/httpd/alias/ touch $RPM_BUILD_ROOT%{_sysconfdir}/httpd/alias/secmod.db touch $RPM_BUILD_ROOT%{_sysconfdir}/httpd/alias/cert8.db touch $RPM_BUILD_ROOT%{_sysconfdir}/httpd/alias/key3.db @@ -181,6 +179,43 @@ fi %{_sbindir}/gencert %changelog +* Wed Sep 21 2016 Rob Crittenden - 1.0.14-7 +- Add the permission patch to the repository (#1312583) + +* Wed Sep 21 2016 Rob Crittenden - 1.0.14-6 +- Check the NSS certificate database directory for read permissions + by the Apache user. (#1312583) + +* Wed Aug 10 2016 Rob Crittenden - 1.0.14-5 +- Update clean semaphore patch to not free the pinList twice. + (#1364560) + +* Tue Aug 9 2016 Rob Crittenden - 1.0.14-4 +- Update clean semaphore patch to not close pipe twice and to + shutdown NSS database (#1364560) + +* Mon Aug 8 2016 Rob Crittenden - 1.0.14-3 +- Clean up semaphore in nss_pcache on shutdown (#1364560) + +* Tue Jun 28 2016 Matthew Harmsen - 1.0.14-2 +- mod_nss sets r->user in fixup even if it was long ago changed + by other module (#1347298) + +* Mon May 23 2016 Rob Crittenden - 1.0.14-1 +- Rebase to 1.0.14 (#1299063) +- Add support for Server Name Indication (SNI) (#1053327) +- Use upstream method to not execute live tests as root (#1256887) +- Always call SSL_ShutdownServerSessionIDCache() in ModuleKill + (#1263301, #1296685) +- Don't require NSSProxyNickname (#1280287) +- Make link to libnssckbi.so an absolute link (#1288471) +- Fail for colons in credentials with FakeBasicAuth (#1295970) +- Don't ignore NSSProtocol when NSSFIPS is enabled (#1312491) +- Check filesystem permissions on NSS database at startup (#1312583) +- OpenSSL ciphers stopped parsing at +, CVE-2016-3099 (#1323913) +- Patch to match available ciphers so tests pass (#1299063) +- Patch to fix tests in brew (#1299063) + * Tue Sep 22 2015 Rob Crittenden - 1.0.11-6 - Add the supported NSS SHA384 ciphers (#1253570) - Add kECDH, AECDH, ECDSA and aECDSA macros (#1253570)