GnuPG

 view release on metacpan or  search on metacpan

ChangeLog  view on Meta::CPAN


	* GnuPG.pm: Updated copyrigh notice.
	(check_sig): Ignore patent warnings. Thanks goes to
	Nuutti Kotivuori <nuutti.kotivuori@sonera.com> for spotting
	that bug.
	(decrypt): Fixes for gnupg 1.02 protocol changes.
	(import_keys): Fixes for gnupg 1.02 protocol changes.

	* README: Updated copyrigh notice.

	* gpgmailtunl: Updated copyrigh notice.

	* GnuPG/Tie.pm: Updated copyrigh notice.

	* GnuPG/Tie/Decrypt.pm: Updated copyrigh notice.

	* GnuPG/Tie/Encrypt.pm: Updated copyrigh notice.

2000-06-21  Francis J. Lacoste  <francis.lacoste@iNsu.COM>


ChangeLog  view on Meta::CPAN


	* NEWS:		    Added a news file.

	* GnuPG/Tie.pm(new): Make sure that pipes aren't closed after an
			    exec and that they are unbuffered. Also use
			    CORE::Exit(0) instead of exit(0) so that the
			    things works under mod_perl.
			    (version): Upgraded to version 0.04.

	* GnuPG.pm (new):   Specifying gnupg_path wasn't working properly.
			    When gpg isn't found in PATH print the content
			    of PATH in the error message.
			    (run_gnupg): /dev/null wasn't open for
			    writing. Use CORE::exit(1) so that the
			    function still works under mod_perl.

1999-11-30  Francis J. Lacoste  <francis.lacoste@iNsu.COM>

	* GnuPG.pm (pod):   Inserted a line before a =over line. Added
			    reference to documentation on tied file handle
			    operations.

ChangeLog  view on Meta::CPAN

	* GnuPG/Tie/Encrypt.pm: Added decryption on a tied filehandle.

	* GnuPG/Tie.pm:	    Added abstract implementation for tied
			    filehandle operations on GnuPG.

1999-09-22  Francis J. Lacoste  <francis.lacoste@iNsu.COM>

	* GnuPG.pm:	    Unloop single line for to support
			    perl 5.004. (Thanks to David E. Weekly)

	* gpgmailtunl:	    Insert blank line between =pod and
			    first header. This broke pod2man.
			    (Thanks to David E. Weekly)

1999-09-08  Francis J. Lacoste  <francis.lacoste@iNsu.COM>

	* TAG:		    GNUPG_0_02

	* GnuPG.pm:	    Removed colons from tag names.

	* GnuPG.pm(run_gnupg): Handled input and output from
			    file handle correctly.

	* GnuPG.pm(abort_gnupg): Aborting now correctly throws
			    the error message.


	* gpgmailtunl:	    Added as sample program.

1999-09-05  Francis J. Lacoste  <francis.lacoste@iNsu.COM>

	* GnuPG.pm:  Release 0.01.


GnuPG.pm  view on Meta::CPAN

      or croak "error while closing pipe: $!\n";

    print STDERR "GnuPG: closing command fd " . fileno ($self->{command_fd})
      . "\n"
    if $self->{trace};

    close $self->{command_fd}
      or croak "error while closing pipe: $!\n";

    waitpid $self->{gnupg_pid}, 0
      or croak "error while waiting for gpg: $!\n";


    for ( qw(protocol gnupg_pid command options args status_fd command_fd 
             input output next_status ) )
    {
    delete $self->{$_};
    }

}

