Add geturl connectivity unit tests

Addresses #232
This commit is contained in:
Richard Hansen 2020-06-21 23:18:53 -04:00
parent b6770a4d9f
commit 323208e9cc
9 changed files with 770 additions and 2 deletions

View file

@ -29,7 +29,14 @@ jobs:
automake \ automake \
ca-certificates \ ca-certificates \
git \ git \
libhttp-daemon-perl \
libhttp-daemon-ssl-perl \
libio-socket-inet6-perl \
libio-socket-ip-perl \
libplack-perl \
libtest-tcp-perl \
libtest-warnings-perl \ libtest-warnings-perl \
liburi-perl \
make \ make \
; ;
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View file

@ -58,6 +58,8 @@ sysconf_DATA = ddclient.conf
install-data-local: install-data-local:
$(MKDIR_P) '$(DESTDIR)$(localstatedir)'/cache/ddclient $(MKDIR_P) '$(DESTDIR)$(localstatedir)'/cache/ddclient
AM_TESTS_ENVIRONMENT = \
abs_top_srcdir='$(abs_top_srcdir)'; export abs_top_srcdir;
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/build-aux/tap-driver.sh $(top_srcdir)/build-aux/tap-driver.sh
TEST_EXTENSIONS = .pl TEST_EXTENSIONS = .pl
@ -67,8 +69,13 @@ AM_PL_LOG_FLAGS = -Mstrict -w \
-I'$(abs_top_builddir)' \ -I'$(abs_top_builddir)' \
-I'$(abs_top_srcdir)'/t/lib -I'$(abs_top_srcdir)'/t/lib
handwritten_tests = \ handwritten_tests = \
t/geturl_connectivity.pl \
t/parse_assignments.pl t/parse_assignments.pl
generated_tests = \ generated_tests = \
t/version.pl t/version.pl
TESTS = $(handwritten_tests) $(generated_tests) TESTS = $(handwritten_tests) $(generated_tests)
EXTRA_DIST += $(handwritten_tests) EXTRA_DIST += $(handwritten_tests) \
t/lib/ddclient/Test/Fake/HTTPD.pm \
t/lib/ddclient/Test/Fake/HTTPD/dummy-ca-cert.pem \
t/lib/ddclient/Test/Fake/HTTPD/dummy-server-cert.pem \
t/lib/ddclient/Test/Fake/HTTPD/dummy-server-key.pem

View file

