Net::SSL::ExpireDateはすごい

SSL証明書

証明書の管理ってめんどくさいなぁと思っていたら,id:hirose31さんがNet::SSL::ExpireDateというモジュールを作られていました.これはすごい.何気なく試してみて期限切れの証明書を発見(だめじゃん).ぜひこのモジュールには,オレオレ証明書を発見するメソッドも追加して欲しいです.

Test::More

Net::SSL::ExpireDateを使わずに,証明書のCNがホスト名と一致するかってテストと,期限まで1週間を切ってないかっていうテストをするスクリプトを書いてみました.

#!/usr/local/bin/perl

use IO::Socket::SSL;
use Net::SSLeay;
use Test::More qw(no_plan);
use Date::Parse;
use DateTime;
use DateTime::Duration;
use Time::Duration::Parse;
use strict;

my $duration = '1 week';

while ($host = <DATA>) {
    my ( $sock, $cert, $sub );
    my ( $name, $expire, $ex_epoc, $limit_epoch );

    chomp($host);

    $sock = IO::Socket::SSL->new("$host:443");
    next if ( !$sock );

    $cert = $sock->peer_certificate();
    $sub =
      Net::SSLeay::X509_NAME_oneline(
        Net::SSLeay::X509_get_subject_name($cert) );

    $expire =
      Net::SSLeay::P_ASN1_UTCTIME_put2string(
        Net::SSLeay::X509_get_notAfter($cert) );
    $ex_epoc = DateTime->from_epoch( epoch => str2time($expire) );

    $sock->close;

    is( $name, $host, $host ) if ( ($name) = $sub =~ m{CN=(\S+)} );

    $limit_epoch =
      DateTime->now->add_duration(
        DateTime::Duration->new( seconds => parse_duration($duration) ) );

    cmp_ok( DateTime->compare( $ex_epoc, $limit_epoch ),
        ">=", 0, "$host expired at $expire" );

}
__END__
この後に対象となるfqdnを列挙

出力がきれいじゃないなぁ.

not ok 7 - foo.co.jp
#   Failed test 'foo.co.jp'
#   in ./fraud.pl at line 35.
#          got: 'bar.foo.co.jp'
#     expected: 'foo.co.jp'

とか

not ok 64 - foo.co.jp expired at Jul 15 23:59:59 2006 GMT
#   Failed test 'foo.co.jp expired at Jul 15 23:59:59 2006 GMT'
#   in ./fraud.pl at line 42.
#     '-1'
#         >=
#     '0'

ってなってしまう.もう少し工夫できないものかしら.