GnuPG.pm  view on Meta::CPAN

    }# Defaults to stdin

    # This is where the output goes
    if ( ref $self->{output} && defined fileno $self->{output} ) {
        open ( STDOUT, ">&" . fileno $self->{output} )
          or die "can't redirect stdout to proper output fd: $!\n";
    } elsif ( $self->{output} && -t STDOUT ) {
        open ( STDOUT, ">".$self->{output} )
          or die "can't open $self->{output} for output: $!\n";
    } elsif ( $self->{output} ) {
      my $gpg = shift(@{$cmdline});
      unshift(@{$cmdline}, '--output', $self->{output});
      unshift(@{$cmdline}, $gpg);
    } # Defaults to stdout

    # Close all open file descriptors except STDIN, STDOUT, STDERR
    # and the status filedescriptor.
    #
    # This is needed for the tie interface which opens pipes which
    # some ends must be closed in the child.
    #
    # Besides this is just plain good hygiene
    my $max_fd = POSIX::sysconf( &POSIX::_SC_OPEN_MAX ) || 256;

GnuPG.pm  view on Meta::CPAN

    croak ( "Invalid home directory: $args{homedir}\n")
      unless -d $args{homedir} && -x _;
    $self->{homedir} = $args{homedir};
    }
    if ($args{options}) {
    croak ( "Invalid options file: $args{options}\n")
      unless -r $args{options};
    $self->{options} = $args{options};
    }
    if ( $args{gnupg_path} ) {
    croak ( "Invalid gpg path: $args{gnupg_path}\n")
      unless -x $args{gnupg_path};
    $self->{gnupg_path} = $args{gnupg_path};
    } else {
    my ($path) = grep { -x "$_/gpg" } split /:/, $ENV{PATH};
    croak ( "Couldn't find gpg in PATH ($ENV{PATH})\n" )
      unless $path;
    $self->{gnupg_path} = "$path/gpg";
    }
    $self->{trace} = $args{trace} ? 1 : 0;

    bless $self, $class;
}

