File Coverage

blib/lib/Mail/DKIM/DkSignature.pm
Criterion Covered Total %
statement 92 101 91.0
branch 26 38 68.4
condition 11 14 78.5
subroutine 22 29 75.8
pod 16 22 72.7
total 167 204 81.8


line stmt bran cond sub pod time code
1             package Mail::DKIM::DkSignature;
2 7     7   1599 use strict;
  7         15  
  7         209  
3 7     7   32 use warnings;
  7         14  
  7         296  
4             our $VERSION = '1.20230911'; # VERSION
5             # ABSTRACT: represents a DomainKeys-Signature header
6              
7             # Copyright 2005-2006 Messiah College. All rights reserved.
8             # Jason Long
9              
10             # Copyright (c) 2004 Anthony D. Urso. All rights reserved.
11             # This program is free software; you can redistribute it and/or
12             # modify it under the same terms as Perl itself.
13              
14 7     7   42 use Mail::DKIM::PublicKey;
  7         23  
  7         162  
15 7     7   3201 use Mail::DKIM::Algorithm::dk_rsa_sha1;
  7         21  
  7         197  
16              
17 7     7   45 use base 'Mail::DKIM::Signature';
  7         15  
  7         662  
18 7     7   46 use Carp;
  7         13  
  7         4610  
19              
20              
21             sub new {
22 23     23 1 74 my $type = shift;
23 23         55 my %prms = @_;
24 23         44 my $self = {};
25 23         42 bless $self, $type;
26              
27 23   100     114 $self->algorithm( $prms{'Algorithm'} || 'rsa-sha1' );
28 23         115 $self->signature( $prms{'Signature'} );
29 23   100     108 $self->canonicalization( $prms{'Method'} || 'simple' );
30 23         87 $self->domain( $prms{'Domain'} );
31 23         105 $self->headerlist( $prms{'Headers'} );
32 23   50     118 $self->protocol( $prms{'Query'} || 'dns' );
33 23         95 $self->selector( $prms{'Selector'} );
34 23 50       63 $self->key( $prms{'Key'} ) if defined $prms{'Key'};
35              
36 23         77 return $self;
37             }
38              
39              
40             sub parse {
41 17     17 1 32 my $class = shift;
42 17 50       40 croak 'wrong number of arguments' unless ( @_ == 1 );
43 17         36 my ($string) = @_;
44              
45             # remove line terminator, if present
46 17         88 $string =~ s/\015\012\z//;
47              
48             # remove field name, if present
49 17         34 my $prefix;
50 17 50       67 if ( $string =~ /^(domainkey-signature:)(.*)/si ) {
51              
52             # save the field name (capitalization), so that it can be
53             # restored later
54 17         40 $prefix = $1;
55 17         35 $string = $2;
56             }
57              
58 17         73 my $self = $class->Mail::DKIM::KeyValueList::parse($string);
59 17         37 $self->{prefix} = $prefix;
60              
61 17         42 return $self;
62             }
63              
64              
65              
66             sub as_string_without_data {
67 0     0 1 0 croak 'as_string_without_data not implemented';
68             }
69              
70             sub body_count {
71 0     0 1 0 croak 'body_count not implemented';
72             }
73              
74             sub body_hash {
75 0     0 1 0 croak 'body_hash not implemented';
76             }
77              
78              
79             sub algorithm {
80 91     91 1 130 my $self = shift;
81              
82 91 100       232 if (@_) {
83 23         82 $self->set_tag( 'a', shift );
84             }
85              
86 91         205 my $a = $self->get_tag('a');
87 91 100 66     460 return defined $a && $a ne '' ? lc $a : 'rsa-sha1';
88             }
89              
90              
91             sub canonicalization {
92 61     61 1 90 my $self = shift;
93 61 50       137 croak 'too many arguments' if ( @_ > 1 );
94              
95 61 100       120 if (@_) {
96 23         50 $self->set_tag( 'c', shift );
97             }
98              
99 61   50     137 return lc( $self->get_tag('c') ) || 'simple';
100             }
101              
102             sub DEFAULT_PREFIX {
103 22     22 0 114 return 'DomainKey-Signature:';
104             }
105              
106              
107             sub domain {
108 83     83 1 132 my $self = shift;
109              
110 83 100       172 if (@_) {
111 23         62 $self->set_tag( 'd', shift );
112             }
113              
114 83         197 my $d = $self->get_tag('d');
115 83 100       325 return defined $d ? lc $d : undef;
116             }
117              
118             sub expiration {
119 15     15 1 20 my $self = shift;
120 15 50       31 croak 'cannot change expiration on ' . ref($self) if @_;
121 15         29 return undef;
122             }
123              
124 7     7   57 use MIME::Base64;
  7         20  
  7         3728  
