/[pdpsoft]/nl.nikhef.pdp.fetchcrl/tags/fetch-crl-3.0.17-2/CRL.pm
ViewVC logotype

Annotation of /nl.nikhef.pdp.fetchcrl/tags/fetch-crl-3.0.17-2/CRL.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2420 - (hide annotations) (download) (as text)
Fri Sep 9 11:18:11 2011 UTC (10 years, 2 months ago) by davidg
Original Path: nl.nikhef.pdp.fetchcrl/trunk/CRL.pm
File MIME type: application/x-perl
File size: 4904 byte(s)
Allow CRL URL files to be named differenly from CA, and still resolve the CA name

1 davidg 1758 #
2     # @(#)$Id$
3     #
4     #
5     package CRL;
6     use strict;
7     require OSSL and import OSSL unless defined &OSSL::new;
8     use vars qw/ $log $cnf /;
9    
10     # Syntax:
11     # CRL->new( [name [,data]] );
12     # CRL->setName( name);
13     # CRL->setData( datablob ); # load a CRL in PEM format or bails out
14     # CRL->verify( cafilelist ); # returns path to CA or undef if verify failed
15     #
16     #
17     sub new {
18     my $obref = {}; bless $obref;
19     my $self = shift;
20     $self = $obref;
21     my $name = shift;
22     my $data = shift;
23    
24     $self->{"name"} = "unknown";
25    
26     $self->setName($name) if $name;
27     $self->setData($data) if $data;
28    
29     return $self;
30     }
31    
32     sub setName($$) {
33     my $self = shift or die "Invalid invocation of CRL::setName\n";
34     my $name = shift;
35     return 0 unless $name;
36    
37     $self->{"name"} = $name;
38     return 1;
39     }
40    
41     sub setData($$) {
42     my $self = shift or die "Invalid invocation of CRL::setData\n";
43     my $data = shift;
44     my $pemdata = undef;
45     my $errormsg;
46     my $openssl = OSSL->new() or $::log->err("OpenSSL not found") and return 0;
47    
48     # try to recognise data type and normalise to PEM string
49     # but extract only the first blob of PEM (so max one CRL per data object)
50     #
51     if ( $data =~
52     /(^-----BEGIN X509 CRL-----\n[^-]+\n-----END X509 CRL-----$)/sm ) {
53     $pemdata = $1;
54     } elsif ( substr($data,0,1) eq "0" ) { # looks a bit like an ASN.1 SEQ
55     ($pemdata,$errormsg) =
56     $openssl->Exec3($data, qw/ crl -inform DER -outform PEM / );
57     $pemdata or
58     $::log->warn("Apparent DER data for",$self->{"name"},"not recognised")
59     and return 0;
60     } else {
61     $::log->warn("CRL data for",$self->{"name"},"not recognised");
62     return 0;
63     }
64    
65     # extract other data from the pem blob with openssl
66     (my $statusdata,$errormsg) =
67     $openssl->Exec3($pemdata, qw/ crl
68 davidg 2420 -noout -issuer -sha1 -fingerprint -lastupdate -nextupdate -hash/);
69 davidg 1758 defined $statusdata or do {
70     ( my $eline = $errormsg ) =~ s/\n.*//sgm;
71     $::log->warn("Unable to extract CRL data for",$self->{"name"},$eline);
72     return 0;
73     };
74     $statusdata =~ /(?:^|\n)SHA1 Fingerprint=([^\n]+)\n/ and
75     $self->{"sha1fp"} = $1;
76     $statusdata =~ /(?:^|\n)issuer=([^\n]+)\n/ and
77     $self->{"issuer"} = $1;
78     $statusdata =~ /(?:^|\n)lastUpdate=([^\n]+)\n/ and
79     $self->{"lastupdatestr"} = $1;
80     $statusdata =~ /(?:^|\n)nextUpdate=([^\n]+)\n/ and
81     $self->{"nextupdatestr"} = $1;
82 davidg 2420 $statusdata =~ /(?:^|\n)([0-9a-f]{8})\n/ and
83     $self->{"hash"} = $1;
84 davidg 1758
85     $self->{"nextupdatestr"} and
86     $self->{"nextupdate"} = $openssl->gms2t($self->{"nextupdatestr"});
87     $self->{"lastupdatestr"} and
88     $self->{"lastupdate"} = $openssl->gms2t($self->{"lastupdatestr"});
89    
90     #$self->{"nextupdate"} = time - 200;
91     #$self->{"lastupdate"} = time + 200;
92    
93     $self->{"data"} = $data;
94     $self->{"pemdata"} = $pemdata;
95    
96     return 1;
97     }
98    
99     sub getLastUpdate($) {
100     my $self = shift or die "Invalid invocation of CRL::getLastUpdate\n";
101     return $self->{"lastupdate"} || undef;
102     }
103    
104     sub getNextUpdate($) {
105     my $self = shift or die "Invalid invocation of CRL::getNextUpdate\n";
106     return $self->{"nextupdate"} || undef;
107     }
108    
109     sub getAttribute($$) {
110 davidg 2420 my $self = shift or die "Invalid invocation of CRL::getAttribute\n";
111 davidg 1758 my $key = shift;
112     return $self->{$key} or undef;
113     }
114    
115     sub getPEMdata($) {
116     my $self = shift or die "Invalid invocation of CRL::getPEMdata\n";
117     $self->{"pemdata"} or
118     $::log->err("Attempt to extract PEM data from bad CRL object",
119     ($self->{"name"}||"unknown")) and
120     return undef;
121     return $self->{"pemdata"};
122     }
123    
124     sub verify($@) {
125     my $self = shift or die "Invalid invocation of CRL::verify\n";
126     my $openssl = OSSL->new() or $::log->err("OpenSSL not found") and return 0;
127     $self->{"pemdata"} or
128     $::log->err("verify called on empty data blob") and return 0;
129    
130     my @verifyStatus = ();
131     # openssl crl verify works against a single CA and does not need a
132     # full chain to be present. That suits us file (checked with OpenSSL
133     # 0.9.5a and 1.0.0a)
134    
135     my $verifyOK;
136     foreach my $cafile ( @_ ) {
137     -e $cafile or
138     $::log->err("CRL::verify called with nonexistent CA file $cafile") and
139     next;
140    
141     my ($dataout,$dataerr) =
142     $openssl->Exec3($self->{"pemdata"}, qw/crl -noout -CAfile/,$cafile);
143     $dataerr and $dataout .= $dataerr;
144     $dataout =~ /verify OK/ and $verifyOK = $cafile and last;
145     }
146     $verifyOK or push @verifyStatus, "CRL signature failed";
147     $verifyOK and
148     $::log->verb(4,"Verified CRL",$self->{"name"},"against $verifyOK");
149    
150     $self->{"nextupdate"} or
151     push @verifyStatus, "CRL nextUpdate determination failed";
152     $self->{"lastupdate"} or
153     push @verifyStatus, "CRL lastUpdate determination failed";
154     if ( $self->{"nextupdate"} and $self->{"nextupdate"} < time ) {
155     push @verifyStatus, "CRL has nextUpdate time in the past";
156     }
157     if ( $self->{"lastupdate"} and $self->{"lastupdate"} > time ) {
158     push @verifyStatus, "CRL has lastUpdate time in the future";
159     }
160    
161     return @verifyStatus;
162     }
163    
164    
165     1;

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28