File Coverage

blib/lib/Mail/DKIM/Algorithm/dk_rsa_sha1.pm
Criterion Covered Total %
statement 67 67 100.0
branch 15 22 68.1
condition 4 9 44.4
subroutine 16 16 100.0
pod 3 8 37.5
total 105 122 86.0


line stmt bran cond sub pod time code
1             package Mail::DKIM::Algorithm::dk_rsa_sha1;
2 8     8   59 use strict;
  8         16  
  8         329  
3 8     8   43 use warnings;
  8         15  
  8         595  
4             our $VERSION = '1.20240923'; # VERSION
5             # ABSTRACT: Base algorithm class
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   4197 use Mail::DKIM::Canonicalization::dk_simple;
  8         29  
  8         348  
15 8     8   4116 use Mail::DKIM::Canonicalization::dk_nofws;
  8         34  
  8         353  
16              
17 8     8   191 use base 'Mail::DKIM::Algorithm::Base';
  8         60  
  8         982  
18 8     8   52 use Carp;
  8         14  
  8         485  
19 8     8   78 use MIME::Base64;
  8         16  
  8         428  
20 8     8   117 use Digest::SHA;
  8         17  
  8         6351  
21              
22             sub finish_header {
23 21     21 1 43 my $self = shift;
24 21         102 $self->SUPER::finish_header(@_);
25              
26 21 50 33     114 if ( ( my $s = $self->signature )
27             && $self->{canon}->{interesting_header} )
28             {
29 21         55 my $sender = $self->{canon}->{interesting_header}->{sender};
30 21   66     285 $sender = defined($sender) && ( Mail::Address->parse($sender) )[0];
31 21         1194 my $author = $self->{canon}->{interesting_header}->{from};
32 21   33     246 $author = defined($author) && ( Mail::Address->parse($author) )[0];
33              
34 21 100       6806 if ($sender) {
    50          
35 4         20 $s->init_identity( $sender->address, 'header.sender' );
36             }
37             elsif ($author) {
38 17         690 $s->init_identity( $author->address, 'header.from' );
39             }
40             }
41 21         116 return;
42             }
43              
44             sub get_canonicalization_class {
45 21     21 0 43 my $self = shift;
46 21 50       65 croak 'wrong number of arguments' unless ( @_ == 1 );
47 21         51 my ($method) = @_;
48              
49 21 50       91 my $class =
    100          
50             $method eq 'nofws' ? 'Mail::DKIM::Canonicalization::dk_nofws'
51             : $method eq 'simple' ? 'Mail::DKIM::Canonicalization::dk_simple'
52             : die "unknown method $method\n";
53 21         61 return $class;
54             }
55              
56             sub init {
57 21     21 0 56 my $self = shift;
58              
59 21 50       86 die 'no signature' unless $self->{Signature};
60              
61 21 100       151 $self->{mode} = $self->{Signature}->signature ? 'verify' : 'sign';
62              
63             # allows subclasses to set the header_digest and body_digest
64             # properties
65 21         88 $self->init_digests;
66              
67 21         84 my $method = $self->{Signature}->canonicalization;
68              
69 21         75 my $canon_class = $self->get_canonicalization_class($method);
70             $self->{canon} = $canon_class->new(
71             output_digest => $self->{header_digest},
72             Signature => $self->{Signature},
73             Debug_Canonicalization => $self->{Debug_Canonicalization}
74 21         285 );
75             }
76              
77             sub init_digests {
78 21     21 0 43 my $self = shift;
79              
80             # initialize a SHA-1 Digest
81 21         202 $self->{header_digest} = Digest::SHA->new(1);
82 21         454 $self->{body_digest} = $self->{header_digest};
83             }
84              
85             sub sign {
86 6     6 1 11 my $self = shift;
87 6 50       15 croak 'wrong number of arguments' unless ( @_ == 1 );
88 6         22 my ($private_key) = @_;
89              
90 6         47 my $digest = $self->{header_digest}->digest;
91 6         31 my $signature = $private_key->sign_digest( 'SHA-1', $digest );
92              
93 6         91 return encode_base64( $signature, '' );
94             }
95              
96             sub verify {
97 13     13 1 27 my $self = shift;
98 13 50       46 croak 'wrong number of arguments' unless ( @_ == 0 );
99              
100 13         73 my $base64 = $self->signature->data;
101 13         47 my $public_key = $self->signature->get_public_key;
102              
103 13         128 my $digest = $self->{header_digest}->digest;
104 13         90 my $sig = decode_base64($base64);
105 13         96 return $public_key->verify_digest( 'SHA-1', $digest, $sig );
106             }
107              
108             sub finish_message {
109 21     21 0 40 my $self = shift;
110              
111             # DomainKeys doesn't include the signature in the digest,
112             # but we still want it to look "pretty" :).
113              
114 21 100       80 if ( $self->{mode} eq 'sign' ) {
115 6         56 $self->{Signature}->prettify;
116             }
117             }
118              
119             sub wants_pre_signature_headers {
120 15     15 0 53 return 0;
121             }
122              
123             1;
124              
125             __END__