diff options
| author | Rob Crittenden <rcritten@redhat.com> | 2014-10-16 16:54:18 -0400 |
|---|---|---|
| committer | Rob Crittenden <rcritten@redhat.com> | 2014-10-17 10:25:31 -0400 |
| commit | 3a33252f4daaa39bbb77110a1f1f29a4e3ec1546 (patch) | |
| tree | 209ad4a66258a9b7e8dd535784d6dfd4ba83d34a /test | |
| parent | 051f87219c90fd2880d432e1d3ca62c45e91209c (diff) | |
| download | mod_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/README | 39 | ||||
| -rwxr-xr-x | test/createinstance.sh | 11 | ||||
| -rwxr-xr-x | test/setup.sh | 1 | ||||
| -rw-r--r-- | test/suite1.tmpl | 59 | ||||
| -rw-r--r-- | test/test.py | 89 | ||||
| -rw-r--r-- | test/test_config.py | 11 | ||||
| -rw-r--r-- | test/test_request.py | 7 |
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 """ |
