1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21
22-module(openssl_renegotiate_SUITE).
23
24-include_lib("common_test/include/ct.hrl").
25
26%% Callback functions
27-export([all/0,
28         groups/0,
29         init_per_suite/1,
30         end_per_suite/1,
31         init_per_group/2,
32         end_per_group/2,
33         init_per_testcase/2,
34         end_per_testcase/2]).
35
36%% Testcases
37-export([erlang_client_openssl_server_renegotiate/0,
38         erlang_client_openssl_server_renegotiate/1,
39         erlang_client_openssl_server_renegotiate_after_client_data/0,
40         erlang_client_openssl_server_renegotiate_after_client_data/1,
41         erlang_client_openssl_server_nowrap_seqnum/0,
42         erlang_client_openssl_server_nowrap_seqnum/1,
43         erlang_server_openssl_client_nowrap_seqnum/0,
44         erlang_server_openssl_client_nowrap_seqnum/1
45        ]).
46
47%% Apply export
48-export([delayed_send/2,
49         send_wait_send/2
50         ]).
51
52-define(SLEEP, 1000).
53-define(OPENSSL_RENEGOTIATE, "R\n").
54-define(DEFAULT_TIMEOUT, {seconds, 30}).
55
56%%--------------------------------------------------------------------
57%% Common Test interface functions -----------------------------------
58%%--------------------------------------------------------------------
59
60all() ->
61    case ssl_test_lib:openssl_sane_dtls() of
62        true ->
63            [{group, 'tlsv1.2'},
64             {group, 'tlsv1.1'},
65             {group, 'tlsv1'},
66             {group, 'dtlsv1.2'},
67             {group, 'dtlsv1'}];
68        false ->
69            [{group, 'tlsv1.2'},
70             {group, 'tlsv1.1'},
71             {group, 'tlsv1'}
72             ]
73    end.
74
75groups() ->
76     case ssl_test_lib:openssl_sane_dtls() of
77         true ->
78             [{'tlsv1.2', [], all_versions_tests()},
79              {'tlsv1.1', [], all_versions_tests()},
80              {'tlsv1', [], all_versions_tests()},
81              {'dtlsv1.2', [], all_versions_tests()},
82              {'dtlsv1', [], all_versions_tests()}
83             ];
84        false ->
85             [{'tlsv1.2', [], all_versions_tests()},
86              {'tlsv1.1', [], all_versions_tests()},
87              {'tlsv1', [], all_versions_tests()}
88           ]
89     end.
90
91all_versions_tests() ->
92    [
93     erlang_client_openssl_server_renegotiate,
94     erlang_client_openssl_server_renegotiate_after_client_data,
95     erlang_client_openssl_server_nowrap_seqnum,
96     erlang_server_openssl_client_nowrap_seqnum
97    ].
98
99
100init_per_suite(Config0) ->
101    case os:find_executable("openssl") of
102        false ->
103            {skip, "Openssl not found"};
104        _ ->
105            ct:pal("Version: ~p", [os:cmd("openssl version")]),
106            catch crypto:stop(),
107            try crypto:start() of
108                ok ->
109                    ssl_test_lib:clean_start(),
110                    ssl_test_lib:make_rsa_cert(Config0)
111            catch _:_  ->
112                    {skip, "Crypto did not start"}
113            end
114    end.
115
116end_per_suite(_Config) ->
117    ssl:stop(),
118    application:stop(crypto),
119    ssl_test_lib:kill_openssl().
120
121init_per_group(GroupName, Config) ->
122    case ssl_test_lib:check_sane_openssl_version(GroupName) of
123        true ->
124            case ssl_test_lib:check_sane_openssl_renegotiate(Config, GroupName) of
125                {skip,_} = Skip ->
126                    Skip;
127                _ ->
128                    ssl_test_lib:init_per_group_openssl(GroupName, Config)
129            end;
130        false  ->
131            {skip, {atom_to_list(GroupName) ++ " not supported by OpenSSL"}}
132    end.
133end_per_group(GroupName, Config) ->
134    ssl_test_lib:end_per_group(GroupName, Config).
135
136init_per_testcase(erlang_client_openssl_server_nowrap_seqnum, Config) ->
137    ct:timetrap(?DEFAULT_TIMEOUT),
138    ssl_test_lib:openssl_allows_client_renegotiate(Config);
139init_per_testcase(_TestCase, Config) ->
140    ct:timetrap(?DEFAULT_TIMEOUT),
141    Config.
142
143end_per_testcase(_, Config) ->
144    Config.
145
146%%--------------------------------------------------------------------
147%% Test Cases --------------------------------------------------------
148%%--------------------------------------------------------------------
149
150erlang_client_openssl_server_renegotiate() ->
151    [{doc,"Test erlang client when openssl server issuses a renegotiate"}].
152erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
153    ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
154    ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
155
156    {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
157
158    ErlData = "From erlang to openssl",
159    OpenSslData = "From openssl to erlang",
160
161    {Server, OpenSSLPort} = ssl_test_lib:start_server(openssl, [return_port],
162                                                      [{server_opts, ServerOpts} | Config]),
163    Port = ssl_test_lib:inet_port(Server),
164
165    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
166                                        {host, Hostname},
167                                        {from, self()},
168                                        {mfa, {?MODULE,
169                                               delayed_send, [[ErlData, OpenSslData]]}},
170                                         {options, [{reuse_sessions, false} | ClientOpts]}]),
171
172    true = port_command(OpenSSLPort, ?OPENSSL_RENEGOTIATE),
173    ct:sleep(?SLEEP),
174    true = port_command(OpenSSLPort, OpenSslData),
175
176    ssl_test_lib:check_result(Client, OpenSslData),
177    ssl_test_lib:close(Client).
178
179%%--------------------------------------------------------------------
180erlang_client_openssl_server_renegotiate_after_client_data() ->
181    [{doc,"Test erlang client when openssl server issuses a renegotiate after reading client data"}].
182erlang_client_openssl_server_renegotiate_after_client_data(Config) when is_list(Config) ->
183    ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
184    ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
185
186    {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
187
188    ErlData = "From erlang to openssl",
189    OpenSslData = "From openssl to erlang",
190
191    {Server, OpenSSLPort} = ssl_test_lib:start_server(openssl, [return_port],
192                                                      [{server_opts, ServerOpts} | Config]),
193    Port = ssl_test_lib:inet_port(Server),
194
195    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
196                                        {host, Hostname},
197                                        {from, self()},
198                                        {mfa, {?MODULE,
199                                               send_wait_send, [[ErlData, OpenSslData]]}},
200                                        {options, [{reuse_sessions, false} |ClientOpts]}]),
201
202    true = port_command(OpenSSLPort, ?OPENSSL_RENEGOTIATE),
203    ct:sleep(?SLEEP),
204    true = port_command(OpenSSLPort, OpenSslData),
205
206    ssl_test_lib:check_result(Client, OpenSslData),
207    ssl_test_lib:close(Client).
208
209%%--------------------------------------------------------------------
210erlang_client_openssl_server_nowrap_seqnum() ->
211    [{doc, "Test that erlang client will renegotiate session when",
212      "max sequence number celing is about to be reached. Although"
213      "in the testcase we use the test option renegotiate_at"
214      " to lower treashold substantially."}].
215erlang_client_openssl_server_nowrap_seqnum(Config) when is_list(Config) ->
216    ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
217    ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
218
219    {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
220
221    ErlData = "From erlang to openssl\n",
222    N = 10,
223
224    Server = ssl_test_lib:start_server(openssl, [],
225                                       [{server_opts, ServerOpts} | Config]),
226    Port = ssl_test_lib:inet_port(Server),
227    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
228                                        {host, Hostname},
229                                        {from, self()},
230                                        {mfa, {ssl_test_lib,
231                                               trigger_renegotiate, [[ErlData, N+2]]}},
232                                        {options, [{reuse_sessions, false},
233                                                   {renegotiate_at, N} | ClientOpts]}]),
234
235    ssl_test_lib:check_result(Client, ok),
236    ssl_test_lib:close(Client).
237
238%%--------------------------------------------------------------------
239erlang_server_openssl_client_nowrap_seqnum() ->
240    [{doc, "Test that erlang server will renegotiate session when",
241      "max sequence number celing is about to be reached. Although"
242      "in the testcase we use the test option renegotiate_at"
243      " to lower treashold substantially."}].
244erlang_server_openssl_client_nowrap_seqnum(Config) when is_list(Config) ->
245    process_flag(trap_exit, true),
246    ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
247    ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
248
249    {_, ServerNode, _Hostname} = ssl_test_lib:run_where(Config),
250
251    Data = "From openssl to erlang",
252
253    N = 10,
254
255    Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
256                                        {from, self()},
257                                        {mfa, {ssl_test_lib,
258                                               trigger_renegotiate, [[Data, N+2]]}},
259                                        {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]),
260    Port = ssl_test_lib:inet_port(Server),
261
262    {_Client, OpenSSLPort} = ssl_test_lib:start_client(openssl, [{port, Port},
263                                                                 {options, ClientOpts},
264                                                                 return_port], Config),
265    true = port_command(OpenSSLPort, Data),
266
267    ssl_test_lib:check_result(Server, ok),
268    ssl_test_lib:close(Server).
269
270%%--------------------------------------------------------------------
271%% Callbacks
272%%--------------------------------------------------------------------
273delayed_send(Socket, [ErlData, OpenSslData]) ->
274    ct:sleep(?SLEEP),
275    ssl:send(Socket, ErlData),
276    ssl_test_lib:active_recv(Socket, length(OpenSslData)).
277
278
279send_wait_send(Socket, [ErlData, OpenSslData]) ->
280    ssl:send(Socket, ErlData),
281    ct:sleep(?SLEEP),
282    ssl:send(Socket, ErlData),
283    ssl_test_lib:active_recv(Socket, length(OpenSslData)).
284
285