>From ce5bf7de31fbd7947767c051aa0ef59abcbe9436 Mon Sep 17 00:00:00 2001
From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
Date: Tue, 28 Jun 2011 11:01:40 +0200
Subject: [PATCH 2/2] test ssl connections scenarios


Signed-off-by: Guillaume Rousse <Guillaume.Rousse@inria.fr>
---
 t/FusionInventory/Test/Auth.pm   |   23 +++++
 t/FusionInventory/Test/Server.pm |  173 +++++++++++++++++++++++++++++++++++
 t/ssl.t                          |  185 ++++++++++++++++++++++++++++++++++++++
 t/ssl/cnf/alternate.cnf          |   17 ++++
 t/ssl/cnf/bad.cnf                |   16 ++++
 t/ssl/cnf/ca.cnf                 |   45 +++++++++
 t/ssl/cnf/good.cnf               |   16 ++++
 t/ssl/cnf/wrong.cnf              |   16 ++++
 t/ssl/crt/alternate.pem          |   80 ++++++++++++++++
 t/ssl/crt/bad.pem                |   21 +++++
 t/ssl/crt/ca.pem                 |   21 +++++
 t/ssl/crt/good.pem               |   70 ++++++++++++++
 t/ssl/crt/wrong.pem              |   70 ++++++++++++++
 t/ssl/key/alternate.pem          |   28 ++++++
 t/ssl/key/bad.pem                |   28 ++++++
 t/ssl/key/ca.pem                 |   30 ++++++
 t/ssl/key/good.pem               |   28 ++++++
 t/ssl/key/wrong.pem              |   28 ++++++
 18 files changed, 895 insertions(+), 0 deletions(-)
 create mode 100644 t/FusionInventory/Test/Auth.pm
 create mode 100644 t/FusionInventory/Test/Server.pm
 create mode 100644 t/ssl.t
 create mode 100644 t/ssl/cnf/alternate.cnf
 create mode 100644 t/ssl/cnf/bad.cnf
 create mode 100644 t/ssl/cnf/ca.cnf
 create mode 100644 t/ssl/cnf/good.cnf
 create mode 100644 t/ssl/cnf/wrong.cnf
 create mode 100644 t/ssl/crt/alternate.pem
 create mode 100644 t/ssl/crt/bad.pem
 create mode 100644 t/ssl/crt/ca.pem
 create mode 100644 t/ssl/crt/good.pem
 create mode 100644 t/ssl/crt/wrong.pem
 create mode 100644 t/ssl/key/alternate.pem
 create mode 100644 t/ssl/key/bad.pem
 create mode 100644 t/ssl/key/ca.pem
 create mode 100644 t/ssl/key/good.pem
 create mode 100644 t/ssl/key/wrong.pem