sub DESTROY {
    my $self = shift;
    # Signal our child that it is the end
    if ($self->{gnupg_pid} && kill 0 => $self->{gnupg_pid} ) {

GnuPG.pm  view on Meta::CPAN

=pod

=head1 NAME

GnuPG - Perl module interface to the GNU Privacy Guard (v1.x.x series)

=head1 SYNOPSIS

    use GnuPG qw( :algo );

    my $gpg = new GnuPG();

    $gpg->encrypt(  plaintext    => "file.txt",    output        => "file.gpg",
            armor    => 1,         sign    => 1,
            passphrase  => $secret );

    $gpg->decrypt( ciphertext    => "file.gpg",    output        => "file.txt" );

    $gpg->clearsign( plaintext => "file.txt", output => "file.txt.asc",
             passphrase => $secret,   armor => 1,
            );

    $gpg->verify( signature => "file.txt.asc", file => "file.txt" );

    $gpg->gen_key( name => "Joe Blow",        comment => "My GnuPG key",
           passphrase => $secret,
            );

=head1 DESCRIPTION

GnuPG is a perl interface to the GNU Privacy Guard. It uses the
shared memory coprocess interface that gpg provides for its
wrappers. It tries its best to map the interactive interface of
the gpg to a more programmatic model.

=head1 API OVERVIEW

The API is accessed through methods on a GnuPG object which is
a wrapper around the B<gpg> program.  All methods takes their
argument using named parameters, and errors are returned by
throwing an exception (using croak).  If you wan't to catch
errors you will have to use eval.

When handed in a file handle for input or output parameters
on many of the functions, the API attempts to tie that 
handle to STDIN and STDOUT. In certain persistent environments 
(particularly a web environment), this will not work. This 
problem can be avoided by passing in file names to all 
relevant parameters rather than a Perl file handle. 

There is also a tied file handle interface which you may find more
convenient for encryption and decryption. See GnuPG::Tie(3) for details.

=head1 CONSTRUCTOR

=head2 new ( [params] )

You create a new GnuPG wrapper object by invoking its new method.
(How original !).  The module will try to finds the B<gpg> program
in your path and will croak if it can't find it. Here are the
parameters that it accepts :

=over

=item gnupg_path

Path to the B<gpg> program.

=item options

Path to the options file for B<gpg>. If not specified, it will use
the default one (usually F<~/.gnupg/options>).

=item homedir

Path to the B<gpg> home directory. This is the directory that contains
the default F<options> file, the public and private key rings as well
as the trust database.

=item trace

If this variable is set to true, B<gpg> debugging output will be sent
to stderr.

=back

    Example: my $gpg = new GnuPG();

=head1 METHODS

=head2 gen_key( [params] )

This methods is used to create a new gpg key pair. The methods croaks
if there is an error. It is a good idea to press random keys on the
keyboard while running this methods because it consumes a lot of
entropy from the computer. Here are the parameters it accepts :

=over

=item algo

This is the algorithm use to create the key. Can be I<DSA_ELGAMAL>,
I<DSA>, I<RSA_RSA> or I<RSA>.

GnuPG.pm  view on Meta::CPAN


Optional comment portion of the user id.

=item passphrase

The passphrase that will be used to encrypt the private key. Optional
but strongly recommended.

=back

    Example: $gpg->gen_key( algo => DSA_ELGAMAL, size => 1024,
                name => "My name" );

=head2 import_keys( [params] )

Import keys into the GnuPG private or public keyring. The method
croaks if it encounters an error. It returns the number of
keys imported. Parameters :

=over

=item keys

Only parameter and mandatory. It can either be a filename or a
reference to an array containing a list of files that will be
imported.

=back

    Example: $gpg->import_keys( keys => [ qw( key.pub key.sec ) ] );

=head2 export_keys( [params] )

Exports keys from the GnuPG keyrings. The method croaks if it
encounters an error. Parameters :

=over

=item keys

GnuPG.pm  view on Meta::CPAN

a file name or a reference to a file handle. If not specified, the
keys will be exported to stdout.

=item armor

Set this parameter to true, if you want the exported keys to be ASCII
armored.

=back

    Example: $gpg->export_keys( armor => 1, output => "keyring.pub" );


=head2 encrypt( [params] )

This method is used to encrypt a message, either using assymetric
or symmetric cryptography. The methods croaks if an error is
encountered. Parameters:

=over

GnuPG.pm  view on Meta::CPAN

used. This option only makes sense when using the I<sign> option.

=item passphrase

This parameter contains either the secret passphrase for the symmetric
algorithm or the passphrase that should be used to decrypt the private
key.

=back

    Example: $gpg->encrypt( plaintext => file.txt, output => "file.gpg",
                sign => 1, passphrase => $secret
                );

=head2 sign( [params] )

This method is used create a signature for a file or stream of data.
This method croaks on errors. Parameters :

=over

GnuPG.pm  view on Meta::CPAN

to make the signature . If left unspecified, the default user will be
used.

=item detach-sign

If set to true, a digest of the data will be signed rather than
the whole file.

=back

    Example: $gpg->sign( plaintext => "file.txt", output => "file.txt.asc",
             armor => 1,
             );

=head2 clearsign( [params] )

This methods clearsign a message. The output will contains the original
message with a signature appended. It takes the same parameters as
the B<sign> method.

=head2 verify( [params] )

GnuPG.pm  view on Meta::CPAN

The fingerprint of the signature.

=item trust

The trust value of the public key of the signer. Those are values that
can be imported in your namespace with the :trust tag. They are
(TRUST_UNDEFINED, TRUST_NEVER, TRUST_MARGINAL, TRUST_FULLY, TRUST_ULTIMATE).

=back

    Example : my $sig = $gpg->verify( signature => "file.txt.asc",
                      file => "file.txt" );

=head2 decrypt( [params] )

This method decrypts an encrypted message. It croaks, if there is an
error while decrypting the message. If the message was signed, this
method also verifies the signature. If decryption is sucessful, the
method either returns the valid signature parameters if present, or
true. Method parameters :

GnuPG.pm  view on Meta::CPAN


=item passphrase

The passphrase that should be used to decrypt the message (in the case
of a message encrypted using a symmetric cipher) or the secret that
will unlock the private key that should be used to decrypt the
message.

=back

    Example: $gpg->decrypt( ciphertext => "file.gpg", output => "file.txt"
                passphrase => $secret );

=head1 BUGS AND LIMITATIONS

This module doesn't work (yet) with the v2 branch of GnuPG.

=head1 AUTHOR

Francis J. Lacoste <francis.lacoste@Contre.COM>

GnuPG.pm  view on Meta::CPAN

it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

=head1 SEE ALSO

L<GnuPG::Tie>

Alternative module: L<GnuPG::Interface>

gpg(1) 

=cut

GnuPG.spec  view on Meta::CPAN

Copyright: GPL
Group: Development/Languages
Prefix: /usr
URL: http://www.cpan.org/modules/by-module/GnuPG/%{name}-%{version}.readme
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildArchitectures: noarch
Requires: gnupg >= 1.0

%description
GnuPG is a perl interface to the GNU Privacy Guard. It uses the shared
memory coprocess interface that gpg provides for its wrappers. It
tries its best to map the interactive interface of gpg to a more
programmatic model.

%prep
%setup -q
%fix_perl_path

%build
perl Makefile.PL 
make OPTIMIZE="$RPM_OPT_FLAGS"
make test

GnuPG.spec  view on Meta::CPAN

* Mon Dec 06 1999  Francis J. Lacoste <francis.lacoste@iNsu.COM> 
  [0.04-1i]
- Updated to version 0.04.

* Tue Nov 30 1999  Francis J. Lacoste <francis.lacoste@iNsu.COM> 
  [0.03-1i]
- Updated to version 0.03.

* Wed Sep 08 1999  Francis J. Lacoste <francis.lacoste@iNsu.COM> 
  [0.02-1i]
- Added gpgmailtunl and its man pages.
- Updated to version 0.02.

* Sun Sep 05 1999 Francis J. Lacoste <francis.lacoste@iNsu.COM>
  [0.01-1i]
- Packaged for iNs/linux


GnuPG/Tie.pm  view on Meta::CPAN

use Carp;

use Fcntl;

use strict;

sub TIEHANDLE {
    my $class = shift;
    $class = ref $class || $class;

    my ($gpg_in, $gpg_out)  = ( gensym, gensym );
    my ($tie_in,$tie_out)   = ( gensym, gensym );
    pipe $gpg_in, $tie_out
      or croak "error while creating pipe: $!";
    pipe $tie_in, $gpg_out
      or croak "error while creating pipe: $!";

    # Unbuffer writer pipes
    for my $fd ( ($gpg_out, $tie_out) ) {
	my $old = select $fd;
	$| = 1;
	select $old;
    }

    # Keep pipes open after exec
    # Removed close on exec from all file descriptor
    for my $fd ( ( $gpg_in, $gpg_out, $tie_in, $tie_out ) ) {
	fcntl( $fd, F_SETFD, 0 )
	  or croak "error removing close on exec flag: $!\n" ;
    }

    # Operate in non blocking mode
    for my $fd ( $tie_in, $tie_out ) {
	my $flags = fcntl $fd, F_GETFL, 0
	  or croak "error getting flags on pipe: $!\n";
	fcntl $fd, F_SETFL, $flags | O_NONBLOCK
	  or croak "error setting non-blocking IO on pipe: $!\n";

GnuPG/Tie.pm  view on Meta::CPAN

		       len	    => 0,
		       offset	    => 0,
		       line_buffer  => "",
		       eof	    => 0,
		       gnupg	    => new GnuPG( @_ ),
		     }, $class;

    # Let subclass call the appropriate method and set
    # up the GnuPG object.
    $self->run_gnupg( @_,
		      input	=> $gpg_in,
		      output	=> $gpg_out,
		      tie_mode	=> 1,
		    );
    close $gpg_in;
    close $gpg_out;

    return $self;
}

sub WRITE {
    my ( $self, $buf, $len, $offset ) = @_;

    croak "attempt to read on a closed file handle\n"
      unless defined $self->{writer};

GnuPG/Tie.pm  view on Meta::CPAN

Copyright (c) 1999, 2000 iNsu Innovations Inc.
Copyright (c) 2001 Francis J. Lacoste

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

=head1 SEE ALSO

gpg(1) GnuPG(3)

=cut

MANIFEST  view on Meta::CPAN

COPYING
NEWS
ChangeLog
gpgmailtunl
GnuPG.pm
GnuPG/Tie.pm
GnuPG/Tie/Encrypt.pm
GnuPG/Tie/Decrypt.pm
GnuPG/Tie/ClearSign.pm
GnuPG/Tie/Sign.pm
GnuPG.spec
MANIFEST
README
Makefile.PL

Makefile.PL  view on Meta::CPAN

use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'	=> 'GnuPG',
    'VERSION_FROM' => 'GnuPG.pm', # finds $VERSION
    'EXE_FILES'	=> [ gpgmailtunl ],
);

NEWS  view on Meta::CPAN

----------------------------------

	* Fix  POSIX::_SC_OPEN_MAX problem under use strict.

----------------------------------
Noteworthy changes in version 0.08 (2001-05-21)
----------------------------------

	* Updated for gnupg 1.0.5
	* Tie implementation doesn't add an extra fork. Only one 
	fork for the gpg process is done.
	* Added ClearSign and Sign tie interface.

----------------------------------
Noteworthy changes in version 0.07 (2000-08-15)
----------------------------------

	* Output to a file handle reference was broken.

----------------------------------
Noteworthy changes in version 0.06 (2000-08-06)
----------------------------------

	* Local-user wasn't working. Thanks to Chris Andrews for
	  reporting and fixing this.
	* Compatible with gpg 1.02.
	* Ignore warning about RSA or IDEA algorithms.

Noteworthy changes in version 0.05 (2000-06-21)
-----------------------------------

	* Support for paragraph mode in tied interface. 
	* Removed file descriptor leaks.
	* Made CPR interface more robust.

Noteworthy changes in version 0.04 (1999-12-06)

README  view on Meta::CPAN

GnuPG
=====

Version: 0.9

Requirements
------------

perl
gpg 1.0.0 or later. (Version 1.05 recommanded)
SysV compatible shared memory.

Description
-----------

GnuPG is a perl module that interface with the Gnu Privacy Guard using
the coprocess hooks provided by gpg. The communication mechanism uses
is shared memory and a status file descriptor.

There are others perl interface to PGP and GnuPG but none of them
used the coprocess interface  provided by gpg.

The module tries it best to map the rather interactive interface
of gpg to a more programmatic API.

Also the modules now offers a tied file handle interface to encryption
and decryption making a lot more easy to use.

Installing
----------

The usual:

    perl Makefile.PL

README  view on Meta::CPAN


Documentation
-------------

Documentation is included in POD format.

Limitations
-----------

This module doesn't yet provides an interface to the key manipulation
facilities of gpg.

It doesn't also provides the memory protection offered by gpg when
manipulating user passphrase.

There are also several options (like cipher selections) that aren't
available from the perl API.

Bugs
----

Send bug reports and suggestions to <bugs@Contre.COM>

gpgmailtunl  view on Meta::CPAN

#!/usr/bin/perl
#
#    gpgmailtunl - Program that sends encrypted email.
#
#    This file is part of GnuPG.pm.
#
#    Author: Francis J. Lacoste <francis.lacoste@iNsu.COM>
#
#    Copyright (C) 1999, 2000 iNsu Innovations Inc.
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or

gpgmailtunl  view on Meta::CPAN

#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

use strict;

use GnuPG;
use Getopt::Long;

sub usage() {
    die <<EOF;
usage: gpgmailtunl [ options ] --encrypt        or
       gpgmailtunl [ options ] --decrypt
EOF
  exit(64);
}

sub bounce(@) {
    print STDERR "gpgmailtunl: ", @_, "\n";
    exit( 64 );
};

sub read_secret($) {
    open SECRET, shift
      or bounce( "error opening secret file for reading: $!" );
    my $secret = <SECRET>;
    close SECRET;
    chomp $secret;

    return $secret;
}

sub encrypt($\%) {
    my ( $gpg, $opts ) = @_;

    my $from = $opts->{from};
    $opts->{subject}	||= "Encrypted mail";
    $opts->{recipient}	||= $opts->{to};
    my $cmd = "/usr/sbin/sendmail -oi -t";
    $cmd .= " -F\"$from\"" if $from;
    open( SENDMAIL, "|". $cmd )
      or bounce( "error opening pipe to sendmail: $!" );
    select SENDMAIL; $| = 1;
    print SENDMAIL "From: $from\n" if $from;
    print SENDMAIL <<EOF;
To:	    $opts->{to}
Subject:    $opts->{subject}


EOF
    eval {
	$gpg->encrypt( output => \*SENDMAIL, armor => 1,
		       sign		=> $opts->{sign}, 
		       passphrase	=> $opts->{passphrase},
		       recipient	=> $opts->{recipient},
		       "local-user"	=> $opts->{"local-user"},
		     );
    };
    bounce ( $@ ) if $@;
    close SENDMAIL
      or bounce( "error while waiting for sendmail: $!" );
    exit 0;
};

sub decrypt($\%) {
    my ( $gpg, $opts ) = @_;

    open( SENDMAIL, "|/usr/sbin/sendmail -oi -t" )
      or bounce( "error opening pipe to sendmail: $!" );
    select SENDMAIL; $| = 1;
    eval {
	$gpg->decrypt( output => \*SENDMAIL,
		       passphrase => $opts->{passphrase},
		     );
    };
    bounce ( $@ ) if $@;
    close SENDMAIL
      or bounce( "error while waiting for sendmail: $!" );
    exit 0;
}

my %opt = ();

gpgmailtunl  view on Meta::CPAN

	    if $opt{$_} } qw( to from subject sign recipient local-user );
} elsif ( $opt{encrypt} ) {
    bounce( "missing to option" ) unless  $opt{to};
} else {
    bounce( "missing encrypt or decrypt" );
}