125              
126             sub check_canonicalization {
127 17     17 0 29 my $self = shift;
128              
129 17         33 my $c = $self->canonicalization;
130              
131 17         40 my @known = ( 'nofws', 'simple' );
132 17 50       34 return unless ( grep { $_ eq $c } @known );
  34         94  
133 17         51 return 1;
134             }
135              
136             # Returns a filtered list of protocols that can be used to fetch the
137             # public key corresponding to this signature. An empty list means that
138             # all designated protocols are unrecognized.
139             # Note: at this time, the only recognized protocol for DomainKey
140             # signatures is "dns".
141             #
142             sub check_protocol {
143 32     32 0 51 my $self = shift;
144              
145 32         64 my $protocol = $self->protocol;
146 32 100 100     146 return 'dns/txt' if $protocol && $protocol eq 'dns';
147 2         10 return;
148             }
149              
150             sub check_version {
151              
152             #DomainKeys doesn't have a v= tag
153 17     17 0 41 return 1;
154             }
155              
156             sub get_algorithm_class {
157 38     38 0 71 my $self = shift;
158 38 50       81 croak 'wrong number of arguments' unless ( @_ == 1 );
159 38         89 my ($algorithm) = @_;
160              
161 38 50       80 my $class =
162             $algorithm eq 'rsa-sha1'
163             ? 'Mail::DKIM::Algorithm::dk_rsa_sha1'
164             : undef;
165 38         106 return $class;
166             }
167              
168             # get_public_key - same as parent class
169              
170             sub hash_algorithm {
171 13     13 1 24 my $self = shift;
172 13         30 my $algorithm = $self->algorithm;
173              
174 13 50       47 return $algorithm eq 'rsa-sha1' ? 'sha1' : undef;
175             }
176              
177              
178             #sub headerlist
179             # is in Signature.pm
180              
181              
182             sub identity {
183 28     28 1 41 my $self = shift;
184 28 50       60 croak 'cannot change identity on ' . ref($self) if @_;
185 28         70 return $self->{dk_identity};
186             }
187              
188              
189             sub identity_source {
190 0     0 1 0 my $self = shift;
191 0 0       0 croak 'unexpected argument' if @_;
192 0         0 return $self->{dk_identity_source};
193             }
194              
195             # init_identity() - initialize the DomainKeys concept of identity
196             #
197             # The signing identity of a DomainKeys signature is the sender
198             # of the message itself, i.e. the address in the Sender/From header.
199             # The sender may not be known when the signature object is
200             # constructed (since the signature usually precedes the From/Sender
201             # header), so use this method when you have the From/Sender value.
202             # See also finish_header() in Mail::DKIM::Verifier.
203             #
204             sub init_identity {
205 21     21 0 189 my $self = shift;
206 21         44 $self->{dk_identity} = shift;
207 21         85 $self->{dk_identity_source} = shift;
208             }
209              
210             sub method {
211 0     0 1 0 croak 'method not implemented (use canonicalization instead)';
212             }
213              
214              
215             sub protocol {
216 59     59 1 86 my $self = shift;
217              
218 59 100       142 (@_)
219             and $self->set_tag( 'q', shift );
220              
221             # although draft-delany-domainkeys-base-06 does mandate presence of a
222             # q=dns tag, it is quote common that q tag is missing - be merciful
223 59 100       113 return !defined( $self->get_tag('q') ) ? 'dns' : lc $self->get_tag('q');
224             }
225              
226              
227             # same as parent class
228              
229              
230             # same as parent class
231              
232             sub timestamp {
233 0     0 1   croak 'timestamp not implemented';
234             }
235              
236             sub version {
237 0     0 1   croak 'version not implemented';
238             }
239              
240              
241             1;
242              
243             __END__