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