diff --git a/t/FusionInventory/Test/Auth.pm b/t/FusionInventory/Test/Auth.pm
new file mode 100644
index 0000000..09a16d6
--- /dev/null
+++ b/t/FusionInventory/Test/Auth.pm
@@ -0,0 +1,23 @@
+package FusionInventory::Test::Auth;
+
+use strict;
+use base 'Authen::Simple::Adapter';
+
+__PACKAGE__->options({
+    user => {
+        type => Params::Validate::SCALAR
+    },
+    password => {
+        type => Params::Validate::SCALAR
+    }
+});
+
+sub check {
+    my ($self, $user, $password) = @_;
+
+    return
+        $user eq $self->user() &&
+        $password eq $self->password();
+}
+
+1
diff --git a/t/FusionInventory/Test/Server.pm b/t/FusionInventory/Test/Server.pm
new file mode 100644
index 0000000..d15460a
--- /dev/null
+++ b/t/FusionInventory/Test/Server.pm
@@ -0,0 +1,173 @@
+package FusionInventory::Test::Server;
+
+use warnings;
+use strict;
+use base qw(HTTP::Server::Simple::CGI HTTP::Server::Simple::Authen);
+
+use English qw(-no_match_vars);
+use IO::Socket::SSL;
+
+use FusionInventory::Test::Auth;
+
+my $dispatch_table = {};
+
+=head1 OVERLOADED METHODS
+
+=cut
+
+our $pid;
+
+sub new {
+    die 'An instance of Test::Server has already been started.' if $pid;
+
+    my $class = shift;
+    my %params = (
+        port => 8080,
+        ssl  => 0,
+        crt  => undef,
+        key  => undef,
+        @_
+    );
+
+    my $self = $class->SUPER::new($params{port});
+
+    $self->{user}     = $params{user};
+    $self->{password} = $params{password};
+    $self->{ssl}      = $params{ssl};
+    $self->{crt}      = $params{crt};
+    $self->{key}      = $params{key};
+
+    return $self;
+}
+
+sub run {
+    my $self = shift;
+
+    $pid = $self->SUPER::run(@_);
+
+    $SIG{__DIE__} = \&stop;
+
+    return $pid;
+}
+
+sub authen_handler {
+    my ($self) = @_;
+    return FusionInventory::Test::Auth->new(
+        user     => $self->{user},
+        password => $self->{password}
+    );
+}
+
+sub handle_request {
+    my $self = shift;
+    my $cgi  = shift;
+
+    my $path = $cgi->path_info();
+    my $handler = $dispatch_table->{$path};
+
+    if ($handler) {
+        if (ref($handler) eq "CODE") {
+            $handler->($self, $cgi);
+        } else {
+            print "HTTP/1.0 200 OK\r\n";
+            print "\r\n";
+            print $handler;
+        }
+    } else {
+        print "HTTP/1.0 404 Not found\r\n";
+        print
+        $cgi->header(),
+        $cgi->start_html('Not found'),
+        $cgi->h1('Not found'),
+        $cgi->end_html();
+    }
+
+    # fix for strange bug under Test::Harness
+    # where HTTP::Server::Simple::CGI::Environment::header
+    # keep appending value to this variable
+    delete $ENV{CONTENT_LENGTH};
+}
+
+# overriden to add status to return code in the headers
+sub authenticate {
+    my $self = shift;
+    my $user = $self->do_authenticate();
+    unless (defined $user) {
+        my $realm = $self->authen_realm();
+        print "HTTP/1.0 401 Authentication required\r\n";
+        print qq(WWW-Authenticate: Basic realm="$realm"\r\n\r\n);
+        print "Authentication required.";
+        return;
+    }
+    return $user;
+}
+
+sub print_banner {
+}
+
+sub accept_hook {
+   my $self = shift;
+
+   return unless $self->{ssl};
+   my $fh   = $self->stdio_handle;
+
+   $self->SUPER::accept_hook(@_);
+
+   my $newfh = IO::Socket::SSL->start_SSL($fh,
+       SSL_server    => 1,
+       SSL_use_cert  => 1,
+       SSL_cert_file => $self->{crt},
+       SSL_key_file  => $self->{key},
+   );
+
+   $self->stdio_handle($newfh) if $newfh;
+}
+
+=head1 METHODS UNIQUE TO TestServer
+
+=cut
+
+sub set_dispatch {
+    my $self = shift;
+    $dispatch_table = shift;
+
+    return;
+}
+
+sub background {
+    my $self = shift;
+
+    $pid = $self->SUPER::background()
+        or Carp::confess( q{Can't start the test server} );
+
+    sleep 1; # background() may come back prematurely, so give it a second to fire up
+
+    return $pid;
+}
+
+
+sub hostname {
+    my $self = shift;
+
+    return '127.0.0.1';
+}
+
+sub root {
+    my $self = shift;
+    my $port = $self->port;
+    my $hostname = $self->hostname;
+
+    return "http://$hostname:$port";
+}
+
+sub stop {
+    my $signal = ($OSNAME eq 'MSWin32') ? 9 : 15;
+    if ($pid) {
+        kill($signal, $pid) unless $EXCEPTIONS_BEING_CAUGHT;
+        undef $pid;
+    }
+
+    return;
+}
+
+1;
diff --git a/t/ssl.t b/t/ssl.t
new file mode 100644
index 0000000..ff8c25e
--- /dev/null
+++ b/t/ssl.t
@@ -0,0 +1,185 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use lib 't';
+
+use Compress::Zlib;
+use English qw(-no_match_vars);
+use Socket;
+use Test::More;
+use Test::Exception;
+
+use FusionInventory::Agent::Network;
+use FusionInventory::Agent::XML::Query::SimpleMessage;
+use FusionInventory::Test::Server;
+use FusionInventory::Logger;
+
+if ($OSNAME eq 'MSWin32' || $OSNAME eq 'darwin') {
+    plan skip_all => 'non working test on Windows and MacOS';
+} else {
+    plan tests => 6;
+}
+
+my $ok = sub {
+    my ($server, $cgi) = @_;
+
+    print "HTTP/1.0 200 OK\r\n";
+    print "\r\n";
+    print compress("<REPLY><word>hello</word></REPLY>");
+};
+
+my $logger = FusionInventory::Logger->new({
+    backends => [ 'Test' ]
+});
+
+# no connection tests
+BAIL_OUT("port aleady used") if test_port(8080);
+
+my $server;
+my $message = FusionInventory::Agent::XML::Query::SimpleMessage->new({
+    logger => $logger,
+    target => {
+        deviceid => 'bar'
+    },
+    msg => {
+        foo => 'bar'
+    }
+});
+my $unsafe_client = FusionInventory::Agent::Network->new({
+    logger       => $logger,
+    target       => {
+        path => 'https://localhost:8080/public'
+    },
+    config       => {
+        VERSION        => 42,
+        'no-ssl-check' => 1,
+    },
+});
+my $secure_client = FusionInventory::Agent::Network->new({
+    logger       => $logger,
+    target       => {
+        path => 'https://localhost:8080/public'
+    },
+    config       => {
+        VERSION        => 42,
+        'ca-cert-file' => 't/ssl/crt/ca.pem',
+    },
+});
+
+# ensure the server get stopped even if an exception is thrown
+$SIG{__DIE__}  = sub { $server->stop(); };
+
+# trusted certificate, correct hostname
+$server = FusionInventory::Test::Server->new(
+    port     => 8080,
+    user     => 'test',
+    realm    => 'test',
+    password => 'test',
+    ssl      => 1,
+    crt      => 't/ssl/crt/good.pem',
+    key      => 't/ssl/key/good.pem',
+);
+$server->set_dispatch({
+    '/public'  => $ok,
+});
+$server->background();
+
+ok(
+    $secure_client->send({message => $message}),
+    'trusted certificate, correct hostname: connection success'
+);
+
+$server->stop();
+
+# trusted certificate, alternate hostname
+$server = FusionInventory::Test::Server->new(
+    port     => 8080,
+    user     => 'test',
+    realm    => 'test',
+    password => 'test',
+    ssl      => 1,
+    crt      => 't/ssl/crt/alternate.pem',
+    key      => 't/ssl/key/alternate.pem',
+);
+$server->set_dispatch({
+    '/public'  => $ok,
+});
+$server->background();
+
+ok(
+    $secure_client->send({message => $message}),
+    'trusted certificate, alternate hostname: connection success'
+);
+
+$server->stop();
+
+# trusted certificate, wrong hostname
+$server = FusionInventory::Test::Server->new(
+    port     => 8080,
+    user     => 'test',
+    realm    => 'test',
+    password => 'test',
+    ssl      => 1,
+    crt      => 't/ssl/crt/wrong.pem',
+    key      => 't/ssl/key/wrong.pem',
+);
+$server->set_dispatch({
+    '/public'  => $ok,
+});
+$server->background();
+
+ok(
+    !$secure_client->send({message => $message}),
+    'trusted certificate, wrong hostname: connection failure'
+);
+
+ok(
+    $unsafe_client->send({message => $message}),
+    'trusted certificate, wrong hostname, no check: connection success'
+);
+
+$server->stop();
+
+# untrusted certificate, correct hostname
+$server = FusionInventory::Test::Server->new(
+    port     => 8080,
+    user     => 'test',
+    realm    => 'test',
+    password => 'test',
+    ssl      => 1,
+    crt      => 't/ssl/crt/bad.pem',
+    key      => 't/ssl/key/bad.pem',
+);
+$server->set_dispatch({
+    '/public'  => $ok,
+});
+$server->background();
+
+ok(
+    !$secure_client->send({message => $message}),
+    'untrusted certificate, correct hostname: connection failure'
+);
+
+ok(
+    $unsafe_client->send({message => $message}),
+    'untrusted certificate, correct hostname, no check: connection success'
+);
+
+$server->stop();
+
+sub test_port {
+    my $port   = $_[0];
+
+    my $iaddr = inet_aton('localhost');
+    my $paddr = sockaddr_in($port, $iaddr);
+    my $proto = getprotobyname('tcp');
+    if (socket(my $socket, PF_INET, SOCK_STREAM, $proto)) {
+        if (connect($socket, $paddr)) {
+            close $socket;
+            return 1;
+        } 
+    }
+
+    return 0;
+}
diff --git a/t/ssl/cnf/alternate.cnf b/t/ssl/cnf/alternate.cnf
new file mode 100644
index 0000000..263c094
--- /dev/null
+++ b/t/ssl/cnf/alternate.cnf
@@ -0,0 +1,17 @@
+[ req ]
+default_bits       = 2048
+encrypt_key        = no
+distinguished_name = req_dn
+req_extensions     = req_ext
+prompt             = no
+
+[ req_dn ]
+organizationName       = fusioninventory.org
+organizationalUnitName = alternative trusted test certificate
+commonName             = test.fusioninventory.org
+emailAddress           = test@fusioninventory.org
+
+[ req_ext ]
+basicConstraints     = CA:false
+subjectKeyIdentifier = hash
+subjectAltName       = DNS:other.fusioninventory.org, DNS:localhost
diff --git a/t/ssl/cnf/bad.cnf b/t/ssl/cnf/bad.cnf
new file mode 100644
index 0000000..afd2df4
--- /dev/null
+++ b/t/ssl/cnf/bad.cnf
@@ -0,0 +1,16 @@
+[ req ]
+default_bits       = 2048
+encrypt_key        = no
+distinguished_name = req_dn
+req_extensions     = req_ext
+prompt             = no
+
+[ req_dn ]
+organizationName       = fusioninventory.org
+organizationalUnitName = untrusted test certificate
+commonName             = localhost
+emailAddress           = test@fusioninventory.org
+
+[ req_ext ]
+basicConstraints     = CA:false
+subjectKeyIdentifier = hash
diff --git a/t/ssl/cnf/ca.cnf b/t/ssl/cnf/ca.cnf
new file mode 100644
index 0000000..efd29d7
--- /dev/null
+++ b/t/ssl/cnf/ca.cnf
@@ -0,0 +1,45 @@
+[ req ]
+default_bits       = 2048
+default_md         = md5
+distinguished_name = req_dn
+req_extensions     = req_ext
+string_mask        = nombstr
+prompt             = no
+
+[ req_dn ]
+organizationName       = fusioninventory.org
+organizationalUnitName = test certification authority
+commonName             = test_ca
+emailAddress           = test@fusioninventory.org
+
+[ req_ext ]
+basicConstraints       = CA:true
+subjectKeyIdentifier   = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+
+[ ca ]
+default_ca      = default_ca
+
+[ default_ca ]
+dir             = t/ssl
+certificate     = $dir/crt/ca.pem
+private_key     = $dir/key/ca.pem
+certs           = $dir/crt              # Where the issued certs are kept
+serial          = $dir/serial           # The current serial number
+database        = $dir/index.txt        # database index file.
+
+new_certs_dir   = $dir/new              # default place for new certs.
+crl_dir         = $dir/crl              # Where the issued crl are kept
+
+default_days    = 730                   # how long to certify for
+default_crl_days= 30                    # how long before next CRL
+default_md      = md5                   # which md to use.
+preserve        = no                    # keep passed DN ordering
+
+policy          = ca_default_policy
+
+[ ca_default_policy ]
+organizationName        = match
+organizationalUnitName  = supplied
+commonName              = supplied
+emailAddress            = supplied
diff --git a/t/ssl/cnf/good.cnf b/t/ssl/cnf/good.cnf
new file mode 100644
index 0000000..ac8660a
--- /dev/null
+++ b/t/ssl/cnf/good.cnf
@@ -0,0 +1,16 @@
+[ req ]
+default_bits       = 2048
+encrypt_key        = no
+distinguished_name = req_dn
+req_extensions     = req_ext
+prompt             = no
+
+[ req_dn ]
+organizationName       = fusioninventory.org
+organizationalUnitName = trusted test certificate
+commonName             = localhost
+emailAddress           = test@fusioninventory.org
+
+[ req_ext ]
+basicConstraints     = CA:false
+subjectKeyIdentifier = hash
diff --git a/t/ssl/cnf/wrong.cnf b/t/ssl/cnf/wrong.cnf
new file mode 100644
index 0000000..8bbc62b
--- /dev/null
+++ b/t/ssl/cnf/wrong.cnf
@@ -0,0 +1,16 @@
+[ req ]
+default_bits       = 2048
+encrypt_key        = no
+distinguished_name = req_dn
+req_extensions     = req_ext
+prompt             = no
+
+[ req_dn ]
+organizationName       = fusioninventory.org
+organizationalUnitName = wrong trusted test certificate
+commonName             = test.fusioninventory.org
+emailAddress           = test@fusioninventory.org
+
+[ req_ext ]
+basicConstraints     = CA:false
+subjectKeyIdentifier = hash
diff --git a/t/ssl/crt/alternate.pem b/t/ssl/crt/alternate.pem
new file mode 100644
index 0000000..250e676
--- /dev/null
+++ b/t/ssl/crt/alternate.pem
@@ -0,0 +1,80 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: O=fusioninventory.org, OU=test certification authority, CN=test_ca/emailAddress=test@fusioninventory.org
+        Validity
+            Not Before: Jun 26 18:50:55 2011 GMT
+            Not After : Jun 25 18:50:55 2013 GMT
+        Subject: O=fusioninventory.org, OU=alternative trusted test certificate, CN=test.fusioninventory.org/emailAddress=test@fusioninventory.org
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b7:cf:22:c8:7c:3a:2f:90:80:2b:2e:ee:1f:49:
+                    3b:2c:68:7d:a3:a6:2f:7c:a9:05:f2:50:2d:63:5f:
+                    f0:20:9e:b9:9e:01:ab:9b:2a:86:f6:9c:64:e9:95:
+                    56:73:74:d6:8e:12:52:a0:31:80:47:09:17:4e:2a:
+                    5b:b2:77:42:b2:65:3b:14:93:57:d0:09:31:9c:3a:
+                    21:a1:79:c9:9f:13:2c:b5:66:73:5a:1a:76:6b:28:
+                    a4:a3:f9:aa:ec:0f:66:55:e6:98:a1:9d:9b:b8:64:
+                    bc:7a:d8:91:e1:e9:31:68:a5:d2:18:f5:fa:0a:32:
+                    84:77:16:e9:3c:4f:65:90:58:f2:4b:d0:6f:96:c2:
+                    e1:6b:99:59:9a:a2:60:5d:f1:ff:00:1d:42:16:ab:
+                    fb:c5:05:c6:3c:2f:65:c3:1a:45:f7:91:76:2c:df:
+                    01:c3:54:b9:90:65:36:58:52:0f:89:98:a4:a2:4e:
+                    a0:5d:64:37:12:2b:6d:42:e7:3e:2f:ee:bb:8b:38:
+                    1a:4a:ca:51:9e:2a:30:79:0d:bd:ff:92:e0:b0:b7:
+                    9e:9e:ed:d4:ee:bb:d2:df:8b:19:cf:f5:70:cc:be:
+                    2d:37:7c:81:3e:df:e0:33:62:5a:6f:18:cf:2b:8c:
+                    5b:68:84:5b:b4:7a:94:9d:39:be:9d:8c:04:d1:98:
+                    35:c9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            X509v3 Subject Key Identifier: 
+                5C:05:79:B8:C3:CF:17:B4:0D:BB:FD:31:21:01:80:5B:59:B7:63:D9
+            X509v3 Subject Alternative Name: 
+                DNS:other.fusioninventory.org, DNS:localhost
+    Signature Algorithm: md5WithRSAEncryption
+        8b:79:e8:35:0e:66:5f:87:78:82:cc:8f:eb:04:d7:33:4a:cb:
+        da:6e:df:ec:f8:7f:ca:d3:eb:6c:f5:34:af:7d:21:bc:0b:b1:
+        f2:70:5e:ae:4f:53:5a:b5:ab:73:01:69:91:6a:db:1b:51:f5:
+        94:60:d8:ef:69:06:05:4d:c3:b3:51:4a:79:2f:16:41:45:d8:
+        c4:d9:ec:55:89:ee:20:7f:3c:e4:83:72:db:9e:29:0f:6c:9d:
+        39:0c:be:48:04:bb:90:44:ee:90:01:bf:11:91:36:3b:50:13:
+        b7:a9:4e:ae:75:59:90:a3:e8:11:1e:c3:e5:bd:cd:89:a9:6e:
+        eb:6a:db:70:db:26:fd:1c:fc:86:f3:8d:36:d4:95:1a:b6:c5:
+        81:c0:84:73:90:14:d0:8a:fc:d4:1f:8e:d1:fc:e0:4c:b1:04:
+        ae:8b:6f:d4:c7:3c:53:dc:c3:a1:84:d3:16:ed:e8:1a:81:29:
+        0b:9d:4a:53:8f:80:62:84:a8:2f:91:90:2a:98:5b:bd:cf:39:
+        94:ff:06:ce:d7:bc:c1:d9:f0:9f:62:2f:cd:84:c8:38:6d:e0:
+        a2:09:97:ff:62:73:b0:4d:f3:fd:ed:c7:14:cc:36:9c:83:dd:
+        42:18:69:ee:2d:af:39:a4:3d:e3:c4:1f:3a:8d:9b:a0:95:55:
+        56:16:12:0b
+-----BEGIN CERTIFICATE-----
[payload removed: 1365 characters in 21 lines]
+oJVVVhYSCw==
+-----END CERTIFICATE-----
diff --git a/t/ssl/crt/bad.pem b/t/ssl/crt/bad.pem
new file mode 100644
index 0000000..9832812
--- /dev/null
+++ b/t/ssl/crt/bad.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
[payload removed: 1170 characters in 18 lines]
+sF7PJ+SYkTE6wgup0YOngKqdFYeJxX92VFV9BPlSc+2xOw==
+-----END CERTIFICATE-----
diff --git a/t/ssl/crt/ca.pem b/t/ssl/crt/ca.pem
new file mode 100644
index 0000000..96cbcdc
--- /dev/null
+++ b/t/ssl/crt/ca.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
[payload removed: 1170 characters in 18 lines]
+sdDshvKJ9vKINqHOXxiI2zifTaqYwwjSQbwmwWO4m/eKog==
+-----END CERTIFICATE-----
diff --git a/t/ssl/crt/good.pem b/t/ssl/crt/good.pem
new file mode 100644
index 0000000..90fe0bc
--- /dev/null
+++ b/t/ssl/crt/good.pem
@@ -0,0 +1,70 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: O=fusioninventory.org, OU=test certification authority, CN=test_ca/emailAddress=test@fusioninventory.org
+        Validity
+            Not Before: Jul 29 20:21:23 2010 GMT
+            Not After : Jul 28 20:21:23 2012 GMT
+        Subject: O=fusioninventory.org, OU=trusted test certificate, CN=localhost/emailAddress=test@fusioninventory.org
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b6:21:74:de:3d:8c:65:2a:8e:32:54:ca:6a:ab:
+                    f7:8c:2b:01:4d:b0:9a:39:1c:85:bd:26:5b:67:c4:
+                    b8:b0:26:73:59:e2:f0:4a:a1:0d:99:32:d0:54:18:
+                    ae:ae:f2:8e:42:ef:71:1a:3f:f9:1e:df:7f:81:4e:
+                    7c:a3:53:e8:6d:b2:82:b0:76:d0:ea:f7:83:42:6a:
+                    66:85:a3:98:69:b0:07:ea:38:b5:5d:62:9d:6f:b3:
+                    a1:64:39:c4:a3:94:c3:cb:fd:a7:d1:4a:01:ce:99:
+                    b6:dd:83:ed:29:48:96:63:09:9b:96:86:d6:6c:fa:
+                    35:82:19:65:42:be:16:c0:65:ef:50:22:25:ad:2a:
+                    9a:a3:21:e4:76:42:28:bb:7a:9b:4f:7d:11:78:5a:
+                    a6:04:fc:33:03:30:e9:6a:ae:f0:8c:d5:67:43:17:
+                    07:06:43:d6:bc:f9:61:b3:68:a5:1c:04:c6:a7:93:
+                    23:7b:fe:15:35:97:3c:60:0b:78:22:54:a6:3d:4c:
+                    9d:52:3b:33:23:ad:c1:a7:08:24:0b:e5:5d:9c:cb:
+                    39:18:68:b3:80:61:76:e3:6f:81:c8:0e:fa:b9:33:
+                    36:56:a7:e8:43:10:a8:03:91:55:57:f2:73:ff:b2:
+                    ac:85:bc:0d:af:9e:fd:a4:fe:40:00:e8:9b:7f:d0:
+                    c4:53
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5WithRSAEncryption
+        d0:91:39:7a:e6:d8:71:4c:ef:fc:a5:f9:bd:3d:e8:e7:3b:59:
+        83:ec:26:0a:67:ee:4a:7b:ca:0c:41:ed:a6:98:14:4a:06:09:
+        f7:1c:76:e7:68:72:7e:10:e0:4e:f9:98:07:f1:10:86:2b:6c:
+        8d:53:c5:82:f0:f5:02:0b:a8:8d:44:b9:8d:0b:f7:7e:4e:11:
+        dd:e6:2e:a0:37:e1:b9:16:1c:25:f5:29:52:31:8b:38:e2:89:
+        db:49:89:2c:f0:35:a9:06:d7:b7:e5:70:9f:fa:27:a7:b2:ec:
+        3c:b8:bc:33:d8:f6:f3:7e:e9:80:73:e2:5c:99:a0:a5:ce:2e:
+        08:9c:2d:96:d8:2d:c9:38:4b:ed:76:7a:fa:fc:2f:ac:32:62:
+        ba:16:e5:36:3a:ea:8b:22:1d:8c:fd:18:2c:c9:b2:83:91:5b:
+        61:9e:8e:11:a2:ab:ad:09:99:1e:00:56:37:d6:d3:e9:f3:97:
+        d2:2a:65:41:a4:44:db:1b:e2:ae:51:69:f0:38:f9:29:4f:b0:
+        57:9b:60:3a:b1:aa:8d:8c:31:11:d9:64:12:8a:c0:ab:c4:5a:
+        02:08:3c:ef:2d:f2:14:67:ef:97:9a:d7:85:df:18:a1:47:15:
+        cb:9c:f8:2b:1a:d9:c0:f5:b2:d1:58:66:a0:ef:df:44:6c:d7:
+        ce:a6:59:bf
+-----BEGIN CERTIFICATE-----
[payload removed: 1170 characters in 18 lines]
+Fcuc+Csa2cD1stFYZqDv30Rs186mWb8=
+-----END CERTIFICATE-----
diff --git a/t/ssl/crt/wrong.pem b/t/ssl/crt/wrong.pem
new file mode 100644
index 0000000..a9b3ccd
--- /dev/null
+++ b/t/ssl/crt/wrong.pem
@@ -0,0 +1,70 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: O=fusioninventory.org, OU=test certification authority, CN=test_ca/emailAddress=test@fusioninventory.org
+        Validity
+            Not Before: Jun 26 12:33:13 2011 GMT
+            Not After : Jun 25 12:33:13 2013 GMT
+        Subject: O=fusioninventory.org, OU=wrong trusted test certificate, CN=test.fusioninventory.org/emailAddress=test@fusioninventory.org
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c6:41:57:26:32:68:49:67:6a:0d:91:14:c6:3e:
+                    72:39:08:c9:9e:87:8e:76:e9:6b:a9:27:22:a3:fd:
+                    bd:72:2b:54:8d:94:b6:9f:c2:dc:95:63:8f:b1:ed:
+                    18:74:6b:cb:d3:d2:34:04:18:15:56:f5:84:44:82:
+                    d9:61:57:57:9f:0e:f2:6c:ee:e3:85:96:ff:47:b2:
+                    ae:0c:13:a8:e5:65:15:89:44:1d:b7:f4:2b:dc:ae:
+                    01:c2:71:2e:92:75:11:41:f9:ff:52:e8:3e:e0:1e:
+                    bb:3d:57:d3:47:9b:e1:1f:16:de:97:07:89:05:6c:
+                    77:09:98:6b:82:ee:ee:aa:9e:45:c2:f5:3e:10:64:
+                    86:09:62:31:ad:19:a0:14:06:3b:d6:a7:60:bd:20:
+                    47:f6:b7:8d:7e:ec:8b:16:eb:26:29:3f:c3:b4:44:
+                    e2:7a:20:e3:a8:fa:da:91:cf:50:3c:ae:10:42:a5:
+                    09:36:f1:34:9f:30:00:fa:9e:c9:33:f7:e4:d1:89:
+                    0e:d1:f1:eb:de:b0:2a:5e:64:5a:a9:36:f4:82:42:
+                    1d:95:d7:2c:b9:a3:a1:d0:30:cf:eb:21:25:e8:1a:
+                    fb:96:9c:38:d3:9d:9f:04:6a:50:24:10:f4:ad:0a:
+                    de:ba:6e:2b:bd:ca:09:6b:e5:51:d2:dd:03:11:d6:
+                    21:5b
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5WithRSAEncryption
+        a5:45:0a:7d:34:26:3f:87:ab:ed:6b:f0:c9:14:38:06:b5:85:
+        11:e5:00:75:81:82:22:00:68:55:1a:3a:76:cc:9a:8e:6b:96:
+        f9:e4:ac:b2:53:55:97:29:35:09:e1:fe:1b:05:bd:60:d3:d4:
+        02:18:3f:da:d6:d1:61:8a:f0:d5:db:12:a3:a9:59:eb:7d:fc:
+        6c:62:77:4a:49:61:f2:96:a0:a1:86:de:89:f7:35:1f:a4:3b:
+        3f:c1:cb:19:7b:a3:25:cd:0c:ee:45:18:58:11:ce:e0:30:9d:
+        f9:60:f0:45:6a:c7:5f:e1:da:00:4e:68:e3:f8:87:51:ac:df:
+        df:07:dd:8e:d6:86:84:84:b8:e9:c1:f9:f6:43:cb:7a:b3:2e:
+        8a:03:50:f9:0c:16:1c:24:86:9c:f9:f7:96:c5:82:04:82:5a:
+        6f:3d:4f:52:30:98:d1:d3:e5:aa:96:a4:fd:b5:9b:84:6b:20:
+        0e:58:1d:a1:a1:1f:5a:e7:c0:58:a5:f3:5a:ea:26:71:fd:ef:
+        a4:35:74:ea:c4:a7:9d:b2:82:ba:b5:90:93:8c:0f:f6:f1:d8:
+        13:1d:c3:ac:0c:95:67:85:8c:9a:ec:02:62:e2:8a:df:cf:4b:
+        a0:9e:d2:fd:28:41:fe:e3:f5:bb:46:24:1d:7d:dc:0a:9e:f2:
+        40:31:12:3b
+-----BEGIN CERTIFICATE-----
[payload removed: 1231 characters in 19 lines]
+-----END CERTIFICATE-----
diff --git a/t/ssl/key/alternate.pem b/t/ssl/key/alternate.pem
new file mode 100644
index 0000000..74ea036
--- /dev/null
+++ b/t/ssl/key/alternate.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
[payload removed: 1625 characters in 25 lines]
+AfbV6kuxyEnJPZE47wH1hrkFLg==
+-----END PRIVATE KEY-----
diff --git a/t/ssl/key/bad.pem b/t/ssl/key/bad.pem
new file mode 100644
index 0000000..5ae35eb
--- /dev/null
+++ b/t/ssl/key/bad.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
[payload removed: 1625 characters in 25 lines]
+zxnDeDHtSv+ba4N/Jm+UeIQ=
+-----END PRIVATE KEY-----
diff --git a/t/ssl/key/ca.pem b/t/ssl/key/ca.pem
new file mode 100644
index 0000000..f131645
--- /dev/null
+++ b/t/ssl/key/ca.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
[payload removed: 1755 characters in 27 lines]
+XSk=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/t/ssl/key/good.pem b/t/ssl/key/good.pem
new file mode 100644
index 0000000..e8eeccf
--- /dev/null
+++ b/t/ssl/key/good.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
[payload removed: 1625 characters in 25 lines]
+Z0/7KSfELvycMYHZS5vC4cE=
+-----END PRIVATE KEY-----
diff --git a/t/ssl/key/wrong.pem b/t/ssl/key/wrong.pem
new file mode 100644
index 0000000..16a81a8
--- /dev/null
+++ b/t/ssl/key/wrong.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
[payload removed: 1625 characters in 25 lines]
+fybA9qeDRDx6INaQdp8fdUI=
+-----END PRIVATE KEY-----
-- 
1.7.6

