File Coverage

blib/lib/GPG.pm
Criterion Covered Total %
statement 188 332 56.6
branch 52 170 30.5
condition 23 91 25.2
subroutine 27 39 69.2
pod 16 35 45.7
total 306 667 45.8


line stmt bran cond sub pod time code
1             package GPG;
2 1     1   44698 use strict;
  1         4  
  1         722  
3              
4 1     1   9 use vars qw/$VERSION/;
  1         33  
  1         89  
5             $VERSION = "0.05";
6              
7 1     1   2912 use IO::Handle;
  1         12784  
  1         63  
8 1     1   1149 use IPC::Open3;
  1         3856  
  1         5601  
9              
10             my $GNUPG_PATH = '/usr/bin';
11              
12 1     1 1 512 sub new ($%) { my ($this,%params) = @_;
13 1   33     9 my $class = ref($this) || $this;
14 1         5 my $self = {};
15 1   33     9 $self->{'gnupg_path'} = $params{'gnupg_path'} || $GNUPG_PATH;
16 1   33     6 $self->{'homedir'} = $params{'homedir'} || $ENV{'HOME'}.'/.gnupg';
17 1   50     14 $self->{'config'} = $params{'config'} || '';
18 1   50     6 $self->{'armor'} = $params{'armor'} || '1'; # Default IS armored !
19 1   50     7 $self->{'debug'} = $params{'debug'} || '';
20              
21 1         5 $self->{'COMMAND'} = "$self->{'gnupg_path'}/gpg";
22 1 50       5 $self->{'COMMAND'} .= " -a" if $self->{'armor'};
23 1 50       6 $self->{'COMMAND'} .= " --config $self->{'config'}" if $self->{'config'};
24 1 50       6 $self->{'COMMAND'} .= " --homedir $self->{'homedir'}" if $self->{'homedir'};
25 1         3 $self->{'COMMAND'} .= " --batch";
26 1         2 $self->{'COMMAND'} .= " --no-comment";
27 1         3 $self->{'COMMAND'} .= " --no-version";
28 1         3 $self->{'COMMAND'} .= ' '; # so i dont forget the spaces later :-)
29              
30 1 50       4 if ($self->{'debug'}) {
31 0         0 print "\n********************************************************************\n";
32 0         0 print "COMMAND : $self->{'COMMAND'}\n";
33 0         0 print "\$self->{'homedir'} : $self->{'homedir'}\n";
34 0         0 print "\$self->{'config'} : $self->{'config'}\n";
35 0         0 print "\$self->{'armor'} : $self->{'armor'}\n";
36 0         0 print "\$self->{'debug'} : $self->{'debug'}\n";
37 0         0 print "********************************************************************\n";
38             }
39              
40 1         2 $self->{'warning'} = '';
41              
42 1         2 bless $self, $class;
43 1         5 return $self;
44             }
45              
46 0     0 0 0 sub gnupg_path { my ($this,$value) = @_; $this->{gnupg_path} = $value; }
  0         0  
47 0     0 0 0 sub homedir { my ($this,$value) = @_; $this->{homedir} = $value; }
  0         0  
48 0     0 0 0 sub config { my ($this,$value) = @_; $this->{config} = $value; }
  0         0  
49 0     0 0 0 sub armor { my ($this,$value) = @_; $this->{armor} = $value; }
  0         0  
50 0     0 0 0 sub debug { my ($this,$value) = @_; $this->{debug} = $value; }
  0         0  
