File Coverage

lib/Net/Domain/TMCH.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             # Copyrights 2013-2014 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.01.
5 3     3   316452 use warnings;
  3         6  
  3         95  
6 3     3   16 use strict;
  3         6  
  3         148  
7              
8             package Net::Domain::TMCH;
9 3     3   26 use vars '$VERSION';
  3         6  
  3         186  
10             $VERSION = '0.17';
11              
12 3     3   16 use base 'Exporter';
  3         5  
  3         337  
13              
14 3     3   1710 use Log::Report 'net-domain-smd';
  3         246441  
  3         26  
15              
16 3     3   2493 use Net::Domain::SMD::Schema ();
  0            
  0            
17             use Net::Domain::TMCH::CRL ();
18             use Net::Domain::SMD::RL ();
19              
20             use Crypt::OpenSSL::VerifyX509 ();
21             use Crypt::OpenSSL::X509 ();
22             use File::Basename qw(dirname);
23             use File::Spec::Functions qw(catfile);
24             use Scalar::Util qw(blessed);
25             use URI ();
26              
27             use constant
28             { TMV_CRL_LIVE => 'http://crl.icann.org/tmch.crl' # what? no https?
29             , TMV_CRL_PILOT => 'http://crl.icann.org/tmch_pilot.crl'
30             };
31              
32              
33             sub new($%) { my ($class, %args) = @_; (bless {}, $class)->init(\%args) }
34              
35             sub init($)
36             { my ($self, $args) = @_;
37             $self->{NDT_smds} = $args->{smds_admin} ||
38             Net::Domain::SMD::Schema->new
39             ( prepare => 'READER'
40             , auto_datetime => $args->{auto_datetime}
41             );
42              
43             my $pilot = $self->{NDT_pilot} = $args->{is_pilot};
44             my $stage = $pilot ? 'tmch_pilot' : 'tmch';
45              
46             my $tmch_pem = $args->{tmch_certificate}
47             || catfile dirname(__FILE__), 'TMCH', 'icann', "$stage.pem";
48              
49             $self->{NDT_tmch_cert} = Crypt::OpenSSL::X509->new_from_file($tmch_pem);
50             $self->{NDT_tmch_ca} = Crypt::OpenSSL::VerifyX509->new($tmch_pem);
51              
52             $self->{NDT_crl} = $self->_crl($args->{cert_revocations}
53             || ($pilot ? TMV_CRL_PILOT : TMV_CRL_LIVE));
54              
55             $self->{NDT_smdrl} = [ $self->_smdrl($args->{smd_revocations}) ];
56              
57             $self;
58             }
59              
60             sub _crl($)
61             { my ($self, $r) = @_;
62              
63             $r = URI->new($r)
64             if !blessed $r && $r =~ m!^https?://!;
65              
66             return Net::Domain::TMCH::CRL->fromFile($r)
67             if !blessed $r;
68              
69             return $r
70             if $r->isa('Net::Domain::TMCH::CRL');
71              
72             return Net::Domain::TMCH::CRL->fromURI($r)
73             if $r->isa('URI');
74              
75             error __x"revocation list for THMC is not a {pkg}, filename, or uri"
76             , pkg => 'Net::Domain::TMCH::CRL';
77             }
78              
79             sub _smdrl($)
80             { my ($self, $r) = @_;
81              
82             return ()
83             unless defined $r;
84              
85             return map $self->_smdrl($_), @$r
86             if ref $r eq 'ARRAY';
87              
88             $r = URI->new($r)
89             if !blessed $r && $r =~ m!^https?://!;
90              
91             return Net::Domain::SMD::RL->fromFile($r)
92             if !blessed $r;
93              
94             return $r
95             if $r->isa('Net::Domain::SMD::RL');
96              
97             return Net::Domain::SMD::RL->fromURI($r)
98             if $r->isa('URI');
99            
100             error __x"revocation list for SMD is not a {pkg} or filename"
101             , pkg => 'Net::Domain::SMD::RL';
102             }
103              
104             #-------------------------
105              
106              
107             sub smdAdmin() {shift->{NDT_smds}}
108             sub isPilot() {shift->{NDT_pilot}}
109             sub tmchCertificate(){shift->{NDT_tmch_cert}}
110             sub tmchCA() {shift->{NDT_tmch_ca}}
111             sub certRevocations(){shift->{NDT_crl}}
112             sub smdRevocations() { @{shift->{NDT_smdrl}} }
113              
114             #-------------------------
115              
116              
117             sub smd($%)
118             { my ($self, $xml, %args) = @_;
119              
120             my ($smd, $source) = $self->smdAdmin->from($xml);
121             return $smd
122             if !$smd || $args{trust_certificates};
123              
124             my $tmch_cert = $self->tmchCertificate;
125              
126             my ($tmv_cert) = $smd->certificates(issuer => $tmch_cert->subject);
127             defined $tmv_cert
128             or error __x"smd in {source} does not contain a TMV certificate"
129             , source => $source;
130              
131             $self->tmchCA->verify($tmv_cert)
132             or error __x"invalid TMV certificate in {source}", source => $source;
133              
134             $args{accept_expired} || ! $tmv_cert->checkend(0)
135             or error __x"the TMV certificate in {source} has expired"
136             , source => $source;
137              
138             $self->certRevocations->isRevoked($tmv_cert)
139             and error __x"smd in {source} contains revoked TMV certificate"
140             , source => $source;
141              
142             foreach my $rl ($self->smdRevocations)
143             { error __x"smd in {source} is revoked according to {list}"
144             , source => $source, list => $rl->source
145             if $rl->isRevoked($smd);
146             }
147              
148             $smd;
149             }
150              
151             1;