File Coverage

blib/lib/GnuPG/Interface.pm
Criterion Covered Total %
statement 316 345 91.5
branch 100 144 69.4
path n/a
condition 46 62 74.1
subroutine 43 46 93.4
pod 21 28 75.0
total 526 625 84.1


line stmt bran path cond sub pod time code
1               # Interface.pm
2               # - providing an object-oriented approach to interacting with GnuPG
3               #
4               # Copyright (C) 2000 Frank J. Tobin <ftobin@cpan.org>
5               #
6               # This module is free software; you can redistribute it and/or modify it
7               # under the same terms as Perl itself.
8               #
9               # This program is distributed in the hope that it will be useful,
10               # but WITHOUT ANY WARRANTY; without even the implied warranty of
11               # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12               #
13                
14               package GnuPG::Interface;
15 78       78   4203379 use Moo;
  78           695276  
  78           404  
16 78       78   153030 use MooX::late;
  78           2150840  
  78           521  
17               with qw(GnuPG::HashInit);
18                
19 78       78   14725741 use English qw( -no_match_vars );
  78           220  
  78           687  
20 78       78   33401 use Carp;
  78           251  
  78           4837  
21 78       78   546 use Fcntl;
  78           174  
  78           19515  
22 78       78   605 use vars qw( $VERSION );
  78           377  
  78           4406  
23 78       78   5727 use Fatal qw( open close pipe fcntl );
  78           104721  
  78           759  
24 78       78   166454 use Class::Struct;
  78           14328  
  78           925  
25 78       78   9301 use IO::Handle;
  78           225  
  78           3645  
26                
27 78       78   108727 use Math::BigInt try => 'GMP';
  78           2150660  
  78           415  
28 78       78   1992332 use GnuPG::Options;
  78           1460  
  78           3390  
29 78       78   41860 use GnuPG::Handles;
  78           274  
  78           3108  
30 78       78   625 use Scalar::Util 'tainted';
  78           175  
  78           175936  
