summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nss_engine_cipher.c196
-rw-r--r--nss_engine_cipher.h61
-rwxr-xr-xtest/createinstance.sh1
-rw-r--r--test/suite1.tmpl6
-rw-r--r--test/test.py6
-rw-r--r--test/test_cipher.py254
-rw-r--r--test_cipher.c32
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<ciphernum; i++) {
if (!(ciphers_def[i].attr & SSL_eNULL))
- if (cipher_list[i] != -1)
- cipher_list[i] = action;
+ set_cipher_value(cipher_list, i, action);
}
} else if (!strcmp(cipher, "COMPLEMENTOFALL")) {
+ found = PR_TRUE;
for (i=0; i<ciphernum; i++) {
if ((ciphers_def[i].attr & SSL_eNULL))
- if (cipher_list[i] != -1)
- cipher_list[i] = action;
+ set_cipher_value(cipher_list, i, action);
}
} else if (!strcmp(cipher, "DEFAULT")) {
+ found = PR_TRUE;
for (i=0; i < ciphernum; i++) {
if (cipher_list[i] != -1)
SSL_CipherPrefGetDefault(ciphers_def[i].num,
&cipher_list[i]);
}
+ } else if (!strcmp(cipher, "COMPLEMENTOFDEFAULT")) {
+ found = PR_TRUE;
+ /* no-op. In OpenSSL this is the ADH ciphers */
+ } else if (!strcmp(cipher, "@STRENGTH")) {
+ /* No cipher ordering in NSS */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ "Cipher ordering is not supported in NSS");
+ return -1;
} else {
int mask = 0;
int strength = 0;
int protocol = 0;
char *c;
+ int i;
+ PRBool candidate_list[ciphernum];
+ PRBool temp_list[ciphernum];
+
+ for (i = 0; i < ciphernum; i++) {
+ candidate_list[i] = 1;
+ }
c = cipher;
while (c && (strlen(c))) {
+ mask = 0;
+ strength = 0;
+ protocol = 0;
+ for (i = 0; i < ciphernum; i++) {
+ temp_list[i] = 0;
+ }
if ((c = strchr(cipher, '+'))) {
*c++ = '\0';
@@ -184,12 +254,44 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
if (!strcmp(cipher, "RSA")) {
mask |= SSL_RSA;
+ } else if (!strcmp(cipher, "kRSA")) {
+ mask |= SSL_kRSA;
+ } else if (!strcmp(cipher, "aRSA")) {
+ mask |= SSL_aRSA;
} else if (!strcmp(cipher, "EDH")) {
mask |= SSL_EDH;
+#if 0
+ } else if (!strcmp(cipher, "ADH")) {
+ mask |= SSL_ADH;
+#endif
+ } else if (!strcmp(cipher, "ECDH")) {
+ mask |= SSL_ECDH;
+ } else if (!strcmp(cipher, "kECDHe")) {
+ mask |= SSL_kECDHe;
+ } else if (!strcmp(cipher, "kECDHr")) {
+ mask |= SSL_kECDHr;
+ } else if (!strcmp(cipher, "kEECDH")) {
+ mask |= SSL_kEECDH;
+ } else if (!strcmp(cipher, "aECDH")) {
+ mask |= SSL_aECDH;
} else if ((!strcmp(cipher, "NULL")) || (!strcmp(cipher, "eNULL"))) {
mask |= SSL_eNULL;
+ } else if (!strcmp(cipher, "aNULL")) {
+ mask |= SSL_aNULL;
} else if (!strcmp(cipher, "AES")) {
mask |= SSL_AES;
+ } else if (!strcmp(cipher, "AESGCM")) {
+ mask |= SSL_AES128GCM|SSL_AES256GCM;
+ } else if (!strcmp(cipher, "AES128")) {
+ mask |= SSL_AES128|SSL_AES128GCM;
+ } else if (!strcmp(cipher, "AES256")) {
+ mask |= SSL_AES256|SSL_AES256GCM;
+ } else if (!strcmp(cipher, "CAMELLIA")) {
+ mask |= SSL_CAMELLIA128|SSL_CAMELLIA256;
+ } else if (!strcmp(cipher, "CAMELLIA128")) {
+ mask |= SSL_CAMELLIA128;
+ } else if (!strcmp(cipher, "CAMELLIA256")) {
+ mask |= SSL_CAMELLIA256;
} else if (!strcmp(cipher, "3DES")) {
mask |= SSL_3DES;
} else if (!strcmp(cipher, "DES")) {
@@ -210,7 +312,7 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
protocol |= SSLV3;
} else if (!strcmp(cipher, "TLSv1")) {
protocol |= TLSV1;
- } else if (!strcmp(cipher, "TLSv12")) {
+ } else if (!strcmp(cipher, "TLSv1.2")) {
protocol |= TLSV1_2;
} else if (!strcmp(cipher, "HIGH")) {
strength |= SSL_HIGH;
@@ -229,32 +331,58 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
if (c)
cipher = c;
- } /* while */
-
- /* If we have a mask, apply it. If not then perhaps they provided
- * a specific cipher to enable.
- */
- if (mask || 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 we have a mask, apply it. If not then perhaps they
+ * provided a specific cipher to enable.
+ */
+ if (mask || strength || protocol) {
+ merge = PR_TRUE;
+ found = PR_TRUE;
+ 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)) {
+#if 0
+ /* Enable the NULL ciphers only if explicity
+ * requested */
+ if (ciphers_def[i].attr & SSL_eNULL) {
+ if (mask & SSL_eNULL)
+ temp_list[i] = 1;
+ } else
+#endif
+ temp_list[i] = 1;
+ }
+ }
+ /* Merge the temp list into the candidate list */
+ for (i=0; i<ciphernum; i++) {
+ if (!(candidate_list[i] & temp_list[i])) {
+ candidate_list[i] = 0;
+ }
+ }
+ } else if (!strcmp(cipher, "FIPS")) {
+ SSLCipherSuiteInfo suite;
+ for (i=0; i<ciphernum;i++) {
+ if (SSL_GetCipherSuiteInfo(ciphers_def[i].num,
+ &suite, sizeof suite) == SECSuccess) {
+ if (suite.isFIPS)
+ set_cipher_value(cipher_list, i, action);
+ }
+ }
+ } else {
+ for (i=0; i<ciphernum; i++) {
+ if (!strcmp(ciphers_def[i].openssl_name, cipher))
+ set_cipher_value(cipher_list, i, action);
}
}
- else {
+ } /* while */
+ if (PR_TRUE == merge) {
+ /* Merge the candidate list into the cipher list */
for (i=0; i<ciphernum; i++) {
- if (!strcmp(ciphers_def[i].openssl_name, cipher) &&
- cipher_list[i] != -1)
- cipher_list[i] = action;
+ if (candidate_list[i])
+ set_cipher_value(cipher_list, i, action);
}
+ merge = PR_FALSE;
+ found = PR_FALSE;
}
}
@@ -262,6 +390,8 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
cipher = ciphers;
}
+ if (found && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2))
+ return 1; /* no matching ciphers */
return 0;
}
diff --git a/nss_engine_cipher.h b/nss_engine_cipher.h
index f0c12f1..2cd103b 100644
--- a/nss_engine_cipher.h
+++ b/nss_engine_cipher.h
@@ -29,27 +29,30 @@ typedef struct
} cipher_properties;
/* OpenSSL-compatible cipher attributes */
-#define SSL_kRSA 0x00000001L
-#define SSL_aRSA 0x00000002L
-#define SSL_aDSS 0x00000004L
-#define SSL_DSS SSL_aDSS
-#define SSL_eNULL 0x00000008L
-#define SSL_DES 0x00000010L
-#define SSL_3DES 0x00000020L
-#define SSL_RC4 0x00000040L
-#define SSL_RC2 0x00000080L
-#define SSL_MD5 0x00000200L
-#define SSL_SHA1 0x00000400L
-#define SSL_SHA SSL_SHA1
-#define SSL_RSA (SSL_kRSA|SSL_aRSA)
-#define SSL_kEDH 0x00000800L
-#define SSL_EDH (SSL_kEDH)
-#define SSL_aNULL 0x00001000L
-#define SSL_kECDHe 0x00002000L
-#define SSL_aECDH 0x00004000L
-#define SSL_aECDSA 0x00008000L
-#define SSL_kECDHr 0x00010000L
-#define SSL_kEECDH 0x00020000L
+#define SSL_kRSA 0x00000001L
+#define SSL_aRSA 0x00000002L
+#define SSL_aDSS 0x00000004L
+#define SSL_DSS SSL_aDSS
+#define SSL_eNULL 0x00000008L
+#define SSL_DES 0x00000010L
+#define SSL_3DES 0x00000020L
+#define SSL_RC4 0x00000040L
+#define SSL_RC2 0x00000080L
+#define SSL_MD5 0x00000200L
+#define SSL_SHA1 0x00000400L
+#define SSL_SHA SSL_SHA1
+#define SSL_RSA (SSL_kRSA)
+#define SSL_kEDH 0x00000800L
+#define SSL_EDH (SSL_kEDH)
+#define SSL_aNULL 0x00001000L
+#define SSL_kECDHe 0x00002000L
+#define SSL_aECDH 0x00004000L
+#define SSL_aECDSA 0x00008000L
+#define SSL_kECDHr 0x00010000L
+#define SSL_kEECDH 0x00020000L
+#define SSL_ECDH (SSL_kECDHe|SSL_kECDHr|SSL_kEECDH)
+#define SSL_EECDH (SSL_kEECDH)
+#define SSL_ADH (SSL_kEDH)
/* cipher strength */
#define SSL_STRONG_NONE 0x00000001L
@@ -60,14 +63,14 @@ typedef struct
#define SSL_MEDIUM 0x00000020L
#define SSL_HIGH 0x00000040L
-#define SSL_AES128 0x00004000L
-#define SSL_AES256 0x00008000L
-#define SSL_CAMELLIA128 0x00010000L
-#define SSL_CAMELLIA256 0x00020000L
-#define SSL_AES128GCM 0x00040000L
-#define SSL_AES256GCM 0x00080000L
-#define SSL_SHA256 0x00100000L
-#define SSL_AEAD 0x00200000L
+#define SSL_AES128 0x00400000L
+#define SSL_AES256 0x00800000L
+#define SSL_CAMELLIA128 0x01000000L
+#define SSL_CAMELLIA256 0x02000000L
+#define SSL_AES128GCM 0x04000000L
+#define SSL_AES256GCM 0x08000000L
+#define SSL_SHA256 0x10000000L
+#define SSL_AEAD 0x20000000L
#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
diff --git a/test/createinstance.sh b/test/createinstance.sh
index c3b7260..9cdba62 100755
--- a/test/createinstance.sh
+++ b/test/createinstance.sh
@@ -25,6 +25,7 @@ mkdir lib
# Create the content
mkdir content/rc4_cipher
mkdir content/openssl_rc4_cipher
+mkdir content/openssl_aes_cipher
mkdir content/acl
mkdir content/protocolssl2
mkdir content/protocolssl3
diff --git a/test/suite1.tmpl b/test/suite1.tmpl
index eb2a16c..0f739a2 100644
--- a/test/suite1.tmpl
+++ b/test/suite1.tmpl
@@ -39,6 +39,12 @@ NSSUserName SSL_CLIENT_S_DN_UID
NSSCipherSuite RC4-SHA
</Location>
+<Location "/openssl_aes_cipher">
+ # In openssl equivalent of AES:-ECDH:-ADH:-PSK:-DH
+ # In NSS equivalent of AES:-ECDH
+ NSSCipherSuite AES+RSA
+</Location>
+
<Location "/acl/aclS01.html">
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:291, 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] <cipher_list>\n");
+ if (argc != 2 && argc != 3) {
+ fprintf(stderr, "Usage: test_cipher [--count] [--o] <cipher_list>\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;