line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Create a PGP signature for data, securely. |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# THIS IS NOT A GENERAL PGP MODULE. |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# For a general PGP module that handles encryption and decryption, key ring |
6
|
|
|
|
|
|
|
# management, and all of the other wonderful things you want to do with PGP, |
7
|
|
|
|
|
|
|
# see the PGP module directory on CPAN. This module is designed to do one and |
8
|
|
|
|
|
|
|
# only one thing and do it fast, well, and securely -- create and check |
9
|
|
|
|
|
|
|
# detached signatures for some block of data. |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# This above all: to thine own self be true, |
12
|
|
|
|
|
|
|
# And it must follow, as the night the day, |
13
|
|
|
|
|
|
|
# Thou canst not then be false to any man. |
14
|
|
|
|
|
|
|
# -- William Shakespeare, _Hamlet_ |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
############################################################################## |
19
|
|
|
|
|
|
|
# Modules and declarations |
20
|
|
|
|
|
|
|
############################################################################## |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
package PGP::Sign 1.04; |
23
|
|
|
|
|
|
|
|
24
|
6
|
|
|
6
|
|
1802180
|
use 5.020; |
|
6
|
|
|
|
|
92
|
|
25
|
6
|
|
|
6
|
|
60
|
use autodie; |
|
6
|
|
|
|
|
33
|
|
|
6
|
|
|
|
|
162
|
|
26
|
6
|
|
|
6
|
|
37009
|
use warnings; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
488
|
|
27
|
|
|
|
|
|
|
|
28
|
6
|
|
|
6
|
|
46
|
use Carp qw(croak); |
|
6
|
|
|
|
|
26
|
|
|
6
|
|
|
|
|
899
|
|
29
|
6
|
|
|
6
|
|
50
|
use Exporter qw(import); |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
256
|
|
30
|
6
|
|
|
6
|
|
4968
|
use File::Temp (); |
|
6
|
|
|
|
|
87381
|
|
|
6
|
|
|
|
|
198
|
|
31
|
6
|
|
|
6
|
|
46
|
use IO::Handle; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
405
|
|
32
|
6
|
|
|
6
|
|
5809
|
use IPC::Run qw(finish run start timeout); |
|
6
|
|
|
|
|
157247
|
|
|
6
|
|
|
|
|
427
|
|
33
|
6
|
|
|
6
|
|
52
|
use POSIX qw(EAGAIN); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
148
|
|
34
|
6
|
|
|
6
|
|
4415
|
use Scalar::Util qw(blessed); |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
2289
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# Export pgp_sign and pgp_verify by default for backwards compatibility. |
37
|
|
|
|
|
|
|
## no critic (Modules::ProhibitAutomaticExportation) |
38
|
|
|
|
|
|
|
our @EXPORT = qw(pgp_sign pgp_verify); |
39
|
|
|
|
|
|
|
our @EXPORT_OK = qw(pgp_error); |
40
|
|
|
|
|
|
|
## use critic |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# The flags to use with the various PGP styles. |
43
|
|
|
|
|
|
|
my %SIGN_FLAGS = ( |
44
|
|
|
|
|
|
|
GPG => [ |
45
|
|
|
|
|
|
|
qw( |
46
|
|
|
|
|
|
|
--detach-sign --armor |
47
|
|
|
|
|
|
|
--quiet --textmode --batch --no-tty --pinentry-mode=loopback |
48
|
|
|
|
|
|
|
--no-greeting --no-permission-warning |
49
|
|
|
|
|
|
|
), |
50
|
|
|
|
|
|
|
], |
51
|
|
|
|
|
|
|
GPG1 => [ |
52
|
|
|
|
|
|
|
qw( |
53
|
|
|
|
|
|
|
--detach-sign --armor |
54
|
|
|
|
|
|
|
--quiet --textmode --batch --no-tty --no-use-agent |
55
|
|
|
|
|
|
|
--no-greeting --no-permission-warning |
56
|
|
|
|
|
|
|
--force-v3-sigs --allow-weak-digest-algos |
57
|
|
|
|
|
|
|
), |
58
|
|
|
|
|
|
|
], |
59
|
|
|
|
|
|
|
); |
60
|
|
|
|
|
|
|
my %VERIFY_FLAGS = ( |
61
|
|
|
|
|
|
|
GPG => [ |
62
|
|
|
|
|
|
|
qw( |
63
|
|
|
|
|
|
|
--verify |
64
|
|
|
|
|
|
|
--quiet --batch --no-tty |
65
|
|
|
|
|
|
|
--no-greeting --no-permission-warning |
66
|
|
|
|
|
|
|
--no-auto-key-retrieve --no-auto-check-trustdb |
67
|
|
|
|
|
|
|
--allow-weak-digest-algos |
68
|
|
|
|
|
|
|
--disable-dirmngr |
69
|
|
|
|
|
|
|
), |
70
|
|
|
|
|
|
|
], |
71
|
|
|
|
|
|
|
GPG1 => [ |
72
|
|
|
|
|
|
|
qw( |
73
|
|
|
|
|
|
|
--verify |
74
|
|
|
|
|
|
|
--quiet --batch --no-tty |
75
|
|
|
|
|
|
|
--no-greeting --no-permission-warning |
76
|
|
|
|
|
|
|
--no-auto-key-retrieve --no-auto-check-trustdb |
77
|
|
|
|
|
|
|
--allow-weak-digest-algos |
78
|
|
|
|
|
|
|
), |
79
|
|
|
|
|
|
|
], |
80
|
|
|
|
|
|
|
); |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
############################################################################## |
83
|
|
|
|
|
|
|
# Old global variables |
84
|
|
|
|
|
|
|
############################################################################## |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# These variables are part of the legacy PGP::Sign interface and are |
87
|
|
|
|
|
|
|
# maintained for backward compatibility. They are only used by the legacy |
88
|
|
|
|
|
|
|
# pgp_sign and pgp_verify functions, not by the new object-oriented API. |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# Whether or not to perform some standard whitespace munging to make other |
91
|
|
|
|
|
|
|
# signing and checking routines happy. |
92
|
|
|
|
|
|
|
our $MUNGE = 0; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# The default path to PGP. PGPS is for signing, PGPV is for verifying. |
95
|
|
|
|
|
|
|
# (There's no reason to use separate commands any more, but with PGPv5 these |
96
|
|
|
|
|
|
|
# were two different commands, so this became part of the legacy API.) |
97
|
|
|
|
|
|
|
our $PGPS; |
98
|
|
|
|
|
|
|
our $PGPV; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# The path to the directory containing the key ring. If not set, defaults to |
101
|
|
|
|
|
|
|
# $ENV{GNUPGHOME} or $HOME/.gnupg. |
102
|
|
|
|
|
|
|
our $PGPPATH; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# What style of PGP invocation to use by default. If not set, defaults to the |
105
|
|
|
|
|
|
|
# default style for the object-oriented API. |
106
|
|
|
|
|
|
|
our $PGPSTYLE; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# The directory in which temporary files should be created. If not set, |
109
|
|
|
|
|
|
|
# defaults to whatever File::Temp decides to use. |
110
|
|
|
|
|
|
|
our $TMPDIR; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Used by pgp_sign and pgp_verify to store errors returned by the |
113
|
|
|
|
|
|
|
# object-oriented API so that they can be returned via pgp_error. |
114
|
|
|
|
|
|
|
my @ERROR = (); |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
############################################################################## |
117
|
|
|
|
|
|
|
# Utility functions |
118
|
|
|
|
|
|
|
############################################################################## |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# print with error checking and an explicit file handle. autodie |
121
|
|
|
|
|
|
|
# unfortunately can't help us with these because they can't be prototyped and |
122
|
|
|
|
|
|
|
# hence can't be overridden. |
123
|
|
|
|
|
|
|
# |
124
|
|
|
|
|
|
|
# $fh - Output file handle |
125
|
|
|
|
|
|
|
# @args - Remaining arguments to print |
126
|
|
|
|
|
|
|
# |
127
|
|
|
|
|
|
|
# Returns: undef |
128
|
|
|
|
|
|
|
# Throws: Text exception on output failure |
129
|
|
|
|
|
|
|
sub _print_fh { |
130
|
75
|
|
|
75
|
|
379
|
my ($fh, @args) = @_; |
131
|
75
|
50
|
|
|
|
137
|
print {$fh} @args or croak("print failed: $!"); |
|
75
|
|
|
|
|
517
|
|
132
|
75
|
|
|
|
|
169
|
return; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Write to a non-blocking file descriptor. Handles the select loop waiting |
136
|
|
|
|
|
|
|
# for the file descriptor to be ready to accept data. |
137
|
|
|
|
|
|
|
# |
138
|
|
|
|
|
|
|
# $fh - Output file handle |
139
|
|
|
|
|
|
|
# $data - Data to write |
140
|
|
|
|
|
|
|
# |
141
|
|
|
|
|
|
|
# Returns: undef |
142
|
|
|
|
|
|
|
# Throws: Text exception on output failure |
143
|
|
|
|
|
|
|
sub _write_nonblocking { |
144
|
649
|
|
|
649
|
|
1078
|
my ($fh, $data) = @_; |
145
|
649
|
|
|
|
|
947
|
my $win = q{}; |
146
|
649
|
|
|
|
|
2222
|
vec($win, fileno($fh), 1) = 1; |
147
|
649
|
|
|
|
|
1233
|
my $length = length($data); |
148
|
649
|
|
|
|
|
791
|
my $total = 0; |
149
|
649
|
|
|
|
|
1193
|
while ($total < $length) { |
150
|
6
|
|
|
6
|
|
51
|
no autodie qw(syswrite); |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
86
|
|
151
|
763
|
50
|
|
|
|
26103
|
select(undef, my $wout = $win, undef, undef) |
152
|
|
|
|
|
|
|
or croak("cannot select on pipe: $!"); |
153
|
763
|
|
|
|
|
8961
|
my $written = syswrite($fh, $data, $length - $total, $total); |
154
|
763
|
50
|
33
|
|
|
2526
|
if (!defined($written) && $! != EAGAIN) { |
155
|
0
|
|
|
|
|
0
|
croak("write to pipe failed: $!"); |
156
|
|
|
|
|
|
|
} |
157
|
763
|
50
|
|
|
|
1322
|
if (defined($written)) { |
158
|
763
|
|
|
|
|
1673
|
$total += $written; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
649
|
|
|
|
|
1223
|
return; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
############################################################################## |
165
|
|
|
|
|
|
|
# Object-oriented interface |
166
|
|
|
|
|
|
|
############################################################################## |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
# Create a new PGP::Sign object encapsulating the configuration. |
169
|
|
|
|
|
|
|
# |
170
|
|
|
|
|
|
|
# $args_ref - Anonymous hash of arguments with the following keys: |
171
|
|
|
|
|
|
|
# home - Path to the GnuPG homedir containing keyrings |
172
|
|
|
|
|
|
|
# munge - Boolean indicating whether to munge whitespace |
173
|
|
|
|
|
|
|
# path - Path to the GnuPG binary to use |
174
|
|
|
|
|
|
|
# style - Style of OpenPGP backend to use |
175
|
|
|
|
|
|
|
# tmpdir - Directory to use for temporary files |
176
|
|
|
|
|
|
|
# |
177
|
|
|
|
|
|
|
# Returns: Newly created object |
178
|
|
|
|
|
|
|
# Throws: Text exception for an invalid OpenPGP backend style |
179
|
|
|
|
|
|
|
sub new { |
180
|
20
|
|
|
20
|
1
|
26058
|
my ($class, $args_ref) = @_; |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# Check the style argument. |
183
|
20
|
|
100
|
|
|
188
|
my $style = $args_ref->{style} || 'GPG'; |
184
|
20
|
100
|
100
|
|
|
257
|
if ($style ne 'GPG' && $style ne 'GPG1') { |
185
|
1
|
|
|
|
|
222
|
croak("Unknown OpenPGP backend style $style"); |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# If path is not given, set a default based on the style. |
189
|
19
|
|
66
|
|
|
119
|
my $path = $args_ref->{path} // lc($style); |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Create and return the object. |
192
|
|
|
|
|
|
|
my $self = { |
193
|
|
|
|
|
|
|
home => $args_ref->{home}, |
194
|
|
|
|
|
|
|
munge => $args_ref->{munge}, |
195
|
|
|
|
|
|
|
path => $path, |
196
|
|
|
|
|
|
|
style => $style, |
197
|
|
|
|
|
|
|
tmpdir => $args_ref->{tmpdir}, |
198
|
19
|
|
|
|
|
191
|
}; |
199
|
19
|
|
|
|
|
108
|
bless($self, $class); |
200
|
19
|
|
|
|
|
89
|
return $self; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# This function actually sends the data to a file handle. It's necessary to |
204
|
|
|
|
|
|
|
# implement munging (stripping trailing spaces on a line). |
205
|
|
|
|
|
|
|
# |
206
|
|
|
|
|
|
|
# $fh - The file handle to which to write the data |
207
|
|
|
|
|
|
|
# $string - The data to write |
208
|
|
|
|
|
|
|
sub _write_string { |
209
|
639
|
|
|
639
|
|
1248
|
my ($self, $fh, $string) = @_; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# If there were any left-over spaces from the last invocation, prepend |
212
|
|
|
|
|
|
|
# them to the string and clear them. |
213
|
639
|
100
|
|
|
|
1247
|
if ($self->{spaces}) { |
214
|
2
|
|
|
|
|
23
|
$string = $self->{spaces} . $string; |
215
|
2
|
|
|
|
|
13
|
$self->{spaces} = q{}; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# If whitespace munging is enabled, strip any trailing whitespace from |
219
|
|
|
|
|
|
|
# each line of the string for which we've seen the newline. Then, remove |
220
|
|
|
|
|
|
|
# and store any spaces at the end of the string, since the newline may be |
221
|
|
|
|
|
|
|
# in the next chunk. |
222
|
|
|
|
|
|
|
# |
223
|
|
|
|
|
|
|
# If there turn out to be no further chunks, this removes any trailing |
224
|
|
|
|
|
|
|
# whitespace on the last line without a newline, which is still correct. |
225
|
639
|
100
|
|
|
|
1093
|
if ($self->{munge}) { |
226
|
70
|
|
|
|
|
434
|
$string =~ s{ [ ]+ \n }{\n}xmsg; |
227
|
70
|
100
|
|
|
|
309
|
if ($string =~ s{ ([ ]+) \Z }{}xms) { |
228
|
7
|
|
|
|
|
62
|
$self->{spaces} = $1; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
639
|
|
|
|
|
1345
|
_write_nonblocking($fh, $string); |
233
|
639
|
|
|
|
|
1380
|
return; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# This is our generic "take this data and shove it" routine, used both for |
237
|
|
|
|
|
|
|
# signature generation and signature checking. Scalars, references to arrays, |
238
|
|
|
|
|
|
|
# references to IO::Handle objects, file globs, references to code, and |
239
|
|
|
|
|
|
|
# references to file globs are all supported as ways to get the data, and at |
240
|
|
|
|
|
|
|
# most one line at a time is read (cutting down on memory usage). |
241
|
|
|
|
|
|
|
# |
242
|
|
|
|
|
|
|
# References to code are an interesting subcase. A code reference is executed |
243
|
|
|
|
|
|
|
# repeatedly, passing whatever it returns to GnuPG, until it returns undef. |
244
|
|
|
|
|
|
|
# |
245
|
|
|
|
|
|
|
# $fh - The file handle to which to write the data |
246
|
|
|
|
|
|
|
# @sources - The data to write, in any of those formats |
247
|
|
|
|
|
|
|
sub _write_data { |
248
|
35
|
|
|
35
|
|
317
|
my ($self, $fh, @sources) = @_; |
249
|
35
|
|
|
|
|
249
|
$self->{spaces} = q{}; |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Deal with all of our possible sources of input, one at a time. |
252
|
|
|
|
|
|
|
# |
253
|
|
|
|
|
|
|
# We can't do anything interesting or particularly "cool" with references |
254
|
|
|
|
|
|
|
# to references, so those we just print. (Perl allows circular |
255
|
|
|
|
|
|
|
# references, so we can't just dereference references to references until |
256
|
|
|
|
|
|
|
# we get something interesting.) |
257
|
35
|
|
|
|
|
171
|
for my $source (@sources) { |
258
|
517
|
100
|
33
|
|
|
3283
|
if (ref($source) eq 'ARRAY') { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
259
|
3
|
|
|
|
|
38
|
for my $chunk (@$source) { |
260
|
65
|
|
|
|
|
198
|
$self->_write_string($fh, $chunk); |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
} elsif (ref($source) eq 'GLOB' || ref(\$source) eq 'GLOB') { |
263
|
0
|
|
|
|
|
0
|
while (defined(my $chunk = <$source>)) { |
264
|
0
|
|
|
|
|
0
|
$self->_write_string($fh, $chunk); |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
} elsif (ref($source) eq 'SCALAR') { |
267
|
2
|
|
|
|
|
10
|
$self->_write_string($fh, $$source); |
268
|
|
|
|
|
|
|
} elsif (ref($source) eq 'CODE') { |
269
|
1
|
|
|
|
|
21
|
while (defined(my $chunk = &$source())) { |
270
|
31
|
|
|
|
|
317
|
$self->_write_string($fh, $chunk); |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} elsif (blessed($source)) { |
273
|
1
|
50
|
|
|
|
51
|
if ($source->isa('IO::Handle')) { |
274
|
1
|
|
|
|
|
29
|
while (defined(my $chunk = <$source>)) { |
275
|
31
|
|
|
|
|
77
|
$self->_write_string($fh, $chunk); |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
} else { |
278
|
0
|
|
|
|
|
0
|
$self->_write_string($fh, $source); |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
} else { |
281
|
510
|
|
|
|
|
1177
|
$self->_write_string($fh, $source); |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
} |
284
|
35
|
|
|
|
|
145
|
return; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# Construct the command for signing. This will expect the passphrase on file |
288
|
|
|
|
|
|
|
# descriptor 3. |
289
|
|
|
|
|
|
|
# |
290
|
|
|
|
|
|
|
# $keyid - The OpenPGP key ID with which to sign |
291
|
|
|
|
|
|
|
# |
292
|
|
|
|
|
|
|
# Returns: List of the command and arguments. |
293
|
|
|
|
|
|
|
sub _build_sign_command { |
294
|
11
|
|
|
11
|
|
53
|
my ($self, $keyid) = @_; |
295
|
11
|
|
|
|
|
161
|
my @command = ($self->{path}, '-u', $keyid, qw(--passphrase-fd 3)); |
296
|
11
|
|
|
|
|
44
|
push(@command, @{ $SIGN_FLAGS{ $self->{style} } }); |
|
11
|
|
|
|
|
374
|
|
297
|
11
|
100
|
|
|
|
95
|
if ($self->{home}) { |
298
|
10
|
|
|
|
|
50
|
push(@command, '--homedir', $self->{home}); |
299
|
|
|
|
|
|
|
} |
300
|
11
|
|
|
|
|
80
|
return @command; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
# Construct the command for verification. This will send all logging to |
304
|
|
|
|
|
|
|
# standard output and the status messages to file descriptor 3. |
305
|
|
|
|
|
|
|
# |
306
|
|
|
|
|
|
|
# $signature_file - Path to the file containing the signature |
307
|
|
|
|
|
|
|
# $data_file - Path to the file containing the signed data |
308
|
|
|
|
|
|
|
# |
309
|
|
|
|
|
|
|
# Returns: List of the command and arguments. |
310
|
|
|
|
|
|
|
sub _build_verify_command { |
311
|
25
|
|
|
25
|
|
416
|
my ($self, $signature_file, $data_file) = @_; |
312
|
25
|
|
|
|
|
260
|
my @command = ($self->{path}, qw(--status-fd 3 --logger-fd 1)); |
313
|
25
|
|
|
|
|
59
|
push(@command, @{ $VERIFY_FLAGS{ $self->{style} } }); |
|
25
|
|
|
|
|
303
|
|
314
|
25
|
100
|
|
|
|
118
|
if ($self->{home}) { |
315
|
24
|
|
|
|
|
107
|
push(@command, '--homedir', $self->{home}); |
316
|
|
|
|
|
|
|
} |
317
|
25
|
|
|
|
|
68
|
push(@command, $signature_file, $data_file); |
318
|
25
|
|
|
|
|
143
|
return @command; |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# Create a detached signature for the given data. |
322
|
|
|
|
|
|
|
# |
323
|
|
|
|
|
|
|
# $keyid - GnuPG key ID to use to sign the data |
324
|
|
|
|
|
|
|
# $passphrase - Passphrase for the GnuPG key |
325
|
|
|
|
|
|
|
# @sources - The data to sign (see _write_data for more information) |
326
|
|
|
|
|
|
|
# |
327
|
|
|
|
|
|
|
# Returns: The signature as an ASCII-armored block with embedded newlines |
328
|
|
|
|
|
|
|
# Throws: Text exception on failure that includes the GnuPG output |
329
|
|
|
|
|
|
|
sub sign { |
330
|
11
|
|
|
11
|
1
|
12694
|
my ($self, $keyid, $passphrase, @sources) = @_; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# Ignore SIGPIPE, since we're going to be talking to GnuPG. |
333
|
11
|
|
|
|
|
394
|
local $SIG{PIPE} = 'IGNORE'; |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
# Build the command to run. |
336
|
11
|
|
|
|
|
108
|
my @command = $self->_build_sign_command($keyid); |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
# Fork off a pgp process that we're going to be feeding data to, and tell |
339
|
|
|
|
|
|
|
# it to just generate a signature using the given key id and pass phrase. |
340
|
11
|
|
|
|
|
273
|
my $writefh = IO::Handle->new(); |
341
|
11
|
|
|
|
|
821
|
my $passfh = IO::Handle->new(); |
342
|
11
|
|
|
|
|
228
|
my ($signature, $errors); |
343
|
|
|
|
|
|
|
#<<< |
344
|
11
|
|
|
|
|
184
|
my $h = start( |
345
|
|
|
|
|
|
|
\@command, |
346
|
|
|
|
|
|
|
'3
|
347
|
|
|
|
|
|
|
'
|
348
|
|
|
|
|
|
|
'>', \$signature, |
349
|
|
|
|
|
|
|
'2>', \$errors, |
350
|
|
|
|
|
|
|
); |
351
|
|
|
|
|
|
|
#>>> |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
# Push the passphrase to the subprocess so that it doesn't block waiting |
354
|
|
|
|
|
|
|
# for it and not read its input. |
355
|
10
|
|
|
|
|
87383
|
_write_nonblocking($passfh, $passphrase); |
356
|
10
|
|
|
|
|
185
|
close($passfh); |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
# Send in the data to be signed. |
359
|
10
|
|
|
|
|
11601
|
$self->_write_data($writefh, @sources); |
360
|
10
|
|
|
|
|
64
|
close($writefh); |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
# Get the return status and raise an exception on failure. |
363
|
10
|
50
|
|
|
|
832
|
if (!finish($h)) { |
364
|
0
|
|
|
|
|
0
|
my $status = $h->result(); |
365
|
0
|
|
|
|
|
0
|
$errors .= "Execution of $command[0] failed with status $status"; |
366
|
0
|
|
|
|
|
0
|
croak($errors); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# The resulting signature will look something like this: |
370
|
|
|
|
|
|
|
# |
371
|
|
|
|
|
|
|
# -----BEGIN PGP SIGNATURE----- |
372
|
|
|
|
|
|
|
# Version: GnuPG v0.9.2 (SunOS) |
373
|
|
|
|
|
|
|
# Comment: For info see http://www.gnupg.org |
374
|
|
|
|
|
|
|
# |
375
|
|
|
|
|
|
|
# iEYEARECAAYFAjbA/fsACgkQ+YXjQAr8dHYsMQCgpzOkRRopdW0nuiSNMB6Qx2Iw |
376
|
|
|
|
|
|
|
# bw0AoMl82UxQEkh4uIcLSZMdY31Z8gtL |
377
|
|
|
|
|
|
|
# =Dj7i |
378
|
|
|
|
|
|
|
# -----END PGP SIGNATURE----- |
379
|
|
|
|
|
|
|
# |
380
|
|
|
|
|
|
|
# Find and strip the marker line for the start of the signature. |
381
|
10
|
|
|
|
|
65677
|
my @signature = split(m{\n}xms, $signature); |
382
|
10
|
|
|
|
|
162
|
while ((shift @signature) !~ m{-----BEGIN [ ] PGP [ ] SIGNATURE-----}xms) { |
383
|
0
|
0
|
|
|
|
0
|
if (!@signature) { |
384
|
0
|
|
|
|
|
0
|
croak('No signature returned by GnuPG'); |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# Strip any headers off the signature. Thankfully all of the important |
389
|
|
|
|
|
|
|
# data is encoded into the signature itself, so the headers aren't needed. |
390
|
10
|
|
66
|
|
|
167
|
while (@signature && $signature[0] ne q{}) { |
391
|
10
|
|
|
|
|
60
|
shift(@signature); |
392
|
|
|
|
|
|
|
} |
393
|
10
|
|
|
|
|
23
|
shift(@signature); |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
# Remove the trailing marker line. |
396
|
10
|
|
|
|
|
23
|
pop(@signature); |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
# Everything else is the signature that we want. |
399
|
10
|
|
|
|
|
214
|
return join("\n", @signature); |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# Check a detached signature for given data. |
403
|
|
|
|
|
|
|
# |
404
|
|
|
|
|
|
|
# $signature - The signature as an ASCII-armored string with embedded newlines |
405
|
|
|
|
|
|
|
# @sources - The data over which to check the signature |
406
|
|
|
|
|
|
|
# |
407
|
|
|
|
|
|
|
# Returns: The human-readable key ID of the signature, or an empty string if |
408
|
|
|
|
|
|
|
# the signature did not verify |
409
|
|
|
|
|
|
|
# Throws: Text exception on an error other than a bad signature |
410
|
|
|
|
|
|
|
sub verify { |
411
|
25
|
|
|
25
|
1
|
23837
|
my ($self, $signature, @sources) = @_; |
412
|
25
|
|
|
|
|
93
|
chomp($signature); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# Ignore SIGPIPE, since we're going to be talking to PGP. |
415
|
25
|
|
|
|
|
483
|
local $SIG{PIPE} = 'IGNORE'; |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
# To verify a detached signature, we need to save both the signature and |
418
|
|
|
|
|
|
|
# the data to files and then run GnuPG on the pair of files. There |
419
|
|
|
|
|
|
|
# doesn't appear to be a way to feed both the data and the signature in on |
420
|
|
|
|
|
|
|
# file descriptors. |
421
|
25
|
50
|
|
|
|
169
|
my @tmpdir = defined($self->{tmpdir}) ? (DIR => $self->{tmpdir}) : (); |
422
|
25
|
|
|
|
|
426
|
my $sigfh = File::Temp->new(@tmpdir, SUFFIX => '.asc'); |
423
|
25
|
|
|
|
|
20007
|
_print_fh($sigfh, "-----BEGIN PGP SIGNATURE-----\n"); |
424
|
25
|
|
|
|
|
100
|
_print_fh($sigfh, "\n", $signature); |
425
|
25
|
|
|
|
|
101
|
_print_fh($sigfh, "\n-----END PGP SIGNATURE-----\n"); |
426
|
25
|
|
|
|
|
236
|
close($sigfh); |
427
|
25
|
|
|
|
|
4006
|
my $datafh = File::Temp->new(@tmpdir); |
428
|
25
|
|
|
|
|
9664
|
$self->_write_data($datafh, @sources); |
429
|
25
|
|
|
|
|
123
|
close($datafh); |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# Build the command to run. |
432
|
|
|
|
|
|
|
my @command |
433
|
25
|
|
|
|
|
1697
|
= $self->_build_verify_command($sigfh->filename, $datafh->filename); |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# Call GnuPG to check the signature. |
436
|
25
|
|
|
|
|
78
|
my ($output, $results); |
437
|
25
|
|
|
|
|
176
|
run(\@command, '>&', \$output, '3>', \$results); |
438
|
25
|
|
|
|
|
343174
|
my $status = $?; |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
# Check for the message that gives us the key status and return the |
441
|
|
|
|
|
|
|
# appropriate thing to our caller. |
442
|
|
|
|
|
|
|
# |
443
|
|
|
|
|
|
|
# GPG 1.4.23 |
444
|
|
|
|
|
|
|
# [GNUPG:] GOODSIG 7D80315C5736DE75 Russ Allbery |
445
|
|
|
|
|
|
|
# [GNUPG:] BADSIG 7D80315C5736DE75 Russ Allbery |
446
|
|
|
|
|
|
|
# |
447
|
|
|
|
|
|
|
# Note that this returns the human-readable key ID instead of the actual |
448
|
|
|
|
|
|
|
# key ID. This is a historical wart in the API; a future version will |
449
|
|
|
|
|
|
|
# hopefully add an option to return more accurate signer information. |
450
|
25
|
|
|
|
|
382
|
for my $line (split(m{\n}xms, $results)) { |
451
|
44
|
100
|
|
|
|
574
|
if ($line =~ m{ ^ \[GNUPG:\] \s+ GOODSIG \s+ \S+ \s+ (.*) }xms) { |
|
|
100
|
|
|
|
|
|
452
|
18
|
|
|
|
|
965
|
return $1; |
453
|
|
|
|
|
|
|
} elsif ($line =~ m{ ^ \[GNUPG:\] \s+ BADSIG \s+ }xms) { |
454
|
5
|
|
|
|
|
288
|
return q{}; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
# Neither a good nor a bad signature seen. |
459
|
2
|
|
|
|
|
23
|
$output .= $results; |
460
|
2
|
50
|
|
|
|
32
|
if ($status != 0) { |
461
|
2
|
|
|
|
|
61
|
$output .= "Execution of $command[0] failed with status $status"; |
462
|
|
|
|
|
|
|
} |
463
|
2
|
|
|
|
|
1051
|
croak($output); |
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
############################################################################## |
467
|
|
|
|
|
|
|
# Legacy function API |
468
|
|
|
|
|
|
|
############################################################################## |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
# This is the original API from 0.x versions of PGP::Sign. It is maintained |
471
|
|
|
|
|
|
|
# for backwards compatibility, but is now a wrapper around the object-oriented |
472
|
|
|
|
|
|
|
# API that uses the legacy global variables. The object-oriented API should |
473
|
|
|
|
|
|
|
# be preferred for all new code. |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
# Create a detached signature for the given data. |
476
|
|
|
|
|
|
|
# |
477
|
|
|
|
|
|
|
# The original API returned the PGP implementation version from the signature |
478
|
|
|
|
|
|
|
# headers as the second element of the list returned in array context. This |
479
|
|
|
|
|
|
|
# information is pointless and unnecessary and GnuPG doesn't include that |
480
|
|
|
|
|
|
|
# header by default, so the fixed string "GnuPG" is now returned for backwards |
481
|
|
|
|
|
|
|
# compatibility. |
482
|
|
|
|
|
|
|
# |
483
|
|
|
|
|
|
|
# Errors are stored for return by pgp_error(), overwriting any previously |
484
|
|
|
|
|
|
|
# stored error. |
485
|
|
|
|
|
|
|
# |
486
|
|
|
|
|
|
|
# $keyid - GnuPG key ID to use to sign the data |
487
|
|
|
|
|
|
|
# $passphrase - Passphrase for the GnuPG key |
488
|
|
|
|
|
|
|
# @sources - The data to sign (see _write_data for more information) |
489
|
|
|
|
|
|
|
# |
490
|
|
|
|
|
|
|
# Returns: The signature as an ASCII-armored block in scalar context |
491
|
|
|
|
|
|
|
# The signature and the string "GnuPG" in list context |
492
|
|
|
|
|
|
|
# undef or the empty list on error |
493
|
|
|
|
|
|
|
sub pgp_sign { |
494
|
4
|
|
|
4
|
1
|
33954
|
my ($keyid, $passphrase, @sources) = @_; |
495
|
4
|
|
|
|
|
27
|
@ERROR = (); |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
# Create the signer object. |
498
|
4
|
|
|
|
|
157
|
my $signer = PGP::Sign->new( |
499
|
|
|
|
|
|
|
{ |
500
|
|
|
|
|
|
|
home => $PGPPATH, |
501
|
|
|
|
|
|
|
munge => $MUNGE, |
502
|
|
|
|
|
|
|
path => $PGPS, |
503
|
|
|
|
|
|
|
style => $PGPSTYLE, |
504
|
|
|
|
|
|
|
tmpdir => $TMPDIR, |
505
|
|
|
|
|
|
|
}, |
506
|
|
|
|
|
|
|
); |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
# Do the work, capturing any errors. |
509
|
4
|
|
|
|
|
26
|
my $signature = eval { $signer->sign($keyid, $passphrase, @sources) }; |
|
4
|
|
|
|
|
49
|
|
510
|
4
|
50
|
|
|
|
947
|
if ($@) { |
511
|
0
|
|
|
|
|
0
|
@ERROR = split(m{\n}xms, $@); |
512
|
0
|
|
|
|
|
0
|
return; |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
# Return the results, including a dummy version if desired. |
516
|
|
|
|
|
|
|
## no critic (Freenode::Wantarray) |
517
|
4
|
100
|
|
|
|
171
|
return wantarray ? ($signature, 'GnuPG') : $signature; |
518
|
|
|
|
|
|
|
## use critic |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
# Check a detached signature for given data. |
522
|
|
|
|
|
|
|
# |
523
|
|
|
|
|
|
|
# $signature - The signature as an ASCII-armored string with embedded newlines |
524
|
|
|
|
|
|
|
# @sources - The data over which to check the signature |
525
|
|
|
|
|
|
|
# |
526
|
|
|
|
|
|
|
# Returns: The human-readable key ID of the signature |
527
|
|
|
|
|
|
|
# An empty string if the signature did not verify |
528
|
|
|
|
|
|
|
# undef on error |
529
|
|
|
|
|
|
|
sub pgp_verify { |
530
|
9
|
|
|
9
|
1
|
1689
|
my ($signature, $version, @sources) = @_; |
531
|
9
|
|
|
|
|
33
|
@ERROR = (); |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# Create the verifier object. |
534
|
9
|
|
|
|
|
182
|
my $verifier = PGP::Sign->new( |
535
|
|
|
|
|
|
|
{ |
536
|
|
|
|
|
|
|
home => $PGPPATH, |
537
|
|
|
|
|
|
|
munge => $MUNGE, |
538
|
|
|
|
|
|
|
path => $PGPV, |
539
|
|
|
|
|
|
|
style => $PGPSTYLE, |
540
|
|
|
|
|
|
|
tmpdir => $TMPDIR, |
541
|
|
|
|
|
|
|
}, |
542
|
|
|
|
|
|
|
); |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
# Do the work, capturing any errors. |
545
|
9
|
|
|
|
|
32
|
my $signer = eval { $verifier->verify($signature, @sources) }; |
|
9
|
|
|
|
|
55
|
|
546
|
9
|
100
|
|
|
|
4404
|
if ($@) { |
547
|
1
|
|
|
|
|
26
|
@ERROR = split(m{\n}xms, $@); |
548
|
1
|
|
|
|
|
63
|
return; |
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
# Return the results. |
552
|
8
|
|
|
|
|
634
|
return $signer; |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
# Retrieve errors from the previous pgp_sign() or pgp_verify() call. |
556
|
|
|
|
|
|
|
# |
557
|
|
|
|
|
|
|
# Historically the pgp_error() return value in list context had newlines at |
558
|
|
|
|
|
|
|
# the end of each line, so add them back in. |
559
|
|
|
|
|
|
|
# |
560
|
|
|
|
|
|
|
# Returns: A list of GnuPG output and error messages in list context |
561
|
|
|
|
|
|
|
# The block of GnuPG output and error message in scalar context |
562
|
|
|
|
|
|
|
## no critic (Freenode::Wantarray) |
563
|
|
|
|
|
|
|
sub pgp_error { |
564
|
11
|
|
|
11
|
1
|
4031
|
my @error_lines = map { "$_\n" } @ERROR; |
|
44
|
|
|
|
|
82
|
|
565
|
11
|
100
|
|
|
|
211
|
return wantarray ? @error_lines : join(q{}, @error_lines); |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
## use critic |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
############################################################################## |
570
|
|
|
|
|
|
|
# Module return value and documentation |
571
|
|
|
|
|
|
|
############################################################################## |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
# Make sure the module returns true. |
574
|
|
|
|
|
|
|
1; |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
__DATA__ |