Mercurial > hg > nginx-tests
comparison ssl_sni.t @ 237:90af19544dd2
Tests: https sni tests.
author | Valentin Bartenev <ne@vbart.ru> |
---|---|
date | Mon, 01 Oct 2012 02:54:57 +0400 |
parents | |
children | de7338227832 |
comparison
equal
deleted
inserted
replaced
236:5ac875a3088e | 237:90af19544dd2 |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Maxim Dounin | |
4 # (C) Valentin Bartenev | |
5 | |
6 # Tests for Server Name Indication (SNI) TLS extension | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
16 | |
17 use lib 'lib'; | |
18 use Test::Nginx; | |
19 | |
20 ############################################################################### | |
21 | |
22 select STDERR; $| = 1; | |
23 select STDOUT; $| = 1; | |
24 | |
25 my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite/) | |
26 ->has_daemon('openssl') | |
27 ->write_file_expand('nginx.conf', <<'EOF'); | |
28 | |
29 %%TEST_GLOBALS%% | |
30 | |
31 daemon off; | |
32 | |
33 events { | |
34 } | |
35 | |
36 http { | |
37 %%TEST_GLOBALS_HTTP%% | |
38 | |
39 server { | |
40 listen 127.0.0.1:8443 ssl; | |
41 server_name localhost; | |
42 | |
43 ssl_certificate_key localhost.key; | |
44 ssl_certificate localhost.crt; | |
45 | |
46 location / { | |
47 return 200 $server_name; | |
48 } | |
49 } | |
50 | |
51 server { | |
52 listen 127.0.0.1:8443; | |
53 server_name example.com; | |
54 | |
55 ssl_certificate_key example.com.key; | |
56 ssl_certificate example.com.crt; | |
57 | |
58 location / { | |
59 return 200 $server_name; | |
60 } | |
61 } | |
62 } | |
63 | |
64 EOF | |
65 | |
66 eval { require IO::Socket::SSL; die if $IO::Socket::SSL::VERSION < 1.56; }; | |
67 plan(skip_all => 'IO::Socket::SSL version >= 1.56 required') if $@; | |
68 | |
69 eval { | |
70 my $ctx = Net::SSLeay::CTX_new() or die; | |
71 my $ssl = Net::SSLeay::new($ctx) or die; | |
72 Net::SSLeay::set_tlsext_host_name($ssl, 'example.org') == 1 or die; | |
73 }; | |
74 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@; | |
75 | |
76 $t->plan(6); | |
77 | |
78 $t->write_file('openssl.conf', <<EOF); | |
79 [ req ] | |
80 default_bits = 2048 | |
81 encrypt_key = no | |
82 distinguished_name = req_distinguished_name | |
83 [ req_distinguished_name ] | |
84 EOF | |
85 | |
86 my $d = $t->testdir(); | |
87 | |
88 foreach my $name ('localhost', 'example.com') { | |
89 system('openssl req -x509 -new ' | |
90 . "-config '$d/openssl.conf' -subj '/CN=$name/' " | |
91 . "-out '$d/$name.crt' -keyout '$d/$name.key' " | |
92 . ">>$d/openssl.out 2>&1") == 0 | |
93 or die "Can't create certificate for $name: $!\n"; | |
94 } | |
95 | |
96 $t->run(); | |
97 | |
98 ############################################################################### | |
99 | |
100 like(get_cert_cn(), qr!/CN=localhost!, 'default cert'); | |
101 like(get_cert_cn('example.com'), qr!/CN=example.com!, 'sni cert'); | |
102 | |
103 like(https_get_host('example.com'), qr!example.com!, | |
104 'host exists, sni exists, and host is equal sni'); | |
105 | |
106 like(https_get_host('example.com', 'example.org'), qr!example.com!, | |
107 'host exists, sni not found'); | |
108 | |
109 TODO: { | |
110 local $TODO = 'sni restrictions'; | |
111 | |
112 like(https_get_host('example.com', 'localhost'), qr!400 Bad Request!, | |
113 'host exists, sni exists, and host is not equal sni'); | |
114 | |
115 like(https_get_host('example.org', 'example.com'), qr!400 Bad Request!, | |
116 'host not found, sni exists'); | |
117 | |
118 } | |
119 | |
120 ############################################################################### | |
121 | |
122 sub get_ssl_socket { | |
123 my ($host) = @_; | |
124 my $s; | |
125 | |
126 eval { | |
127 local $SIG{ALRM} = sub { die "timeout\n" }; | |
128 local $SIG{PIPE} = sub { die "sigpipe\n" }; | |
129 alarm(2); | |
130 $s = IO::Socket::SSL->new( | |
131 Proto => 'tcp', | |
132 PeerAddr => '127.0.0.1:8443', | |
133 SSL_hostname => $host, | |
134 SSL_error_trap => sub { die $_[1] } | |
135 ); | |
136 alarm(0); | |
137 }; | |
138 alarm(0); | |
139 | |
140 if ($@) { | |
141 log_in("died: $@"); | |
142 return undef; | |
143 } | |
144 | |
145 return $s; | |
146 } | |
147 | |
148 sub get_cert_cn { | |
149 my ($host) = @_; | |
150 my $s = get_ssl_socket($host); | |
151 | |
152 return $s->dump_peer_certificate(); | |
153 } | |
154 | |
155 sub https_get_host { | |
156 my ($host, $sni) = @_; | |
157 my $s = get_ssl_socket($sni ? $sni : $host); | |
158 | |
159 return http(<<EOF, socket => $s); | |
160 GET / HTTP/1.0 | |
161 Host: $host | |
162 | |
163 EOF | |
164 } | |
165 | |
166 ############################################################################### |