|
Packit |
b893dc |
#!/usr/bin/perl
|
|
Packit |
b893dc |
#
|
|
Packit |
b893dc |
# Test various verify and ASN functions
|
|
Packit |
b893dc |
# added 2010-04-16
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
use strict;
|
|
Packit |
b893dc |
use warnings;
|
|
Packit |
b893dc |
use Test::More tests => 103;
|
|
Packit |
b893dc |
use Net::SSLeay;
|
|
Packit |
b893dc |
use File::Spec;
|
|
Packit |
b893dc |
use IO::Socket::INET;
|
|
Packit |
b893dc |
use Config;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::randomize();
|
|
Packit |
b893dc |
Net::SSLeay::load_error_strings();
|
|
Packit |
b893dc |
Net::SSLeay::add_ssl_algorithms();
|
|
Packit |
b893dc |
Net::SSLeay::OpenSSL_add_all_algorithms();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Our CA cert and a cert signed with it
|
|
Packit |
b893dc |
my $ca_pem = File::Spec->catfile('t', 'data', 'test_CA1_2048.crt.pem');
|
|
Packit |
b893dc |
#my $ca_dir = File::Spec->catfile('t', 'data');
|
|
Packit |
b893dc |
my $ca_dir = '';
|
|
Packit |
b893dc |
my $cert_pem = File::Spec->catfile('t', 'data', 'testcert_wildcard_CA1_2048.crt.pem');
|
|
Packit |
b893dc |
my $key_pem = File::Spec->catfile('t', 'data', 'testcert_key_2048.pem');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $pm;
|
|
Packit |
b893dc |
my $pm2;
|
|
Packit |
b893dc |
my $verify_result = -1;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip 'openssl-0.9.8 required', 7 unless Net::SSLeay::SSLeay >= 0x0090800f;
|
|
Packit |
b893dc |
$pm = Net::SSLeay::X509_VERIFY_PARAM_new();
|
|
Packit |
b893dc |
ok($pm, 'X509_VERIFY_PARAM_new');
|
|
Packit |
b893dc |
$pm2 = Net::SSLeay::X509_VERIFY_PARAM_new();
|
|
Packit |
b893dc |
ok($pm2, 'X509_VERIFY_PARAM_new 2');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_inherit($pm2, $pm), 'X509_VERIFY_PARAM_inherit');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_set1($pm2, $pm), 'X509_VERIFY_PARAM_inherit');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_set1_name($pm, 'fred'), 'X509_VERIFY_PARAM_set1_name');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS() == 0x40, 'X509_V_FLAG_ALLOW_PROXY_CERTS');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_set_flags($pm, Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS()), 'X509_VERIFY_PARAM_set_flags');
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip 'openssl-0.9.8a required', 3 unless Net::SSLeay::SSLeay >= 0x0090801f;
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_get_flags($pm) == Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS(), 'X509_VERIFY_PARAM_get_flags');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_clear_flags($pm, Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS()), 'X509_VERIFY_PARAM_clear_flags');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_get_flags($pm) == 0, 'X509_VERIFY_PARAM_get_flags');
|
|
Packit |
b893dc |
};
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip 'openssl-0.9.8 required', 4 unless Net::SSLeay::SSLeay >= 0x0090800f;
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_PURPOSE_SSL_CLIENT() == 1, 'X509_PURPOSE_SSL_CLIENT');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_set_purpose($pm, Net::SSLeay::X509_PURPOSE_SSL_CLIENT()), 'X509_VERIFY_PARAM_set_purpose');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_TRUST_EMAIL() == 4, 'X509_TRUST_EMAIL');
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_VERIFY_PARAM_set_trust($pm, Net::SSLeay::X509_TRUST_EMAIL()), 'X509_VERIFY_PARAM_set_trust');
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_set_depth($pm, 5);
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_set_time($pm, time);
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm);
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm2);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Test ASN1 objects
|
|
Packit |
b893dc |
my $asn_object = Net::SSLeay::OBJ_txt2obj('1.2.3.4', 0);
|
|
Packit |
b893dc |
ok($asn_object, 'OBJ_txt2obj');
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_obj2txt($asn_object, 0) eq '1.2.3.4', 'OBJ_obj2txt');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_txt2nid('1.2.840.113549.1') == 2, 'OBJ_txt2nid'); # NID_pkcs
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_txt2nid('1.2.840.113549.2.5') == 4, 'OBJ_txt2nid'); # NID_md5
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_ln2nid('RSA Data Security, Inc. PKCS') == 2, 'OBJ_ln2nid'); # NID_pkcs
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_ln2nid('md5') == 4, 'OBJ_ln2nid'); # NID_md5
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_sn2nid('pkcs') == 2, 'OBJ_sn2nid'); # NID_pkcs
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_sn2nid('MD5') == 4, 'OBJ_sn2nid'); # NID_md5
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $asn_object2 = Net::SSLeay::OBJ_txt2obj('1.2.3.4', 0);
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_cmp($asn_object2, $asn_object) == 0, 'OBJ_cmp');
|
|
Packit |
b893dc |
$asn_object2 = Net::SSLeay::OBJ_txt2obj('1.2.3.5', 0);
|
|
Packit |
b893dc |
ok(Net::SSLeay::OBJ_cmp($asn_object2, $asn_object) != 0, 'OBJ_cmp');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
ok(1, "Finished with tests that don't need fork");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $server;
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip "fork() not supported on $^O", 54, unless $Config{d_fork};
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', Listen => 3)
|
|
Packit |
b893dc |
or BAIL_OUT("failed to create server socket: $!");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
run_server();
|
|
Packit |
b893dc |
my $server_addr = $server->sockhost.':'.$server->sockport;
|
|
Packit |
b893dc |
close($server);
|
|
Packit |
b893dc |
client($server_addr);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
verify_local_trust();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
sub test_policy_checks
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my ($ctx, $cl, $ok) = @_;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$pm = Net::SSLeay::X509_VERIFY_PARAM_new();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Certificate must have this policy
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_set_flags($pm, Net::SSLeay::X509_V_FLAG_POLICY_CHECK() | Net::SSLeay::X509_V_FLAG_EXPLICIT_POLICY());
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $oid = $ok ? '1.1.3.4' : '1.1.3.3.99.88.77';
|
|
Packit |
b893dc |
my $pobject = Net::SSLeay::OBJ_txt2obj($oid, 1);
|
|
Packit |
b893dc |
ok($pobject, "OBJ_txt2obj($oid)");
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_add0_policy($pm, $pobject), 1, "X509_VERIFY_PARAM_add0_policy($oid)");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $ssl = client_get_ssl($ctx, $cl, $pm);
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::connect($ssl);
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal');
|
|
Packit |
b893dc |
if ($ok) {
|
|
Packit |
b893dc |
is($ret, 1, 'connect ok: policy checks succeeded');
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::X509_V_OK(), 'Verify result is X509_V_OK');
|
|
Packit |
b893dc |
print "connect failed: $ret: " . Net::SSLeay::print_errs() . "\n" unless $ret == 1;
|
|
Packit |
b893dc |
} else {
|
|
Packit |
b893dc |
isnt($ret, 1, 'connect not ok: policy checks must fail') if !$ok;
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::X509_V_ERR_NO_EXPLICIT_POLICY(), 'Verify result is X509_V_ERR_NO_EXPLICIT_POLICY');
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# These need at least OpenSSL 1.0.2 or LibreSSL 2.7.0
|
|
Packit |
b893dc |
sub test_hostname_checks
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my ($ctx, $cl, $ok) = @_;
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip 'No Net::SSLeay::X509_VERIFY_PARAM_set1_host, skipping hostname_checks', 13 unless (exists &Net::SSLeay::X509_VERIFY_PARAM_set1_host);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$pm = Net::SSLeay::X509_VERIFY_PARAM_new();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Note: wildcards are supported by default
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_host($pm, 'server.example.com'), 1, 'X509_VERIFY_PARAM_set1_host(server.example.com)') if $ok;
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_add1_host($pm, 'server.not.example.com'), 1, 'X509_VERIFY_PARAM_add1_host(server.not.example.com)') if !$ok;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_email($pm, 'wildcard@example.com'), 1, 'X509_VERIFY_PARAM_set1_email');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Note: 'set' means that only one successfully set can be active
|
|
Packit |
b893dc |
# set1_ip: IPv4 or IPv6 address as 4 or 16 octet binary.
|
|
Packit |
b893dc |
# setip_ip_asc: IPv4 or IPv6 address as ASCII string
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, pack('CCCC', 10, 20, 30, 40)), 1, 'X509_VERIFY_PARAM_set1_ip(10.20.30.40)');
|
|
Packit |
b893dc |
# is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, pack('NNNN', hex('20010db8'), hex('01480100'), 0, hex('31'))), 1, 'X509_VERIFY_PARAM_set1_ip(2001:db8:148:100::31)');
|
|
Packit |
b893dc |
# is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '10.20.30.40'), 1, 'X509_VERIFY_PARAM_set1_ip_asc(10.20.30.40)');
|
|
Packit |
b893dc |
# is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '2001:db8:148:100::31'), 1, 'X509_VERIFY_PARAM_set1_ip_asc(2001:db8:148:100::31))');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Also see that incorrect values do not change anything.
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, '123'), 0, 'X509_VERIFY_PARAM_set1_ip(123)');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, '123456789012345'), 0, 'X509_VERIFY_PARAM_set1_ip(123456789012345)');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '10.20.30.256'), 0, 'X509_VERIFY_PARAM_set1_ip_asc(10.20.30.256)');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '12345::'), 0, 'X509_VERIFY_PARAM_set1_ip_asc(12345::)');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $ssl = client_get_ssl($ctx, $cl, $pm);
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::connect($ssl);
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal');
|
|
Packit |
b893dc |
if ($ok) {
|
|
Packit |
b893dc |
is($ret, 1, 'connect ok: hostname checks succeeded');
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::X509_V_OK(), 'Verify result is X509_V_OK');
|
|
Packit |
b893dc |
print "connect failed: $ret: " . Net::SSLeay::print_errs() . "\n" unless $ret == 1;
|
|
Packit |
b893dc |
} else {
|
|
Packit |
b893dc |
isnt($ret, 1, 'connect not ok: hostname checks must fail') if !$ok;
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::X509_V_ERR_HOSTNAME_MISMATCH(), 'Verify result is X509_V_ERR_HOSTNAME_MISMATCH');
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# For some reason OpenSSL 1.0.2 and LibreSSL return undef for get0_peername. Are we doing this wrong?
|
|
Packit |
b893dc |
$pm2 = Net::SSLeay::get0_param($ssl);
|
|
Packit |
b893dc |
my $peername = Net::SSLeay::X509_VERIFY_PARAM_get0_peername($pm2);
|
|
Packit |
b893dc |
if ($ok) {
|
|
Packit |
b893dc |
is($peername, '*.example.com', 'X509_VERIFY_PARAM_get0_peername returns *.example.com')
|
|
Packit |
b893dc |
if (Net::SSLeay::SSLeay >= 0x10100000 && !Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"));
|
|
Packit |
b893dc |
is($peername, undef, 'X509_VERIFY_PARAM_get0_peername returns undefined for OpenSSL 1.0.2 and LibreSSL')
|
|
Packit |
b893dc |
if (Net::SSLeay::SSLeay < 0x10100000 || Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"));
|
|
Packit |
b893dc |
} else {
|
|
Packit |
b893dc |
is($peername, undef, 'X509_VERIFY_PARAM_get0_peername returns undefined');
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm);
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm2);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
sub test_wildcard_checks
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my ($ctx, $cl) = @_;
|
|
Packit |
b893dc |
SKIP: {
|
|
Packit |
b893dc |
skip 'No Net::SSLeay::X509_VERIFY_PARAM_set1_host, skipping wildcard_checks', 7 unless (exists &Net::SSLeay::X509_VERIFY_PARAM_set1_host);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$pm = Net::SSLeay::X509_VERIFY_PARAM_new();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Wildcards are allowed by default: disallow
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set1_host($pm, 'www.example.com'), 1, 'X509_VERIFY_PARAM_set1_host');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_VERIFY_PARAM_set_hostflags($pm, Net::SSLeay::X509_CHECK_FLAG_NO_WILDCARDS()), undef, 'X509_VERIFY_PARAM_set_hostflags(X509_CHECK_FLAG_NO_WILDCARDS)');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $ssl = client_get_ssl($ctx, $cl, $pm);
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::connect($ssl);
|
|
Packit |
b893dc |
isnt($ret, 1, 'Connect must fail in wildcard test');
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal');
|
|
Packit |
b893dc |
is($verify_result, Net::SSLeay::X509_V_ERR_HOSTNAME_MISMATCH(), 'Verify result is X509_V_ERR_HOSTNAME_MISMATCH');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::X509_VERIFY_PARAM_free($pm);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
sub verify_local_trust {
|
|
Packit |
b893dc |
my $digicert_ca = File::Spec->catfile('t', 'data', 'test_CA1.crt.pem');
|
|
Packit |
b893dc |
my $twitter_chain = File::Spec->catfile('t', 'data', 'chain_leaf.crt.pem');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# read in twitter chain
|
|
Packit |
b893dc |
my $bio = Net::SSLeay::BIO_new_file($twitter_chain, 'r');
|
|
Packit |
b893dc |
ok(my $x509_info_sk = Net::SSLeay::PEM_X509_INFO_read_bio($bio), "PEM_X509_INFO_read_bio able to read in entire chain");
|
|
Packit |
b893dc |
Net::SSLeay::BIO_free($bio);
|
|
Packit |
b893dc |
# read in just twitter certificate
|
|
Packit |
b893dc |
$bio = Net::SSLeay::BIO_new_file($twitter_chain, 'r');
|
|
Packit |
b893dc |
ok(my $cert = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509 able to read in single cert from chain");
|
|
Packit |
b893dc |
Net::SSLeay::BIO_free($bio);
|
|
Packit |
b893dc |
# read in root CA (digicert CA)
|
|
Packit |
b893dc |
$bio = Net::SSLeay::BIO_new_file($digicert_ca, 'r');
|
|
Packit |
b893dc |
ok(my $ca = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509 able to read in root CA");
|
|
Packit |
b893dc |
Net::SSLeay::BIO_free($bio);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
ok(my $x509_sk = Net::SSLeay::sk_X509_new_null(), "sk_X509_new_null creates STACK_OF(X509) successfully");
|
|
Packit |
b893dc |
ok(my $num = Net::SSLeay::sk_X509_INFO_num($x509_info_sk), "sk_X509_INFO_num is nonzero");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# set up STORE_CTX and verify twitter cert using only root CA, should fail due to incomplete chain
|
|
Packit |
b893dc |
ok(my $store = Net::SSLeay::X509_STORE_new(), "X509_STORE_new creates new store");
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_STORE_add_cert($store, $ca), "X509_STORE_add_cert CA cert");
|
|
Packit |
b893dc |
ok(my $ctx = Net::SSLeay::X509_STORE_CTX_new(), "X509_STORE_CTX_new creates new store context");
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_CTX_init($ctx, $store, $cert);
|
|
Packit |
b893dc |
ok(!Net::SSLeay::X509_verify_cert($ctx), 'X509_verify_cert correctly fails');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_STORE_CTX_get_error($ctx),
|
|
Packit |
b893dc |
Net::SSLeay::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY(), "X509_STORE_CTX_get_error returns unable to get local issuer certificate");
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_free($store);
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_CTX_free($ctx);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# add all certificates from twitter chain to X509 stack
|
|
Packit |
b893dc |
for (my $i = 0; $i < $num; $i++) {
|
|
Packit |
b893dc |
ok(my $x509_info = Net::SSLeay::sk_X509_INFO_value($x509_info_sk, $i), "sk_X509_INFO_value");
|
|
Packit |
b893dc |
ok(my $x509 = Net::SSLeay::P_X509_INFO_get_x509($x509_info), "P_X509_INFO_get_x509");
|
|
Packit |
b893dc |
ok(Net::SSLeay::sk_X509_push($x509_sk, $x509), "sk_X509_push");
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# set up STORE_CTX and verify twitter cert using root CA and chain, should succeed
|
|
Packit |
b893dc |
ok($store = Net::SSLeay::X509_STORE_new(), "X509_STORE_new creates new store");
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_STORE_add_cert($store, $ca), "X509_STORE_add_cert CA cert");
|
|
Packit |
b893dc |
ok($ctx = Net::SSLeay::X509_STORE_CTX_new(), "X509_STORE_CTX_new creates new store context");
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_CTX_init($ctx, $store, $cert, $x509_sk);
|
|
Packit |
b893dc |
ok(Net::SSLeay::X509_verify_cert($ctx), 'X509_verify_cert correctly succeeds');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_STORE_CTX_get_error($ctx), Net::SSLeay::X509_V_OK(), "X509_STORE_CTX_get_error returns ok");
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_free($store);
|
|
Packit |
b893dc |
Net::SSLeay::X509_STORE_CTX_free($ctx);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::sk_X509_free($x509_sk);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Prepare and return a new $ssl based on callers verification needs
|
|
Packit |
b893dc |
# Note that this adds tests to caller's test count.
|
|
Packit |
b893dc |
sub client_get_ssl
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my ($ctx, $cl, $pm) = @_;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $store = Net::SSLeay::CTX_get_cert_store($ctx);
|
|
Packit |
b893dc |
ok($store, 'CTX_get_cert_store');
|
|
Packit |
b893dc |
is(Net::SSLeay::X509_STORE_set1_param($store, $pm), 1, 'X509_STORE_set1_param');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Needs OpenSSL 1.0.0 or later
|
|
Packit |
b893dc |
#Net::SSLeay::CTX_set1_param($ctx, $pm);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$verify_result = -1; # Last verification result, set by callback below
|
|
Packit |
b893dc |
my $verify_cb = sub { $verify_result = Net::SSLeay::X509_STORE_CTX_get_error($_[1]); return $_[0];};
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $ssl = Net::SSLeay::new($ctx);
|
|
Packit |
b893dc |
Net::SSLeay::set_verify($ssl, Net::SSLeay::VERIFY_PEER(), $verify_cb);
|
|
Packit |
b893dc |
Net::SSLeay::set_fd($ssl, $cl);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
return $ssl;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# SSL client - connect to server and test different verification
|
|
Packit |
b893dc |
# settings
|
|
Packit |
b893dc |
sub client {
|
|
Packit |
b893dc |
my ($server_addr) = @_;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my ($ctx, $cl);
|
|
Packit |
b893dc |
foreach my $task (qw(
|
|
Packit |
b893dc |
policy_checks_ok policy_checks_fail
|
|
Packit |
b893dc |
hostname_checks_ok hostname_checks_fail
|
|
Packit |
b893dc |
wildcard_checks
|
|
Packit |
b893dc |
finish))
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
$ctx = Net::SSLeay::CTX_new();
|
|
Packit |
b893dc |
is(Net::SSLeay::CTX_load_verify_locations($ctx, $ca_pem, $ca_dir), 1, "load_verify_locations($ca_pem $ca_dir)");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$cl = IO::Socket::INET->new($server_addr) or BAIL_OUT("failed to connect to server: $!");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
test_policy_checks($ctx, $cl, 1) if $task eq 'policy_checks_ok';
|
|
Packit |
b893dc |
test_policy_checks($ctx, $cl, 0) if $task eq 'policy_checks_fail';
|
|
Packit |
b893dc |
test_hostname_checks($ctx, $cl, 1) if $task eq 'hostname_checks_ok';
|
|
Packit |
b893dc |
test_hostname_checks($ctx, $cl, 0) if $task eq 'hostname_checks_fail';
|
|
Packit |
b893dc |
test_wildcard_checks($ctx, $cl) if $task eq 'wildcard_checks';
|
|
Packit |
b893dc |
last if $task eq 'finish'; # Leaves $cl alive
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
close($cl);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Tell the server to quit and see that our connection is still up
|
|
Packit |
b893dc |
$ctx = Net::SSLeay::CTX_new();
|
|
Packit |
b893dc |
my $ssl = Net::SSLeay::new($ctx);
|
|
Packit |
b893dc |
Net::SSLeay::set_fd($ssl, $cl);
|
|
Packit |
b893dc |
Net::SSLeay::connect($ssl);
|
|
Packit |
b893dc |
my $end = "end";
|
|
Packit |
b893dc |
Net::SSLeay::ssl_write_all($ssl, $end);
|
|
Packit |
b893dc |
Net::SSLeay::shutdown($ssl);
|
|
Packit |
b893dc |
ok($end eq Net::SSLeay::ssl_read_all($ssl), 'Successful termination');
|
|
Packit |
b893dc |
return;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# SSL server - just accept connnections and exit when told to by
|
|
Packit |
b893dc |
# the client
|
|
Packit |
b893dc |
sub run_server
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my $pid;
|
|
Packit |
b893dc |
defined($pid = fork()) or BAIL_OUT("failed to fork: $!");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
return if $pid != 0;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$SIG{'PIPE'} = 'IGNORE';
|
|
Packit |
b893dc |
my $ctx = Net::SSLeay::CTX_new();
|
|
Packit |
b893dc |
Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem);
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::CTX_check_private_key($ctx);
|
|
Packit |
b893dc |
BAIL_OUT("Server: CTX_check_private_key failed: $cert_pem, $key_pem") unless $ret == 1;
|
|
Packit |
b893dc |
if (defined &Net::SSLeay::CTX_set_num_tickets) {
|
|
Packit |
b893dc |
# TLS 1.3 server sends session tickets after a handhake as part of
|
|
Packit |
b893dc |
# the SSL_accept(). If a client finishes all its job including closing
|
|
Packit |
b893dc |
# TCP connectino before a server sends the tickets, SSL_accept() fails
|
|
Packit |
b893dc |
# with SSL_ERROR_SYSCALL and EPIPE errno and the server receives
|
|
Packit |
b893dc |
# SIGPIPE signal. <https://github.com/openssl/openssl/issues/6904>
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::CTX_set_num_tickets($ctx, 0);
|
|
Packit |
b893dc |
BAIL_OUT("Session tickets disabled") unless $ret;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
while (1)
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
my $cl = $server->accept or BAIL_OUT("accept failed: $!");
|
|
Packit |
b893dc |
my $ssl = Net::SSLeay::new($ctx);
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
Net::SSLeay::set_fd($ssl, fileno($cl));
|
|
Packit |
b893dc |
my $ret = Net::SSLeay::accept($ssl);
|
|
Packit |
b893dc |
next unless $ret == 1;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
# Termination request or other message from client
|
|
Packit |
b893dc |
my $msg = Net::SSLeay::ssl_read_all($ssl);
|
|
Packit |
b893dc |
if (defined $msg and $msg eq 'end')
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
Net::SSLeay::ssl_write_all($ssl, 'end');
|
|
Packit |
b893dc |
exit (0);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|