-
-
Save ng-pe/a88da92b7061bbaceff441ac8dca62e2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use 5.008; | |
use IO::Socket::INET; | |
use Net::SSLeay qw/XN_FLAG_RFC2253 ASN1_STRFLGS_ESC_MSB/; | |
use Time::Piece; | |
use Data::Dumper; | |
print "PostgreSQL Certificate"; | |
# get_cert_details() based on https://github.com/rurban/Net-SSLeay/blob/master/examples/x509_cert_details.pl Sample | |
sub get_cert_details { | |
my $x509 = shift; | |
my $rv = {}; | |
my $flag_rfc22536_utf8 = (XN_FLAG_RFC2253) & (~ ASN1_STRFLGS_ESC_MSB); | |
die 'ERROR: $x509 is NULL, gonna quit' unless $x509; | |
warn "Info: dumping subject\n"; | |
my $subj_name = Net::SSLeay::X509_get_subject_name($x509); | |
my $subj_count = Net::SSLeay::X509_NAME_entry_count($subj_name); | |
$rv->{subject}->{count} = $subj_count; | |
$rv->{subject}->{oneline} = Net::SSLeay::X509_NAME_oneline($subj_name); | |
$rv->{subject}->{print_rfc2253} = Net::SSLeay::X509_NAME_print_ex($subj_name); | |
$rv->{subject}->{print_rfc2253_utf8} = Net::SSLeay::X509_NAME_print_ex($subj_name, $flag_rfc22536_utf8); | |
$rv->{subject}->{print_rfc2253_utf8_decoded} = Net::SSLeay::X509_NAME_print_ex($subj_name, $flag_rfc22536_utf8, 1); | |
for my $i (0..$subj_count-1) { | |
my $entry = Net::SSLeay::X509_NAME_get_entry($subj_name, $i); | |
my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry); | |
my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry); | |
my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); | |
$rv->{subject}->{entries}->[$i] = { | |
oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), | |
data => Net::SSLeay::P_ASN1_STRING_get($asn1_string), | |
data_utf8_decoded => Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), | |
nid => ($nid>0) ? $nid : undef, | |
ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, | |
sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, | |
}; | |
} | |
warn "Info: dumping issuer\n"; | |
my $issuer_name = Net::SSLeay::X509_get_issuer_name($x509); | |
my $issuer_count = Net::SSLeay::X509_NAME_entry_count($issuer_name); | |
$rv->{issuer}->{count} = $issuer_count; | |
$rv->{issuer}->{oneline} = Net::SSLeay::X509_NAME_oneline($issuer_name); | |
$rv->{issuer}->{print_rfc2253} = Net::SSLeay::X509_NAME_print_ex($issuer_name); | |
$rv->{issuer}->{print_rfc2253_utf8} = Net::SSLeay::X509_NAME_print_ex($issuer_name, $flag_rfc22536_utf8); | |
$rv->{issuer}->{print_rfc2253_utf8_decoded} = Net::SSLeay::X509_NAME_print_ex($issuer_name, $flag_rfc22536_utf8, 1); | |
for my $i (0..$issuer_count-1) { | |
my $entry = Net::SSLeay::X509_NAME_get_entry($issuer_name, $i); | |
my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry); | |
my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry); | |
my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); | |
$rv->{issuer}->{entries}->[$i] = { | |
oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), | |
data => Net::SSLeay::P_ASN1_STRING_get($asn1_string), | |
data_utf8_decoded => Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), | |
nid => ($nid>0) ? $nid : undef, | |
ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, | |
sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, | |
}; | |
} | |
warn "Info: dumping alternative names\n"; | |
$rv->{subject}->{altnames} = [ Net::SSLeay::X509_get_subjectAltNames($x509) ]; | |
#XXX-TODO maybe add a function for dumping issuerAltNames | |
#$rv->{issuer}->{altnames} = [ Net::SSLeay::X509_get_issuerAltNames($x509) ]; | |
warn "Info: dumping hashes/fingerprints\n"; | |
$rv->{hash}->{subject} = { dec=>Net::SSLeay::X509_subject_name_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_subject_name_hash($x509)) }; | |
$rv->{hash}->{issuer} = { dec=>Net::SSLeay::X509_issuer_name_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_issuer_name_hash($x509)) }; | |
$rv->{hash}->{issuer_and_serial} = { dec=>Net::SSLeay::X509_issuer_and_serial_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_issuer_and_serial_hash($x509)) }; | |
$rv->{fingerprint}->{md5} = Net::SSLeay::X509_get_fingerprint($x509, "md5"); | |
$rv->{fingerprint}->{sha1} = Net::SSLeay::X509_get_fingerprint($x509, "sha1"); | |
my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"); | |
$rv->{digest_sha1}->{pubkey} = Net::SSLeay::X509_pubkey_digest($x509, $sha1_digest); | |
$rv->{digest_sha1}->{x509} = Net::SSLeay::X509_digest($x509, $sha1_digest); | |
warn "Info: dumping expiration\n"; | |
$rv->{not_before} = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($x509)); | |
$rv->{not_after} = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($x509)); | |
warn "Info: dumping serial number\n"; | |
my $ai = Net::SSLeay::X509_get_serialNumber($x509); | |
$rv->{serial} = { | |
hex => Net::SSLeay::P_ASN1_INTEGER_get_hex($ai), | |
dec => Net::SSLeay::P_ASN1_INTEGER_get_dec($ai), | |
long => Net::SSLeay::ASN1_INTEGER_get($ai), | |
}; | |
$rv->{version} = Net::SSLeay::X509_get_version($x509); | |
warn "Info: dumping extensions\n"; | |
my $ext_count = Net::SSLeay::X509_get_ext_count($x509); | |
$rv->{extensions}->{count} = $ext_count; | |
for my $i (0..$ext_count-1) { | |
my $ext = Net::SSLeay::X509_get_ext($x509,$i); | |
my $asn1_string = Net::SSLeay::X509_EXTENSION_get_data($ext); | |
my $asn1_object = Net::SSLeay::X509_EXTENSION_get_object($ext); | |
my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); | |
$rv->{extensions}->{entries}->[$i] = { | |
critical => Net::SSLeay::X509_EXTENSION_get_critical($ext), | |
oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), | |
nid => ($nid>0) ? $nid : undef, | |
ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, | |
sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, | |
data => Net::SSLeay::X509V3_EXT_print($ext), | |
}; | |
} | |
warn "Info: dumping CDP\n"; | |
$rv->{cdp} = [ Net::SSLeay::P_X509_get_crl_distribution_points($x509) ]; | |
warn "Info: dumping extended key usage\n"; | |
$rv->{extkeyusage} = { | |
oid => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,0) ], | |
nid => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,1) ], | |
sn => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,2) ], | |
ln => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,3) ], | |
}; | |
warn "Info: dumping key usage\n"; | |
$rv->{keyusage} = [ Net::SSLeay::P_X509_get_key_usage($x509) ]; | |
warn "Info: dumping netscape cert type\n"; | |
$rv->{ns_cert_type} = [ Net::SSLeay::P_X509_get_netscape_cert_type($x509) ]; | |
warn "Info: dumping other info\n"; | |
$rv->{certificate_type} = Net::SSLeay::X509_certificate_type($x509); | |
$rv->{signature_alg} = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_signature_alg($x509)); | |
$rv->{pubkey_alg} = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_pubkey_alg($x509)); | |
$rv->{pubkey_size} = Net::SSLeay::EVP_PKEY_size(Net::SSLeay::X509_get_pubkey($x509)); | |
$rv->{pubkey_bits} = Net::SSLeay::EVP_PKEY_bits(Net::SSLeay::X509_get_pubkey($x509)); | |
$rv->{pubkey_id} = Net::SSLeay::EVP_PKEY_id(Net::SSLeay::X509_get_pubkey($x509)); | |
return $rv; | |
} | |
sub dump_details { | |
my ($data, $comment) = @_; | |
print "\n"; | |
eval { require Data::Dump }; | |
if (!$@) { | |
# Data::Dump creates nicer output | |
print "# $comment\n"; | |
print "# hashref dumped via Data::Dump\n"; | |
$Data::Dump::TRY_BASE64 = 0 if $Data::Dump::TRY_BASE64; | |
print Data::Dump::pp($data); | |
} | |
else { | |
print "# $comment\n"; | |
print "# hashref dumped via Data::Dumper\n"; | |
print Dumper($data); | |
} | |
print "\n"; | |
} | |
sub check_tlscert { | |
# Create socket | |
my $cc = IO::Socket::INET->new( | |
PeerAddr => "127.0.0.1", | |
PeerPort => 5432, | |
Proto => 'tcp' | |
) or die "Failed to create socket: $!\n"; | |
my $payload = pack('C*', 0, 0, 0, 8, 4, 210, 22, 47); | |
$cc->send($payload); | |
my $resp = ''; | |
$cc->recv($resp, 1); | |
if ($resp eq 'S') { | |
print "Resquest StartTLS : OK\n"; | |
} else { | |
print "Resquest StartTLS : PostgreSQL refuse start SSL! (not available or activate feature)\n"; | |
} | |
# Create SSL Wrap on Socket | |
my $ctx = Net::SSLeay::CTX_new() or die "Failed to create SSL context: $!\n"; | |
my $ssl = Net::SSLeay::new($ctx); | |
Net::SSLeay::set_fd($ssl, fileno($cc)); | |
Net::SSLeay::connect($ssl); | |
print "Info -> Actual Cipher is :`" . Net::SSLeay::get_cipher($ssl) . "'\n"; | |
my $x509 = Net::SSLeay::get_peer_certificate($ssl); | |
my $cert_details = get_cert_details($x509); | |
dump_details($cert_details, ""); | |
# Close SSL and socket properly : | |
my $sslshutdown = Net::SSLeay::shutdown($ssl); | |
Net::SSLeay::free($ssl); | |
Net::SSLeay::CTX_free ($ctx); | |
close $cc; | |
} | |
check_tlscert(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment