File Coverage

blib/lib/PGP/Sign.pm
Criterion Covered Total %
statement 135 146 92.4
branch 36 46 78.2
condition 10 14 71.4
subroutine 20 20 100.0
pod 6 6 100.0
total 207 232 89.2


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__