]>
Commit | Line | Data |
---|---|---|
ddcc5e5b MC |
1 | #!/usr/bin/perl |
2 | # Written by Matt Caswell for the OpenSSL project. | |
3 | # ==================================================================== | |
4 | # Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. | |
5 | # | |
6 | # Redistribution and use in source and binary forms, with or without | |
7 | # modification, are permitted provided that the following conditions | |
8 | # are met: | |
9 | # | |
10 | # 1. Redistributions of source code must retain the above copyright | |
11 | # notice, this list of conditions and the following disclaimer. | |
12 | # | |
13 | # 2. Redistributions in binary form must reproduce the above copyright | |
14 | # notice, this list of conditions and the following disclaimer in | |
15 | # the documentation and/or other materials provided with the | |
16 | # distribution. | |
17 | # | |
18 | # 3. All advertising materials mentioning features or use of this | |
19 | # software must display the following acknowledgment: | |
20 | # "This product includes software developed by the OpenSSL Project | |
21 | # for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | |
22 | # | |
23 | # 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
24 | # endorse or promote products derived from this software without | |
25 | # prior written permission. For written permission, please contact | |
26 | # openssl-core@openssl.org. | |
27 | # | |
28 | # 5. Products derived from this software may not be called "OpenSSL" | |
29 | # nor may "OpenSSL" appear in their names without prior written | |
30 | # permission of the OpenSSL Project. | |
31 | # | |
32 | # 6. Redistributions of any form whatsoever must retain the following | |
33 | # acknowledgment: | |
34 | # "This product includes software developed by the OpenSSL Project | |
35 | # for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
36 | # | |
37 | # THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
38 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
39 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
40 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
41 | # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
42 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
43 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
44 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
45 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
46 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
47 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
48 | # OF THE POSSIBILITY OF SUCH DAMAGE. | |
49 | # ==================================================================== | |
50 | # | |
51 | # This product includes cryptographic software written by Eric Young | |
52 | # (eay@cryptsoft.com). This product includes software written by Tim | |
53 | # Hudson (tjh@cryptsoft.com). | |
54 | ||
55 | use strict; | |
42e0ccdf | 56 | use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; |
3f22ed2f | 57 | use OpenSSL::Test::Utils; |
ddcc5e5b MC |
58 | use TLSProxy::Proxy; |
59 | use File::Temp qw(tempfile); | |
60 | ||
c27a4049 RL |
61 | my $test_name = "test_sslsessiontick"; |
62 | setup($test_name); | |
63 | ||
60f9f1e1 | 64 | plan skip_all => "TLSProxy isn't usable on $^O" |
2d32d3be | 65 | if $^O =~ /^(VMS|MSWin32)$/; |
60f9f1e1 | 66 | |
2dd400bd | 67 | plan skip_all => "$test_name needs the dynamic engine feature enabled" |
19ab5790 | 68 | if disabled("engine") || disabled("dynamic-engine"); |
c27a4049 | 69 | |
f9e55034 MC |
70 | plan skip_all => "$test_name needs the sock feature enabled" |
71 | if disabled("sock"); | |
72 | ||
c27a4049 RL |
73 | $ENV{OPENSSL_ia32cap} = '~0x200000200000000'; |
74 | ||
75 | sub checkmessages($$$$$$); | |
5427976d | 76 | sub clearclient(); |
c27a4049 RL |
77 | sub clearall(); |
78 | ||
ddcc5e5b MC |
79 | my $chellotickext = 0; |
80 | my $shellotickext = 0; | |
81 | my $fullhand = 0; | |
82 | my $ticketseen = 0; | |
83 | ||
84 | my $proxy = TLSProxy::Proxy->new( | |
85 | undef, | |
25c78440 | 86 | cmdstr(app(["openssl"]), display => 1), |
b44b935e RL |
87 | srctop_file("apps", "server.pem"), |
88 | (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) | |
ddcc5e5b MC |
89 | ); |
90 | ||
cf7f8592 | 91 | plan tests => 8; |
c27a4049 | 92 | |
ddcc5e5b MC |
93 | #Test 1: By default with no existing session we should get a session ticket |
94 | #Expected result: ClientHello extension seen; ServerHello extension seen | |
95 | # NewSessionTicket message seen; Full handshake | |
96 | $proxy->start(); | |
97 | checkmessages(1, "Default session ticket test", 1, 1, 1, 1); | |
98 | ||
99 | #Test 2: If the server does not accept tickets we should get a normal handshake | |
100 | #with no session tickets | |
101 | #Expected result: ClientHello extension seen; ServerHello extension not seen | |
102 | # NewSessionTicket message not seen; Full handshake | |
103 | clearall(); | |
104 | $proxy->serverflags("-no_ticket"); | |
105 | $proxy->start(); | |
106 | checkmessages(2, "No server support session ticket test", 1, 0, 0, 1); | |
107 | ||
108 | #Test 3: If the client does not accept tickets we should get a normal handshake | |
109 | #with no session tickets | |
110 | #Expected result: ClientHello extension not seen; ServerHello extension not seen | |
111 | # NewSessionTicket message not seen; Full handshake | |
112 | clearall(); | |
113 | $proxy->clientflags("-no_ticket"); | |
114 | $proxy->start(); | |
115 | checkmessages(3, "No client support session ticket test", 0, 0, 0, 1); | |
116 | ||
117 | #Test 4: Test session resumption with session ticket | |
118 | #Expected result: ClientHello extension seen; ServerHello extension not seen | |
119 | # NewSessionTicket message not seen; Abbreviated handshake | |
120 | clearall(); | |
121 | (my $fh, my $session) = tempfile(); | |
122 | $proxy->serverconnects(2); | |
123 | $proxy->clientflags("-sess_out ".$session); | |
124 | $proxy->start(); | |
5427976d | 125 | $proxy->clearClient(); |
ddcc5e5b MC |
126 | $proxy->clientflags("-sess_in ".$session); |
127 | $proxy->clientstart(); | |
128 | checkmessages(4, "Session resumption session ticket test", 1, 0, 0, 0); | |
129 | ||
130 | #Test 5: Test session resumption with ticket capable client without a ticket | |
131 | #Expected result: ClientHello extension seen; ServerHello extension seen | |
132 | # NewSessionTicket message seen; Abbreviated handshake | |
133 | clearall(); | |
c27a4049 | 134 | ($fh, $session) = tempfile(); |
ddcc5e5b MC |
135 | $proxy->serverconnects(2); |
136 | $proxy->clientflags("-sess_out ".$session." -no_ticket"); | |
137 | $proxy->start(); | |
5427976d | 138 | $proxy->clearClient(); |
ddcc5e5b MC |
139 | $proxy->clientflags("-sess_in ".$session); |
140 | $proxy->clientstart(); | |
141 | checkmessages(5, "Session resumption with ticket capable client without a " | |
142 | ."ticket", 1, 1, 1, 0); | |
143 | ||
7f6d90ac EK |
144 | #Test 6: Client accepts empty ticket. |
145 | #Expected result: ClientHello extension seen; ServerHello extension seen; | |
146 | # NewSessionTicket message seen; Full handshake. | |
147 | clearall(); | |
148 | $proxy->filter(\&ticket_filter); | |
149 | $proxy->start(); | |
150 | checkmessages(6, "Empty ticket test", 1, 1, 1, 1); | |
151 | ||
cf7f8592 EK |
152 | #Test 7-8: Client keeps existing ticket on empty ticket. |
153 | clearall(); | |
154 | ($fh, $session) = tempfile(); | |
155 | $proxy->serverconnects(3); | |
156 | $proxy->filter(undef); | |
157 | $proxy->clientflags("-sess_out ".$session); | |
158 | $proxy->start(); | |
5427976d | 159 | $proxy->clearClient(); |
cf7f8592 EK |
160 | $proxy->clientflags("-sess_in ".$session." -sess_out ".$session); |
161 | $proxy->filter(\&inject_empty_ticket_filter); | |
162 | $proxy->clientstart(); | |
163 | #Expected result: ClientHello extension seen; ServerHello extension seen; | |
164 | # NewSessionTicket message seen; Abbreviated handshake. | |
165 | checkmessages(7, "Empty ticket resumption test", 1, 1, 1, 0); | |
5427976d | 166 | clearclient(); |
cf7f8592 EK |
167 | $proxy->clientflags("-sess_in ".$session); |
168 | $proxy->filter(undef); | |
169 | $proxy->clientstart(); | |
170 | #Expected result: ClientHello extension seen; ServerHello extension not seen; | |
171 | # NewSessionTicket message not seen; Abbreviated handshake. | |
172 | checkmessages(8, "Empty ticket resumption test", 1, 0, 0, 0); | |
173 | ||
7f6d90ac EK |
174 | |
175 | sub ticket_filter | |
176 | { | |
177 | my $proxy = shift; | |
178 | ||
179 | foreach my $message (@{$proxy->message_list}) { | |
180 | if ($message->mt == TLSProxy::Message::MT_NEW_SESSION_TICKET) { | |
181 | $message->ticket(""); | |
182 | $message->repack(); | |
183 | } | |
184 | } | |
185 | } | |
186 | ||
cf7f8592 EK |
187 | sub inject_empty_ticket_filter { |
188 | my $proxy = shift; | |
189 | ||
190 | foreach my $message (@{$proxy->message_list}) { | |
191 | if ($message->mt == TLSProxy::Message::MT_NEW_SESSION_TICKET) { | |
192 | # Only inject the message first time we're called. | |
193 | return; | |
194 | } | |
195 | } | |
196 | ||
197 | my @new_message_list = (); | |
198 | foreach my $message (@{$proxy->message_list}) { | |
199 | push @new_message_list, $message; | |
200 | if ($message->mt == TLSProxy::Message::MT_SERVER_HELLO) { | |
aa474d1f | 201 | $message->set_extension(TLSProxy::Message::EXT_SESSION_TICKET, ""); |
cf7f8592 EK |
202 | $message->repack(); |
203 | # Tack NewSessionTicket onto the ServerHello record. | |
204 | # This only works if the ServerHello is exactly one record. | |
205 | my $record = ${$message->records}[0]; | |
206 | ||
207 | my $offset = $message->startoffset + $message->encoded_length; | |
208 | my $newsessionticket = TLSProxy::NewSessionTicket->new( | |
209 | 1, "", [$record], $offset, []); | |
210 | $newsessionticket->repack(); | |
211 | push @new_message_list, $newsessionticket; | |
212 | } | |
213 | } | |
214 | $proxy->message_list([@new_message_list]); | |
215 | } | |
216 | ||
c27a4049 | 217 | sub checkmessages($$$$$$) |
ddcc5e5b MC |
218 | { |
219 | my ($testno, $testname, $testch, $testsh, $testtickseen, $testhand) = @_; | |
220 | ||
c27a4049 RL |
221 | subtest $testname => sub { |
222 | ||
223 | foreach my $message (@{$proxy->message_list}) { | |
224 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO | |
ddcc5e5b | 225 | || $message->mt == TLSProxy::Message::MT_SERVER_HELLO) { |
c27a4049 RL |
226 | #Get the extensions data |
227 | my %extensions = %{$message->extension_data}; | |
228 | if (defined | |
aa474d1f | 229 | $extensions{TLSProxy::Message::EXT_SESSION_TICKET}) { |
c27a4049 RL |
230 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { |
231 | $chellotickext = 1; | |
232 | } else { | |
233 | $shellotickext = 1; | |
234 | } | |
235 | } | |
236 | } elsif ($message->mt == TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE) { | |
237 | #Must be doing a full handshake | |
238 | $fullhand = 1; | |
239 | } elsif ($message->mt == TLSProxy::Message::MT_NEW_SESSION_TICKET) { | |
240 | $ticketseen = 1; | |
241 | } | |
242 | } | |
ddcc5e5b | 243 | |
c27a4049 RL |
244 | plan tests => 5; |
245 | ||
7f6d90ac | 246 | ok(TLSProxy::Message->success, "Handshake"); |
c27a4049 RL |
247 | ok(($testch && $chellotickext) || (!$testch && !$chellotickext), |
248 | "ClientHello extension Session Ticket check"); | |
249 | ok(($testsh && $shellotickext) || (!$testsh && !$shellotickext), | |
250 | "ServerHello extension Session Ticket check"); | |
251 | ok(($testtickseen && $ticketseen) || (!$testtickseen && !$ticketseen), | |
252 | "Session Ticket message presence check"); | |
253 | ok(($testhand && $fullhand) || (!$testhand && !$fullhand), | |
254 | "Session Ticket full handshake check"); | |
ddcc5e5b | 255 | } |
ddcc5e5b MC |
256 | } |
257 | ||
5427976d MC |
258 | |
259 | sub clearclient() | |
ddcc5e5b MC |
260 | { |
261 | $chellotickext = 0; | |
262 | $shellotickext = 0; | |
263 | $fullhand = 0; | |
264 | $ticketseen = 0; | |
5427976d MC |
265 | $proxy->clearClient(); |
266 | } | |
267 | ||
268 | sub clearall() | |
269 | { | |
270 | clearclient(); | |
ddcc5e5b MC |
271 | $proxy->clear(); |
272 | } |