File Coverage

blib/lib/PGP/Sign.pm
Criterion Covered Total %
statement 157 168 93.4
branch 40 52 76.9
condition 11 17 64.7
subroutine 23 23 100.0
pod 6 6 100.0
total 237 266 89.1


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__