1use Mojo::Base -strict;
2
3BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }
4
5use Test::More;
6use Mojo::IOLoop::TLS;
7
8plan skip_all => 'set TEST_TLS to enable this test (developer only!)' unless $ENV{TEST_TLS} || $ENV{TEST_ALL};
9plan skip_all => 'IO::Socket::SSL 2.009+ required for this test!'     unless Mojo::IOLoop::TLS->can_tls;
10
11use Mojo::IOLoop;
12use Mojo::Promise;
13use Socket;
14
15subtest 'Built-in certificate' => sub {
16  socketpair(my $client_sock, my $server_sock, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
17    or die "Couldn't create socket pair: $!";
18  $client_sock->blocking(0);
19  $server_sock->blocking(0);
20  my $promise  = Mojo::Promise->new;
21  my $promise2 = Mojo::Promise->new;
22  my $server   = Mojo::IOLoop::TLS->new($server_sock);
23  $server->once(upgrade => sub { $promise->resolve(pop) });
24  $server->once(error   => sub { warn pop });
25  $server->negotiate({server => 1});
26  my $client = Mojo::IOLoop::TLS->new($client_sock);
27  $client->once(upgrade => sub { $promise2->resolve(pop) });
28  $client->once(error   => sub { warn pop });
29  $client->negotiate(tls_options => {SSL_verify_mode => 0x00});
30  my ($client_result, $server_result);
31  Mojo::Promise->all($promise, $promise2)->then(sub {
32    ($server_result, $client_result) = map { $_->[0] } @_;
33  })->wait;
34  is ref $client_result, 'IO::Socket::SSL', 'right class';
35  is ref $server_result, 'IO::Socket::SSL', 'right class';
36};
37
38subtest 'Built-in certificate (custom event loop and cipher)' => sub {
39  my $loop = Mojo::IOLoop->new;
40  socketpair(my $client_sock2, my $server_sock2, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
41    or die "Couldn't create socket pair: $!";
42  $client_sock2->blocking(0);
43  $server_sock2->blocking(0);
44  my $promise  = Mojo::Promise->new->ioloop($loop);
45  my $promise2 = Mojo::Promise->new->ioloop($loop);
46  my $server   = Mojo::IOLoop::TLS->new($server_sock2)->reactor($loop->reactor);
47  $server->once(upgrade => sub { $promise->resolve(pop) });
48  $server->once(error   => sub { warn pop });
49  $server->negotiate(server => 1, tls_options => {SSL_cipher_list => 'AES256-SHA:ALL'});
50  my $client = Mojo::IOLoop::TLS->new($client_sock2)->reactor($loop->reactor);
51  $client->once(upgrade => sub { $promise2->resolve(pop) });
52  $client->once(error   => sub { warn pop });
53  $client->negotiate(tls_options => {SSL_verify_mode => 0x00});
54  my ($client_result, $server_result);
55  Mojo::Promise->all($promise, $promise2)->then(sub {
56    ($server_result, $client_result) = map { $_->[0] } @_;
57  })->wait;
58  is ref $client_result, 'IO::Socket::SSL', 'right class';
59  is ref $server_result, 'IO::Socket::SSL', 'right class';
60  my $expect = $server_result->get_sslversion eq 'TLSv1_3' ? 'TLS_AES_256_GCM_SHA384' : 'AES256-SHA';
61  is $client_result->get_cipher, $expect, "$expect has been negotiatied";
62  is $server_result->get_cipher, $expect, "$expect has been negotiatied";
63};
64
65done_testing;
66