$opt{passphrase} = read_secret( $opt{"secret-file"})
  if $opt{"secret-file"};

my $gpg = new GnuPG( homedir => $opt{homedir} );

if ($opt{encrypt}) {
    encrypt $gpg, %opt;
} else {
    decrypt $gpg, %opt;
}

__END__

=pod

=head1 NAME

gpgmailtunl - Encrypts an email message into the body of another email.

=head1 SYNOPSIS

gpgmailtunl [options] --encrypt | --decrypt

=head1 DESCRIPTION

B<gpgmailtunl> is a filter program that either encrypts an email message
using the Gnu Privacy Guard and sends it to another recipient or decrypt
an email message and forwards unencrypted to another destination.

It can be used to exchange emails across an open network betweeen two
trusted systems.

=head1 TYPICAL USAGE

This program is intended to run from program like B<procmail> or
B<sendmail> to create an email tunnel between two systems.  Of course
this is not as secure as using B<gpg> as an end user program, it may
be convenient in certain case.

=head1 ENCRYPTION

To encapsulates an email within another you pipe the message to 
B<gpgmailtunl>.

=head2 OPTIONS

GetOptions( \%opt, "encrypt", "decrypt", "sign", "secret-file=s",
	    "from=s", "to=s", "subject=s", "homedir=s", "local-user=s",
	    "recipient=s",
	  )
  or usage;

