File: user_agent_tls.t

package info (click to toggle)
libmojolicious-perl 9.31%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,260 kB
  • sloc: perl: 10,139; makefile: 31; javascript: 1
file content (125 lines) | stat: -rw-r--r-- 4,928 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use Mojo::Base -strict;

BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }

use Test::More;
use Mojo::IOLoop::TLS;

plan skip_all => 'set TEST_TLS to enable this test (developer only!)' unless $ENV{TEST_TLS} || $ENV{TEST_ALL};
plan skip_all => 'IO::Socket::SSL 2.009+ required for this test!'     unless Mojo::IOLoop::TLS->can_tls;

use Mojo::IOLoop;
use Mojo::Server::Daemon;
use Mojo::UserAgent;
use Mojolicious::Lite;

# Silence
app->log->level('fatal');

get '/' => {text => 'works!'};

subtest 'Web server with valid certificates' => sub {
  my $daemon = Mojo::Server::Daemon->new(app => app, ioloop => Mojo::IOLoop->singleton, silent => 1);
  my $listen
    = 'https://127.0.0.1'
    . '?cert=t/mojo/certs/server.crt'
    . '&key=t/mojo/certs/server.key'
    . '&ca=t/mojo/certs/ca.crt&verify=0x03';
  my $port = $daemon->listen([$listen])->start->ports->[0];

  subtest 'No certificate' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    my $tx = $ua->get("https://127.0.0.1:$port");
    ok $tx->error, 'has error';
    $tx = $ua->get("https://127.0.0.1:$port");
    ok $tx->error, 'has error';
    $tx = $ua->ca('t/mojo/certs/ca.crt')->get("https://127.0.0.1:$port");
    ok $tx->error, 'has error';
    $tx = $ua->get("https://127.0.0.1:$port");
    ok $tx->error, 'has error';
  };

  subtest 'Valid certificates' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    $ua->ca('t/mojo/certs/ca.crt')->cert('t/mojo/certs/client.crt')->key('t/mojo/certs/client.key');
    my $tx = $ua->get("https://127.0.0.1:$port");
    ok !$tx->error, 'no error';
    is $tx->res->code, 200,      'right status';
    is $tx->res->body, 'works!', 'right content';
  };

  subtest 'Valid certificates (env)' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    local $ENV{MOJO_CA_FILE}   = 't/mojo/certs/ca.crt';
    local $ENV{MOJO_CERT_FILE} = 't/mojo/certs/client.crt';
    local $ENV{MOJO_KEY_FILE}  = 't/mojo/certs/client.key';
    local $ENV{MOJO_INSECURE}  = 0;
    my $tx = $ua->get("https://127.0.0.1:$port");
    is $ua->ca,       't/mojo/certs/ca.crt',     'right path';
    is $ua->cert,     't/mojo/certs/client.crt', 'right path';
    is $ua->key,      't/mojo/certs/client.key', 'right path';
    is $ua->insecure, 0,                         'secure';
    ok !$tx->error, 'no error';
    is $tx->res->code, 200,      'right status';
    is $tx->res->body, 'works!', 'right content';
  };

  subtest 'Invalid certificate' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    $ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
    my $tx = $ua->get("https://127.0.0.1:$port");
    ok $tx->error, 'has error';
  };
};


subtest 'Web server with valid certificates and no verification' => sub {
  my $daemon = Mojo::Server::Daemon->new(app => app, ioloop => Mojo::IOLoop->singleton, silent => 1);
  my $listen
    = 'https://127.0.0.1'
    . '?cert=t/mojo/certs/server.crt'
    . '&key=t/mojo/certs/server.key'
    . '&ca=t/mojo/certs/ca.crt'
    . '&ciphers=AES256-SHA:ALL'
    . '&verify=0x00'
    . '&version=TLSv1';
  my $port = $daemon->listen([$listen])->start->ports->[0];

  # Invalid certificate
  my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
  $ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
  my $tx = $ua->get("https://127.0.0.1:$port");
  ok $tx->error, 'has error';
  $ua = Mojo::UserAgent->new(ioloop => $ua->ioloop, insecure => 1);
  $ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
  $tx = $ua->get("https://127.0.0.1:$port");
  ok !$tx->error, 'no error';
  is $ua->ioloop->stream($tx->connection)->handle->get_cipher,     'AES256-SHA', 'AES256-SHA has been negotiatied';
  is $ua->ioloop->stream($tx->connection)->handle->get_sslversion, 'TLSv1',      'TLSv1 has been negotiatied';
};

subtest 'Client side TLS options' => sub {
  my $daemon = Mojo::Server::Daemon->new(app => app, ioloop => Mojo::IOLoop->singleton, silent => 1);
  my $listen = 'https://127.0.0.1/?version=TLSv1_1';
  my $port   = $daemon->listen([$listen])->start->ports->[0];

  subtest '(Not) setting verification mode' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    my $tx = $ua->get("https://127.0.0.1:$port");
    like $tx->error->{message}, qr/certificate verify failed/, 'has error';

    $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    $ua->tls_options({SSL_verify_mode => 0x00});
    $tx = $ua->get("https://127.0.0.1:$port");
    ok !$tx->error, 'no error';
  };

  subtest 'Setting acceptable protocol version' => sub {
    my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
    $ua->tls_options({SSL_version => 'TLSv1_2'});
    my $tx = $ua->get("https://127.0.0.1:$port");
    like $tx->error->{message}, qr/wrong ssl version/, 'has error';
  };
};

done_testing();