51              
52             # error() : get/set errors
53 18     18 0 153 sub error { my ($this,$string) = @_;
54 18 100       128 if ($string) {
55 11 100       2956 $this->{'error'} = $this->{'error'} ? "$this->{'error'}\n$string" : $string;
56             }
57             else {
58 7   100     760 return $this->{'error'} || '';
59             }
60             }
61              
62             # warning() : same code as for error(), but otherwise :-)
63 0     0 0 0 sub warning { my ($this,$string) = @_;
64 0 0 0     0 $string
    0          
65             ? $this->{'warning'}
66             ? $this->{'warning'} .= "\n$string"
67             : $this->{'warning'} = "$string"
68             : return $this->{'warning'} || '';
69             }
70              
71 18     18 0 69 sub start_gpg { my ($this,$command,$input) = @_;
72 18         449 my ($stdin,$stdout,$stderr) = (IO::Handle->new(),IO::Handle->new(),IO::Handle->new());
73 18         17095 my $pid = open3($stdin,$stdout,$stderr, $command);
74 18 50       208028 if (!$pid) {
75 0         0 $this->error("Cannot fork [COMMAND: '$command'].");
76 0         0 return (0);
77             }
78              
79 18         262 print $stdin $input;
80 18         155 close $stdin;
81              
82 18         244041 my $output = join('',<$stdout>);
83 18         442 close $stdout;
84              
85 18         488 my $error = join('',<$stderr>);
86 18         533 close $stderr;
87              
88 18         667 wait();
89              
90 18 50       241 if ($error =~ /Warning/m) {
91 0         0 $this->{'warning'} .= "Warning: using insecure memory!";
92 0         0 $error =~ s/\n?.*using insecure memory.*\n?\s*//m;
93             # add new warning messages from gnupg here...
94             }
95              
96              
97 18 50       114 if ($this->{'debug'}) {
98 0         0 print "\n********************************************************************\n";
99 0         0 print "COMMAND : \n$command [PID $pid]\n";
100 0         0 print "STDIN : \n$input\n";
101 0         0 print "STDOUT : \n$output\n";
102 0         0 print "WARNING : \n$this->{'warning'}\n";
103 0         0 print "STDERR : \n$error\n";
104 0         0 print "\n********************************************************************\n";
105             }
106              
107 18         1246 return($pid,$output,$error);
108             }
109              
110              
111             ### gen_key #####################################################
112              
113 1     1 1 70 sub gen_key($%) { my ($this,%params) = @_;
114 1         3 my $key_size = $params{'key_size'};
115 1 50 0     3 $this->error("no key_size defined !") and return if !$key_size;
116 1         3 my $real_name = $params{'real_name'};
117 1 50 0     3 $this->error("no real_name defined !") and return if !$real_name;
118 1         2 my $email = $params{'email'};
119 1 50 0     2 $this->error("no email defined !") and return if !$email;
120 1   50     12 my $comment = $params{'comment'} || '';
121 1         2 my $passphrase = $params{'passphrase'};
122 1 50 0     4 $this->error("no passphrase defined !") and return if !$passphrase;
123              
124 1         52 srand();
125 1         8 my $tmp_filename = $this->{homedir}."/tmp_".sprintf("%08d",int(rand()*100000000));
126              
127 1         3 my $pubring = "$tmp_filename.pub";
128 1         2 my $secring = "$tmp_filename.sec";
129              
130 1         1 my $script = '';
131 1         2 $script .= "Key-Type: 20\n";
132 1         3 $script .= "Key-Length: $key_size\n";
133 1         2 $script .= "Name-Real: $real_name\n";
134 1 50       35 $script .= "Name-Comment: $comment\n" if $comment;
135 1         2 $script .= "Name-Email: $email\n";
136 1         536 $script .= "Expire-Date: 0\n";
137 1         3 $script .= "Passphrase: $passphrase\n";
138 1         2 $script .= "\%pubring $pubring\n";
139 1         3 $script .= "\%secring $secring\n";
140 1         2 $script .= "\%commit\n";
141              
142 1         7 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.' --gen-key', $script);
143 1 50       9 return if !$pid;
144              
145             # output of "gen_key" comes on stderr, we cannot stop here...
146             #$this->error($error) and return if $error;
147              
148 1         52 open(*PUBRING,"$pubring");
149 1         85 my @pubring = ;
150 1         7 close PUBRING;
151 1   50     26 unlink "$pubring" || die "cannot unlink '$pubring'";
152 1         24 open(*SECRING,"$secring");
153 1         40 my @secring= ;
154 1         6 close SECRING;
155 1   50     20 unlink "$secring" || die "cannot unlink '$secring'";;
156              
157 1         57 return(join('',@pubring),join('',@secring));
158             }
159              
160              
161             ### list_packets ################################################
162              
163 1     1 1 132 sub list_packets { my ($this,$string) = @_;
164 1         9 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.' --list-packets', $string);
165 1 50       41 return if !$pid;
166              
167 1 50       30 return [] if $output !~ /^\s*\:\S+ key packet\:/; # no key found.
168              
169 0         0 $output =~ s/^\s*\:\S+ key packet\:\s*//;
170 0         0 my @pubkeys = split(/\s*\n\:\S+ key packet\:\s*/,$output);
171 0         0 my $res = [];
172 0         0 for my $i (@pubkeys) { # for each keys found...
173 0         0 my $hash = {};
174 0         0 my @part = split(/\s*\n\:signature packet\:\s*/,$i);
175 0         0 my $key = shift @part;
176 0         0 $key =~ / created (\d+)/;
177 0 0       0 $hash->{created} = $1 if $1;
178 0         0 $key =~ /\:user ID packet\: \"(.*)\"/;
179 0 0       0 $hash->{user_id} = $1 if $1;
180 0         0 $hash->{user_name} = $hash->{user_id};
181 0         0 $hash->{user_name} =~ s/\s[\(\<].*$//;
182 0         0 $hash->{user_id} =~ /\s\<(.*)\>$/;
183 0 0       0 $hash->{user_mail} = $1 if $1;
184 0         0 $hash->{sig} = [];
185 0         0 $key =~ /\s(\w)key\[0\]\: \[(\d+) bits\]\s+/;
186 0 0 0     0 $hash->{key_type} = 'public' if $1 and $1 eq 'p';
187 0 0 0     0 $hash->{key_type} = 'secret' if $1 and $1 eq 's';
188 0 0       0 $hash->{key_size} = $2 if $2;
189 0         0 for my $j (@part) { # for all key_sig...
190 0         0 my $sub_hash = {};
191 0         0 $j =~ / keyid (\S*)\s/;
192 0 0       0 $sub_hash->{key_id} = $1 if $1;
193 0         0 $j =~ / created (\d*)\s/;
194 0 0       0 $sub_hash->{created} = $1 if $1;
195 0         0 push @{$hash->{sig}},$sub_hash;
  0         0  
196             }
197 0         0 $hash->{key_id} = $hash->{sig}[0]{key_id};
198 0         0 push @$res, $hash;
199             }
200 0         0 return $res;
201             }
202              
203              
204             ### import #################################################
205              
206 2     2 0 11 sub read_import_key_result { my ($msg) = @_;
207 2         7 my $ret = {};
208 2         22 $ret->{total_ok} = 0;
209 2         8 $ret->{total_found} = 0;
210 2         18 $ret->{secret} = [];
211 2         14 $ret->{public} = [];
212              
213 2         21 my @secret = grep(/secret key imported/,$msg);
214 2         8 for my $i (@secret) {
215 0         0 $i =~ /.*\skey\s(\w+)\:\ssecret key imported/;
216 0 0 0     0 push @{$ret->{secret}}, $1 and $ret->{total_ok}++ if $1;
  0         0  
217            
218             }
219              
220 2         9 my @public = grep(/public key imported/,$msg);
221 2         5 for my $i (@public) {
222 0         0 $i =~ /.*\skey\s(\w+)\:\spublic key imported/;
223 0 0 0     0 push @{$ret->{public}}, $1 and $ret->{total_ok}++ if $1;
  0         0  
224             }
225              
226 2         19 $msg =~ /Total number processed\:\s+(\d+)\s/;
227 2 50       28 $ret->{total_found} = $1 if $1;
228              
229 2         8 return $ret;
230             }
231              
232             # import is a Perl reserved keyword, sorry...
233 1     1 1 134 sub import_keys { my ($this,$import) = @_;
234 1         13 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.' --import', $import);
235 1 50       21 return if !$pid;
236              
237 1         229 my $res = read_import_key_result($error);
238             #$this->error($error) and return if !$res;
239              
240 1         10 return $res;
241             }
242              
243 1     1 0 127 sub fast_import { my ($this,$import) = @_;
244 1         19 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.' --fast-import', $import);
245 1 50       16 return if !$pid;
246              
247 1         17 my $res = read_import_key_result($error);
248             #$this->error($error) and return if !$res;
249              
250 1         13 return $res;
251             }
252              
253 1     1 0 125 sub update_trustdb { my ($this) = @_;
254 1         15 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.' --update-trustdb', '');
255 1 50       14 return if !$pid;
256              
257 1         13 $error =~ s/^gpg: (\d+) keys processed\s*//;
258 1   50     39 my $number_processed = $1 || '0';
259              
260 1 50 50     17 $this->error($error) and return if $error;
261 0         0 return $number_processed;
262             }
263              
264             ### fingerprint ############################################
265              
266 1     1 0 125 sub fingerprint { my ($this,$key_id) = @_;
267 1         427 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
268             "--fingerprint $key_id", "");
269 1 50       14 return if !$pid;
270 1 50 50     24 $this->error($error) and return if $error;
271              
272 0         0 my $fingerprint = [];
273 0         0 my @text = split(/\s*\n/,$output);
274              
275 0         0 for(my $i = 0; $i < $#text; $i++) {
276 0 0       0 if ($text[$i] =~ /^pub\s+.*\/(\w+)\s+\S+\s+(.*)\s*$/) {
277 0         0 my $hash = {};
278 0 0       0 $hash->{'key_id'} = $1 if $1;
279 0 0       0 $hash->{'key_name'} = $2 if $2;
280              
281 0         0 $text[$i+1] =~ /^\s+Key fingerprint = (.*)\s*$/m;
282 0 0       0 $hash->{'fingerprint'} = $1 if $1;
283 0         0 push @$fingerprint, $hash;
284 0         0 $i++;
285             }
286             }
287              
288 0         0 return $fingerprint;
289             }
290              
291              
292             ### sign_key ###############################################
293              
294 0     0 0 0 sub sign_key { my ($this,$key_id,$passphrase,$key_to_sign) = @_;
295 0         0 return "gpg: can't do that in batchmode (thanks gnupg...)";
296 0         0 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
297             "--passphrase-fd 0 --default-key $key_id --sign-key $key_to_sign","$passphrase");
298 0 0       0 return if !$pid;
299              
300 0 0 0     0 $this->error($error) and return if $error;
301 0         0 return $output;
302             }
303              
304 0     0 0 0 sub lsign_key { my ($this,$key_id) = @_;
305 0         0 return "gpg: can't do that in batchmode (thanks gnupg...)";
306             }
307              
308              
309             ### export_key #############################################
310              
311 1     1 0 95 sub export_key { my ($this,$key_id) = @_;
312 1         32 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
313             "--export-all $key_id", "");
314 1 50       15 return if !$pid;
315              
316 1 50 50     20 $this->error($error) and return if $error;
317 0         0 return $output;
318             }
319              
320 1     1 0 249 sub export_secret_key { my ($this,$key_id) = @_;
321 1         40 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
322             "--export-secret-key $key_id", "");
323 1 50       17 return if !$pid;
324              
325 1 50 50     26 $this->error($error) and return if $error;
326 0         0 return $output;
327             }
328              
329              
330             ### clearsign ##############################################
331              
332 1     1 1 243 sub clearsign { my ($this,$key_id,$passphrase,$text) = @_;
333 1         82 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
334             "--passphrase-fd 0 --default-key $key_id --clearsign", "$passphrase\n$text");
335 1 50       232 return if !$pid;
336              
337 1 50 50     24 $this->error($error) and return if $error;
338 0         0 return $output;
339             }
340              
341              
342             ### detach_sign ############################################
343              
344 1     1 1 376 sub detach_sign { my ($this,$key_id,$passphrase,$text) = @_;
345 1         44 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
346             "--passphrase-fd 0 --default-key $key_id --detach-sign", "$passphrase\n$text");
347 1 50       20 return if !$pid;
348              
349 1 50 50     95 $this->error($error) and return if $error;
350 0         0 return $output;
351             }
352              
353              
354             ### verify #################################################
355              
356 2     2 0 12 sub check_verify_result { my ($text) = @_;
357 2         9 my $verify = [];
358 2         59 my @text = split(/\s*\n/,$text);
359 2         22 for(my $i = 0; $i < $#text; $i++) {
360 2 50       21 if ($text[$i] =~ /\sSignature made (.*) using (\w+) key ID (\w+)\s*/) {
361 0         0 my $hash = {};
362 0 0       0 $hash->{'sig_date'} = $1 if $1;
363 0 0       0 $hash->{'algo'} = $2 if $2;
364 0 0       0 $hash->{'key_id'} = $3 if $3;
365              
366 0 0       0 $hash->{'ok'} = $text[$i+1] =~ /\sGood signature from \"/m ? 1 : 0;
367 0         0 $text[$i+1] =~ / signature from \"(.*)\"\s*/m;
368 0 0       0 $hash->{'key_user'} = $1 if $1;
369 0         0 push @$verify, $hash;
370 0         0 $i++;
371             }
372             }
373              
374 2         25 return $verify;
375             }
376              
377 1     1 1 4140 sub verify { my ($this,$string) = @_;
378 1         414 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
379             "--verify", "$string");
380 1 50       16 return if !$pid;
381              
382 1         94 return check_verify_result($error);
383             }
384              
385             ### verify_files ###########################################
386              
387 1     1 1 409 sub verify_files { my ($this,$string) = @_;
388 1         36 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
389             "--verify", "$string");
390 1 50       14 return if !$pid;
391              
392 1         16 return check_verify_result($error);
393             }
394              
395              
396             ### encrypt ################################################
397              
398 1     1 1 103 sub encrypt { my ($this,$text,@dest) = @_;
399 1         19 my $dest = '-r '.join(' -r ',@dest);
400 1         14 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
401             "$dest --encrypt", "$text");
402 1 50       20 return if !$pid;
403              
404 1 50 50     23 $this->error($error) and return if $error;
405 0         0 return $output;
406             }
407              
408              
409             ### decrypt ################################################
410              
411 1     1 1 121 sub decrypt { my ($this,$passphrase,$text) = @_;
412 1         24 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
413             "--passphrase-fd 0 --decrypt", "$passphrase\n$text");
414 1 50       22 return if !$pid;
415              
416 1 50 50     43 $this->error($error) and return if $error;
417 0         0 return $output;
418             }
419              
420              
421             ### sign_encrypt ###########################################
422              
423 1     1 1 12157 sub sign_encrypt { my ($this,$key_id,$passphrase,$text,@dest) = @_;
424 1         65 my $dest = '-r '.join(' -r ',@dest);
425 1         41 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
426             "--passphrase-fd 0 $dest --default-key $key_id -se", "$passphrase\n$text");
427 1 50       21 return if !$pid;
428              
429 1 50 50     27 $this->error($error) and return if $error;
430 0         0 return $output;
431             }
432              
433              
434             ### decrypt_verify #########################################
435              
436 1     1 1 139 sub decrypt_verify { my ($this,$passphrase,$text) = @_;
437 1         21 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
438             "--passphrase-fd 0", "$passphrase\n$text");
439 1 50       24 return if !$pid;
440              
441 1         6 my $verify = {};
442 1 50       26 $verify->{'ok'} = $error =~ /\sGood signature from \"/m ? 1 : 0;
443 1         4 $error =~ / signature from \"(.*)\"\s/m;
444 1 50       15 $verify->{'key_user'} = $1 if $1;
445 1         5 $error =~ /\susing \w+ key ID (\w+)\s/m;
446 1 50       8 $verify->{'key_id'} = $1 if $1;
447 1         6 $error =~ /\sSignature made (.*) using\s/m;
448 1 50       85 $verify->{'sig_date'} = $1 if $1;
449              
450 1         8 $verify->{'text'} = $output;
451              
452 1         65 return $verify;
453             }
454              
455             ### list_keys ##############################################
456              
457 0     0 0 0 sub build_list_keys { my ($text) = @_;
458 0         0 my $list = [];
459 0         0 my $last_key_sig = [];
460 0         0 for my $i (split(/\n/,$text)) {
461 0         0 my @line = split(/\:/,$i);
462 0 0       0 next if @line < 3; # not a descriptor line...
463              
464 0         0 my $hash = {};
465 0         0 $hash->{'type'} = $line[0];
466 0         0 $hash->{'trust'} = $line[1];
467 0         0 $hash->{'key_size'} = $line[2];
468 0         0 $hash->{'algo'} = $line[3];
469 0         0 $hash->{'key_id'} = $line[4];
470 0         0 $hash->{'created'} = $line[5];
471 0         0 $hash->{'expiration'} = $line[6];
472 0         0 $hash->{'local_id'} = $line[7];
473 0         0 $hash->{'ownertrust'} = $line[8];
474 0         0 $hash->{'user_id'} = $line[9];
475              
476 0 0 0     0 $hash->{'trust'} = 0 if !$line[1] || ($line[1] ne 'm' && $line[1] ne 'f' && $line[1] ne 'u'); # no trust
      0        
      0        
477 0 0 0     0 $hash->{'sig'} = [] and $last_key_sig = $hash->{'sig'} if $hash->{'type'} ne 'sig';
478 0 0 0     0 push @$last_key_sig,$hash and next if $hash->{'type'} eq 'sig';
479            
480 0         0 push @$list,$hash;
481             }
482 0         0 return $list;
483             }
484              
485 1     1 1 102 sub list_keys { my ($this) = @_;
486 1         11 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
487             "--with-colons --list-keys", "");
488 1 50       17 return if !$pid;
489 1 50 50     22 $this->error($error) and return if $error;
490              
491 0         0 return build_list_keys($output);
492             }
493              
494              
495             ### list_sig ##############################################
496              
497 1     1 1 114 sub list_sig { my ($this) = @_;
498 1         13 my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
499             "--with-colons --list-sig", "");
500 1 50       18 return if !$pid;
501 1 50 50     24 $this->error($error) and return if $error;
502 0           return build_list_keys($output);
503             }
504              
505              
506             ### PROTOTYPE ##############################################
507              
508 0     0 0   sub prototype { my ($this) = @_;
509 0           return; # XXX 'prototype' : only as example if you would add new function
510 0           my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
511             "--passphrase-fd 0", "passphrase here...");
512 0 0         return if !$pid;
513 0 0 0       $this->error($error) and return if $error;
514              
515 0           return $output;
516             }
517              
518              
519             ### delete_key #############################################
520              
521 0     0 1   sub delete_key { my ($this,$key_id) = @_;
522 0 0         CORE::warn "Not yet implemented - read the doc please." and return;
523              
524 0           my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
525             "--delete-key $key_id", "y\n");
526 0 0         return if !$pid;
527              
528 0 0 0       $this->error($error) and return if $error;
529             }
530              
531              
532             ### delete_secret_key ######################################
533              
534 0     0 1   sub delete_secret_key { my ($this,$key_id) = @_;
535 0 0         CORE::warn "Not yet implemented - read the doc please." and return;
536              
537 0           my ($pid,$output,$error) = start_gpg($this,$this->{'COMMAND'}.
538             "--delete-secret-key $key_id", "y\n");
539 0 0         return if !$pid;
540              
541 0 0 0       $this->error($error) and return if $error;
542             }
543              
544              
545             =head1 NAME
546              
547             GPG - a Perl2GnuPG interface
548              
549             =head1 DESCRIPTION
550              
551             GPG.pm is a Perl5 interface for using GnuPG. GPG works with $scalar (string),
552             as opposed to the existing Perl5 modules (GnuPG.pm and GnuPG::Interface, which
553             communicate with gnupg through filehandles or filenames)
554              
555              
556             =head1 SYNOPSIS
557              
558             use GPG;
559              
560             my ($passphrase,$key_id) = ("1234567890123456",'');
561              
562             my $gpg = new GPG(homedir => './test'); # Creation
563              
564             die $gpg->error() if $gpg->error(); # Error handling
565              
566             my ($pubring,$secring) = $gpg->gen_key(key_size => "512",
567             real_name => "Joe Test",
568             email => 'nobody@yahoo.com',
569             comment => "",
570             passphrase => $passphrase);
571              
572             my $pubkey = $gpg->list_packets($pubring);
573             my $seckey = $gpg->list_packets($secring);
574             $key_id = $pubkey->[0]{'key_id'};
575              
576              
577             $gpg->import_keys($secring);
578             $gpg->import_keys($pubring);
579              
580             my $signed = $gpg->clearsign($key_id,$passphrase,"TEST_TEXT");
581             my $verify = $gpg->verify($signed);
582              
583             my $TEST_TEXT = $gpg->encrypt("TEST_TEXT",$key_id);
584             $TEST_TEXT = $gpg->decrypt($passphrase,$TEST_TEXT);
585              
586             $TEST_TEXT = $gpg->sign_encrypt($key_id,$passphrase,$TEST_TEXT,$key_id);
587             my $decrypt_verify = $gpg->decrypt_verify($passphrase,$TEST_TEXT);
588              
589             my $keys = $gpg->list_keys();
590             my $sigd = $gpg->list_sig();
591              
592              
593             =head1 INSTALLATION
594              
595             % perl Makefile.PL
596             % make
597             % make test
598             % make install
599              
600             Tips :
601             - if you want secure memory, do not forget :
602             % chown root /usr/bin/gpg ; chmod 4755 /usr/local/bin/gpg
603              
604             =head1 METHODS
605              
606             Look at the "test.pl" and "quick_test.pl" for examples and futher explanations.
607              
608             You can set "VERBOSE" in "test.pl" to "1" and restart the test, to see more extensive output.
609              
610             =over 4
611              
612             =item I
613              
614             Parameters are :
615             - gnupg_path (most of time, 'gpg' stand inside /usr/bin)
616             - homedir (gnupg homedir, default is $HOME/.gnupg)
617             - config (gnupg config file)
618             - armor (armored if 1, DEFAULT IS *1* !)
619             - debug (1 for debugging, default is 0)
620              
621             =item I
622              
623             Parameters are :
624             - key_size (see gnupg doc)
625             - real_name (usually first name and last name, must not be empty)
626             - email (email address, must not be empty)
627             - comment (may be empty)
628             - passphrase (*SHOULD* be at least 16 chars long...)
629              
630             Please note that the keys are not imported after creation, please read "test.pl" for an example,
631             or read the description of the "list_packets" method.
632              
633             =item I
634              
635             Output a packet description for public and secret keys, run "test.pl"
636             with "VERBOSE=1" for a better description.
637              
638             =item I
639              
640             Import the key(s) into the current keyring.
641              
642             =item I
643              
644             Clearsign the current text.
645              
646             =item I
647              
648             Make a detached signature of the current text.
649              
650             =item I
651              
652             Verify a signature.
653              
654             =item I
655              
656             Verify signature of a all files from stdin, faster than verify() method.
657              
658             =item I
659              
660             Encrypt.
661              
662             =item I
663              
664             Decrypt (yes, really).
665              
666             =item I
667              
668             Sign and Encrypt.
669              
670             =item I
671              
672             Decrypt and verify signature.
673              
674             =item I
675              
676             List all keys from your standard pubring
677              
678             =item I
679              
680             List all keys and signatures from your standard pubring
681              
682             =item I
683              
684             No yet implemented, gnupg doesn't accpt this in batch mode.
685              
686             =item I
687              
688             No yet implemented, gnupg doesn't accept this in batch mode.
689              
690             =back
691              
692             =head1 FAQ
693              
694             Q: How does it work ?
695             A: it uses IPC::Open3 to connect the 'gpg' program.
696             IPC::Open3 is executing the fork and managing the filehandles for you.
697              
698             Q: How secure is GPG ?
699             A: As secure as you want... Be carefull. First, GPG is no
700             more securer than 'gpg'.
701             Second, all passphrases are stored in non-secure memory, unless
702             you "chown root" and "chmod 4755" your script first. Third, your
703             script probably store passpharses somewhere on the disk, and
704             this is *not* secure.
705              
706             Q: Why using GPG, and not GnuPG or GnuPG::Interface ??
707             A: Because of their input/output facilities,
708             GnuPG.pm only works on filenames.
709             GnuPG::Interface works with fileshandles, but is hard to use - all filehandle
710             management is left up to the user. GPG is working with $scalar only for both
711             input and output. Since I am developing for a web interface, I don't want to
712             write new files each time I need to communicate with gnupg.
713              
714              
715             =head1 KNOWN BUGS
716              
717             Currently known bugs are caused by gnupg (www.gnupg.org) and *not* by GPG.pm :
718              
719             - the methods "delete_key" and "delete_secret_key" do not work,
720             Not because of a bug but because gnupg cannot do that in batch mode.
721             - sign_key() and lsign_key() : "gpg: can't do that in batchmode"
722             - verify() and verify_files() output only the wrong file, even only one has
723             a wrong signature. Other files are ignored.
724              
725             I hope a later version of gnupg will correct this issues...
726              
727             =head1 TODO
728              
729             see CHANGES.txt.
730              
731             most of awaiting changes cannot be done until gnupg itself
732             get an extented batch mode (currently very limited)
733              
734             =head1 SUPPORT
735              
736             Feel free to send me your questions and comments.
737              
738             Feedback is ALWAYS welcome !
739              
740             Commercial support on demand, but for most problems read the "Support" section
741             on http://www.gnupg.org.
742              
743             =head1 DOWNLOAD
744              
745             CPAN : ${CPAN}/authors/id/M/MI/MILES/
746              
747             sourceforge : https://sourceforge.net/project/filelist.php?group_id=8630
748              
749             developpers info at https://sourceforge.net/projects/gpg
750              
751             doc and home-page at http://gpg.sourceforge.net/ (this document)
752              
753             =head1 DEVELOPPEMENT
754              
755             CVS access :
756            
757             look at http://acity.sourceforge.net/devel.html
758             ... and replace "agora" or "acity" by "gpg".
759              
760              
761             =head1 SEE ALSO
762              
763             GnuPG - http://www.gnupg.org
764             GnuPG.pm - input/output only through file_names
765             GnuPG::Interface - input/output only through file_handles
766             see http://GnuPG-Interface.sourceforge.net/ or CPAN
767             IPC::Open3 - communication with 'gpg', see "perldoc perlipc"
768              
769             =head1 AUTHOR
770              
771             miles@_REMOVE_THIS_users.sourceforge.net, pf@_REMOVE_THIS_spin.ch
772             extra thanks to tpo_at_spin
773              
774             =cut
775             1; # End.