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   1641 use strict;
  7         16  
  7         214  
3 7     7   35 use warnings;
  7         16  
  7         300  
4             our $VERSION = '1.20230630'; # 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   45 use Mail::DKIM::PublicKey;
  7         14  
  7         160  
15 7     7   3082 use Mail::DKIM::Algorithm::dk_rsa_sha1;
  7         18  
  7         199  
16              
17 7     7   46 use base 'Mail::DKIM::Signature';
  7         14  
  7         662  
18 7     7   47 use Carp;
  7         13  
  7         4319  
19              
20              
21             sub new {
22 23     23 1 75 my $type = shift;
23 23         55 my %prms = @_;
24 23         42 my $self = {};
25 23         43 bless $self, $type;
26              
27 23   100     113 $self->algorithm( $prms{'Algorithm'} || 'rsa-sha1' );
28 23         120 $self->signature( $prms{'Signature'} );
29 23   100     117 $self->canonicalization( $prms{'Method'} || 'simple' );
30 23         89 $self->domain( $prms{'Domain'} );
31 23         109 $self->headerlist( $prms{'Headers'} );
32 23   50     135 $self->protocol( $prms{'Query'} || 'dns' );
33 23         98 $self->selector( $prms{'Selector'} );
34 23 50       61 $self->key( $prms{'Key'} ) if defined $prms{'Key'};
35              
36 23         78 return $self;
37             }
38              
39              
40             sub parse {
41 17     17 1 31 my $class = shift;
42 17 50       39 croak 'wrong number of arguments' unless ( @_ == 1 );
43 17         32 my ($string) = @_;
44              
45             # remove line terminator, if present
46 17         86 $string =~ s/\015\012\z//;
47              
48             # remove field name, if present
49 17         33 my $prefix;
50 17 50       68 if ( $string =~ /^(domainkey-signature:)(.*)/si ) {
51              
52             # save the field name (capitalization), so that it can be
53             # restored later
54 17         38 $prefix = $1;
55 17         37 $string = $2;
56             }
57              
58 17         71 my $self = $class->Mail::DKIM::KeyValueList::parse($string);
59 17         33 $self->{prefix} = $prefix;
60              
61 17         43 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 139 my $self = shift;
81              
82 91 100       189 if (@_) {
83 23         79 $self->set_tag( 'a', shift );
84             }
85              
86 91         206 my $a = $self->get_tag('a');
87 91 100 66     447 return defined $a && $a ne '' ? lc $a : 'rsa-sha1';
88             }
89              
90              
91             sub canonicalization {
92 61     61 1 93 my $self = shift;
93 61 50       135 croak 'too many arguments' if ( @_ > 1 );
94              
95 61 100       125 if (@_) {
96 23         54 $self->set_tag( 'c', shift );
97             }
98              
99 61   50     156 return lc( $self->get_tag('c') ) || 'simple';
100             }
101              
102             sub DEFAULT_PREFIX {
103 22     22 0 102 return 'DomainKey-Signature:';
104             }
105              
106              
107             sub domain {
108 83     83 1 129 my $self = shift;
109              
110 83 100       164 if (@_) {
111 23         56 $self->set_tag( 'd', shift );
112             }
113              
114 83         164 my $d = $self->get_tag('d');
115 83 100       331 return defined $d ? lc $d : undef;
116             }
117              
118             sub expiration {
119 15     15 1 20 my $self = shift;
120 15 50       32 croak 'cannot change expiration on ' . ref($self) if @_;
121 15         31 return undef;
122             }
123              
124 7     7   55 use MIME::Base64;
  7         19  
  7         3672  
125              
126             sub check_canonicalization {
127 17     17 0 28 my $self = shift;
128              
129 17         30 my $c = $self->canonicalization;
130              
131 17         47 my @known = ( 'nofws', 'simple' );
132 17 50       29 return unless ( grep { $_ eq $c } @known );
  34         106  
133 17         49 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 48 my $self = shift;
144              
145 32         85 my $protocol = $self->protocol;
146 32 100 100     164 return 'dns/txt' if $protocol && $protocol eq 'dns';
147 2         7 return;
148             }
149              
150             sub check_version {
151              
152             #DomainKeys doesn't have a v= tag
153 17     17 0 40 return 1;
154             }
155              
156             sub get_algorithm_class {
157 38     38 0 68 my $self = shift;
158 38 50       79 croak 'wrong number of arguments' unless ( @_ == 1 );
159 38         67 my ($algorithm) = @_;
160              
161 38 50       76 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 27 my $self = shift;
172 13         28 my $algorithm = $self->algorithm;
173              
174 13 50       51 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 40 my $self = shift;
184 28 50       53 croak 'cannot change identity on ' . ref($self) if @_;
185 28         65 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 184 my $self = shift;
206 21         43 $self->{dk_identity} = shift;
207 21         83 $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 87 my $self = shift;
217              
218 59 100       162 (@_)
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       119 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__