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 8     8   2101 use strict;
  8         18  
  8         325  
3 8     8   43 use warnings;
  8         17  
  8         615  
4             our $VERSION = '1.20240923'; # 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 8     8   137 use Mail::DKIM::PublicKey;
  8         16  
  8         300  
15 8     8   6064 use Mail::DKIM::Algorithm::dk_rsa_sha1;
  8         27  
  8         293  
16              
17 8     8   52 use base 'Mail::DKIM::Signature';
  8         20  
  8         1060  
18 8     8   51 use Carp;
  8         15  
  8         5488  
19              
20              
21             sub new {
22 23     23 1 101 my $type = shift;
23 23         77 my %prms = @_;
24 23         113 my $self = {};
25 23         82 bless $self, $type;
26              
27 23   100     186 $self->algorithm( $prms{'Algorithm'} || 'rsa-sha1' );
28 23         187 $self->signature( $prms{'Signature'} );
29 23   100     163 $self->canonicalization( $prms{'Method'} || 'simple' );
30 23         115 $self->domain( $prms{'Domain'} );
31 23         150 $self->headerlist( $prms{'Headers'} );
32 23   50     191 $self->protocol( $prms{'Query'} || 'dns' );
33 23         145 $self->selector( $prms{'Selector'} );
34 23 50       82 $self->key( $prms{'Key'} ) if defined $prms{'Key'};
35              
36 23         94 return $self;
37             }
38              
39              
40             sub parse {
41 17     17 1 43 my $class = shift;
42 17 50       69 croak 'wrong number of arguments' unless ( @_ == 1 );
43 17         55 my ($string) = @_;
44              
45             # remove line terminator, if present
46 17         3473 $string =~ s/\015\012\z//;
47              
48             # remove field name, if present
49 17         44 my $prefix;
50 17 50       123 if ( $string =~ /^(domainkey-signature:)(.*)/si ) {
51              
52             # save the field name (capitalization), so that it can be
53             # restored later
54 17         56 $prefix = $1;
55 17         47 $string = $2;
56             }
57              
58 17         141 my $self = $class->Mail::DKIM::KeyValueList::parse($string);
59 17         54 $self->{prefix} = $prefix;
60              
61 17         65 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 191 my $self = shift;
81              
82 91 100       216 if (@_) {
83 23         117 $self->set_tag( 'a', shift );
84             }
85              
86 91         309 my $a = $self->get_tag('a');
87 91 100 66     601 return defined $a && $a ne '' ? lc $a : 'rsa-sha1';
88             }
89              
90              
91             sub canonicalization {
92 61     61 1 102 my $self = shift;
93 61 50       173 croak 'too many arguments' if ( @_ > 1 );
94              
95 61 100       137 if (@_) {
96 23         69 $self->set_tag( 'c', shift );
97             }
98              
99 61   50     203 return lc( $self->get_tag('c') ) || 'simple';
100             }
101              
102             sub DEFAULT_PREFIX {
103 22     22 0 159 return 'DomainKey-Signature:';
104             }
105              
106              
107             sub domain {
108 83     83 1 140 my $self = shift;
109              
110 83 100       223 if (@_) {
111 23         67 $self->set_tag( 'd', shift );
112             }
113              
114 83         219 my $d = $self->get_tag('d');
115 83 100       575 return defined $d ? lc $d : undef;
116             }
117              
118             sub expiration {
119 15     15 1 29 my $self = shift;
120 15 50       44 croak 'cannot change expiration on ' . ref($self) if @_;
121 15         36 return undef;
122             }
123              
124 8     8   66 use MIME::Base64;
  8         16  
  8         4459  
125              
126             sub check_canonicalization {
127 17     17 0 63 my $self = shift;
128              
129 17         58 my $c = $self->canonicalization;
130              
131 17         56 my @known = ( 'nofws', 'simple' );
132 17 50       47 return unless ( grep { $_ eq $c } @known );
  34         106  
133 17         69 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 52 my $self = shift;
144              
145 32         80 my $protocol = $self->protocol;
146 32 100 100     210 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 68 return 1;
154             }
155              
156             sub get_algorithm_class {
157 38     38 0 85 my $self = shift;
158 38 50       106 croak 'wrong number of arguments' unless ( @_ == 1 );
159 38         83 my ($algorithm) = @_;
160              
161 38 50       120 my $class =
162             $algorithm eq 'rsa-sha1'
163             ? 'Mail::DKIM::Algorithm::dk_rsa_sha1'
164             : undef;
165 38         138 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         40 my $algorithm = $self->algorithm;
173              
174 13 50       79 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 49 my $self = shift;
184 28 50       222 croak 'cannot change identity on ' . ref($self) if @_;
185 28         130 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 348 my $self = shift;
206 21         65 $self->{dk_identity} = shift;
207 21         127 $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 100 my $self = shift;
217              
218 59 100       174 (@_)
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       157 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__