line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mail::DKIM::Algorithm::Base; |
2
|
14
|
|
|
14
|
|
121
|
use strict; |
|
14
|
|
|
|
|
32
|
|
|
14
|
|
|
|
|
426
|
|
3
|
14
|
|
|
14
|
|
91
|
use warnings; |
|
14
|
|
|
|
|
49
|
|
|
14
|
|
|
|
|
677
|
|
4
|
|
|
|
|
|
|
our $VERSION = '1.20230630'; # VERSION |
5
|
|
|
|
|
|
|
# ABSTRACT: base class for DKIM "algorithms" |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# Copyright 2005-2007 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
|
14
|
|
|
14
|
|
10490
|
use Mail::DKIM::Canonicalization::nowsp; |
|
14
|
|
|
|
|
39
|
|
|
14
|
|
|
|
|
425
|
|
15
|
14
|
|
|
14
|
|
6122
|
use Mail::DKIM::Canonicalization::relaxed; |
|
14
|
|
|
|
|
44
|
|
|
14
|
|
|
|
|
475
|
|
16
|
14
|
|
|
14
|
|
5500
|
use Mail::DKIM::Canonicalization::simple; |
|
14
|
|
|
|
|
35
|
|
|
14
|
|
|
|
|
403
|
|
17
|
14
|
|
|
14
|
|
5972
|
use Mail::DKIM::Canonicalization::seal; |
|
14
|
|
|
|
|
85
|
|
|
14
|
|
|
|
|
424
|
|
18
|
|
|
|
|
|
|
|
19
|
14
|
|
|
14
|
|
87
|
use Carp; |
|
14
|
|
|
|
|
24
|
|
|
14
|
|
|
|
|
831
|
|
20
|
14
|
|
|
14
|
|
92
|
use MIME::Base64; |
|
14
|
|
|
|
|
26
|
|
|
14
|
|
|
|
|
15469
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub new { |
23
|
481
|
|
|
481
|
0
|
912
|
my $class = shift; |
24
|
481
|
|
|
|
|
1824
|
my %args = @_; |
25
|
481
|
|
|
|
|
1006
|
my $self = bless \%args, $class; |
26
|
481
|
|
|
|
|
1329
|
$self->init; |
27
|
481
|
|
|
|
|
1187
|
return $self; |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub init { |
31
|
460
|
|
|
460
|
0
|
700
|
my $self = shift; |
32
|
|
|
|
|
|
|
|
33
|
460
|
50
|
|
|
|
1091
|
croak 'no signature' unless $self->{Signature}; |
34
|
|
|
|
|
|
|
|
35
|
460
|
100
|
|
|
|
1092
|
$self->{mode} = $self->{Signature}->signature ? 'verify' : 'sign'; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# allows subclasses to set the header_digest and body_digest |
38
|
|
|
|
|
|
|
# properties |
39
|
460
|
|
|
|
|
1872
|
$self->init_digests; |
40
|
|
|
|
|
|
|
|
41
|
460
|
|
|
|
|
5104
|
my ( $header_method, $body_method ) = $self->{Signature}->canonicalization; |
42
|
|
|
|
|
|
|
|
43
|
460
|
|
|
|
|
1184
|
my $header_class = $self->get_canonicalization_class($header_method); |
44
|
460
|
|
|
|
|
877
|
my $body_class = $self->get_canonicalization_class($body_method); |
45
|
|
|
|
|
|
|
$self->{canon} = $header_class->new( |
46
|
|
|
|
|
|
|
output_digest => $self->{header_digest}, |
47
|
|
|
|
|
|
|
Signature => $self->{Signature}, |
48
|
|
|
|
|
|
|
Debug_Canonicalization => $self->{Debug_Canonicalization} |
49
|
460
|
|
|
|
|
1943
|
); |
50
|
|
|
|
|
|
|
$self->{body_canon} = $body_class->new( |
51
|
|
|
|
|
|
|
output_digest => $self->{body_digest}, |
52
|
|
|
|
|
|
|
Signature => $self->{Signature}, |
53
|
|
|
|
|
|
|
Debug_Canonicalization => $self->{Debug_Canonicalization} |
54
|
460
|
|
|
|
|
1413
|
); |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# override this method, please... |
58
|
|
|
|
|
|
|
# this method should set the "header_digest" and "body_digest" properties |
59
|
|
|
|
|
|
|
sub init_digests { |
60
|
0
|
|
|
0
|
0
|
0
|
die 'not implemented'; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# private method - DKIM-specific |
64
|
|
|
|
|
|
|
sub get_canonicalization_class { |
65
|
920
|
|
|
920
|
0
|
1336
|
my $self = shift; |
66
|
920
|
50
|
|
|
|
1791
|
croak 'wrong number of arguments' unless ( @_ == 1 ); |
67
|
920
|
|
|
|
|
1494
|
my ($method) = @_; |
68
|
|
|
|
|
|
|
|
69
|
920
|
50
|
|
|
|
2470
|
my $class = |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
70
|
|
|
|
|
|
|
$method eq 'nowsp' ? 'Mail::DKIM::Canonicalization::nowsp' |
71
|
|
|
|
|
|
|
: $method eq 'relaxed' ? 'Mail::DKIM::Canonicalization::relaxed' |
72
|
|
|
|
|
|
|
: $method eq 'simple' ? 'Mail::DKIM::Canonicalization::simple' |
73
|
|
|
|
|
|
|
: $method eq 'seal' ? 'Mail::DKIM::Canonicalization::seal' |
74
|
|
|
|
|
|
|
: die "unknown method $method\n"; |
75
|
920
|
|
|
|
|
1522
|
return $class; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub add_body { |
80
|
458
|
|
|
458
|
1
|
738
|
my $self = shift; |
81
|
458
|
|
66
|
|
|
1152
|
my $canon = $self->{body_canon} || $self->{canon}; |
82
|
458
|
|
|
|
|
1173
|
$canon->add_body(@_); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub add_header { |
87
|
6040
|
|
|
6040
|
1
|
8328
|
my $self = shift; |
88
|
6040
|
|
|
|
|
12687
|
$self->{canon}->add_header(@_); |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub finish_body { |
93
|
439
|
|
|
439
|
1
|
672
|
my $self = shift; |
94
|
439
|
|
66
|
|
|
1064
|
my $body_canon = $self->{body_canon} || $self->{canon}; |
95
|
439
|
|
|
|
|
1291
|
$body_canon->finish_body; |
96
|
439
|
|
|
|
|
951
|
$self->finish_message; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub finish_header { |
101
|
477
|
|
|
477
|
1
|
811
|
my $self = shift; |
102
|
477
|
|
|
|
|
1458
|
$self->{canon}->finish_header(@_); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# checks the bh= tag of the signature to see if it has the same body |
106
|
|
|
|
|
|
|
# hash as computed by canonicalizing/digesting the actual message body. |
107
|
|
|
|
|
|
|
# If it doesn't match, a false value is returned, and the |
108
|
|
|
|
|
|
|
# verification_details property is set to "body has been altered" |
109
|
|
|
|
|
|
|
sub check_body_hash { |
110
|
259
|
|
|
259
|
0
|
445
|
my $self = shift; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# The body_hash value is set in finish_message(), if we're operating |
113
|
|
|
|
|
|
|
# from a version of the DKIM spec that uses the bh= tag. Otherwise, |
114
|
|
|
|
|
|
|
# the signature shouldn't have a bh= tag to check. |
115
|
|
|
|
|
|
|
|
116
|
259
|
|
|
|
|
816
|
my $sighash = $self->{Signature}->body_hash(); |
117
|
259
|
100
|
66
|
|
|
1020
|
if ( $self->{body_hash} and $sighash ) { |
118
|
149
|
|
|
|
|
286
|
my $body_hash = $self->{body_hash}; |
119
|
149
|
|
|
|
|
457
|
my $expected = decode_base64($sighash); |
120
|
149
|
100
|
|
|
|
398
|
if ( $body_hash ne $expected ) { |
121
|
6
|
|
|
|
|
22
|
$self->{verification_details} = 'body has been altered'; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# print STDERR "I calculated " |
124
|
|
|
|
|
|
|
# . encode_base64($body_hash, "") . "\n"; |
125
|
|
|
|
|
|
|
# print STDERR "signature has " |
126
|
|
|
|
|
|
|
# . encode_base64($expected, "") . "\n"; |
127
|
6
|
|
|
|
|
26
|
return; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
253
|
|
|
|
|
913
|
return 1; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub finish_message { |
134
|
418
|
|
|
418
|
0
|
615
|
my $self = shift; |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# DKIM requires the signature itself to be committed into the digest. |
137
|
|
|
|
|
|
|
# But first, we need to set the bh= tag on the signature, then |
138
|
|
|
|
|
|
|
# "prettify" it. |
139
|
|
|
|
|
|
|
|
140
|
418
|
|
|
|
|
3164
|
$self->{body_hash} = $self->{body_digest}->digest; |
141
|
418
|
100
|
|
|
|
1272
|
if ( $self->{mode} eq 'sign' ) { |
142
|
|
|
|
|
|
|
$self->{Signature} |
143
|
58
|
|
|
|
|
329
|
->body_hash( encode_base64( $self->{body_hash}, '' ) ); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
418
|
100
|
|
|
|
881
|
if ( $self->{mode} eq 'sign' ) { |
147
|
58
|
|
|
|
|
218
|
$self->{Signature}->prettify; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
418
|
|
|
|
|
1197
|
my $sig_line = $self->{Signature}->as_string_without_data; |
151
|
418
|
|
|
|
|
1676
|
my $canonicalized = $self->{canon}->canonicalize_header($sig_line); |
152
|
|
|
|
|
|
|
|
153
|
418
|
|
|
|
|
1452
|
$self->{canon}->output($canonicalized); |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# override this method, please... |
158
|
|
|
|
|
|
|
sub sign { |
159
|
0
|
|
|
0
|
1
|
0
|
die 'Not implemented'; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub signature { |
164
|
2156
|
|
|
2156
|
1
|
3322
|
my $self = shift; |
165
|
|
|
|
|
|
|
@_ |
166
|
2156
|
50
|
|
|
|
4255
|
and $self->{Signature} = shift; |
167
|
2156
|
|
|
|
|
5403
|
return $self->{Signature}; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# override this method, please... |
172
|
|
|
|
|
|
|
sub verify { |
173
|
0
|
|
|
0
|
1
|
|
die 'Not implemented'; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
1; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
__END__ |