Check Public Key Bit Length With This
Update: There is an updated version of this script located on my post: Here's a New Version of skeypatrol.pl
With only about 6 months left before Certificate Authorities stop supporting certificates with 1024-bit keys, I thought it would be neat to find a quicker way than using OpenSSL's s_client or a web browser to determine whether or not the server certificate on a web site needed to be replaced. Believe me, if you have a bunch of sites, visiting all of them with browser, click the lock icon, and then view the certificate details gets really tedious after the first 5 or 10 sites.
So, here's a new script, skeypatrol.pl, based on work I did in cryptonark, and this functionality will make it into the next cnark release in a week or so. The initial version outputs the size of the public key included in the ssl certificate. Other than a tcp handshake and a TLS handshake, no requests are sent to the server. If the number of bits in the cert is below 2048, the script's output will be colored red, (or whatever color your terminal theme decides is "RED").
#!/usr/bin/env perl use Modern::Perl; use Term::ANSIColor qw(:constants); use IO::Socket::SSL 1.33 'debug0'; use Mozilla::CA; use Getopt::Long; #use Data::Dumper; my $scriptname = "skeypatrol.pl"; my $version = "v0.1"; my ( $host, $port ); my $insecure = ''; my $verifymode = 2; my $pkeybits; my $sslclient; my $x509; sub usage{ say "Usage: $scriptname <host> <port>\n\t\t-h|--host\tSSL host or common name \n\t\t-p|--port\tPort number site listens on (e.g. 443)\n\t\t-i|--insecure\tDo not verify certificates"; exit; } usage() if ( ! GetOptions("h|host=s" => \$host, "p|port=s" => \$port, "i|insecure" => $insecure ) or ( ! defined $host ) or ( ! defined $port ) ); if ( $insecure eq 1 ) { $verifymode = 0; } sub key_length { if ( $pkeybits lt 2048 ) { print RED, "Certificate for $host uses a $pkeybits bit key\n", RESET; } else { print GREEN, "Certificate for $host uses a $pkeybits bit key\n", RESET; } } sub ssl_client { $sslclient = IO::Socket::SSL->new( PeerHost => "$host:$port", SSL_ca_file => Mozilla::CA::SSL_ca_file(), SSL_verify_mode => $verifymode, SSL_version => 'TLSv1', SSL_cipher => 'RC4-SHA', Proto => 'tcp', Timeout => '15' ) ||die("Certificate Peer Verification Failed.\n$!,$SSL_ERROR\n\nRun $scriptname with the -i|--insecure switch if you wish to disable certificate validation\n\n"); $sslclient->verify_hostname($host, "http") ||die("Hostname verification failed.\n$host does not match common name on certificate.\nYou can bypass this by passing the -i|--insecure switch to $scriptname\n\n"); say "Certificate Peer Validation Successful"; $x509 = get_cert($sslclient); } sub get_cert { my $sslclient = shift()->_get_ssl_object || return; return Net::SSLeay::get_peer_certificate($sslclient); } sub get_key_size { $pkeybits = Net::SSLeay::EVP_PKEY_bits(Net::SSLeay::X509_get_pubkey($x509)); } ssl_client(); get_key_size(); key_length(); #Begin perldoc __END__ =pod =head1 TITLE skeypatrol.pl =head1 VERSION Version 0.1 =head1 DATE June 24, 2013 =head1 AUTHOR Chris Mahns Contact me at: techstacks [at] gmail [dot] com or follow me on Twitter: @techstacks =head1 DESCRIPTION skeypatrol.pl was written because I wanted to know whether the public key at the end of the ssl connection was 1024 bits or not. This is useful in case you're looking to know what ssl certificates you need to replace before they stop working on January 1, 2014. =head1 USAGE skeypatrol.pl --host <host_to_scan> --port <port_number> Both parameters are required in this version and I assume that the script is marked user-executable. =head1 DEPENDENCIES CPAN modules Modern::Perl, Term::ANSIColor, IO::Socket::SSL, Getopt::Long, and Mozilla::CA are used. If you have already used cryptonark, you've already got these. =head1 VERSION HISTORY =head2 VERSION 0.1 + Initial release. =cut