diff options
Diffstat (limited to 'debian/perl-framework/t/ssl')
-rw-r--r-- | debian/perl-framework/t/ssl/all.t | 12 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/basicauth.t | 45 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/env.t | 89 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/extlookup.t | 32 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/fakeauth.t | 35 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/headers.t | 28 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/http.t | 48 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/ocsp.t | 53 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/pr12355.t | 55 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/pr43738.t | 28 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/proxy.t | 116 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/require.t | 55 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/v2.t | 28 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/varlookup.t | 261 | ||||
-rw-r--r-- | debian/perl-framework/t/ssl/verify.t | 39 |
15 files changed, 924 insertions, 0 deletions
diff --git a/debian/perl-framework/t/ssl/all.t b/debian/perl-framework/t/ssl/all.t new file mode 100644 index 0000000..d3965d8 --- /dev/null +++ b/debian/perl-framework/t/ssl/all.t @@ -0,0 +1,12 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +my $vars = Apache::Test::vars(); + +#skip all tests in this directory unless ssl is enabled +#and LWP has https support +plan tests => 1, [$vars->{ssl_module_name}, qw(LWP::Protocol::https)]; + +ok 1; + diff --git a/debian/perl-framework/t/ssl/basicauth.t b/debian/perl-framework/t/ssl/basicauth.t new file mode 100644 index 0000000..dde2131 --- /dev/null +++ b/debian/perl-framework/t/ssl/basicauth.t @@ -0,0 +1,45 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestUtil; + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/ssl-fakebasicauth/index.html'; + +plan tests => 4, need need_auth, need_lwp; + +Apache::TestRequest::scheme('https'); + +# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise +# expect a TLS alert which is represented as a 500 by LWP. +ok t_cmp (GET_RC($url, cert => undef), + qr/^(500|403)$/, + "Getting $url with no cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_snakeoil'), + 200, + "Getting $url with client_snakeoil cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_ok'), + 401, + "Getting $url with client_ok cert" + ); + +if (!have_min_apache_version("2.5.1")) { + skip "Colon in username test skipped."; +} +else { + ok t_cmp (GET_RC($url, cert => 'client_colon'), + 403, + "Getting $url with client_colon cert" + ); +} diff --git a/debian/perl-framework/t/ssl/env.t b/debian/perl-framework/t/ssl/env.t new file mode 100644 index 0000000..912a4dc --- /dev/null +++ b/debian/perl-framework/t/ssl/env.t @@ -0,0 +1,89 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestUtil; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestSSLCA (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. +Apache::TestRequest::user_agent_keepalive(0); + +my $cert = 'client_snakeoil'; + +my $server_expect = + Apache::TestSSLCA::dn_vars('ca', 'SERVER_I'); + +my $client_expect = + Apache::TestSSLCA::dn_vars($cert, 'CLIENT_S'); + +my $url = '/ssl-cgi/env.pl'; + +my $tests = (keys(%$server_expect) + keys(%$client_expect) + 1) * 2; +plan tests => $tests, need need_cgi, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $r = GET($url); + +ok t_cmp($r->code, 200, "response status OK"); + +my $env = getenv($r->as_string); + +verify($env, $server_expect); +verify($env, $client_expect, 1); + +$url = '/require-ssl-cgi/env.pl'; + +$r = GET($url, cert => $cert); + +ok t_cmp($r->code, 200, "second response status OK"); + +$env = getenv($r->as_string); + +verify($env, $server_expect); +verify($env, $client_expect); + +sub verify { + my($env, $expect, $ne) = @_; + + while (my($key, $val) = each %$expect) { + # the emailAddress attribute is still exported using the name + # _DN_Email by mod_ssl, even when using OpenSSL 0.9.7. + if ($key =~ /(.*)_emailAddress/) { + $key = $1 . "_Email"; + } + if (Apache::TestConfig::WIN32) { + #perl uppercases all %ENV keys + #which causes SSL_*_DN_Email lookups to fail + $key = uc $key; + } + unless ($ne || $env->{$key}) { + print "#$key does not exist\n"; + $env->{$key} = ""; #prevent use of unitialized value + } + if ($ne) { + print "#$key should not exist\n"; + ok not exists $env->{$key}; + } + else { + print "#$key: expect '$val', got '$env->{$key}'\n"; + ok $env->{$key} eq $val; + } + } +} + +sub getenv { + my $str = shift; + + my %env; + + for my $line (split /[\r\n]+/, $str) { + my($key, $val) = split /\s*=\s*/, $line, 2; + next unless $key and $val; + $env{$key} = $val; + } + + \%env; +} diff --git a/debian/perl-framework/t/ssl/extlookup.t b/debian/perl-framework/t/ssl/extlookup.t new file mode 100644 index 0000000..d40e76e --- /dev/null +++ b/debian/perl-framework/t/ssl/extlookup.t @@ -0,0 +1,32 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +Apache::TestRequest::scheme("https"); + +my %exts = ( + "2.16.840.1.113730.1.13" => "This Is A Comment" +); + +if (have_min_apache_version("2.4.0")) { + $exts{"1.3.6.1.4.1.18060.12.0"} = "Lemons", +} + +plan tests => 2 * (keys %exts), need 'test_ssl', need_min_apache_version(2.1); + +my ($actual, $expected, $r, $c); + +foreach (sort keys %exts) { + $r = GET("/test_ssl_ext_lookup?$_", cert => 'client_ok'); + + ok t_cmp($r->code, 200, "ssl_ext_lookup works for $_"); + + $c = $r->content; + chomp $c; + + ok t_cmp($c, $exts{$_}, "Extension value match for $_"); +} + diff --git a/debian/perl-framework/t/ssl/fakeauth.t b/debian/perl-framework/t/ssl/fakeauth.t new file mode 100644 index 0000000..9009cf4 --- /dev/null +++ b/debian/perl-framework/t/ssl/fakeauth.t @@ -0,0 +1,35 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); +use Apache::TestUtil; + +# check fake authentication using mod_auth_anon +# no cert should fail but the presence of any cert +# should pass. see also t/ssl/basicauth.t + +my $url = '/ssl-fakebasicauth2/index.html'; + +plan tests => 3, need need_auth, + need_module('mod_authn_anon'), + need_min_apache_version(2.1); + +Apache::TestRequest::scheme('https'); + +# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise +# expect a TLS alert which is represented as a 500 by LWP. +ok t_cmp (GET_RC($url, cert => undef), + qr/^(500|403)$/, + "Getting $url with no cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_snakeoil'), + 200, + "Getting $url with client_snakeoil cert" + ); + +ok t_cmp (GET_RC($url, cert => 'client_ok'), + 200, + "Getting $url with client_ok cert" + ); diff --git a/debian/perl-framework/t/ssl/headers.t b/debian/perl-framework/t/ssl/headers.t new file mode 100644 index 0000000..825d6a9 --- /dev/null +++ b/debian/perl-framework/t/ssl/headers.t @@ -0,0 +1,28 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +my $tests = 3; + +plan tests => $tests, need need_lwp, need_module('headers', 'ssl'); + +Apache::TestRequest::scheme('https'); + +my $h = HEAD_STR "/modules/headers/ssl/"; + +# look for 500 when mod_headers doesn't grok the %s tag +if ($h =~ /^HTTP\/1.1 500 Internal Server Error\n/) { + foreach (1..$tests) { + skip "Skipping because mod_headers doesn't grok %s\n"; + } + exit 0; +} + +$h =~ s/Client-Bad-Header-Line:.*$//g; + +ok t_cmp($h, qr/X-SSL-Flag: on/, "SSLFlag header set"); +ok t_cmp($h, qr/X-SSL-Cert:.*END CERTIFICATE-----/, "SSL certificate is unwrapped"); +ok t_cmp($h, qr/X-SSL-None: \(null\)\n/, "unknown SSL variable not given"); diff --git a/debian/perl-framework/t/ssl/http.t b/debian/perl-framework/t/ssl/http.t new file mode 100644 index 0000000..e556224 --- /dev/null +++ b/debian/perl-framework/t/ssl/http.t @@ -0,0 +1,48 @@ +use strict; +use warnings FATAL => 'all'; +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +BEGIN { + # prevent TestRequest from croaking on an HTTP/0.9 response + $ENV{APACHE_TEST_HTTP_09_OK} = 1; +} + +#verify we can send an non-ssl http request to the ssl port +#without dumping core. + +my $url = '/index.html'; + +my @todo; + +if (Apache::TestConfig::WIN32) { + print "\n#ap_core_translate() chokes on ':' here\n", + "#where r->uri = /mod_ssl:error:HTTP-request\n"; + @todo = (todo => [2]); +} + +plan tests => 2, @todo, need_lwp; + +my $config = Apache::Test::config(); +my $ssl_module = $config->{vars}->{ssl_module_name}; +my $hostport = $config->{vhosts}->{$ssl_module}->{hostport}; +my $rurl = "http://$hostport$url"; + +my $res = GET($rurl); +my $proto = $res->protocol; + +if ($proto and $proto eq "HTTP/0.9") { + skip "server gave HTTP/0.9 response"; +} else { + ok t_cmp($res->code, + 400, + "Expected bad request from 'GET $rurl'" + ); +} + +ok t_cmp($res->content, + qr{speaking plain HTTP to an SSL-enabled server port}, + "that error document contains the proper hint" + ); + diff --git a/debian/perl-framework/t/ssl/ocsp.t b/debian/perl-framework/t/ssl/ocsp.t new file mode 100644 index 0000000..9e0d776 --- /dev/null +++ b/debian/perl-framework/t/ssl/ocsp.t @@ -0,0 +1,53 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestSSLCA; +use Apache::TestRequest; +use Apache::TestConfig (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/index.html'; + +Apache::TestRequest::scheme('https'); +Apache::TestRequest::module('ssl_ocsp'); + +my $openssl = Apache::TestSSLCA::openssl(); +if (!have_min_apache_version('2.4.26') + or `$openssl list -commands 2>&1` !~ /ocsp/) { + print "1..0 # skip: No OpenSSL or mod_ssl OCSP support"; + exit 0; +} + +plan tests => 3, need_lwp; + +my $r; + +sok { + $r = GET $url, cert => undef; + my $message = $r->message() || ''; + my $warning = $r->header('Client-Warning') || ''; + print $r->as_string; + $r->code == 500 && $warning =~ 'Internal response' && + $message =~ /alert handshake failure|read failed/; +}; + +sok { + $r = GET $url, cert => 'client_ok'; + print $r->as_string; + $r->code == 200; +}; + +sok { + $r = GET $url, cert => 'client_revoked'; + my $message = $r->message() || ''; + my $warning = $r->header('Client-Warning') || ''; + print $r->as_string; + $r->code == 500 && $warning =~ 'Internal response' && + $message =~ /alert certificate revoked|read failed/; +}; diff --git a/debian/perl-framework/t/ssl/pr12355.t b/debian/perl-framework/t/ssl/pr12355.t new file mode 100644 index 0000000..51be00f --- /dev/null +++ b/debian/perl-framework/t/ssl/pr12355.t @@ -0,0 +1,55 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 10, need 'ssl', need_min_apache_version('2.0'); + +Apache::TestRequest::user_agent( ssl_opts => { SSL_cipher_list => 'ALL'}); +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); + +my $r; + +# Send a series of POST requests with varying size request bodies. +# Alternate between the location which requires a AES128-SHA ciphersuite +# and one which requires AES256-SHA; mod_ssl will attempt to perform the +# renegotiation between each request, and hence needs to perform the +# buffering of request body data. + +$r = POST "/require-aes256-cgi/perl_echo.pl", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "hello world", "request body matches response"); + +$r = POST "/require-aes128-cgi/perl_echo.pl", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "hello world", "request body matches response"); + +$r = POST "/require-aes256-cgi/perl_echo.pl", content => 'x'x10000; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); + +$r = POST "/require-aes128-cgi/perl_echo.pl", content => 'x'x60000; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, $r->request->content, "request body matches response"); + +# Test that content-level input filters are still run as expected by +# using a request which triggers the mod_case_filter_in: + +my @filter = ('X-AddInputFilter' => 'CaseFilterIn'); #mod_client_add_filter + +if (have_module('case_filter_in')) { + $r = POST "/require-aes256-cgi/perl_echo.pl", @filter, content => "hello"; + + ok t_cmp($r->code, 200, "renegotiation on POST works"); + ok t_cmp($r->content, "HELLO", "request body matches response"); +} else { + skip "mod_case_filter_in not available" foreach (1..2); +} + diff --git a/debian/perl-framework/t/ssl/pr43738.t b/debian/perl-framework/t/ssl/pr43738.t new file mode 100644 index 0000000..0814a39 --- /dev/null +++ b/debian/perl-framework/t/ssl/pr43738.t @@ -0,0 +1,28 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; + +plan tests => 4, + need 'ssl', need_module('actions'), + need_min_apache_version('2.2.7'); + +Apache::TestRequest::user_agent( ssl_opts => { SSL_cipher_list => 'ALL'}); +Apache::TestRequest::user_agent_keepalive(1); +Apache::TestRequest::scheme('https'); + +my $r; + +# Variation of the PR 12355 test which breaks per PR 43738. + +$r = POST "/modules/ssl/aes128/empty.pfa", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "/modules/ssl/aes128/empty.pfa\nhello world", "request body matches response"); + +$r = POST "/modules/ssl/aes256/empty.pfa", content => "hello world"; + +ok t_cmp($r->code, 200, "renegotiation on POST works"); +ok t_cmp($r->content, "/modules/ssl/aes256/empty.pfa\nhello world", "request body matches response"); diff --git a/debian/perl-framework/t/ssl/proxy.t b/debian/perl-framework/t/ssl/proxy.t new file mode 100644 index 0000000..bbeddb6 --- /dev/null +++ b/debian/perl-framework/t/ssl/proxy.t @@ -0,0 +1,116 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestCommon (); + +my %frontend = ( + proxy_http_https => 'http', + proxy_https_https => 'https', + proxy_https_http => 'https', +); +my %backend = ( + proxy_http_https => 'https', + proxy_https_https => 'https', + proxy_https_http => 'http', +); + +my $num_modules = scalar keys %frontend; +my $post_module = 'eat_post'; + +my $post_tests = have_module($post_module) ? + Apache::TestCommon::run_post_test_sizes() : 0; + +my $num_http_backends = 0; +for my $module (sort keys %backend) { + if ($backend{$module} eq "http") { + $num_http_backends++; + } +} + +plan tests => (8 + $post_tests) * $num_modules - 5 * $num_http_backends, + need need_lwp, [qw(mod_proxy proxy_http.c)]; + +for my $module (sort keys %frontend) { + + my $scheme = $frontend{$module}; + Apache::TestRequest::module($module); + Apache::TestRequest::scheme($scheme); + + my $hostport = Apache::TestRequest::hostport(); + my $res; + my %vars; + + sok { + t_cmp(GET('/')->code, + 200, + "/ with $module ($scheme)"); + }; + + sok { + t_cmp(GET('/modules/cgi/nph-foldhdr.pl')->code, + 200, + "CGI script with folded headers"); + }; + + if ($backend{$module} eq "https") { + sok { + t_cmp(GET('/verify')->code, + 200, + "using valid proxyssl client cert"); + }; + + sok { + t_cmp(GET('/require/snakeoil')->code, + 403, + "using invalid proxyssl client cert"); + }; + + $res = GET('/require-ssl-cgi/env.pl'); + + sok { + t_cmp($res->code, 200, "protected cgi script"); + }; + + my $body = $res->content || ""; + + for my $line (split /\s*\r?\n/, $body) { + my($key, $val) = split /\s*=\s*/, $line, 2; + next unless $key; + $vars{$key} = $val || ""; + } + + sok { + t_cmp($vars{HTTP_X_FORWARDED_HOST}, + $hostport, + "X-Forwarded-Host header"); + }; + + sok { + t_cmp($vars{SSL_CLIENT_S_DN_CN}, + 'client_ok', + "client subject common name"); + }; + } + + sok { + #test that ProxyPassReverse rewrote the Location header + #to use the frontend server rather than downstream server + my $uri = '/modules'; + my $ruri = Apache::TestRequest::resolve_url($uri) . '/'; + + #tell lwp not to follow redirect so we can see the Location header + local $Apache::TestRequest::RedirectOK = 0; + + $res = GET($uri); + + my $location = $res->header('Location') || 'NONE'; + + t_cmp($location, $ruri, 'ProxyPassReverse Location rewrite'); + }; + + Apache::TestCommon::run_post_test($post_module) if $post_tests; + Apache::TestRequest::user_agent(reset => 1); +} diff --git a/debian/perl-framework/t/ssl/require.t b/debian/perl-framework/t/ssl/require.t new file mode 100644 index 0000000..2a218d4 --- /dev/null +++ b/debian/perl-framework/t/ssl/require.t @@ -0,0 +1,55 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $sslrequire_oid_needed_version = '2.1.7'; +my $have_sslrequire_oid = have_min_apache_version($sslrequire_oid_needed_version); + +plan tests => 10, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $url = '/require/asf/index.html'; + +ok GET_RC($url, cert => undef) != 200; + +ok GET_RC($url, cert => 'client_ok') == 200; + +ok GET_RC($url, cert => 'client_revoked') != 200; + +$url = '/require/snakeoil/index.html'; + +ok GET_RC($url, cert => 'client_ok') != 200; + +ok GET_RC($url, cert => 'client_snakeoil') == 200; + +ok GET_RC('/require/strcmp/index.html', cert => undef) == 200; + +ok GET_RC('/require/intcmp/index.html', cert => undef) == 200; + +if ($have_sslrequire_oid) { + + $url = '/require/certext/index.html'; + + ok GET_RC($url, cert => undef) != 200; + + if (!have_min_apache_version("2.4.0")) { + skip "not backported, see 2.2.19 vote thread for analysis"; + } + else { + ok GET_RC($url, cert => 'client_ok') == 200; + } + + ok GET_RC($url, cert => 'client_snakeoil') != 200; + +} else { + skip "skipping certificate extension test (httpd < $sslrequire_oid_needed_version)" foreach (1..3); +} diff --git a/debian/perl-framework/t/ssl/v2.t b/debian/perl-framework/t/ssl/v2.t new file mode 100644 index 0000000..643c9d7 --- /dev/null +++ b/debian/perl-framework/t/ssl/v2.t @@ -0,0 +1,28 @@ +BEGIN { + $ENV{HTTPS_VERSION} = 2; #use SSLv2 instead of SSLv3 +} + +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; + +plan tests => 1, need need_lwp, + { "SSLv2 test(s) not applicable" => + sub { !need_min_apache_version('2.4.0') } }; + +Apache::TestRequest::scheme('https'); + +#just make sure the basics work for SSLv2 +ok GET_OK('/'); + +#per-dir renegotiation does not work with SSLv2, +#same breakage with apache-1.3.22+mod_ssl-2.8.5 +my $url = '/require/asf/index.html'; + +#ok GET_RC($url, cert => undef) != 200; + +#ok GET_RC($url, cert => 'client_ok') == 200; + +#ok GET_RC($url, cert => 'client_revoked') != 200; diff --git a/debian/perl-framework/t/ssl/varlookup.t b/debian/perl-framework/t/ssl/varlookup.t new file mode 100644 index 0000000..126d442 --- /dev/null +++ b/debian/perl-framework/t/ssl/varlookup.t @@ -0,0 +1,261 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestUtil; +use Apache::TestSSLCA qw(dn dn_oneline); + +unless (have_lwp) { + # bail out early, since the parser below relies on $LWP::VERSION + plan tests => 0, need_lwp; +} + +use Time::localtime; + +my $config = Apache::Test::config(); +my $vars = Apache::Test::vars(); +my $server = $config->server; +my $time = localtime(); + +(my $mmn = $config->{httpd_info}->{MODULE_MAGIC_NUMBER}) =~ s/:\d+$//; + +#Apache::TestRequest::scheme('https'); +local $vars->{scheme} = 'https'; +my $port = $config->port; +my $rfc2253 = have_min_apache_version('2.3.11'); + +my $url = '/test_ssl_var_lookup'; +my(%lookup, @vars); + +my %client_dn = dn('client_ok'); + +my $client_dn = dn_oneline(\%client_dn, $rfc2253); + +my %client_i_dn = dn('ca'); + +my $client_i_dn = dn_oneline(\%client_i_dn, $rfc2253); + +my %server_dn = dn('server'); + +my $dgst = Apache::TestSSLCA::dgst(); + +my $email_field = Apache::TestSSLCA::email_field(); + +my $san_email = "$client_dn{$email_field}"; + +my $san_dns = "$server_dn{CN}"; + +my $san_msupn = $san_email; + +my $san_dnssrv = "_https.$server_dn{CN}"; + +if (not have_min_apache_version('2.4.13')) { + $san_email = $san_dns = "NULL"; +} + +if (not have_min_apache_version('2.4.17') or + Apache::Test::normalize_vstring(Apache::TestSSLCA::version()) < + Apache::Test::normalize_vstring("0.9.8")) { + $san_msupn = $san_dnssrv = "NULL"; +} + +# YYY will be turned into a pattern match: httpd-test/([-\w]+) +# so we can test with different server keys/certs +$server_dn{OU} = 'httpd-test/YYY'; +$server_dn{CN} = $vars->{servername}; + +my $server_dn = dn_oneline(\%server_dn, $rfc2253); + +$server_dn =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)}; +$server_dn{OU} =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)}; + +my %server_i_dn = %client_i_dn; +my $server_i_dn = $client_i_dn; + +my $cert_datefmt = '^\w{3} {1,2}\d{1,2} \d{2}:\d{2}:\d{2} \d{4} GMT$'; + +while (<DATA>) { + chomp; + s/^\s+//; s/\s+$//; + s/\#.*//; + next unless $_; + my($key, $val) = split /\s+/, $_, 2; + next unless $key and $val; + + if ($val =~ /^\"/) { + $val = eval qq($val); + } + elsif ($val =~ /^\'([^\']+)\'$/) { + $val = $1; + } + else { + $val = eval $val; + } + + die $@ if $@; + + $lookup{$key} = $val; + push @vars, $key; +} + +if (not have_min_apache_version('2.4.32')) { + @vars = grep(!/_RAW/, @vars); +} + +plan tests => scalar (@vars), need need_lwp, need_module('test_ssl'); + +for my $key (@vars) { + sok { verify($key); }; +} + +sub verify { + my $key = shift; + my @headers; + if ($key eq 'HTTP_REFERER') { + push @headers, Referer => $0; + } + my $str = GET_BODY("$url?$key", cert => 'client_ok', + @headers); + t_cmp($str, $lookup{$key}, "$key"); +} + +__END__ +#http://www.modssl.org/docs/2.8/ssl_reference.html#ToC23 +HTTP_USER_AGENT "libwww-perl/$LWP::VERSION", +HTTP:User-Agent "libwww-perl/$LWP::VERSION", +HTTP_REFERER "$0" +HTTP_COOKIE +HTTP_FORWARDED +HTTP_HOST Apache::TestRequest::hostport() +HTTP_PROXY_CONNECTION +HTTP_ACCEPT + +#standard CGI variables +PATH_INFO +AUTH_TYPE +QUERY_STRING 'QUERY_STRING' +SERVER_SOFTWARE qr(^$server->{version}) +SERVER_ADMIN $vars->{serveradmin} +SERVER_PORT "$port" +SERVER_NAME $vars->{servername} +SERVER_PROTOCOL qr(^HTTP/1\.\d$) +REMOTE_IDENT +REMOTE_ADDR $vars->{remote_addr} +REMOTE_HOST +REMOTE_USER +DOCUMENT_ROOT $vars->{documentroot} +REQUEST_METHOD 'GET' +REQUEST_URI $url + +#mod_ssl specific variables +TIME_YEAR $time->year()+1900 +TIME_MON sprintf "%02d", $time->mon()+1 +TIME_DAY sprintf "%02d", $time->mday() +TIME_WDAY $time->wday() +TIME +TIME_HOUR +TIME_MIN +TIME_SEC + +IS_SUBREQ 'false' +API_VERSION "$mmn" +THE_REQUEST qr(^GET $url\?THE_REQUEST HTTP/1\.\d$) +REQUEST_SCHEME $vars->{scheme} +REQUEST_FILENAME +HTTPS 'on' +ENV:THE_ARGS 'ENV:THE_ARGS' + +#XXX: should use Net::SSLeay to parse the certs +#rather than just pattern match and hardcode + +SSL_CLIENT_M_VERSION qr(^\d+$) +SSL_SERVER_M_VERSION qr(^\d+$) +SSL_CLIENT_M_SERIAL qr(^[0-9A-F]+$) +SSL_SERVER_M_SERIAL qr(^[0-9A-F]+$) +SSL_PROTOCOL qr((TLS|SSL)v([1-3]|1\.[0-3])$) +SSL_CLIENT_V_START qr($cert_datefmt); +SSL_SERVER_V_START qr($cert_datefmt); +SSL_SESSION_ID +SSL_CLIENT_V_END qr($cert_datefmt); +SSL_SERVER_V_END qr($cert_datefmt); +SSL_CIPHER qr(^[A-Z0-9_-]+$) +SSL_CIPHER_EXPORT 'false' +SSL_CIPHER_ALGKEYSIZE qr(^\d+$) +SSL_CIPHER_USEKEYSIZE qr(^\d+$) +SSL_SECURE_RENEG qr(^(false|true)$) + +SSL_CLIENT_S_DN "$client_dn" +SSL_SERVER_S_DN qr(^$server_dn$) +SSL_CLIENT_S_DN_C "$client_dn{C}" +SSL_SERVER_S_DN_C "$server_dn{C}" +SSL_CLIENT_S_DN_ST "$client_dn{ST}" +SSL_SERVER_S_DN_ST "$server_dn{ST}" +SSL_CLIENT_S_DN_L "$client_dn{L}" +SSL_SERVER_S_DN_L "$server_dn{L}" +SSL_CLIENT_S_DN_O "$client_dn{O}" +SSL_SERVER_S_DN_O "$server_dn{O}" +SSL_CLIENT_S_DN_OU "$client_dn{OU}" +SSL_SERVER_S_DN_OU qr(^$server_dn{OU}) +SSL_CLIENT_S_DN_CN "$client_dn{CN}" +SSL_SERVER_S_DN_CN "$server_dn{CN}" +SSL_CLIENT_S_DN_T +SSL_SERVER_S_DN_T +SSL_CLIENT_S_DN_I +SSL_SERVER_S_DN_I +SSL_CLIENT_S_DN_G +SSL_SERVER_S_DN_G +SSL_CLIENT_S_DN_S +SSL_SERVER_S_DN_S +SSL_CLIENT_S_DN_D +SSL_SERVER_S_DN_D +SSL_CLIENT_S_DN_UID +SSL_SERVER_S_DN_UID +SSL_CLIENT_S_DN_Email "$client_dn{$email_field}" +SSL_SERVER_S_DN_Email "$server_dn{$email_field}" +SSL_CLIENT_SAN_Email_0 "$san_email" +SSL_SERVER_SAN_DNS_0 "$san_dns" +SSL_CLIENT_SAN_OTHER_msUPN_0 "$san_msupn" +SSL_SERVER_SAN_OTHER_dnsSRV_0 "$san_dnssrv" + +SSL_CLIENT_I_DN "$client_i_dn" +SSL_SERVER_I_DN "$server_i_dn" +SSL_CLIENT_I_DN_C "$client_i_dn{C}" +SSL_SERVER_I_DN_C "$server_i_dn{C}" +SSL_CLIENT_I_DN_ST "$client_i_dn{ST}" +SSL_SERVER_I_DN_ST "$server_i_dn{ST}" +SSL_CLIENT_I_DN_L "$client_i_dn{L}" +SSL_SERVER_I_DN_L "$server_i_dn{L}" +SSL_CLIENT_I_DN_O "$client_i_dn{O}" +SSL_SERVER_I_DN_O "$server_i_dn{O}" +SSL_CLIENT_I_DN_OU "$client_i_dn{OU}" +SSL_SERVER_I_DN_OU "$server_i_dn{OU}" +SSL_CLIENT_I_DN_CN "$client_i_dn{CN}" +SSL_SERVER_I_DN_CN "$server_i_dn{CN}" +SSL_SERVER_I_DN_CN_RAW "$server_i_dn{CN}" +SSL_SERVER_I_DN_CN_0_RAW "$server_i_dn{CN}" +SSL_CLIENT_I_DN_T +SSL_SERVER_I_DN_T +SSL_CLIENT_I_DN_I +SSL_SERVER_I_DN_I +SSL_CLIENT_I_DN_G +SSL_SERVER_I_DN_G +SSL_CLIENT_I_DN_S +SSL_SERVER_I_DN_S +SSL_CLIENT_I_DN_D +SSL_SERVER_I_DN_D +SSL_CLIENT_I_DN_UID +SSL_SERVER_I_DN_UID +SSL_CLIENT_I_DN_Email "$client_i_dn{$email_field}" +SSL_SERVER_I_DN_Email "$server_i_dn{$email_field}" +SSL_CLIENT_A_SIG "${dgst}WithRSAEncryption" +SSL_SERVER_A_SIG "${dgst}WithRSAEncryption" +SSL_CLIENT_A_KEY 'rsaEncryption' +SSL_SERVER_A_KEY qr(^[rd]saEncryption$) +SSL_CLIENT_CERT qr(^-----BEGIN CERTIFICATE-----) +SSL_SERVER_CERT qr(^-----BEGIN CERTIFICATE-----) +#SSL_CLIENT_CERT_CHAINn +SSL_CLIENT_VERIFY 'SUCCESS' +SSL_VERSION_LIBRARY +SSL_VERSION_INTERFACE + diff --git a/debian/perl-framework/t/ssl/verify.t b/debian/perl-framework/t/ssl/verify.t new file mode 100644 index 0000000..7bca845 --- /dev/null +++ b/debian/perl-framework/t/ssl/verify.t @@ -0,0 +1,39 @@ +use strict; +use warnings FATAL => 'all'; + +use Apache::Test; +use Apache::TestRequest; +use Apache::TestConfig (); + +#if keepalives are on, renegotiation not happen again once +#a client cert is presented. so on test #3, the cert from #2 +#will be used. this test scenerio would never +#happen in real-life, so just disable keepalives here. +Apache::TestRequest::user_agent_keepalive(0); + +my $url = '/verify/index.html'; + +plan tests => 3, need_lwp; + +Apache::TestRequest::scheme('https'); + +my $r; + +sok { + $r = GET $url, cert => undef; + print $r->as_string; + $r->code != 200; +}; + +sok { + $r = GET $url, cert => 'client_ok'; + print $r->as_string; + $r->code == 200; +}; + +sok { + $r = GET $url, cert => 'client_revoked'; + print $r->as_string; + $r->code != 200; +}; + |