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