31                
32               $VERSION = '1.03';
33                
34               has passphrase => (
35               isa => 'Any',
36               is => 'rw',
37               clearer => 'clear_passphrase',
38               );
39                
40               has call => (
41               isa => 'Any',
42               is => 'rw',
43               trigger => 1,
44               clearer => 'clear_call',
45               );
46                
47               # NB: GnuPG versions
48               #
49               # There are now two supported versions of GnuPG: legacy 1.4 and stable 2.2
50               # They are detected and each behave slightly differently.
51               #
52               # When using features specific to branches, check that the system's
53               # version of gpg corresponds to the branch.
54               #
55               # legacy: 1.4
56               # stable: >= 2.2
57               #
58               # You can find examples of version comparison in the tests.
59               has version => (
60               isa => 'Str',
61               is => 'ro',
62               reader => 'version',
63               writer => '_set_version',
64               );
65                
66               has options => (
67               isa => 'GnuPG::Options',
68               is => 'rw',
69               lazy_build => 1,
70               );
71                
72 83       83   26938 sub _build_options { GnuPG::Options->new() }
73                
74               # deprecated!
75 4       4 0 1038 sub gnupg_call { shift->call(@_); }
76                
77               sub BUILD {
78 91       91 0 420451 my ( $self, $args ) = @_;
79 91           1691 $self->hash_init( call => 'gpg', %$args );
80               }
81                
82               struct(
83               fh_setup => {
84               parent_end => '$', child_end => '$',
85               direct => '$', is_std => '$',
86               parent_is_source => '$', name_shows_dup => '$',
87               }
88               );
89                
90               # Update version if "call" is updated
91               sub _trigger_call {
92 120       120   47059 my ( $self, $gpg ) = @_;
93 120           683 $self->_set_version( $self->_version() );
94               }
95                
96               #################################################################
97               # real worker functions
98                
99               # This function does any 'extra' stuff that the user might
100               # not want to handle himself, such as passing in the passphrase
101               sub wrap_call( $% ) {
102 241       241 1 32221 my ( $self, %args ) = @_;
103                
104               my $handles = $args{handles}
105 241 50         2033 or croak 'error: no handles defined';
106                
107 241 100         7202 $handles->stdin('<&STDIN') unless $handles->stdin();
108 241 50         15992 $handles->stdout('>&STDOUT') unless $handles->stdout();
109 241 100         9290 $handles->stderr('>&STDERR') unless $handles->stderr();
110                
111 241 100         16484 $self->passphrase("\n") unless $self->passphrase();
112                
113 241 100   66     10191 my $needs_passphrase_handled
114               = ( $self->passphrase() =~ m/\S/ and not $handles->passphrase() ) ? 1 : 0;
115                
116 241 100         12997 if ($needs_passphrase_handled) {
117 187           1408 $handles->passphrase( IO::Handle->new() );
118               }
119                
120 241           18055 my $pid = $self->fork_attach_exec(%args);
121                
122 186 100         3261 if ($needs_passphrase_handled) {
123 146           8257 my $passphrase_handle = $handles->passphrase();
124 146           8792 print $passphrase_handle $self->passphrase();
125 146           10493 close $passphrase_handle;
126                
127               # We put this in in case the user wants to re-use this object
128 146           7632 $handles->clear_passphrase();
129               }
130                
131 186           10001 return $pid;
132               }
133                
134               # does does command-line creation, forking, and execcing
135               # the reasing cli creation is done here is because we should
136               # fork before finding the fd's for stuff like --status-fd
137               sub fork_attach_exec( $% ) {
138 241       241 0 1486 my ( $self, %args ) = @_;
139                
140 241 50         1421 my $handles = $args{handles} or croak 'no GnuPG::Handles passed';
141 241           702 my $use_loopback_pinentry = 0;
142                
143               # Don't use loopback pintentry for legacy (1.4) GPG
144               #
145               # Check that $version is populated before running cmp_version. If
146               # we are invoked as part of BUILD to populate $version, then any
147               # methods that depend on $version will fail. We don't care about
148               # loopback when we're called just to check gpg version.
149 241 50   100     6401 $use_loopback_pinentry = 1
        66        
150               if ($handles->passphrase() && $self->version && $self->cmp_version($self->version, '2.2') > 0 );
151                
152               # deprecation support
153 241     66     3320 $args{commands} ||= $args{gnupg_commands};
154                
155               my @commands
156 241           1934 = ref $args{commands} ? @{ $args{commands} } : ( $args{commands} )
157 241 50         1612 or croak "no gnupg commands passed";
    50            
158                
159               # deprecation support
160 241     100     2680 $args{command_args} ||= $args{gnupg_command_args};
161                
162               my @command_args
163               = ref $args{command_args}
164 24           191 ? @{ $args{command_args} }
165 241 100   100     2016 : ( $args{command_args} || () );
166 241 100   66     1749 unshift @command_args, "--"
167               if @command_args and $command_args[0] ne "--";
168                
169 241           625 my %fhs;
170 241           959 foreach my $fh_name (
171               qw( stdin stdout stderr status
172               logger passphrase command
173               )
174               ) {
175 1687 100         55161 my $fh = $handles->$fh_name() or next;
176 919           26060 $fhs{$fh_name} = fh_setup->new();
177 919           71600 $fhs{$fh_name}->parent_end($fh);
178               }
179                
180 241           4017 foreach my $fh_name (qw( stdin stdout stderr )) {
181 723           15895 $fhs{$fh_name}->is_std(1);
182               }
183                
184 241           2401 foreach my $fh_name (qw( stdin passphrase command )) {
185 723 100         5234 my $entry = $fhs{$fh_name} or next;
186 433           7259 $entry->parent_is_source(1);
187               }
188                
189               # Below is code derived heavily from
190               # Marc Horowitz's IPC::Open3, a base Perl module
191 241           1622 foreach my $fh_name ( keys %fhs ) {
192 919           18839 my $entry = $fhs{$fh_name};
193                
194 919           14967 my $parent_end = $entry->parent_end();
195 919           11331 my $name_shows_dup = ( $parent_end =~ s/^[<>]&// );
196 919           16828 $entry->parent_end($parent_end);
197                
198 919           20610 $entry->name_shows_dup($name_shows_dup);
199                
200               $entry->direct( $name_shows_dup
201               || $handles->options($fh_name)->{direct}
202 919     100     15287 || 0 );
203               }
204                
205 241           7260 foreach my $fh_name ( keys %fhs ) {
206 919           32839 $fhs{$fh_name}->child_end( IO::Handle->new() );
207               }
208                
209 241           12158 foreach my $fh_name ( keys %fhs ) {
210 919           33335 my $entry = $fhs{$fh_name};
211 919 100         18978 next if $entry->direct();
212                
213 639           6274 my $reader_end;
214               my $writer_end;
215 639 100         10988 if ( $entry->parent_is_source() ) {
216 293           7213 $reader_end = $entry->child_end();
217 293           6714 $writer_end = $entry->parent_end();
218               }
219               else {
220 346           8968 $reader_end = $entry->parent_end();
221 346           11989 $writer_end = $entry->child_end();
222               }
223                
224 639           17270 pipe $reader_end, $writer_end;
225               }
226                
227 241           514780 my $pid = fork;
228                
229 241 50         17824 die "fork failed: $ERRNO" unless defined $pid;
230                
231 241 100         8193 if ( $pid == 0 ) # child
232               {
233                
234               # these are for safety later to help lessen autovifying,
235               # speed things up, and make the code smaller
236 55           5139 my $stdin = $fhs{stdin};
237 55           2372 my $stdout = $fhs{stdout};
238 55           1835 my $stderr = $fhs{stderr};
239                
240               # Paul Walmsley says:
241               # Perl 5.6's POSIX.pm has a typo in it that prevents us from
242               # importing STDERR_FILENO. So we resort to requiring it.
243 55           129043 require POSIX;
244                
245 55           539265 my $standard_out
246               = IO::Handle->new_from_fd( &POSIX::STDOUT_FILENO, 'w' );
247 55           17239 my $standard_in
248               = IO::Handle->new_from_fd( &POSIX::STDIN_FILENO, 'r' );
249                
250               # Paul Walmsley says:
251               # this mess is due to a typo in POSIX.pm on Perl 5.6
252 55           5317 my $stderr_fd = eval {&POSIX::STDERR_FILENO};
  55           456  
253 55 50         668 $stderr_fd = 2 unless defined $stderr_fd;
254 55           578 my $standard_err = IO::Handle->new_from_fd( $stderr_fd, 'w' );
255                
256               # If she wants to dup the kid's stderr onto her stdout I need to
257               # save a copy of her stdout before I put something else there.
258 55 50   66     7324 if ( $stdout->parent_end() ne $stderr->parent_end()
        66        
259               and $stderr->direct()
260               and my_fileno( $stderr->parent_end() )
261               == my_fileno($standard_out) ) {
262 0           0 my $tmp = IO::Handle->new();
263 0           0 open $tmp, '>&' . my_fileno( $stderr->parent_end() );
264 0           0 $stderr->parent_end($tmp);
265               }
266                
267 55 100         9388 if ( $stdin->direct() ) {
268 21 100         619 open $standard_in, '<&' . my_fileno( $stdin->parent_end() )
269               unless my_fileno($standard_in)
270               == my_fileno( $stdin->parent_end() );
271               }
272               else {
273 34           1312 close $stdin->parent_end();
274 34           4830 open $standard_in, '<&=' . my_fileno( $stdin->child_end() );
275               }
276                
277 55 100         5078 if ( $stdout->direct() ) {
278 5 50         75 open $standard_out, '>&' . my_fileno( $stdout->parent_end() )
279               unless my_fileno($standard_out)
280               == my_fileno( $stdout->parent_end() );
281               }
282               else {
283 50           1658 close $stdout->parent_end();
284 50           4547 open $standard_out, '>&=' . my_fileno( $stdout->child_end() );
285               }
286                
287 55 50         4192 if ( $stdout->parent_end() ne $stderr->parent_end() ) {
288                
289               # I have to use a fileno here because in this one case
290               # I'm doing a dup but the filehandle might be a reference
291               # (from the special case above).
292 55 100         2359 if ( $stderr->direct() ) {
293 16 50         251 open $standard_err, '>&' . my_fileno( $stderr->parent_end() )
294               unless my_fileno($standard_err)
295               == my_fileno( $stderr->parent_end() );
296               }
297               else {
298 39           1099 close $stderr->parent_end();
299 39           2912 open $standard_err, '>&=' . my_fileno( $stderr->child_end() );
300               }
301               }
302               else {
303 0 0         0 open $standard_err, '>&STDOUT'
304               unless my_fileno($standard_err) == my_fileno($standard_out);
305               }
306                
307 55           2891 foreach my $fh_name ( keys %fhs ) {
308 209           9831 my $entry = $fhs{$fh_name};
309 209 100         4667 next if $entry->is_std();
310                
311 44           1163 my $parent_end = $entry->parent_end();
312 44           1233 my $child_end = $entry->child_end();
313                
314 44 100         1215 if ( $entry->direct() ) {
315 1 50         36 if ( $entry->name_shows_dup() ) {
316 0 0         0 my $open_prefix
317               = $entry->parent_is_source() ? '<&' : '>&';
318 0           0 open $child_end, $open_prefix . $parent_end;
319               }
320               else {
321 1           13 $child_end = $parent_end;
322 1           18 $entry->child_end($child_end);
323               }
324               }
325               else {
326 43           1188 close $parent_end;
327               }
328                
329               # we want these fh's to stay open after the exec
330 44           3242 fcntl $child_end, F_SETFD, 0;
331                
332               # now set the options for the call to GnuPG
333 44           1735 my $fileno = my_fileno($child_end);
334 44           363 my $option = $fh_name . '_fd';
335 44           2523 $self->options->$option($fileno);
336               }
337                
338 55           4971 my @args = $self->options->get_args();
339                
340               # Get around a bug in 2.2, see also https://dev.gnupg.org/T4667
341               # this covers both --delete-secret-key(s) and --delete-secret-and-public-key(s)
342 55 50   100     3463 if ( $self->version && $self->cmp_version( $self->version, 2.2 ) >= 0 && $commands[0] =~ /^--delete-secret-.*keys?$/ ) {
        66        
343 0           0 push @args, '--yes';
344               }
345                
346 55 50         376 push @args, '--pinentry-mode', 'loopback'
347               if $use_loopback_pinentry;
348                
349 55           3559 my @command = (
350               $self->call(), @args,
351               @commands, @command_args
352               );
353                
354               # On Unix, PATH is by default '.' and Perl >= v5.38 rejects '.'
355               # being in the path when in taint mode. Set a path, if running
356               # in taint mode whomever is calling us should be providing the
357               # path to the gpg program to use.
358 55 100         3602 local $ENV{PATH} = '/usr/bin' if tainted $ENV{PATH};
359 55 0         0 exec @command or die "exec() error: $ERRNO";
360               }
361                
362               # parent
363                
364               # close the child end of any pipes (non-direct stuff)
365 186           17132 foreach my $fh_name ( keys %fhs ) {
366 710           52322 my $entry = $fhs{$fh_name};
367 710 100         57336 close $entry->child_end() unless $entry->direct();
368               }
369                
370 186           10389 foreach my $fh_name ( keys %fhs ) {
371 710           4451 my $entry = $fhs{$fh_name};
372 710 100         16020 next unless $entry->parent_is_source();
373                
374 335           10622 my $parent_end = $entry->parent_end();
375                
376               # close any writing handles if they were a dup
377               #any real reason for this? It bombs if we're doing
378               #the automagic >& stuff.
379               #close $parent_end if $entry->direct();
380                
381               # unbuffer pipes
382 335 50         12907 select( ( select($parent_end), $OUTPUT_AUTOFLUSH = 1 )[0] )
383               if $parent_end;
384               }
385                
386 186           48225 return $pid;
387               }
388                
389               sub my_fileno {
390 78       78   764 no strict 'refs';
  78           258  
  78           271338  
391 297       297 0 5108 my ($fh) = @_;
392 297 50         1021 croak "fh is undefined" unless defined $fh;
393 297 50         2840 return $1 if $fh =~ /^=?(\d+)$/; # is it a fd in itself?
394 297           1136 my $fileno = fileno $fh;
395 297 50         798 croak "error determining fileno for $fh: $ERRNO" unless defined $fileno;
396 297           7455 return $fileno;
397               }
398                
399                
400               sub unescape_string {
401 19       19 0 48 my($str) = splice(@_);
402 19           55 $str =~ s/\\x(..)/chr(hex($1))/eg;
  0           0  
403 19           365 return $str;
404               }
405                
406               ###################################################################
407                
408               sub get_public_keys ( $@ ) {
409 4       4 1 13344 my ( $self, @key_ids ) = @_;
410                
411 4           124 return $self->get_keys(
412               commands => ['--list-public-keys'],
413               command_args => [@key_ids],
414               );
415               }
416                
417               sub get_secret_keys ( $@ ) {
418 2       2 1 2432 my ( $self, @key_ids ) = @_;
419                
420 2           14 return $self->get_keys(
421               commands => ['--list-secret-keys'],
422               command_args => [@key_ids],
423               );
424               }
425                
426               sub get_public_keys_with_sigs ( $@ ) {
427 2       2 1 2570 my ( $self, @key_ids ) = @_;
428                
429 2           14 return $self->get_keys(
430               commands => ['--check-sigs'],
431               command_args => [@key_ids],
432               );
433               }
434                
435               sub get_keys {
436 8       8 0 110 my ( $self, %args ) = @_;
437                
438 8           328 my $saved_options = $self->options();
439 8           372 my $new_options = $self->options->copy();
440 8           590 $self->options($new_options);
441 8           1334 $self->options->push_extra_args(
442               '--with-colons',
443               '--fixed-list-mode',
444               '--with-fingerprint',
445               '--with-fingerprint',
446               '--with-key-data',
447               );
448                
449 8           1794 my $stdin = IO::Handle->new();
450 8           278 my $stdout = IO::Handle->new();
451                
452 8           462 my $handles = GnuPG::Handles->new(
453               stdin => $stdin,
454               stdout => $stdout,
455               );
456                
457 8           454 my $pid = $self->wrap_call(
458               handles => $handles,
459               %args,
460               );
461                
462 5           289 my @returned_keys;
463               my $current_primary_key;
464 5           0 my $current_signed_item;
465 5           0 my $current_key;
466                
467 5           5690 require GnuPG::PublicKey;
468 5           2271 require GnuPG::SecretKey;
469 5           1675 require GnuPG::SubKey;
470 5           2461 require GnuPG::Fingerprint;
471 5           2435 require GnuPG::UserId;
472 5           2403 require GnuPG::UserAttribute;
473 5           2412 require GnuPG::Signature;
474 5           2396 require GnuPG::Revoker;
475                
476 5           3000026 while (<$stdout>) {
477 75           113463 my $line = $_;
478 75           362 chomp $line;
479 75           459 my @fields = split ':', $line, -1;
480 75 50         270 next unless @fields > 3;
481                
482 75           223 my $record_type = $fields[0];
483                
484 75 100   100     1086 if ( $record_type eq 'pub' or $record_type eq 'sec' ) {
    100   66        
    100   100        
    100   33        
    50            
    100            
    100            
    100            
    50            
485 5 50         81 push @returned_keys, $current_primary_key
486               if $current_primary_key;
487                
488               my (
489 5           113 $user_id_validity, $key_length, $algo_num, $hex_key_id,
490               $creation_date, $expiration_date,
491               $local_id, $owner_trust, $user_id_string,
492               $sigclass, #unused
493               $usage_flags,
494               ) = @fields[ 1 .. $#fields ];
495                
496               # --fixed-list-mode uses epoch time for creation and expiration date strings.
497               # For backward compatibility, we convert them back using GMT;
498 5           37 my $expiration_date_string;
499 5 50         61 if ($expiration_date eq '') {
500 5           32 $expiration_date = undef;
501               } else {
502 0           0 $expiration_date_string = $self->_downrez_date($expiration_date);
503               }
504 5           193 my $creation_date_string = $self->_downrez_date($creation_date);
505                
506 5 100         348 $current_primary_key = $current_key
507               = $record_type eq 'pub'
508               ? GnuPG::PublicKey->new()
509               : GnuPG::SecretKey->new();
510                
511 5           141 $current_primary_key->hash_init(
512               length => $key_length,
513               algo_num => $algo_num,
514               hex_id => $hex_key_id,
515               local_id => $local_id,
516               owner_trust => $owner_trust,
517               creation_date => $creation_date,
518               expiration_date => $expiration_date,
519               creation_date_string => $creation_date_string,
520               expiration_date_string => $expiration_date_string,
521               usage_flags => $usage_flags,
522               );
523                
524 5           391 $current_signed_item = $current_primary_key;
525               }
526               elsif ( $record_type eq 'fpr' ) {
527 10           64 my $hex = $fields[9];
528 10           205 my $f = GnuPG::Fingerprint->new( as_hex_string => $hex );
529 10           2132 $current_key->fingerprint($f);
530               }
531               elsif ( $record_type eq 'sig' or
532               $record_type eq 'rev'
533               ) {
534               my (
535 9           41 $validity,
536               $algo_num, $hex_key_id,
537               $signature_date,
538               $expiration_date,
539               $user_id_string,
540               $sig_type,
541               ) = @fields[ 1, 3 .. 6, 9, 10 ];
542                
543 9           15 my $expiration_date_string;
544 9 50         17 if ($expiration_date eq '') {
545 9           15 $expiration_date = undef;
546               } else {
547 0           0 $expiration_date_string = $self->_downrez_date($expiration_date);
548               }
549 9           32 my $signature_date_string = $self->_downrez_date($signature_date);
550                
551 9           18 my ($sig_class, $is_exportable);
552 9 50         46 if ($sig_type =~ /^([[:xdigit:]]{2})([xl])$/ ) {
553 9           25 $sig_class = hex($1);
554 9           23 $is_exportable = ('x' eq $2);
555               }
556                
557 9           32 my $signature = GnuPG::Signature->new(
558               validity => $validity,
559               algo_num => $algo_num,
560               hex_id => $hex_key_id,
561               date => $signature_date,
562               date_string => $signature_date_string,
563               expiration_date => $expiration_date,
564               expiration_date_string => $expiration_date_string,
565               user_id_string => unescape_string($user_id_string),
566               sig_class => $sig_class,
567               is_exportable => $is_exportable,
568               );
569                
570 9 50   100     7367 if ( $current_signed_item->isa('GnuPG::Key') ||
        66        
        33        
571               $current_signed_item->isa('GnuPG::UserId') ||
572               $current_signed_item->isa('GnuPG::Revoker') ||
573               $current_signed_item->isa('GnuPG::UserAttribute')) {
574 9 50         26 if ($record_type eq 'sig') {
    0            
575 9           47 $current_signed_item->push_signatures($signature);
576               } elsif ($record_type eq 'rev') {
577 0           0 $current_signed_item->push_revocations($signature);
578               }
579               } else {
580 0           0 warn "do not know how to handle signature line: $line\n";
581               }
582               }
583               elsif ( $record_type eq 'uid' ) {
584 10           54 my ( $validity, $user_id_string ) = @fields[ 1, 9 ];
585                
586 10           46 $current_signed_item = GnuPG::UserId->new(
587               validity => $validity,
588               as_string => unescape_string($user_id_string),
589               );
590                
591 10           993 $current_primary_key->push_user_ids($current_signed_item);
592               }
593               elsif ( $record_type eq 'uat' ) {
594 0           0 my ( $validity, $subpacket ) = @fields[ 1, 9 ];
595                
596 0           0 my ( $subpacket_count, $subpacket_total_size ) = split(/ /,$subpacket);
597                
598 0           0 $current_signed_item = GnuPG::UserAttribute->new(
599               validity => $validity,
600               subpacket_count => $subpacket_count,
601               subpacket_total_size => $subpacket_total_size,
602               );
603                
604 0           0 $current_primary_key->push_user_attributes($current_signed_item);
605               }
606               elsif ( $record_type eq 'sub' or $record_type eq 'ssb' ) {
607               my (
608 5           74 $validity, $key_length, $algo_num, $hex_id,
609               $creation_date, $expiration_date,
610               $local_id,
611               $dummy0, $dummy1, $dummy2, #unused
612               $usage_flags,
613               ) = @fields[ 1 .. 11 ];
614                
615 5           15 my $expiration_date_string;
616 5 50         21 if ($expiration_date eq '') {
617 5           18 $expiration_date = undef;
618               } else {
619 0           0 $expiration_date_string = $self->_downrez_date($expiration_date);
620               }
621 5           47 my $creation_date_string = $self->_downrez_date($creation_date);
622                
623 5           87 $current_signed_item = $current_key
624               = GnuPG::SubKey->new(
625               validity => $validity,
626               length => $key_length,
627               algo_num => $algo_num,
628               hex_id => $hex_id,
629               creation_date => $creation_date,
630               expiration_date => $expiration_date,
631               creation_date_string => $creation_date_string,
632               expiration_date_string => $expiration_date_string,
633               local_id => $local_id,
634               usage_flags => $usage_flags,
635               );
636                
637 5           392 $current_primary_key->push_subkeys($current_signed_item);
638               }
639               elsif ($record_type eq 'rvk') {
640 4           39 my ($algo_num, $fpr, $class) = @fields[ 3,9,10 ];
641 4           73 my $rvk = GnuPG::Revoker->new(
642               fingerprint => GnuPG::Fingerprint->new( as_hex_string => $fpr ),
643               algo_num => ($algo_num + 0),
644               class => hex($class),
645               );
646               # pushing to either primary key or subkey, to handle
647               # designated revokers to the subkeys too:
648 4           149 $current_key->push_revokers($rvk);
649               # revokers should be bound to the key with signatures:
650 4           110 $current_signed_item = $rvk;
651               }
652               elsif ($record_type eq 'pkd') {
653 28           87 my ($pos, $size, $data) = @fields[ 1,2,3 ];
654 28           277 $current_key->pubkey_data->[$pos+0] = Math::BigInt->from_hex('0x'.$data);
655               }
656               elsif ( $record_type ne 'tru' and $record_type ne 'grp' ) {
657 0           0 warn "unknown record type $record_type";
658               }
659               }
660                
661 5           13708 waitpid $pid, 0;
662                
663 5 50         63 push @returned_keys, $current_primary_key
664               if $current_primary_key;
665                
666 5           202 $self->options($saved_options);
667                
668 5           1129 return @returned_keys;
669               }
670                
671               sub _downrez_date {
672 19       19   86 my $self = shift;
673 19           57 my $date = shift;
674 19 50         252 if ($date =~ /^\d+$/) {
675 19           571 my ($year,$month,$day) = (gmtime($date))[5,4,3];
676 19           95 $year += 1900;
677 19           44 $month += 1;
678 19           212 return sprintf('%04d-%02d-%02d', $year, $month, $day);
679               }
680 0           0 return $date;
681               }
682                
683                
684               ################################################################
685                
686               sub list_public_keys {
687 9       9 1 13853 my ( $self, %args ) = @_;
688 9           228 return $self->wrap_call(
689               %args,
690               commands => ['--list-public-keys'],
691               );
692               }
693                
694               sub list_sigs {
695 9       9 1 12661 my ( $self, %args ) = @_;
696 9           136 return $self->wrap_call(
697               %args,
698               commands => ['--list-sigs'],
699               );
700               }
701                
702               sub list_secret_keys {
703 9       9 1 12222 my ( $self, %args ) = @_;
704 9           134 return $self->wrap_call(
705               %args,
706               commands => ['--list-secret-keys'],
707               );
708               }
709                
710               sub encrypt( $% ) {
711 10       10 1 1004 my ( $self, %args ) = @_;
712 10           749 return $self->wrap_call(
713               %args,
714               commands => ['--encrypt']
715               );
716               }
717                
718               sub encrypt_symmetrically( $% ) {
719 5       5 1 3802 my ( $self, %args ) = @_;
720               # Strip the homedir and put it back after encrypting;
721 5           145 my $homedir = $self->options->homedir;
722 5 50         356 $self->options->clear_homedir
723               unless $self->cmp_version($self->version, '2.2') >= 0;
724 5           294 my $pid = $self->wrap_call(
725               %args,
726               commands => ['--symmetric']
727               );
728 3 50         216 $self->options->homedir($homedir)
729               unless $self->cmp_version($self->version, '2.2') >= 0;
730 3           636 return $pid;
731               }
732                
733               sub sign( $% ) {
734 14       14 1 13493 my ( $self, %args ) = @_;
735 14           179 return $self->wrap_call(
736               %args,
737               commands => ['--sign']
738               );
739               }
740                
741               sub clearsign( $% ) {
742 5       5 1 3406 my ( $self, %args ) = @_;
743 5           55 return $self->wrap_call(
744               %args,,
745               commands => ['--clearsign']
746               );
747               }
748                
749               sub detach_sign( $% ) {
750 5       5 1 3828 my ( $self, %args ) = @_;
751 5           64 return $self->wrap_call(
752               %args,
753               commands => ['--detach-sign']
754               );
755               }
756                
757               sub sign_and_encrypt( $% ) {
758 5       5 1 358 my ( $self, %args ) = @_;
759 5           64 return $self->wrap_call(
760               %args,
761               commands => [
762               '--sign',
763               '--encrypt'
764               ]
765               );
766               }
767                
768               sub decrypt( $% ) {
769 5       5 1 3345 my ( $self, %args ) = @_;
770 5           79 return $self->wrap_call(
771               %args,
772               commands => ['--decrypt']
773               );
774               }
775                
776               sub verify( $% ) {
777 5       5 1 3421 my ( $self, %args ) = @_;
778 5           49 return $self->wrap_call(
779               %args,
780               commands => ['--verify']
781               );
782               }
783                
784               sub import_keys( $% ) {
785 7       7 1 5807 my ( $self, %args ) = @_;
786 7           62 return $self->wrap_call(
787               %args,
788               commands => ['--import']
789               );
790               }
791                
792               sub export_keys( $% ) {
793 5       5 1 3802 my ( $self, %args ) = @_;
794 5           66 return $self->wrap_call(
795               %args,
796               commands => ['--export']
797               );
798               }
799                
800               sub recv_keys( $% ) {
801 0       0 1 0 my ( $self, %args ) = @_;
802 0           0 return $self->wrap_call(
803               %args,
804               commands => ['--recv-keys']
805               );
806               }
807                
808               sub send_keys( $% ) {
809 0       0 1 0 my ( $self, %args ) = @_;
810 0           0 return $self->wrap_call(
811               %args,
812               commands => ['--send-keys']
813               );
814               }
815                
816               sub search_keys( $% ) {
817 0       0 1 0 my ( $self, %args ) = @_;
818 0           0 return $self->wrap_call(
819               %args,
820               commands => ['--search-keys']
821               );
822               }
823                
824               sub _version {
825 120       120   480 my ( $self ) = @_;
826                
827 120           1899 my $out = IO::Handle->new;
828 120           8818 my $handles = GnuPG::Handles->new( stdout => $out );
829 120           6965 my $pid = $self->wrap_call( commands => [ '--no-options', '--version' ], handles => $handles );
830 108           8961 my $line = $out->getline;
831 108           65238124 $line =~ /(\d+\.\d+\.\d+)/;
832                
833 108           2026 my $version = $1;
834 108 50   33     2857 unless ($self->cmp_version($version, '2.2') >= 0 or
        66        
835               ($self->cmp_version($version, '1.4') >= 0 and $self->cmp_version($version, '1.5') < 0 )) {
836 0           0 croak "GnuPG Version 1.4 or 2.2+ required";
837               }
838 108           11602 waitpid $pid, 0;
839                
840 108           27823 return $version;
841               }
842                
843               sub cmp_version($$) {
844 506       506 0 2709988 my ( $self, $a, $b ) = (@_);
845 506           5180 my @a = split '\.', $a;
846 506           15998 my @b = split '\.', $b;
847 506 50         4295 @a > @b
848               ? push @b, (0) x (@a-@b)
849               : push @a, (0) x (@b-@a);
850 506           3157 for ( my $i = 0; $i < @a; $i++ ) {
851 821 100         10769 return $a[$i] <=> $b[$i] if $a[$i] <=> $b[$i];
852               }
853 0           0 return 0;
854               }
855                
856               sub test_default_key_passphrase() {
857 4       4 1 5612 my ($self) = @_;
858                
859               # We can't do something like let the user pass
860               # in a passphrase handle because we don't exist
861               # anymore after the user runs off with the
862               # attachments
863 4 50         112 croak 'No passphrase defined to test!'
864               unless defined $self->passphrase();
865                
866 4           168 my $stdin = IO::Handle->new();
867 4           88 my $stdout = IO::Handle->new();
868 4           80 my $stderr = IO::Handle->new();
869 4           144 my $status = IO::Handle->new();
870                
871 4           176 my $handles = GnuPG::Handles->new(
872               stdin => $stdin,
873               stdout => $stdout,
874               stderr => $stderr,
875               status => $status
876               );
877                
878               # save this setting since we need to be in non-interactive mode
879 4           352 my $saved_meta_interactive_option = $self->options->meta_interactive();
880 4           260 $self->options->clear_meta_interactive();
881                
882 4           172 my $pid = $self->sign( handles => $handles );
883                
884 3           237 close $stdin;
885                
886               # restore this setting to its original setting
887 3           219 $self->options->meta_interactive($saved_meta_interactive_option);
888                
889               # all we realy want to check is the status fh
890 3           1940715 while (<$status>) {
891 9 100         7656 if (/^\[GNUPG:\]\s*(GOOD_PASSPHRASE|SIG_CREATED)/) {
892 3           11166 waitpid $pid, 0;
893 3           900 return 1;
894               }
895               }
896                
897               # If we didn't catch the regexp above, we'll assume
898               # that the passphrase was incorrect
899 0             waitpid $pid, 0;
900 0             return 0;
901               }
902                
903               1;
904                
905               ##############################################################
906                
907               =head1 NAME
908                
909               GnuPG::Interface - Perl interface to GnuPG
910                
911               =head1 SYNOPSIS
912                
913               # A simple example
914               use IO::Handle;
915               use GnuPG::Interface;
916                
917               # setting up the situation
918               my $gnupg = GnuPG::Interface->new();
919               $gnupg->options->hash_init( armor => 1,
920               homedir => '/home/foobar' );
921                
922               # Note you can set the recipients even if you aren't encrypting!
923               $gnupg->options->push_recipients( 'ftobin@cpan.org' );
924               $gnupg->options->meta_interactive( 0 );
925                
926               # how we create some handles to interact with GnuPG
927               my $input = IO::Handle->new();
928               my $output = IO::Handle->new();
929               my $handles = GnuPG::Handles->new( stdin => $input,
930               stdout => $output );
931                
932               # Now we'll go about encrypting with the options already set
933               my @plaintext = ( 'foobar' );
934               my $pid = $gnupg->encrypt( handles => $handles );
935                
936               # Now we write to the input of GnuPG
937               print $input @plaintext;
938               close $input;
939                
940               # now we read the output
941               my @ciphertext = <$output>;
942               close $output;
943                
944               waitpid $pid, 0;
945                
946               =head1 DESCRIPTION
947                
948               GnuPG::Interface and its associated modules are designed to
949               provide an object-oriented method for interacting with GnuPG,
950               being able to perform functions such as but not limited
951               to encrypting, signing,
952               decryption, verification, and key-listing parsing.
953                
954               =head2 How Data Member Accessor Methods are Created
955                
956               Each module in the GnuPG::Interface bundle relies
957               on Moo to generate the get/set methods
958               used to set the object's data members.
959               I<This is very important to realize.> This means that
960               any data member which is a list has special
961               methods assigned to it for pushing, popping, and
962               clearing the list.
963                
964               =head2 Understanding Bidirectional Communication
965                
966               It is also imperative to realize that this package
967               uses interprocess communication methods similar to
968               those used in L<IPC::Open3>
969               and L<perlipc/"Bidirectional Communication with Another Process">,
970               and that users of this package
971               need to understand how to use this method because this package
972               does not abstract these methods for the user greatly.
973               This package is not designed
974               to abstract this away entirely (partly for security purposes), but rather
975               to simply help create 'proper', clean calls to GnuPG, and to implement
976               key-listing parsing.
977               Please see L<perlipc/"Bidirectional Communication with Another Process">
978               to learn how to deal with these methods.
979                
980               Using this package to do message processing generally
981               invovlves creating a GnuPG::Interface object, creating
982               a GnuPG::Handles object,
983               setting some options in its B<options> data member,
984               and then calling a method which invokes GnuPG, such as
985               B<clearsign>. One then interacts with with the handles
986               appropriately, as described in
987               L<perlipc/"Bidirectional Communication with Another Process">.
988                
989               =head1 GnuPG Versions
990                
991               As of this version of GnuPG::Interface, there are two supported
992               versions of GnuPG: 1.4.x and 2.2.x. The
993               L<GnuPG download page|https://gnupg.org/download/index.html> has
994               updated information on the currently supported versions.
995                
996               GnuPG released 2.0 and 2.1 versions in the past and some packaging
997               systems may still provide these if you install the default C<gpg>,
998               C<gnupg>, C<gnupg2>, etc. packages. This modules supports only
999               version 2.2.x, so you may need to find additional package
1000               repositories or build from source to get the updated version.
1001                
1002               =head1 OBJECT METHODS
1003                
1004               =head2 Initialization Methods
1005                
1006               =over 4
1007                
1008               =item new( I<%initialization_args> )
1009                
1010               This methods creates a new object. The optional arguments are
1011               initialization of data members.
1012                
1013               =item hash_init( I<%args> ).
1014                
1015                
1016               =back
1017                
1018               =head2 Object Methods which use a GnuPG::Handles Object
1019                
1020               =over 4
1021                
1022               =item list_public_keys( % )
1023                
1024               =item list_sigs( % )
1025                
1026               =item list_secret_keys( % )
1027                
1028               =item encrypt( % )
1029                
1030               =item encrypt_symmetrically( % )
1031                
1032               =item sign( % )
1033                
1034               =item clearsign( % )
1035                
1036               =item detach_sign( % )
1037                
1038               =item sign_and_encrypt( % )
1039                
1040               =item decrypt( % )
1041                
1042               =item verify( % )
1043                
1044               =item import_keys( % )
1045                
1046               =item export_keys( % )
1047                
1048               =item recv_keys( % )
1049                
1050               =item send_keys( % )
1051                
1052               =item search_keys( % )
1053                
1054               These methods each correspond directly to or are very similar
1055               to a GnuPG command described in L<gpg>. Each of these methods
1056               takes a hash, which currently must contain a key of B<handles>
1057               which has the value of a GnuPG::Handles object.
1058               Another optional key is B<command_args> which should have the value of an
1059               array reference; these arguments will be passed to GnuPG as command arguments.
1060               These command arguments are used for such things as determining the keys to
1061               list in the B<export_keys> method. I<Please note that GnuPG command arguments
1062               are not the same as GnuPG options>. To understand what are options and
1063               what are command arguments please read L<gpg/"COMMANDS"> and L<gpg/"OPTIONS">.
1064                
1065               Each of these calls returns the PID for the resulting GnuPG process.
1066               One can use this PID in a C<waitpid> call instead of a C<wait> call
1067               if more precise process reaping is needed.
1068                
1069               These methods will attach the handles specified in the B<handles> object
1070               to the running GnuPG object, so that bidirectional communication
1071               can be established. That is, the optionally-defined B<stdin>,
1072               B<stdout>, B<stderr>, B<status>, B<logger>, and
1073               B<passphrase> handles will be attached to
1074               GnuPG's input, output, standard error,
1075               the handle created by setting B<status-fd>, the handle created by setting B<logger-fd>, and the handle created by setting
1076               B<passphrase-fd> respectively.
1077               This tying of handles of similar to the process
1078               done in I<IPC::Open3>.
1079                
1080               If you want the GnuPG process to read or write directly to an already-opened
1081               filehandle, you cannot do this via the normal I<IPC::Open3> mechanisms.
1082               In order to accomplish this, set the appropriate B<handles> data member
1083               to the already-opened filehandle, and then set the option B<direct> to be true
1084               for that handle, as described in L<GnuPG::Handles/options>. For example,
1085               to have GnuPG read from the file F<input.txt> and write to F<output.txt>,
1086               the following snippet may do:
1087                
1088               my $infile = IO::File->new( 'input.txt' );
1089               my $outfile = IO::File->new( '>output.txt' );
1090               my $handles = GnuPG::Handles->new( stdin => $infile,
1091               stdout => $outfile,
1092               );
1093               $handles->options( 'stdin' )->{direct} = 1;
1094               $handles->options( 'stdout' )->{direct} = 1;
1095                
1096               If any handle in the B<handles> object is not defined, GnuPG's input, output,
1097               and standard error will be tied to the running program's standard error,
1098               standard output, or standard error. If the B<status> or B<logger> handle
1099               is not defined, this channel of communication is never established with GnuPG,
1100               and so this information is not generated and does not come into play.
1101                
1102               If the B<passphrase> data member handle of the B<handles> object
1103               is not defined, but the the B<passphrase> data member handle of GnuPG::Interface
1104               object is, GnuPG::Interface will handle passing this information into GnuPG
1105               for the user as a convenience. Note that this will result in
1106               GnuPG::Interface storing the passphrase in memory, instead of having
1107               it simply 'pass-through' to GnuPG via a handle.
1108                
1109               If neither the B<passphrase> data member of the GnuPG::Interface nor
1110               the B<passphrase> data member of the B<handles> object is defined,
1111               then GnuPG::Interface assumes that access and control over the secret
1112               key will be handled by the running gpg-agent process. This represents
1113               the simplest mode of operation with the GnuPG "stable" suite (version
1114               2.2 and later). It is also the preferred mode for tools intended to
1115               be user-facing, since the user will be prompted directly by gpg-agent
1116               for use of the secret key material. Note that for programmatic use,
1117               this mode requires the gpg-agent and pinentry to already be correctly
1118               configured.
1119                
1120               =back
1121                
1122               =head2 Other Methods
1123                
1124               =over 4
1125                
1126               =item get_public_keys( @search_strings )
1127                
1128               =item get_secret_keys( @search_strings )
1129                
1130               =item get_public_keys_with_sigs( @search_strings )
1131                
1132               These methods create and return objects of the type GnuPG::PublicKey
1133               or GnuPG::SecretKey respectively. This is done by parsing the output
1134               of GnuPG with the option B<with-colons> enabled. The objects created
1135               do or do not have signature information stored in them, depending
1136               if the method ends in I<_sigs>; this separation of functionality is there
1137               because of performance hits when listing information with signatures.
1138                
1139               =item test_default_key_passphrase()
1140                
1141               This method will return a true or false value, depending
1142               on whether GnuPG reports a good passphrase was entered
1143               while signing a short message using the values of
1144               the B<passphrase> data member, and the default
1145               key specified in the B<options> data member.
1146                
1147               =item version()
1148                
1149               Returns the version of GnuPG that GnuPG::Interface is running.
1150                
1151               =back
1152                
1153                
1154               =head1 Invoking GnuPG with a custom call
1155                
1156               GnuPG::Interface attempts to cover a lot of the commands
1157               of GnuPG that one would want to perform; however, there may be a lot
1158               more calls that GnuPG is and will be capable of, so a generic command
1159               interface is provided, C<wrap_call>.
1160                
1161               =over 4
1162                
1163               =item wrap_call( %args )
1164                
1165               Call GnuPG with a custom command. The %args hash must contain
1166               at least the following keys:
1167                
1168               =over 4
1169                
1170               =item commands
1171                
1172               The value of this key in the hash must be a reference to a a list of
1173               commands for GnuPG, such as C<[ qw( --encrypt --sign ) ]>.
1174                
1175               =item handles
1176                
1177               As with most other GnuPG::Interface methods, B<handles>
1178               must be a GnuPG::Handles object.
1179                
1180               =back
1181                
1182               The following keys are optional.
1183                
1184               =over 4
1185                
1186               =item command_args
1187                
1188               As with other GnuPG::Interface methods, the value in hash
1189               for this key must be a reference to a list of arguments
1190               to be passed to the GnuPG command, such as which
1191               keys to list in a key-listing.
1192                
1193               =back
1194                
1195               =back
1196                
1197                
1198               =head1 OBJECT DATA MEMBERS
1199                
1200               =over 4
1201                
1202               =item call
1203                
1204               This defines the call made to invoke GnuPG. Defaults to 'gpg'; this
1205               should be changed if 'gpg' is not in your path, or there is a different
1206               name for the binary on your system.
1207                
1208               =item passphrase
1209                
1210               In order to lessen the burden of using handles by the user of this package,
1211               setting this option to one's passphrase for a secret key will allow
1212               the package to enter the passphrase via a handle to GnuPG by itself
1213               instead of leaving this to the user. See also L<GnuPG::Handles/passphrase>.
1214                
1215               =item options
1216                
1217               This data member, of the type GnuPG::Options; the setting stored in this
1218               data member are used to determine the options used when calling GnuPG
1219               via I<any> of the object methods described in this package.
1220               See L<GnuPG::Options> for more information.
1221                
1222               =back
1223                
1224               =head1 EXAMPLES
1225                
1226               The following setup can be done before any of the following examples:
1227                
1228               use IO::Handle;
1229               use GnuPG::Interface;
1230                
1231               my @original_plaintext = ( "How do you doo?" );
1232               my $passphrase = "Three Little Pigs";
1233                
1234               my $gnupg = GnuPG::Interface->new();
1235                
1236               $gnupg->options->hash_init( armor => 1,
1237               recipients => [ 'ftobin@uiuc.edu',
1238               '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ],
1239               meta_interactive => 0 ,
1240               );
1241                
1242               $gnupg->options->debug_level(4);
1243                
1244               $gnupg->options->logger_file("/tmp/gnupg-$$-decrypt-".time().".log");
1245                
1246                
1247               =head2 Encrypting
1248                
1249               # We'll let the standard error of GnuPG pass through
1250               # to our own standard error, by not creating
1251               # a stderr-part of the $handles object.
1252               my ( $input, $output ) = ( IO::Handle->new(),
1253               IO::Handle->new() );
1254                
1255               my $handles = GnuPG::Handles->new( stdin => $input,
1256               stdout => $output );
1257                
1258               # this sets up the communication
1259               # Note that the recipients were specified earlier
1260               # in the 'options' data member of the $gnupg object.
1261               my $pid = $gnupg->encrypt( handles => $handles );
1262                
1263               # this passes in the plaintext
1264               print $input @original_plaintext;
1265                
1266               # this closes the communication channel,
1267               # indicating we are done
1268               close $input;
1269                
1270               my @ciphertext = <$output>; # reading the output
1271                
1272               waitpid $pid, 0; # clean up the finished GnuPG process
1273                
1274               =head2 Signing
1275                
1276               # This time we'll catch the standard error for our perusing
1277               my ( $input, $output, $error ) = ( IO::Handle->new(),
1278               IO::Handle->new(),
1279               IO::Handle->new(),
1280               );
1281                
1282               my $handles = GnuPG::Handles->new( stdin => $input,
1283               stdout => $output,
1284               stderr => $error,
1285               );
1286                
1287               # indicate our pasphrase through the
1288               # convenience method
1289               $gnupg->passphrase( $passphrase );
1290                
1291               # this sets up the communication
1292               my $pid = $gnupg->sign( handles => $handles );
1293                
1294               # this passes in the plaintext
1295               print $input @original_plaintext;
1296                
1297               # this closes the communication channel,
1298               # indicating we are done
1299               close $input;
1300                
1301               my @ciphertext = <$output>; # reading the output
1302               my @error_output = <$error>; # reading the error
1303                
1304               close $output;
1305               close $error;
1306                
1307               waitpid $pid, 0; # clean up the finished GnuPG process
1308                
1309               =head2 Decryption
1310                
1311               # This time we'll catch the standard error for our perusing
1312               # as well as passing in the passphrase manually
1313               # as well as the status information given by GnuPG
1314               my ( $input, $output, $error, $passphrase_fh, $status_fh )
1315               = ( IO::Handle->new(),
1316               IO::Handle->new(),
1317               IO::Handle->new(),
1318               IO::Handle->new(),
1319               IO::Handle->new(),
1320               );
1321                
1322               my $handles = GnuPG::Handles->new( stdin => $input,
1323               stdout => $output,
1324               stderr => $error,
1325               passphrase => $passphrase_fh,
1326               status => $status_fh,
1327               );
1328                
1329               # this time we'll also demonstrate decrypting
1330               # a file written to disk
1331               # Make sure you "use IO::File" if you use this module!
1332               my $cipher_file = IO::File->new( 'encrypted.gpg' );
1333                
1334               # this sets up the communication
1335               my $pid = $gnupg->decrypt( handles => $handles );
1336                
1337               # This passes in the passphrase
1338               print $passphrase_fh $passphrase;
1339               close $passphrase_fh;
1340                
1341               # this passes in the plaintext
1342               print $input $_ while <$cipher_file>;
1343                
1344               # this closes the communication channel,
1345               # indicating we are done
1346               close $input;
1347               close $cipher_file;
1348                
1349               my @plaintext = <$output>; # reading the output
1350               my @error_output = <$error>; # reading the error
1351               my @status_info = <$status_fh>; # read the status info
1352                
1353               # clean up...
1354               close $output;
1355               close $error;
1356               close $status_fh;
1357                
1358               waitpid $pid, 0; # clean up the finished GnuPG process
1359                
1360               =head2 Printing Keys
1361                
1362               # This time we'll just let GnuPG print to our own output
1363               # and read from our input, because no input is needed!
1364               my $handles = GnuPG::Handles->new();
1365                
1366               my @ids = ( 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' );
1367                
1368               # this time we need to specify something for
1369               # command_args because --list-public-keys takes
1370               # search ids as arguments
1371               my $pid = $gnupg->list_public_keys( handles => $handles,
1372               command_args => [ @ids ] );
1373                
1374               waitpid $pid, 0;
1375                
1376               =head2 Creating GnuPG::PublicKey Objects
1377                
1378               my @ids = [ 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ];
1379                
1380               my @keys = $gnupg->get_public_keys( @ids );
1381                
1382               # no wait is required this time; it's handled internally
1383               # since the entire call is encapsulated
1384                
1385               =head2 Custom GnuPG call
1386                
1387               # assuming $handles is a GnuPG::Handles object
1388               my $pid = $gnupg->wrap_call
1389               ( commands => [ qw( --list-packets ) ],
1390               command_args => [ qw( test/key.1.asc ) ],
1391               handles => $handles,
1392               );
1393                
1394               my @out = <$handles->stdout()>;
1395               waitpid $pid, 0;
1396                
1397                
1398               =head1 FAQ
1399                
1400               =over 4
1401                
1402               =item How do I get GnuPG::Interface to read/write directly from
1403               a filehandle?
1404                
1405               You need to set GnuPG::Handles B<direct> option to be true for the
1406               filehandles in concern. See L<GnuPG::Handles/options> and
1407               L<"Object Methods which use a GnuPG::Handles Object"> for more
1408               information.
1409                
1410               =item Why do you make it so difficult to get GnuPG to write/read
1411               from a filehandle? In the shell, I can just call GnuPG
1412               with the --outfile option!
1413                
1414               There are lots of issues when trying to tell GnuPG to read/write
1415               directly from a file, such as if the file isn't there, or
1416               there is a file, and you want to write over it! What do you
1417               want to happen then? Having the user of this module handle
1418               these questions beforehand by opening up filehandles to GnuPG
1419               lets the user know fully what is going to happen in these circumstances,
1420               and makes the module less error-prone.
1421                
1422               =item When having GnuPG process a large message, sometimes it just
1423               hanges there.
1424                
1425               Your problem may be due to buffering issues; when GnuPG reads/writes
1426               to B<non-direct> filehandles (those that are sent to filehandles
1427               which you read to from into memory, not that those access the disk),
1428               buffering issues can mess things up. I recommend looking into
1429               L<GnuPG::Handles/options>.
1430                
1431               =back
1432                
1433               =head1 NOTES
1434                
1435               This package is the successor to PGP::GPG::MessageProcessor,
1436               which I found to be too inextensible to carry on further.
1437               A total redesign was needed, and this is the resulting
1438               work.
1439                
1440               After any call to a GnuPG-command method of GnuPG::Interface
1441               in which one passes in the handles,
1442               one should all B<wait> to clean up GnuPG from the process table.
1443                
1444                
1445               =head1 BUGS
1446                
1447               =head2 Large Amounts of Data
1448                
1449               Currently there are problems when transmitting large quantities
1450               of information over handles; I'm guessing this is due
1451               to buffering issues. This bug does not seem specific to this package;
1452               IPC::Open3 also appears affected.
1453                
1454               =head2 OpenPGP v3 Keys
1455                
1456               I don't know yet how well this module handles parsing OpenPGP v3 keys.
1457                
1458               =head2 RHEL 7 Test Failures
1459                
1460               Testing with the updates for version 1.00 we saw intermittent test failures
1461               on RHEL 7 with GnuPG version 2.2.20. In some cases the tests would all pass
1462               for several runs, then one would fail. We're unable to reliably reproduce
1463               this so we would be interested in feedback from other users.
1464                
1465               =head1 SEE ALSO
1466                
1467               L<GnuPG::Options>,
1468               L<GnuPG::Handles>,
1469               L<GnuPG::PublicKey>,
1470               L<GnuPG::SecretKey>,
1471               L<gpg>,
1472               L<perlipc/"Bidirectional Communication with Another Process">
1473                
1474               =head1 LICENSE
1475                
1476               This module is free software; you can redistribute it and/or modify it
1477               under the same terms as Perl itself.
1478                
1479               =head1 AUTHOR
1480                
1481               GnuPG::Interface is currently maintained by Best Practical Solutions <BPS@cpan.org>.
1482                
1483               Frank J. Tobin, ftobin@cpan.org was the original author of the package.
1484                
1485               =cut
1486                
1487               1;
1488