=over

=item to

This is the address to which the encrypted message will be sent. This
is the only required fields. 

=item recipient

This sets the keyid that will be used to encrypt the outgoing message.
If unset, B<gpgmailtunl> will try to find a key matching the B<to> 
option.

=item subject

Sets the subject of the outgoing message. This defaults to 
"Encrypted mail".

=item from

Sets the From header line of the outgoing message which will contains

gpgmailtunl  view on Meta::CPAN

File from which the secret to unlock the private used to sign the
message can be read.

=item local-user

The keyid of the user that should sign the outgoing message. The 
default user will be used if not specified.

=item homedir

Sets an alternate B<gpg> home directory. (This is where the
keyrings are stored.)

=back

=head1 DECRYPTION

To extract an email to be forwarded to the final user you pipe
the encrypted email to B<gpgmailtunl> using the B<decrypt> switch.

Once decrypted, the encapsulated email message will be sent to the
original destinator of the message.

=head2 OPTIONS

=over

=item homedir

Sets an alternate B<gpg> home directory. (This is where the
keyrings are stored.)

=item secret-file

File from which the secret to unlock the private used to decrypt the
message can be read.

=back

=head1 AUTHOR

gpgmailtunl  view on Meta::CPAN


Copyright (c) 1999, 2000 iNsu Innovations Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

