in reply to GPG batch mode, GPG.pm, and win32
I had this exact same problem a couple months ago. There are three modules on CPAN that deal with GPG: GPG.pm, GnuPG.pm, and Crypt::GPG.pm. I couldn't get any of them to work, so I wrote my own interface. Here it is:
You should be able to extend this code to call any other GPG methods you desire. The asymmetric methods are in current use, so I'll vouch for their reliability. The symmetric methods worked ok the last time I checked...package GPGWrapper; use IPC::Open2; use IO::File; use POSIX qw(tmpnam); use strict; our @ISA = qw(Exporter); our @EXPORT = qw(GPG_Encrypt GPG_Decrypt GPG_Encrypt_Asym GPG_Decrypt_Asym); our $VERSION = 1.0; # The regular encrypt methods are not in current use because they requ +ire me to write # the data out to a file. This incurs a I/O penalty for no good reaso +n. # The asymmetric methods do this too, but I only call those each once, + # so I don't care about the penalty. # # Actually, there is a good reason: I am unable to pipe in the data st +ream to GPG (although # I _can_ pipe in other things, like the passphrase). Attempting to d +o so hangs the program # indefinately. Incidentally, none of GPG package on CPAN (GPG, GnuPG +, and Crypt::GPG) # solve this problem: GPG also hangs indefinately, GnuPG writes the da +ta to IPC (which Windows lacks), and # Crypt::GPG won't compile on Windows systems. sub GPG_Encrypt($$) { my $passphrase = shift; my $data = shift; my @result; $passphrase .= "\n" if $passphrase !~ /\n$/; my $hackname; my $fh; do { $hackname = tmpnam(); } until $fh = IO::File->new($hackname, O_RDWR | O_CREAT | O_EXCL); binmode($fh); print $fh $data; close $fh; if (eval { open2(*README, *WRITEME, "gpg --no-tty --passphrase-fd +0 --output - --symmetric $hackname"); }) { binmode(README); binmode(WRITEME); print WRITEME $passphrase; close WRITEME; @result = <README>; close README; } wait(); unlink $hackname; return join("", @result); } sub GPG_Decrypt($$) { my $passphrase = shift; my $data = shift; my @result; $passphrase .= "\n" if $passphrase !~ /\n$/; my $hackname; my $fh; do { $hackname = tmpnam(); } until $fh = IO::File->new($hackname, O_RDWR | O_CREAT | O_EXCL); binmode($fh); print $fh $data; close $fh; if (eval { open2(*README, *WRITEME, "gpg --no-tty --passphrase-fd +0 --output - --decrypt $hackname"); }) { binmode(README); binmode(WRITEME); print WRITEME $passphrase; close WRITEME; @result = <README>; close README; } wait(); unlink $hackname; return join("", @result); } # Asymmetric encryption. Used for the handshake. sub GPG_Encrypt_Asym($$) { my $user = shift; # We will encrypt using this user's public ke +y my $data = shift; my @result; my $hackname; my $fh; do { $hackname = tmpnam(); } until $fh = IO::File->new($hackname, O_RDWR | O_CREAT | O_EXCL); binmode($fh); print $fh $data; close $fh; open(README, "gpg --no-tty --quiet --output - --recipient \"$user\ +" --encrypt $hackname |") || die "Error on asymmetric encryption with user $user: $!\n"; binmode(README); @result = <README>; close README; unlink $hackname; return join("", @result); } sub GPG_Decrypt_Asym($) { my $data = shift; my @result; my $hackname; my $fh; do { $hackname = tmpnam(); } until $fh = IO::File->new($hackname, O_RDWR | O_CREAT | O_EXCL); binmode($fh); print $fh $data; close $fh; open(README, "gpg --no-tty --quiet --output - --decrypt $hackname +|") || die "Error on asymmetric decryption: $!\n"; binmode(README); @result = <README>; close README; unlink $hackname; return join("", @result); } 1;
Hope this helps,
-Ton
-----
Be bloody, bold, and resolute; laugh to scorn
The power of man...
|
|---|