summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2014-10-16 16:54:18 -0400
committerRob Crittenden <rcritten@redhat.com>2014-10-17 10:25:31 -0400
commit3a33252f4daaa39bbb77110a1f1f29a4e3ec1546 (patch)
tree209ad4a66258a9b7e8dd535784d6dfd4ba83d34a /test
parent051f87219c90fd2880d432e1d3ca62c45e91209c (diff)
downloadmod_nss-3a33252f4daaa39bbb77110a1f1f29a4e3ec1546.tar.gz
mod_nss-3a33252f4daaa39bbb77110a1f1f29a4e3ec1546.tar.xz
mod_nss-3a33252f4daaa39bbb77110a1f1f29a4e3ec1546.zip
Add a new VirtualHost for testing TLS v1.2
Protocol is a per-server or Virtual Host setting so I added a new VH to do TLSv1.2 testing. It isn't as configurable as I'd like because the port is hardcoded but it'll do for now.
Diffstat (limited to 'test')
-rw-r--r--test/README39
-rwxr-xr-xtest/createinstance.sh11
-rwxr-xr-xtest/setup.sh1
-rw-r--r--test/suite1.tmpl59
-rw-r--r--test/test.py89
-rw-r--r--test/test_config.py11
-rw-r--r--test/test_request.py7
7 files changed, 202 insertions, 15 deletions
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..bd29b1f
--- /dev/null
+++ b/test/README
@@ -0,0 +1,39 @@
+Overview
+--------
+Some basic Apache tests using a local instance of Apache that goes into
+the work subdirectory.
+
+suite1.tmpl defines the basic configuration for the tests.
+
+This tries to load libmodnss.so from the parent directory so you must do
+a 'make' first before trying to run the tests.
+
+Run the tests
+-------------
+./setup.sh
+nosetests -v test.py
+
+Adding tests
+------------
+
+1. Create a new Location in suite1.tmpl with a local configuration to test
+ against.
+
+2. Add a call to this location in test.py
+
+Here are the things that can be tested for:
+
+expected = HTTP response code or SSLError() exception
+protocol =
+cipher = OpenSSL cipher name
+
+
+3. If you make a change to the mod_nss code you'll need to either copy
+ the new module to work/httpd/lib or rm -rf work and re-run setup.sh
+ otherwise you'll be testing against old code.
+
+When testing with NSSRequire I sometimes found it difficult to figure out
+why a request was being rejected. I added a new compile-time define,
+VAR_DEBUG. If this is set then whenever a SSL_ variable is looked up the
+result is logged. This is way too much for a running server but great for
+debugging tests.
diff --git a/test/createinstance.sh b/test/createinstance.sh
index 1eaa644..fac0a7d 100755
--- a/test/createinstance.sh
+++ b/test/createinstance.sh
@@ -13,6 +13,7 @@ mkdir -p $target
cd $target
mkdir alias
+mkdir bin
mkdir conf
mkdir conf.d
mkdir logs
@@ -24,6 +25,11 @@ mkdir lib
# Create the content
mkdir content/rc4_cipher
mkdir content/acl
+mkdir content/protocolssl2
+mkdir content/protocolssl3
+mkdir content/protocoltls1
+mkdir content/protocoltls11
+mkdir content/protocoltls12
cat > content/index.html << EOF
<html>
@@ -34,6 +40,11 @@ cp content/index.html content/acl/aclS01.html
cp content/index.html content/acl/aclS02.html
cp content/index.html content/acl/aclS03.html
cp content/index.html content/secret-test.html
+cp content/index.html content/protocolssl2/index.html
+cp content/index.html content/protocolssl3/index.html
+cp content/index.html content/protocoltls1/index.html
+cp content/index.html content/protocoltls11/index.html
+cp content/index.html content/protocoltls12/index.html
ln -s /etc/httpd/modules modules
diff --git a/test/setup.sh b/test/setup.sh
index 693d603..32f2b8e 100755
--- a/test/setup.sh
+++ b/test/setup.sh
@@ -20,6 +20,7 @@ fi
./createinstance.sh ${test_root}
cp ../.libs/libmodnss.so ${test_root}/lib
+cp ../nss_pcache ${test_root}/bin
../gencert ${test_root}/alias
echo internal:httptest > ${test_root}/conf/password.conf
diff --git a/test/suite1.tmpl b/test/suite1.tmpl
index 999c4d7..8c9e7a3 100644
--- a/test/suite1.tmpl
+++ b/test/suite1.tmpl
@@ -1,3 +1,17 @@
+# Global SSL configuration
+NSSPassPhraseDialog file:$SERVER_ROOT/conf/password.conf
+
+NSSPassPhraseHelper $SERVER_ROOT/bin/nss_pcache
+
+NSSSessionCacheSize 10000
+NSSSessionCacheTimeout 100
+NSSSession3CacheTimeout 86400
+
+Listen 0.0.0.0:$SERVER_PORT
+Listen 0.0.0.0:8001
+
+LogLevel debug
+
<VirtualHost *:$SERVER_PORT>
NSSEngine on
@@ -51,15 +65,46 @@ NSSUserName SSL_CLIENT_S_DN_UID
<Location "/secret-test-impossible.html">
NSSRequire %{SSL_CIPHER_USEKEYSIZE} > 4000
</Location>
+
+<Location "/protocolssl3">
+ NSSRequire %{SSL_PROTOCOL} eq "SSLv3"
+</Location>
+
+<Location "/protocoltls1">
+ NSSRequire %{SSL_PROTOCOL} eq "TLSv1"
+</Location>
+
+<Location "/protocoltls11">
+ NSSRequire %{SSL_PROTOCOL} eq "TLSv1.1"
+</Location>
+
+<Location "/protocoltls12">
+ NSSRequire %{SSL_PROTOCOL} eq "TLSv1.2"
+</Location>
</VirtualHost>
-# SSL configuration
-NSSPassPhraseDialog file:$SERVER_ROOT/conf/password.conf
+#
+# For testing protocol handling
+#
+<VirtualHost *:8001>
-NSSPassPhraseHelper /usr/sbin/nss_pcache
+NSSEngine on
+NSSFIPS off
+NSSOCSP off
+NSSRenegotiation on
-NSSSessionCacheSize 10000
-NSSSessionCacheTimeout 100
-NSSSession3CacheTimeout 86400
+NSSCipherSuite +rc4,+rc4export,+rc2,+rc2export,+des,+desede3,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,+rsa_rc4_128_md5,+rsa_3des_sha,+rsa_des_sha,+rsa_rc4_40_md5,+rsa_rc2_40_md5,+rsa_null_md5,+rsa_des_56_sha,+rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha,+fips_des_sha,+fips_3des_sha
-Listen 0.0.0.0:$SERVER_PORT
+NSSProtocol TLSv1.2
+
+NSSNickname Server-Cert
+
+NSSCertificateDatabase $SERVER_ROOT/alias
+
+NSSVerifyClient none
+
+# A bit redundant since the initial handshake should fail if no TLSv1.2
+<Location "/protocoltls12">
+ NSSRequire %{SSL_PROTOCOL} eq "TLSv1.2"
+</Location>
+</VirtualHost>
diff --git a/test/test.py b/test/test.py
index e7136e6..93e8518 100644
--- a/test/test.py
+++ b/test/test.py
@@ -1,5 +1,6 @@
from test_config import Declarative, write_template_file, restart_apache
from test_config import stop_apache
+import ssl
import requests.exceptions
class test_suite1(Declarative):
@@ -135,4 +136,92 @@ class test_suite1(Declarative):
expected=403,
),
+ # Only SSLv3-TLSv1.1 enabled on 8000
+ dict(
+ desc='Requires TLS v1.2, no support',
+ request=('/protocoltls12/index.html', {}),
+ expected=403,
+ ),
+
+ dict(
+ desc='Try SSLv2 on default server',
+ request=('/protocoltls12/index.html',
+ {'ssl_version': ssl.PROTOCOL_SSLv2}
+ ),
+ expected=requests.exceptions.SSLError(),
+ ),
+
+ dict(
+ desc='Try SSLv23 client on SSLv3 location',
+ request=('/protocolssl3/index.html',
+ {'ssl_version': ssl.PROTOCOL_SSLv23}
+ ),
+ expected=403, # connects as TLSv1
+ ),
+
+ dict(
+ desc='Try TLSv1 client on SSLv3 location',
+ request=('/protocoltls1/index.html',
+ {'ssl_version': ssl.PROTOCOL_TLSv1}
+ ),
+ expected=200,
+ ),
+
+ dict(
+ desc='Try TLSv1 client on TLSv1.1 location',
+ request=('/protocoltls11/index.html',
+ {'ssl_version': ssl.PROTOCOL_TLSv1}
+ ),
+ expected=403,
+ ),
+
+ dict(
+ desc='Try SSLv23 client on TLSv1 location',
+ request=('/protocoltls1/index.html',
+ {'ssl_version': ssl.PROTOCOL_SSLv23}
+ ),
+ expected=200,
+ ),
+
+ dict(
+ desc='Try SSLv23 client on 1.2-only location',
+ request=('/protocoltls12/index.html',
+ {'ssl_version': ssl.PROTOCOL_SSLv23}
+ ),
+ expected=403,
+ ),
+
+ dict(
+ desc='Requires TLSv1.2 on VH that provides it',
+ request=('/protocoltls12/index.html', {'port': 8001}),
+ expected=200,
+ ),
+
+ dict(
+ desc='Try SSLv2 client on 1.2-only VH',
+ request=('/protocoltls12/index.html',
+ {'port': 8001,
+ 'ssl_version': ssl.PROTOCOL_SSLv2}
+ ),
+ expected=requests.exceptions.SSLError(),
+ ),
+
+ dict(
+ desc='Try SSLv3 client on 1.2-only VH',
+ request=('/protocoltls12/index.html',
+ {'port': 8001,
+ 'ssl_version': ssl.PROTOCOL_SSLv3}
+ ),
+ expected=requests.exceptions.SSLError(),
+ ),
+
+ dict(
+ desc='Try TLSv1 client on 1.2-only VH',
+ request=('/protocoltls12/index.html',
+ {'port': 8001,
+ 'ssl_version': ssl.PROTOCOL_TLSv1}
+ ),
+ expected=requests.exceptions.SSLError(),
+ ),
+
]
diff --git a/test/test_config.py b/test/test_config.py
index 9990a92..838ebd7 100644
--- a/test/test_config.py
+++ b/test/test_config.py
@@ -29,11 +29,11 @@ import test_request
# Utility functions to assist in creating Apache configuration based
# on test suite
-PORT=8000
+DEF_PORT=8000
FQDN = socket.gethostname()
default_vars = dict(
- SERVER_PORT = PORT,
+ SERVER_PORT = DEF_PORT,
SERVER_NAME = FQDN,
TEST_ROOT = '%s/work/httpd' % os.getcwd(),
SERVER_ROOT = '%s/work/httpd' % os.getcwd(),
@@ -82,7 +82,7 @@ def restart_apache():
p = subprocess.Popen(['./start'],
close_fds=True)
os.chdir(cwd)
- test_util.wait_for_open_ports(FQDN, PORT)
+ test_util.wait_for_open_ports(FQDN, DEF_PORT)
EXPECTED = """Expected %r to raise %s.
options = %r
@@ -134,7 +134,8 @@ class Declarative(object):
session = requests.Session()
session.mount('https://', test_request.MyAdapter())
verify = dict(verify = options)
- request = session.get('https://%s:%d%s' % (FQDN, PORT, uri), **verify)
+ port = options.get('port', DEF_PORT)
+ request = session.get('https://%s:%d%s' % (FQDN, port, uri), **verify)
return request
@@ -178,7 +179,7 @@ class Declarative(object):
client_cipher = request.raw._pool._get_conn().client_cipher
if protocol != client_cipher[1]:
raise AssertionError(
- 'Expected cipher %s, got %s' % (cipher, client_cipher[1])
+ 'Expected protocol %s, got %s' % (protocol, client_cipher[1])
)
if expected != request.status_code:
raise AssertionError(
diff --git a/test/test_request.py b/test/test_request.py
index 40d8024..bac2a2d 100644
--- a/test/test_request.py
+++ b/test/test_request.py
@@ -141,7 +141,8 @@ class MyVerifiedHTTPSConnection(HTTPSConnection):
match_hostname(self.sock.getpeercert(), self.host)
def close(self):
- self.client_cipher = self.sock.cipher()
+ if self.sock:
+ self.client_cipher = self.sock.cipher()
HTTPSConnection.close(self)
class MyAdapter(requests.adapters.HTTPAdapter):
@@ -177,7 +178,7 @@ class MyAdapter(requests.adapters.HTTPAdapter):
s = requests.Session()
s.mount('https://', MyAdapter())
try:
- r = s.get('https://darlene.greyoak.com:8000/', verify={'verify': False, 'ssl_version': ssl.PROTOCOL_SSLv23, 'ciphers': 'HIGH'})
+ r = s.get('https://test.example.com:8000/', verify={'verify': False, 'ssl_version': ssl.PROTOCOL_SSLv23, 'ciphers': 'HIGH'})
cipher = r.raw._pool._get_conn().client_cipher
except requests.exceptions.SSLError, e:
print e.message
@@ -185,6 +186,6 @@ else:
print r.status_code
print cipher
-#request = requests.get('https://darlene.greyoak.com:8000/', verify=False)
+#request = requests.get('https://test.example.com:8000/', verify=False)
#print request.status_code
"""