=head1 SEE ALSO

gpg(1) gpgmailtunl(1) GnuPG(3)

=cut

test.pl  view on Meta::CPAN

                tie_decrypt_para_mode_test
                multiple_recipients 
    	        );

if ( defined $ENV{TESTS} ) {
    @tests = split /\s+/, $ENV{TESTS};
}

plan tests => scalar @tests;

my $gpg = new GnuPG( homedir => "test", trace => $ENV{TRACING} );

for ( @tests ) {
    eval {
	    no strict 'refs';   # We are using symbolic references
	    &$_();
    };

    (ok !$@, $_) || diag $@;
}

sub multiple_recipients {
    $gpg->encrypt(
          recipient => [ USERID, UNTRUSTED ],
		  output    => "test/file.txt.gpg",
		  armor	    => 1,
		  plaintext => "test/file.txt",
    );

    open my $fh, '<', "test/file.txt.gpg";

    die "'test/file.txt.gpg' is empty\n" unless -s 'test/file.txt.gpg';

}


sub gen_key_test {
    diag "Generating a key - can take some time";
    $gpg->gen_key(
		  passphrase => PASSWD,
		  name	     => USERID,
    );
}

sub import_test {
    $gpg->import_keys( keys => "test/key1.pub" );
}

sub import2_test {
    $gpg->import_keys( keys => "test/key1.pub" );
}