@ -53,7 +53,17 @@ m4_foreach_w([_m], [
# then some tests will be skipped, but no tests should fail. Only # then some tests will be skipped, but no tests should fail. Only
# prints a warning if not installed. # prints a warning if not installed.
m4_foreach_w([_m], [ m4_foreach_w([_m], [
Carp
Exporter
HTTP::Daemon=6.12
HTTP::Daemon::SSL
HTTP::Message::PSGI
IO::Socket::IP
Scalar::Util
Test::TCP
Test::Warnings Test::Warnings
Time::HiRes
URI
], [AX_PROG_PERL_MODULES([_m], [], ], [AX_PROG_PERL_MODULES([_m], [],
[AC_MSG_WARN([some tests may be skipped due to missing module _m])])]) [AC_MSG_WARN([some tests may be skipped due to missing module _m])])])

View file

@ -66,7 +66,8 @@ local $lineno = '';
$ENV{'PATH'} = (exists($ENV{PATH}) ? "$ENV{PATH}:" : "") . "/sbin:/usr/sbin:/bin:/usr/bin:/etc:/usr/lib:"; $ENV{'PATH'} = (exists($ENV{PATH}) ? "$ENV{PATH}:" : "") . "/sbin:/usr/sbin:/bin:/usr/bin:/etc:/usr/lib:";
my ($result, %config, %globals, %cache); our %globals;
my ($result, %config, %cache);
my $saved_cache; my $saved_cache;
my %saved_opt; my %saved_opt;
my $daemon; my $daemon;

89
t/geturl_connectivity.pl Normal file
View file

@ -0,0 +1,89 @@
use Test::More;
eval { require ddclient::Test::Fake::HTTPD; } or plan(skip_all => $@);
SKIP: { eval { require Test::Warnings; } or skip($@, 1); }
eval { require 'ddclient'; } or BAIL_OUT($@);
my $has_http_daemon_ssl = eval { require HTTP::Daemon::SSL; };
my $ipv6_supported = eval {
require IO::Socket::IP;
my $ipv6_socket = IO::Socket::IP->new(
Domain => 'PF_INET6',
LocalHost => '::1',
Listen => 1,
);
defined($ipv6_socket);
};
my $http_daemon_supports_ipv6 = eval {
require HTTP::Daemon;
HTTP::Daemon->VERSION(6.12);
};
# To aid in debugging, uncomment the following lines. (They are normally left commented to avoid
# accidentally interfering with the Test Anything Protocol messages written by Test::More.)
#STDOUT->autoflush(1);
#$ddclient::globals{'verbose'} = 1;
my $certdir = "$ENV{abs_top_srcdir}/t/lib/ddclient/Test/Fake/HTTPD";
$ddclient::globals{'ssl_ca_file'} = "$certdir/dummy-ca-cert.pem";
sub run_httpd {
my ($ipv6, $ssl) = @_;
return undef if $ssl && !$has_http_daemon_ssl;
return undef if $ipv6 && (!$ipv6_supported || !$http_daemon_supports_ipv6);
my $httpd = ddclient::Test::Fake::HTTPD->new(
host => $ipv6 ? '::1' : '127.0.0.1',
scheme => $ssl ? 'https' : 'http',
daemon_args => {
SSL_cert_file => "$certdir/dummy-server-cert.pem",
SSL_key_file => "$certdir/dummy-server-key.pem",
V6Only => 1,
},
);
$httpd->run(sub {
# Echo back the full request.
return [ 200, [ 'Content-Type' => 'application/octet-stream' ], [ $_[0]->as_string() ] ];
});
diag(sprintf("started IPv%s%s server running at %s",
$ipv6 ? '6' : '4', $ssl ? ' SSL' : '', $httpd->endpoint()));
return $httpd;
}
my %httpd = (
'4' => { 'http' => run_httpd(0, 0), 'https' => run_httpd(0, 1) },
'6' => { 'http' => run_httpd(1, 0), 'https' => run_httpd(1, 1) },
);
# Note: IPv* client to IPv6 server is not expected to work unless $globals{'ipv6'} is true.
my @test_cases = (
{ ipv6_opt => 0, client_ipv => '', server_ipv => '4', ssl => 0 },
{ ipv6_opt => 0, client_ipv => '', server_ipv => '4', ssl => 1 },
{ ipv6_opt => 0, client_ipv => '4', server_ipv => '4', ssl => 0 },
{ ipv6_opt => 0, client_ipv => '4', server_ipv => '4', ssl => 1 },
{ ipv6_opt => 0, client_ipv => '6', server_ipv => '6', ssl => 0 },
{ ipv6_opt => 0, client_ipv => '6', server_ipv => '6', ssl => 1 },
{ ipv6_opt => 1, client_ipv => '', server_ipv => '4', ssl => 0 },
{ ipv6_opt => 1, client_ipv => '', server_ipv => '4', ssl => 1 },
{ ipv6_opt => 1, client_ipv => '', server_ipv => '6', ssl => 0 },
{ ipv6_opt => 1, client_ipv => '', server_ipv => '6', ssl => 1 },
{ ipv6_opt => 1, client_ipv => '4', server_ipv => '4', ssl => 0 },
{ ipv6_opt => 1, client_ipv => '4', server_ipv => '4', ssl => 1 },
{ ipv6_opt => 1, client_ipv => '6', server_ipv => '6', ssl => 0 },
{ ipv6_opt => 1, client_ipv => '6', server_ipv => '6', ssl => 1 },
);
for my $tc (@test_cases) {
SKIP: {
skip("IPv6 not supported on this system", 1)
if $tc->{server_ipv} eq '6' && !$ipv6_supported;
skip("HTTP::Daemon too old for IPv6 support", 1)
if $tc->{server_ipv} eq '6' && !$http_daemon_supports_ipv6;
skip("HTTP::Daemon::SSL not available", 1) if $tc->{ssl} && !$has_http_daemon_ssl;
my $uri = $httpd{$tc->{server_ipv}}{$tc->{ssl} ? 'https' : 'http'}->endpoint();
my $name = sprintf("IPv%s client to %s (-%sipv6)",
$tc->{client_ipv} || '*', $uri, $tc->{ipv6_opt} ? '' : 'no');
$ddclient::globals{'ipv6'} = $tc->{ipv6_opt};
my $got = ddclient::geturl({ url => $uri, ipversion => $tc->{client_ipv} });
isnt($got // '', '', $name);
}
}
done_testing();

View file

@ -0,0 +1,381 @@
# Copied from https://metacpan.org/pod/release/MASAKI/Test-Fake-HTTPD-0.08/lib/Test/Fake/HTTPD.pm
# and modified as follows:
# * Patched with https://github.com/masaki/Test-Fake-HTTPD/pull/4 to add IPv6 support.
# * Changed package name to ddclient::Test::Fake::HTTPD.
#
# License: This library is free software; you can redistribute it and/or modify it under the same
# terms as Perl itself.
package ddclient::Test::Fake::HTTPD;
use 5.008_001;
use strict;
use warnings;
use HTTP::Daemon;
use HTTP::Message::PSGI qw(res_from_psgi);
use Test::TCP qw(wait_port);
use URI;
use Time::HiRes ();
use Scalar::Util qw(blessed weaken);
use Carp qw(croak);
use Exporter qw(import);
our $VERSION = '0.08';
$VERSION = eval $VERSION;
our @EXPORT = qw(
run_http_server run_https_server
extra_daemon_args
);
our $ENABLE_SSL = eval { require HTTP::Daemon::SSL; 1 };
sub enable_ssl { $ENABLE_SSL }
our %EXTRA_DAEMON_ARGS = ();
sub extra_daemon_args (%) { %EXTRA_DAEMON_ARGS = @_ }
sub run_http_server (&) {
my $app = shift;
__PACKAGE__->new->run($app);
}
sub run_https_server (&) {} # noop
if ($ENABLE_SSL) {
no warnings 'redefine';
*run_https_server = sub (&) {
my $app = shift;
__PACKAGE__->new(scheme => 'https')->run($app);
};
}
sub new {
my ($class, %args) = @_;
bless {
host => '127.0.0.1',
timeout => 5,
listen => 5,
scheme => 'http',
%args
}, $class;
}
our $DAEMON_MAP = {
http => 'HTTP::Daemon',
https => 'HTTP::Daemon::SSL',
};
sub _daemon_class {
my $self = shift;
return $DAEMON_MAP->{$self->{scheme}};
}
sub run {
my ($self, $app) = @_;
my %extra_daemon_args = $self->{daemon_args} && ref $self->{daemon_args} eq 'HASH'
? %{ $self->{daemon_args} }
: %EXTRA_DAEMON_ARGS;
$self->{server} = Test::TCP->new(
($self->host ? (host => $self->host) : ()),
code => sub {
my $port = shift;
my $d;
for (1..10) {
$d = $self->_daemon_class->new(
# Note: IO::Socket::IP ignores LocalAddr if LocalHost is set.
($self->host ? (LocalAddr => $self->host) : ()),
LocalPort => $port,
Timeout => $self->{timeout},
Proto => 'tcp',
Listen => $self->{listen},
($self->_is_win32 ? () : (ReuseAddr => 1)),
%extra_daemon_args,
) and last;
Time::HiRes::sleep(0.1);
}
croak(sprintf("failed to listen on address %s port %s%s",
$self->host || '<default>',
$self->port || '<default>',
$@ eq '' ? '' : ": $@")) unless $d;
$d->accept; # wait for port check from parent process
while (my $c = $d->accept) {
while (my $req = $c->get_request) {
my $res = $self->_to_http_res($app->($req));
$c->send_response($res);
}
$c->close;
undef $c;
}
},
($self->{port} ? (port => $self->{port}) : ()),
);
weaken($self);
$self;
}
sub scheme {
my $self = shift;
return $self->{scheme};
}
sub host {
my $self = shift;
return $self->{host};
}
sub port {
my $self = shift;
return $self->{server} ? $self->{server}->port : 0;
}
sub host_port {
my $self = shift;
return $self->endpoint->host_port;
}
sub endpoint {
my $self = shift;
my $uri = URI->new($self->scheme . ':');
my $host = $self->host;
$host = 'localhost' if !defined($host) || $host eq '0.0.0.0' || $host eq '::';
$uri->host($host);
$uri->port($self->port);
return $uri;
}
sub _is_win32 { $^O eq 'MSWin32' }
sub _is_psgi_res {
my ($self, $res) = @_;
return unless ref $res eq 'ARRAY';
return unless @$res == 3;
return unless $res->[0] && $res->[0] =~ /^\d{3}$/;
return unless ref $res->[1] eq 'ARRAY' || ref $res->[1] eq 'HASH';
return 1;
}
sub _to_http_res {
my ($self, $res) = @_;
my $http_res;
if (blessed($res) and $res->isa('HTTP::Response')) {
$http_res = $res;
}
elsif (blessed($res) and $res->isa('Plack::Response')) {
$http_res = res_from_psgi($res->finalize);
}
elsif ($self->_is_psgi_res($res)) {
$http_res = res_from_psgi($res);
}
croak(sprintf '%s: response must be HTTP::Response or Plack::Response or PSGI', __PACKAGE__)
unless $http_res;
return $http_res;
}
1;
=head1 NAME
Test::Fake::HTTPD - a fake HTTP server
=head1 SYNOPSIS
DSL-style
use Test::Fake::HTTPD;
my $httpd = run_http_server {
my $req = shift;
# ...
# 1. HTTP::Response ok
return $http_response;
# 2. Plack::Response ok
return $plack_response;
# 3. PSGI response ok
return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Hello World' ] ];
};
printf "Listening on address:port %s\n", $httpd->host_port;
# or
printf "Listening on address %s port %s\n", $httpd->host, $httpd->port;
# access to fake HTTP server
use LWP::UserAgent;
my $res = LWP::UserAgent->new->get($httpd->endpoint); # "http://127.0.0.1:{port}"
# Stop http server automatically at destruction time.
OO-style
use Test::Fake::HTTPD;
my $httpd = Test::Fake::HTTPD->new(
timeout => 5,
daemon_args => { ... }, # HTTP::Daemon args
);
$httpd->run(sub {
my $req = shift;
# ...
[ 200, [ 'Content-Type', 'text/plain' ], [ 'Hello World' ] ];
});
# Stop http server automatically at destruction time.
=head1 DESCRIPTION
Test::Fake::HTTPD is a fake HTTP server module for testing.
=head1 FUNCTIONS
=over 4
=item * C<run_http_server { ... }>
Starts HTTP server and returns the guard instance.
my $httpd = run_http_server {
my $req = shift;
# ...
return $http_or_plack_or_psgi_res;
};
# can use $httpd guard object, same as OO-style
LWP::UserAgent->new->get($httpd->endpoint);
=item * C<run_https_server { ... }>
Starts B<HTTPS> server and returns the guard instance.
If you use this method, you MUST install L<HTTP::Daemon::SSL>.
extra_daemon_args
SSL_key_file => "certs/server-key.pem",
SSL_cert_file => "certs/server-cert.pem";
my $httpd = run_https_server {
my $req = shift;
# ...
return $http_or_plack_or_psgi_res;
};
# can use $httpd guard object, same as OO-style
my $ua = LWP::UserAgent->new(
ssl_opts => {
SSL_verify_mode => 0,
verify_hostname => 0,
},
);
$ua->get($httpd->endpoint);
=back
=head1 METHODS
=over 4
=item * C<new( %args )>
Returns a new instance.
my $httpd = Test::Fake::HTTPD->new(%args);
C<%args> are:
=over 8
=item * C<timeout>
timeout value (default: 5)
=item * C<listen>
queue size for listen (default: 5)
=item * C<host>
local address to listen on (default: 127.0.0.1)
=item * C<port>
TCP port to listen on (default: auto detection)
=back
my $httpd = Test::Fake::HTTPD->new(
timeout => 10,
listen => 10,
port => 3333,
);
=item * C<run( sub { ... } )>
Starts this HTTP server.
$httpd->run(sub { ... });
=item * C<scheme>
Returns a scheme of running, "http" or "https".
my $scheme = $httpd->scheme;
=item * C<host>
Returns the address the server is listening on.
=item * C<port>
Returns the TCP port the server is listening on.
my $port = $httpd->port;
=item * C<host_port>
Returns the host:port from C<endpoint> (e.g., "127.0.0.1:1234", "[::1]:1234").
my $host_port = $httpd->host_port;
=item * C<endpoint>
Returns a URI object to the running server (e.g., "http://127.0.0.1:1234",
"https://[::1]:1234"). If C<host> returns C<undef>, C<''>, C<'0.0.0.0'>,
or C<'::'>, the host portion of the URI is set to C<localhost>.
use LWP::UserAgent;
my $res = LWP::UserAgent->new->get($httpd->endpoint);
my $url = $httpd->endpoint;
$url->path('/foo/bar');
my $res = LWP::UserAgent->new->get($url);
=back
=head1 AUTHOR
NAKAGAWA Masaki E<lt>masaki@cpan.orgE<gt>
=head1 THANKS TO
xaicron
=head1 LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=head1 SEE ALSO
L<Test::TCP>, L<HTTP::Daemon>, L<HTTP::Daemon::SSL>, L<HTTP::Message::PSGI>
=cut

View file

@ -0,0 +1,80 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
11:82:5d:80:30:4c:a9:6d:ed:68:88:10:c8:90:4d:08:50:3c:4c:b0
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Root Certification Authority
Validity
Not Before: Jul 3 19:47:44 2020 GMT
Not After : Jul 4 19:47:44 2120 GMT
Subject: CN=Root Certification Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c5:f2:d9:a9:48:a2:06:dc:89:7d:e8:ab:2e:1f:
70:ea:da:82:46:45:4e:42:38:6e:8d:a6:3e:28:84:
f1:25:c0:ea:25:af:61:ca:87:38:a5:7b:3f:d0:3a:
57:82:c7:eb:f1:b5:b4:70:0e:71:69:22:5f:ae:49:
d3:51:df:19:97:bf:00:c3:de:99:3a:4d:f3:6d:4a:
bf:73:7e:b1:aa:72:40:b1:0d:fc:d4:af:11:f5:a9:
7e:c3:36:7a:ac:25:86:a4:3e:7a:fe:3f:0f:22:f7:
d6:87:15:ba:33:c1:36:c3:79:4d:79:b3:ca:a5:2d:
15:9a:63:ad:38:32:99:74:76:d7:72:7e:2f:69:ff:
7b:b0:f6:79:ad:da:2d:9f:51:4e:d9:70:15:9c:83:
e9:10:8c:ec:7f:39:27:5d:b9:6e:86:c9:93:54:6b:
aa:82:12:82:b0:32:36:c5:94:6c:48:bb:3f:c6:af:
ef:1c:e1:0c:18:e6:0c:4c:bf:58:67:5b:1a:cd:15:
62:37:40:40:5f:1d:76:e2:24:01:28:65:cc:ed:3f:
e1:f1:08:79:94:12:13:4c:4c:e2:a4:53:b8:fe:78:
7f:07:00:cd:c1:3a:7b:0e:f4:35:ce:83:c7:f3:ce:
71:9d:1f:7b:88:66:bc:b6:39:5e:26:28:e5:ef:5a:
0d:05
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
21:E8:DE:B6:D8:64:01:72:02:C5:1C:CA:16:0C:D9:05:1A:14:A1:0C
X509v3 Authority Key Identifier:
keyid:21:E8:DE:B6:D8:64:01:72:02:C5:1C:CA:16:0C:D9:05:1A:14:A1:0C
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
9d:4c:17:84:f3:83:90:97:a7:df:e5:af:53:ac:d7:75:94:c4:
a0:29:fa:d7:8f:a6:f8:fa:4b:d6:5e:d2:6e:8d:6d:46:89:1f:
7b:30:2c:2d:d3:3b:b6:64:1d:ec:ad:60:c1:96:4b:9a:bc:f9:
d0:5d:af:a1:73:f7:03:99:8a:e2:59:47:48:1c:8f:7a:99:97:
20:78:e2:16:16:e4:c3:c9:82:4e:25:58:23:75:c9:9c:71:67:
8e:c4:79:e1:b9:ac:d9:c2:51:41:3d:a6:bf:07:0b:4b:14:8c:
ca:42:0f:c3:b7:71:c0:fb:3e:5e:de:2b:e5:7f:92:52:50:12:
4f:63:a5:fa:3b:63:59:fa:37:3f:42:f4:ec:13:a0:c7:5d:0c:
9c:cd:6b:32:96:e7:44:da:5f:8c:cf:c7:51:eb:81:3b:cc:e8:
39:41:0c:a1:bb:8f:3a:f8:b1:ee:2b:97:f4:13:c9:a8:9c:1c:
2f:2f:51:57:e4:0c:4e:2b:29:7f:5e:12:72:63:8c:bb:40:2c:
97:14:bf:1e:7a:66:bc:64:af:78:80:64:19:37:ca:7a:f3:de:
15:e6:23:1d:d0:90:7d:e6:5f:21:88:23:c5:23:ca:f2:29:00:
1d:9a:7a:58:37:6d:a9:9e:ab:24:b1:c6:c5:3b:46:11:a7:53:
80:ef:aa:9c
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUEYJdgDBMqW3taIgQyJBNCFA8TLAwDQYJKoZIhvcNAQEL
BQAwJzElMCMGA1UEAwwcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAgFw0y
MDA3MDMxOTQ3NDRaGA8yMTIwMDcwNDE5NDc0NFowJzElMCMGA1UEAwwcUm9vdCBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAMXy2alIogbciX3oqy4fcOragkZFTkI4bo2mPiiE8SXA6iWvYcqHOKV7
P9A6V4LH6/G1tHAOcWkiX65J01HfGZe/AMPemTpN821Kv3N+sapyQLEN/NSvEfWp
fsM2eqwlhqQ+ev4/DyL31ocVujPBNsN5TXmzyqUtFZpjrTgymXR213J+L2n/e7D2
ea3aLZ9RTtlwFZyD6RCM7H85J125bobJk1RrqoISgrAyNsWUbEi7P8av7xzhDBjm
DEy/WGdbGs0VYjdAQF8dduIkAShlzO0/4fEIeZQSE0xM4qRTuP54fwcAzcE6ew70
Nc6Dx/POcZ0fe4hmvLY5XiYo5e9aDQUCAwEAAaNjMGEwHQYDVR0OBBYEFCHo3rbY
ZAFyAsUcyhYM2QUaFKEMMB8GA1UdIwQYMBaAFCHo3rbYZAFyAsUcyhYM2QUaFKEM
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
A4IBAQCdTBeE84OQl6ff5a9TrNd1lMSgKfrXj6b4+kvWXtJujW1GiR97MCwt0zu2
ZB3srWDBlkuavPnQXa+hc/cDmYriWUdIHI96mZcgeOIWFuTDyYJOJVgjdcmccWeO
xHnhuazZwlFBPaa/BwtLFIzKQg/Dt3HA+z5e3ivlf5JSUBJPY6X6O2NZ+jc/QvTs
E6DHXQyczWsyludE2l+Mz8dR64E7zOg5QQyhu486+LHuK5f0E8monBwvL1FX5AxO
Kyl/XhJyY4y7QCyXFL8eema8ZK94gGQZN8p6894V5iMd0JB95l8hiCPFI8ryKQAd
mnpYN22pnqskscbFO0YRp1OA76qc
-----END CERTIFICATE-----

View file

@ -0,0 +1,165 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
11:82:5d:80:30:4c:a9:6d:ed:68:88:10:c8:90:4d:08:50:3c:4c:b1
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Root Certification Authority
Validity
Not Before: Jul 3 19:47:44 2020 GMT
Not After : Jul 4 19:47:44 2120 GMT
Subject: CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e7:3f:9a:d6:f8:4d:c3:89:69:1f:ab:95:00:b4:
20:eb:36:72:e1:47:ba:0c:d8:20:76:9f:78:ec:f2:
d4:1c:2d:47:6c:79:a7:af:ce:e8:f6:91:c1:e8:f2:
77:41:3b:37:70:36:13:f2:5b:30:45:eb:74:d0:f4:
37:6e:20:d5:5a:aa:de:fc:df:72:b2:07:bb:da:1c:
66:b7:72:20:cf:34:5f:55:f0:23:36:c3:9f:01:54:
45:70:65:e5:2a:b3:03:b1:9e:73:dc:a2:32:cb:02:
e0:60:89:a5:f4:9a:87:e2:8a:bc:4d:80:1b:93:c2:
61:d5:10:eb:ed:6c:fc:a0:b3:a5:22:3c:03:02:72:
e1:71:08:86:42:03:3a:0d:7b:6e:1c:f3:bb:3d:ad:
a8:e4:c2:3f:7c:0a:eb:bd:c1:89:1d:f1:bc:ed:43:
7e:47:94:e0:f3:17:6d:13:96:be:af:74:e5:20:25:
71:95:c5:7f:26:d2:28:a4:ee:bd:12:fe:04:e8:8b:
46:da:7f:e1:fc:54:c0:dc:52:be:55:e2:49:25:ca:
21:09:cf:e2:ed:e9:70:26:24:62:2e:89:6e:22:2d:
8c:20:3d:83:f7:d1:b5:e1:74:1c:5d:b9:cb:b6:d5:
60:93:06:96:1c:cc:b4:0a:4e:00:6a:04:d6:ba:2f:
ea:c7
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
72:14:A2:93:7E:96:27:D7:E9:F0:89:D7:53:52:11:11:D9:B5:5B:8B
X509v3 Authority Key Identifier:
keyid:21:E8:DE:B6:D8:64:01:72:02:C5:1C:CA:16:0C:D9:05:1A:14:A1:0C
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha256WithRSAEncryption
29:03:4e:91:19:6b:48:b4:09:89:fb:33:47:bf:43:97:57:f1:
23:0a:e7:89:22:df:7b:05:97:cf:2c:3f:2f:26:2f:db:81:2e:
88:40:97:ce:58:a5:c3:d0:78:08:2a:89:d7:a6:fd:87:9a:22:
2b:82:e8:5e:f9:96:56:8b:09:7c:84:35:08:20:c5:1e:ba:fb:
7f:aa:92:5d:2c:1e:6e:35:51:6d:8b:f4:de:ba:01:43:a0:7f:
e0:03:f8:94:5f:8a:c5:a9:4b:64:dd:64:ae:8e:79:d3:48:11:
77:c4:78:a9:14:dc:08:29:76:bd:ea:9d:88:09:b4:95:9c:29:
41:96:77:21:ce:a7:cb:ba:5b:05:38:bc:5b:06:63:24:f4:41:
25:b3:4d:45:86:95:f1:8a:41:b4:4d:8a:20:70:b9:99:88:a6:
96:93:b3:81:6d:80:06:49:29:47:fd:30:83:3f:e5:ef:52:97:
d2:92:fb:43:ba:fd:fe:15:bf:a3:84:55:e5:c9:db:3e:5f:00:
14:28:3f:86:8e:72:65:cb:2c:e5:8e:75:39:14:e7:e5:82:92:
6e:fb:3d:ab:40:1c:c9:f8:6c:bc:a4:b1:68:b5:8f:58:82:78:
a1:94:8e:c9:b7:fb:bb:bd:aa:cd:f5:0c:d9:00:70:fb:4f:ca:
3d:d1:e7:6b
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIUEYJdgDBMqW3taIgQyJBNCFA8TLEwDQYJKoZIhvcNAQEL
BQAwJzElMCMGA1UEAwwcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAgFw0y
MDA3MDMxOTQ3NDRaGA8yMTIwMDcwNDE5NDc0NFowFDESMBAGA1UEAwwJbG9jYWxo
b3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5z+a1vhNw4lpH6uV
ALQg6zZy4Ue6DNggdp947PLUHC1HbHmnr87o9pHB6PJ3QTs3cDYT8lswRet00PQ3
biDVWqre/N9ysge72hxmt3IgzzRfVfAjNsOfAVRFcGXlKrMDsZ5z3KIyywLgYIml
9JqH4oq8TYAbk8Jh1RDr7Wz8oLOlIjwDAnLhcQiGQgM6DXtuHPO7Pa2o5MI/fArr
vcGJHfG87UN+R5Tg8xdtE5a+r3TlICVxlcV/JtIopO69Ev4E6ItG2n/h/FTA3FK+
VeJJJcohCc/i7elwJiRiLoluIi2MID2D99G14XQcXbnLttVgkwaWHMy0Ck4AagTW
ui/qxwIDAQABo4GhMIGeMB0GA1UdDgQWBBRyFKKTfpYn1+nwiddTUhER2bVbizAf
BgNVHSMEGDAWgBQh6N622GQBcgLFHMoWDNkFGhShDDAsBgNVHREEJTAjgglsb2Nh
bGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwCQYDVR0TBAIwADAOBgNVHQ8B
Af8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEB
ACkDTpEZa0i0CYn7M0e/Q5dX8SMK54ki33sFl88sPy8mL9uBLohAl85YpcPQeAgq
idem/YeaIiuC6F75llaLCXyENQggxR66+3+qkl0sHm41UW2L9N66AUOgf+AD+JRf
isWpS2TdZK6OedNIEXfEeKkU3Agpdr3qnYgJtJWcKUGWdyHOp8u6WwU4vFsGYyT0
QSWzTUWGlfGKQbRNiiBwuZmIppaTs4FtgAZJKUf9MIM/5e9Sl9KS+0O6/f4Vv6OE
VeXJ2z5fABQoP4aOcmXLLOWOdTkU5+WCkm77PatAHMn4bLyksWi1j1iCeKGUjsm3
+7u9qs31DNkAcPtPyj3R52s=
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
11:82:5d:80:30:4c:a9:6d:ed:68:88:10:c8:90:4d:08:50:3c:4c:b0
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Root Certification Authority
Validity
Not Before: Jul 3 19:47:44 2020 GMT
Not After : Jul 4 19:47:44 2120 GMT
Subject: CN=Root Certification Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c5:f2:d9:a9:48:a2:06:dc:89:7d:e8:ab:2e:1f:
70:ea:da:82:46:45:4e:42:38:6e:8d:a6:3e:28:84:
f1:25:c0:ea:25:af:61:ca:87:38:a5:7b:3f:d0:3a:
57:82:c7:eb:f1:b5:b4:70:0e:71:69:22:5f:ae:49:
d3:51:df:19:97:bf:00:c3:de:99:3a:4d:f3:6d:4a:
bf:73:7e:b1:aa:72:40:b1:0d:fc:d4:af:11:f5:a9:
7e:c3:36:7a:ac:25:86:a4:3e:7a:fe:3f:0f:22:f7:
d6:87:15:ba:33:c1:36:c3:79:4d:79:b3:ca:a5:2d:
15:9a:63:ad:38:32:99:74:76:d7:72:7e:2f:69:ff:
7b:b0:f6:79:ad:da:2d:9f:51:4e:d9:70:15:9c:83:
e9:10:8c:ec:7f:39:27:5d:b9:6e:86:c9:93:54:6b:
aa:82:12:82:b0:32:36:c5:94:6c:48:bb:3f:c6:af:
ef:1c:e1:0c:18:e6:0c:4c:bf:58:67:5b:1a:cd:15:
62:37:40:40:5f:1d:76:e2:24:01:28:65:cc:ed:3f:
e1:f1:08:79:94:12:13:4c:4c:e2:a4:53:b8:fe:78:
7f:07:00:cd:c1:3a:7b:0e:f4:35:ce:83:c7:f3:ce:
71:9d:1f:7b:88:66:bc:b6:39:5e:26:28:e5:ef:5a:
0d:05
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
21:E8:DE:B6:D8:64:01:72:02:C5:1C:CA:16:0C:D9:05:1A:14:A1:0C
X509v3 Authority Key Identifier:
keyid:21:E8:DE:B6:D8:64:01:72:02:C5:1C:CA:16:0C:D9:05:1A:14:A1:0C
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
9d:4c:17:84:f3:83:90:97:a7:df:e5:af:53:ac:d7:75:94:c4:
a0:29:fa:d7:8f:a6:f8:fa:4b:d6:5e:d2:6e:8d:6d:46:89:1f:
7b:30:2c:2d:d3:3b:b6:64:1d:ec:ad:60:c1:96:4b:9a:bc:f9:
d0:5d:af:a1:73:f7:03:99:8a:e2:59:47:48:1c:8f:7a:99:97:
20:78:e2:16:16:e4:c3:c9:82:4e:25:58:23:75:c9:9c:71:67:
8e:c4:79:e1:b9:ac:d9:c2:51:41:3d:a6:bf:07:0b:4b:14:8c:
ca:42:0f:c3:b7:71:c0:fb:3e:5e:de:2b:e5:7f:92:52:50:12:
4f:63:a5:fa:3b:63:59:fa:37:3f:42:f4:ec:13:a0:c7:5d:0c:
9c:cd:6b:32:96:e7:44:da:5f:8c:cf:c7:51:eb:81:3b:cc:e8:
39:41:0c:a1:bb:8f:3a:f8:b1:ee:2b:97:f4:13:c9:a8:9c:1c:
2f:2f:51:57:e4:0c:4e:2b:29:7f:5e:12:72:63:8c:bb:40:2c:
97:14:bf:1e:7a:66:bc:64:af:78:80:64:19:37:ca:7a:f3:de:
15:e6:23:1d:d0:90:7d:e6:5f:21:88:23:c5:23:ca:f2:29:00:
1d:9a:7a:58:37:6d:a9:9e:ab:24:b1:c6:c5:3b:46:11:a7:53:
80:ef:aa:9c
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIUEYJdgDBMqW3taIgQyJBNCFA8TLAwDQYJKoZIhvcNAQEL
BQAwJzElMCMGA1UEAwwcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAgFw0y
MDA3MDMxOTQ3NDRaGA8yMTIwMDcwNDE5NDc0NFowJzElMCMGA1UEAwwcUm9vdCBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAMXy2alIogbciX3oqy4fcOragkZFTkI4bo2mPiiE8SXA6iWvYcqHOKV7
P9A6V4LH6/G1tHAOcWkiX65J01HfGZe/AMPemTpN821Kv3N+sapyQLEN/NSvEfWp
fsM2eqwlhqQ+ev4/DyL31ocVujPBNsN5TXmzyqUtFZpjrTgymXR213J+L2n/e7D2
ea3aLZ9RTtlwFZyD6RCM7H85J125bobJk1RrqoISgrAyNsWUbEi7P8av7xzhDBjm
DEy/WGdbGs0VYjdAQF8dduIkAShlzO0/4fEIeZQSE0xM4qRTuP54fwcAzcE6ew70
Nc6Dx/POcZ0fe4hmvLY5XiYo5e9aDQUCAwEAAaNjMGEwHQYDVR0OBBYEFCHo3rbY
ZAFyAsUcyhYM2QUaFKEMMB8GA1UdIwQYMBaAFCHo3rbYZAFyAsUcyhYM2QUaFKEM
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
A4IBAQCdTBeE84OQl6ff5a9TrNd1lMSgKfrXj6b4+kvWXtJujW1GiR97MCwt0zu2
ZB3srWDBlkuavPnQXa+hc/cDmYriWUdIHI96mZcgeOIWFuTDyYJOJVgjdcmccWeO
xHnhuazZwlFBPaa/BwtLFIzKQg/Dt3HA+z5e3ivlf5JSUBJPY6X6O2NZ+jc/QvTs
E6DHXQyczWsyludE2l+Mz8dR64E7zOg5QQyhu486+LHuK5f0E8monBwvL1FX5AxO
Kyl/XhJyY4y7QCyXFL8eema8ZK94gGQZN8p6894V5iMd0JB95l8hiCPFI8ryKQAd
mnpYN22pnqskscbFO0YRp1OA76qc
-----END CERTIFICATE-----

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnP5rW+E3DiWkf
q5UAtCDrNnLhR7oM2CB2n3js8tQcLUdseaevzuj2kcHo8ndBOzdwNhPyWzBF63TQ
9DduINVaqt7833KyB7vaHGa3ciDPNF9V8CM2w58BVEVwZeUqswOxnnPcojLLAuBg
iaX0mofiirxNgBuTwmHVEOvtbPygs6UiPAMCcuFxCIZCAzoNe24c87s9rajkwj98
Cuu9wYkd8bztQ35HlODzF20Tlr6vdOUgJXGVxX8m0iik7r0S/gToi0baf+H8VMDc
Ur5V4kklyiEJz+Lt6XAmJGIuiW4iLYwgPYP30bXhdBxducu21WCTBpYczLQKTgBq
BNa6L+rHAgMBAAECggEBAMSWe+m4mVNb47R6x2cbush7N1pxAaedrKtrkv/Mx6lU
jN2Y5oc9HStQakrApcUctFp+fqKQBw/JxTtGAkFrRDWaAYtz4iubC4W2k1PsgBvm
aA3E4grSbsBQhd+xoAqWuNMs405zzT5sqZcoLZ8uJ8rdKouwFsGchFL/2bGz72gk
8smGqMdH4sQep3kJhJyWio47C7pC1qnG1xNmsfJ7+MkEL/+b95WsbNUTZHkAFzE8
l5BBLILXR10EqGCAWiuz9WGffw7JASyrV1spojOmPBneBDhfLSgWjuv/0S1pUxVx
iZWDlukHPUVQWaDWQxE9Uscup3hORRENTOIJpBsYWhECgYEA9qACG2oHCa+a3xj/
QMdWKWVZeMnKUDlpPhlyC9ue+K4NMBSzgG3K1qURX0xAvkPEApYKBh+rqvJqTMYk
N5K+CfLaU53Weyko5v5xPj3aSnGVsYazkoxfZ31MbbIqn+JPoNjYafTo2SZJsaQ6
Y416FMxlWf7eR4rZGr1iqptSWvUCgYEA8An2Qdk+NMGYrnL6xr+AKygm2ri1Mz7k
XVr/jhkUxhBsvPumNQAVQaEuWAx6Mwgs+uzgJrsW8UCVAta/Jo+dWlCewqrpTsIh
jJZjkP9H91oEA6GkUNy9JI6j3KRQ6I5rGNr8nJrJ4c9+yLZa85BTkTriHvZl5zZX
SberAyPREUsCgYEAx9C4JFHxRc27Ispz9J4MlxmANjb37au2MxQWrLjRwhXypWQA
UyuhTesLejSjuAPbiWTa1j9OrQAfU/itW0FPK2xRq7GUFtEwTIcWZSFj/TCt4dmL
IE8O9SA1jiLuGgAYF+/Y13AQP++fgYfXrtTvdm5sJ1Ax87DxWZLbn/Kb9QkCgYEA
xjgDwlbKVrh0A8LxMcSb64eJpl6XS40o+aqWlFpD3Fdd5CWPF/9Mjliys4UCODgN
JN0NMQ6YIHsrUh/R098OmrEumSSX6zDGkZjy+Z7FaA5OeE04KopOKu0bha2vHovV
Br53kj8EbVNyp/5mVvGdALX2Wokwl2E5baedMceW8scCgYAwhrNIV1I6f76EgXP6
3XU1B5c6VVk/Mlaid1Y7IrqPrhp1vcY2txZQ/NFEnvS1UMTvTskccgpIJJLd27D7
CxDQGrXTfFOONZN6KzArGtX/m3PiTs6Mz3Zn8R5rJsCvda4kxEu0WV9KqZRSDGoM
pAawXm36qael22agLPA2zeH9Gg==
-----END PRIVATE KEY-----