File Coverage

blib/lib/Crypt/SimpleGPG.pm
Criterion Covered Total %
statement 32 72 44.4
branch 6 24 25.0
condition 5 11 45.4
subroutine 7 11 63.6
pod 0 4 0.0
total 50 122 40.9


line stmt bran cond sub pod time code
1             package Crypt::SimpleGPG;
2              
3             =head1 NAME
4              
5             Crypt::SimpleGPG - easy encryption and decryption using GPG
6              
7             =head1 SYNOPSIS
8              
9             =head2 Encrypting
10              
11             my $gpg = Crypt::SimpleGPG->new(home_dir = '/home/user/.gnupg');
12             $gpg->import_key('/path/to/public/key');
13             my $ciphertext = $gpg->encrypt($plaintext, $recipient);
14              
15             =head2 Decrypting
16              
17             my $gpg = Crypt::SimpleGPG->new(home_dir = '/home/user/.gnupg');
18             $gpg->import_key('/path/to/private/key');
19             my $plaintext = $gpg->decrypt($ciphertext, $passphrase);
20              
21             =head1 NOTES
22              
23             C will default to C if not specified in the constructor. You probably don't want this, but it might be okay
24             if you're only using public keys.
25              
26             C will be used to store temporary files when decrypting using a passphrase.
27              
28             =head1 COPYRIGHT
29              
30             Copyright (c) 2010 Corey Cossentino
31              
32             You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.
33              
34             =cut
35              
36 1     1   25113 use strict;
  1         2  
  1         41  
37 1     1   6 use warnings;
  1         1  
  1         30  
38              
39 1     1   1558 use IPC::Run;
  1         87757  
  1         44  
40 1     1   1085 use File::Temp qw(tempfile);
  1         13244  
  1         57  
41 1     1   7 use Carp;
  1         1  
  1         649  
42              
43             our $VERSION = "0.3";
44              
45             my @options = qw( --batch --yes --armor --trust-model always --quiet --no-secmem-warning --no-permission-warning --no-tty --no-greeting );
46              
47             sub new {
48 1     1 0 11 my $self = shift;
49 1   33     6 my $class = ref($self) || $self;
50 1         4 $self = bless {}, $class;
51              
52 1         5 $self->__populate(@_);
53 1         2 return $self;
54             }
55              
56             sub __populate {
57 1     1   2 my $self = shift;
58 1         3 my %args = @_;
59              
60 1   50     11 $self->{home_dir} = $args{home_dir} || "/var/tmp/gnupg";
61 1   50     6 $self->{gpg_path} = $args{gpg_path} || "/usr/bin/gpg";
62 1   50     7 $self->{temp_dir} = $args{temp_dir} || "/var/tmp";
63 1   50     7 $self->{debug} = $args{debug} || 0;
64              
65 1 50       37 if(not -d $self->{home_dir}) {
66 0 0       0 mkdir($self->{home_dir})
67             or confess "$self->{home_dir} is not a valid home directory";
68             }
69              
70 1 50       28 if(not -e $self->{gpg_path}) {
71 0         0 confess "$self->{gpg_path} does not exist";
72             }
73              
74 1 50       23 if(not -x $self->{gpg_path}) {
75 0         0 confess "$self->{gpg_path} is not executable";
76             }
77              
78 1 50       21 if(not -w $self->{home_dir}) {
79 0         0 confess "$self->{home_dir} is not writeable";
80             }
81              
82 1 50       18 if(not -d $self->{temp_dir}) {
83 0         0 confess "$self->{temp_dir} is not a valid directory";
84             }
85              
86 1 50       19 if(not -w $self->{temp_dir}) {
87 0           confess "$self->{temp_dir} is not writeable";
88             }
89             }
90              
91             sub import_key {
92 0     0 0   my $self = shift;
93 0           my $key_fn = shift;
94              
95 0           $self->__run(cmd_args => [ "--import", $key_fn ]);
96             }
97              
98             sub encrypt {
99 0     0 0   my $self = shift;
100 0           my $plaintext = shift;
101 0           my $recipient = shift;
102              
103 0 0         confess "No recipient." if not $recipient;
104              
105 0           my $ciphertext = $self->__run(cmd_args => [ "--output", "-", "--recipient", $recipient, "--encrypt", "-" ], stdin => $plaintext);
106 0           return $ciphertext;
107             }
108              
109             sub decrypt {
110 0     0 0   my $self = shift;
111 0           my $ciphertext = shift;
112 0           my $passphrase = shift;
113            
114 0           my ($encfile_fh, $encfile_fn);
115              
116 0           my $args = [];
117 0 0         if($passphrase) {
118 0           ($encfile_fh, $encfile_fn) = tempfile("gpg_file_XXXXXXXXX", DIR => $self->{temp_dir});
119 0           print $encfile_fh $ciphertext;
120 0           close $encfile_fh;
121              
122 0           my $plaintext = $self->__run(cmd_args => [ "--passphrase-fd", "0", "--output", "-", $encfile_fn ], stdin => $passphrase);
123 0           unlink $encfile_fn;
124              
125 0           return $plaintext;
126             }
127             else {
128 0           my $plaintext = $self->__run(cmd_args => [ "-" ], stdin => $ciphertext);
129 0           return $plaintext;
130             }
131             }
132              
133             sub __run {
134 0     0     my ($self, %args) = @_;
135              
136 0           my ($stdin, $stdout, $stderr);
137 0           my @cmd = ( $self->{gpg_path}, @options, "--homedir", $self->{home_dir}, @{$args{cmd_args}} );
  0            
138              
139 0           my $harness = IPC::Run::start( \@cmd, \$stdin, \$stdout, \$stderr, IPC::Run::timeout(10) );
140 0 0         if($args{stdin}) {
141 0           $stdin .= $args{stdin};
142             }
143              
144 0           $harness->pump();
145 0           $harness->finish();
146              
147 0 0         print STDERR $stderr if $self->{debug};
148 0 0         return wantarray ? ($stdout, $stderr) : $stdout;
149             }
150              
151             1;