sub import3_test {
    $gpg->import_keys( keys => [ qw( test/key1.pub test/key2.pub ) ] );
}
sub export_test {
    $gpg->export_keys( keys	=> USERID,
		       armor	=> 1,
		       output	=> "test/key.pub",
		     );
}

sub export2_test {
    $gpg->export_keys( armor	=> 1,
		       output	=> "test/keyring.pub",
		     );
}

sub export_secret_test {
    $gpg->export_keys( secret	=> 1,
		       armor	=> 1,
		       output	=> "test/key.sec",
		     );
}

sub encrypt_test {
    $gpg->encrypt(
		  recipient => USERID,
		  output    => "test/file.txt.gpg",
		  armor	    => 1,
		  plaintext => "test/file.txt",
		 );
}

sub pipe_encrypt_test {
    open CAT, "| cat > test/pipe-file.txt.gpg"
      or die "can't fork: $!\n";
    $gpg->encrypt(
		  recipient => USERID,
		  output    => \*CAT,
		  armor	    => 1,
		  plaintext => "test/file.txt",
		 );
    close CAT;
}

sub encrypt_sign_test {
    $gpg->encrypt(
		  recipient	=> USERID,
		  output	=> "test/file.txt.sgpg",
		  armor		=> 1,
		  sign		=> 1,
		  plaintext	=> "test/file.txt",
		  passphrase	=> PASSWD,
		 );
}

sub encrypt_sym_test {
    $gpg->encrypt(
		  output	=> "test/file.txt.cipher",
		  armor		=> 1,
		  plaintext	=> "test/file.txt",
		  symmetric	=> 1,
		  passphrase	=> PASSWD,
		 );
}

sub encrypt_notrust_test {
    $gpg->encrypt(
		  recipient	=> UNTRUSTED,
		  output	=> "test/file.txt.dist.gpg",
		  armor		=> 1,
		  sign		=> 1,
		  plaintext	=> "test/file.txt",
		  passphrase	=> PASSWD,
		 );
}

sub sign_test {
    $gpg->sign(
		  recipient	=> USERID,
		  output	=> "test/file.txt.sig",
		  armor		=> 1,
		  plaintext	=> "test/file.txt",
		  passphrase	=> PASSWD,
		 );
}

sub detachsign_test {
    $gpg->sign(
		  recipient	=> USERID,
		  output	=> "test/file.txt.asc",
		  "detach-sign" => 1,
		  armor		=> 1,
		  plaintext	=> "test/file.txt",
		  passphrase	=> PASSWD,
		 );
}

sub clearsign_test {
    $gpg->clearsign(
		    output	=> "test/file.txt.clear",
		    armor	=> 1,
		    plaintext	=> "test/file.txt",
		    passphrase  => PASSWD,
		 );
}

sub decrypt_test {
    $gpg->decrypt(
		    output	=> "test/file.txt.plain",
		    ciphertext	=> "test/file.txt.gpg",
		    passphrase  => PASSWD,
		 );
}
sub pipe_decrypt_test {
    open CAT, "cat test/file.txt.gpg|"
      or die "can't fork: $!\n";
    $gpg->decrypt(
		    output	=> "test/file.txt.plain",
		    ciphertext	=> \*CAT,
		    passphrase  => PASSWD,
		 );
    close CAT;
}

sub decrypt_sign_test {
    $gpg->decrypt(
		    output	=> "test/file.txt.plain2",
		    ciphertext	=> "test/file.txt.sgpg",
		    passphrase  => PASSWD,
		 );
}

sub decrypt_sym_test {
    $gpg->decrypt(
		    output	=> "test/file.txt.plain3",
		    ciphertext	=> "test/file.txt.cipher",
		    symmetric	=> 1,
		    passphrase  => PASSWD,
		 );
}

sub verify_sign_test {
    $gpg->verify( signature	=> "test/file.txt.sig" );
}

sub verify_detachsign_test {
    $gpg->verify( signature	=> "test/file.txt.asc",
		  file		=> "test/file.txt",
		);
}

sub verify_clearsign_test {
    $gpg->verify( signature => "test/file.txt.clear" );
}

sub encrypt_from_fh_test {
    open ( FH, "test/file.txt" )
      or die "error opening file: $!\n";
    $gpg->encrypt(
		  recipient => UNTRUSTED,
		  output    => "test/file-fh.txt.gpg",
		  armor	    => 1,
		  plaintext => \*FH,
		 );
    close ( FH )
      or die "error closing file: $!\n";
}

sub encrypt_to_fh_test {
    open ( FH, ">test/file-fho.txt.gpg" )
      or die "error opening file: $!\n";
    $gpg->encrypt(
		  recipient => UNTRUSTED,
		  output    => \*FH,
		  armor	    => 1,
		  plaintext => "test/file.txt",
		 );
    close ( FH )
      or die "error closing file: $!\n";
}

sub tie_encrypt_test {



( run in 0.952 second using v1.01-cache-2.11-cpan-e1769b4cff6 )