Mail-GnuPG

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

  - [RT #60246] Use undecoded text for decode and get_decrypt_key of inline PGP
  - [RT #4388, #2718, #46168]  Add test case for verify of encoded bodies

0.15 Sat Mar  8 19:51:55 PST 2008

  This is the ntyni release, as he provided most of the fixes:
 
  - Fix roundtrip test by trusting test keyring.
  - New test to show blocking issues on large messages.
  - Switch to a non-blocking (select) based mechanism for interacting
    with gpg.

0.10 Mon Jul  9 15:12:10 PDT 2007

  - Fixed "-1" result code from waitpid handling. (On OSX, it can mean 'reaped' not actually an error)

0.09

  - MIME content type of signed portion will be same as content type
    of original message.

Changes  view on Meta::CPAN


  (From Paul J. Schinder)
   - bugfix for encrypt without signing

  (For Jesse)
   - verify(): return uid/email on success
   - new methods: is_signed() and is_encrypted(), which are
     encapsulations of the simple tests for guessing whether something
     is signed or encrypted.

   - get_decrypt_key(): fix for gpg not in current path
   - decrypt(): return uid/email on successful decrypt of signed msg

   - verify() : fix tempfile creation location

0.06   Wed Jul 23 19:59:51 PDT 2003

  (From Jörn Reder)
   - bugfix in decrypt(): with ASCII armor messages the first line of
   the cleartext was removed by MIME::Parser, if the cleartext was no
   entity but simple ASCII text.

README  view on Meta::CPAN

  Mail::GnuPG assumes the signature is calculated on the decoded MIME
  data (which is the only thing it can get from MIME::Entity).  Jörn
  Reder is working on a solution.

TODO

- Get rid of 'cut' dependency.
- Consider nicer/prettier interface
- Use GnuPG::Interface's internal passphrase handling
- Add tests
- Use GnuPG::Handle->{direct} to pass files directly to gpg

AUTHOR

Robert Spier
rspier at cpan.org

MAINTAINER
David Bremner
ddb at cpan.org

lib/Mail/GnuPG.pm  view on Meta::CPAN

use IO::Select;
use Errno qw(EPIPE);

=head2 new

  Create a new Mail::GnuPG instance.

 Arguments:
   Paramhash...

   key    => gpg key id
   keydir => gpg configuration/key directory
   passphrase => primary key password
   use_agent => use gpg-agent if non-zero
   always_trust => always trust a public key
   # FIXME: we need more things here, maybe primary key id.


=cut

sub new {
  my $proto = shift;
  my $class = ref($proto) || $proto;
  my $self  = {
	       key	    => undef,
	       keydir	    => undef,
	       passphrase   => "",
	       gpg_path	    => "gpg",
	       use_agent    => 0,	
	       @_
	      };
  $self->{last_message} = [];
  $self->{plaintext} = [];
  bless ($self, $class);
  return $self;
}

sub _set_options {

lib/Mail/GnuPG.pm  view on Meta::CPAN

#			      ( defined $self->{passphrase} ?
#				( passphrase => $self->{passphrase} ) : () ),
			    );
  if ($self->{use_agent}) {
    push @{$gnupg->options->extra_args}, '--use-agent';
  }

  if (defined $self->{always_trust}) {
    $gnupg->options->always_trust($self->{always_trust})
  }
  $gnupg->call( $self->{gpg_path} ) if defined $self->{gpg_path};
}


=head2 decrypt

 Decrypt an encrypted message

 Input:
   MIME::Entity containing email message to decrypt.

  The message can either be in RFC compliant-ish multipart/encrypted
  format, or just a single part ascii armored message.

 Output:
  On Failure:
    Exit code of gpg.  (0 on success)

  On Success: (just encrypted)
    (0, undef, undef)

  On success: (signed and encrypted)
    ( 0,
      keyid,           # ABCDDCBA
      emailaddress     # Foo Bar <foo@bar.com>
    )

   where the keyid is the key that signed it, and emailaddress is full
   name and email address of the primary uid


  $self->{last_message} => any errors from gpg
  $self->{plaintext}    => plaintext output from gpg
  $self->{decrypted}    => parsed output as MIME::Entity

=cut

sub decrypt {
  my ($self, $message) = @_;
  my $ciphertext = "";

  $self->{last_message} = [];

lib/Mail/GnuPG.pm  view on Meta::CPAN

  	if ( not exists $no_sec_keys{$k} ) {
	  	$key = $k;
		last;
	}
  }

  return if not $key;

  # get mail address of this key
  die "Invalid Key Format: $key" unless $key =~ /^[0-9A-F]+$/i;
  my $cmd = $self->{gpg_path} . " --with-colons --list-keys $key 2>&1";
  my $gpg_out = qx[ $cmd ];
  ## FIXME: this should probably use open| instead.
  die "Couldn't find key $key in keyring" if $gpg_out !~ /\S/ or $?;
  my $mail = (split(":", $gpg_out))[9];

  return ($mail, $key);
}

=head2 verify

 verify a signed message

 Input:
   MIME::Entity containing email message to verify.

lib/Mail/GnuPG.pm  view on Meta::CPAN

  format, or just a single part ascii armored message.

  Note that MIME-encoded data should be supplied unmodified inside
  the MIME::Entity input message, otherwise the signature will be
  broken. Since MIME-tools version 5.419, this can be achieved with
  the C<decode_bodies> method of MIME::Parser. See the MIME::Parser
  documentation for more information.

 Output:
  On error:
    Exit code of gpg.  (0 on success)
  On success
    ( 0,
      keyid,           # ABCDDCBA
      emailaddress     # Foo Bar <foo@bar.com>
    )

   where the keyid is the key that signed it, and emailaddress is full
   name and email address of the primary uid. The email/uid is UTF8
   encoded, as output by GPG.

  $self->{last_message} => any errors from gpg

=cut

# Verify RFC2015/RFC3156 email
sub verify {
  my ($self, $message) = @_;

  my $ciphertext = "";
  my $sigtext    = "";

lib/Mail/GnuPG.pm  view on Meta::CPAN


sub _rebuild_key_cache {
  my $self = shift;
  local $_;
  %key_cache = ();
  my $gnupg = GnuPG::Interface->new();
  $self->_set_options($gnupg);
  my @keys = $gnupg->get_public_keys();
  foreach my $key (@keys) {
    foreach my $uid ($key->user_ids) {
      # M::A may not parse the gpg stuff properly.  Cross fingers
      my ($a) = Mail::Address->parse($uid->as_string); # list context, please
      $key_cache{$a->address}=1 if ref $a;
    }
  }
}

=head2 has_public_key

Does the keyring have a public key for the specified email address? 

lib/Mail/GnuPG.pm  view on Meta::CPAN

}

=head2 mime_sign

  sign an email message

 Input:
   MIME::Entity containing email message to sign

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be signed.  (i.e. it _will_ be modified.)

=cut


sub mime_sign {
  my ($self,$entity) = @_;

  die "Not a mime entity"

lib/Mail/GnuPG.pm  view on Meta::CPAN


=head2 clear_sign

  clearsign the body of an email message

 Input:
   MIME::Entity containing email message to sign.
   This entity MUST have a body.

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be signed.  (i.e. it _will_ be modified.)

=cut

sub clear_sign {
  my ($self, $entity) = @_;
  
  die "Not a mime entity"
    unless $entity->isa("MIME::Entity");

lib/Mail/GnuPG.pm  view on Meta::CPAN


  encrypt an email message body using ascii armor

 Input:
   MIME::Entity containing email message to encrypt.
   This entity MUST have a body.

   list of recipients

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be encrypted.  (i.e. it _will_ be modified.)

=head2 ascii_signencrypt

  encrypt and sign an email message body using ascii armor

 Input:
   MIME::Entity containing email message to encrypt.
   This entity MUST have a body.

   list of recipients

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be encrypted.  (i.e. it _will_ be modified.)

=cut

sub ascii_encrypt {
  my ($self, $entity, @recipients) = @_;
  $self->_ascii_encrypt($entity, 0, @recipients);
}

lib/Mail/GnuPG.pm  view on Meta::CPAN


=head2 mime_encrypt

  encrypt an email message

 Input:
   MIME::Entity containing email message to encrypt
   list of email addresses to sign to

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be encrypted.  (i.e. it _will_ be modified.)

=head2 mime_signencrypt

  sign and encrypt an email message

 Input:
   MIME::Entity containing email message to sign encrypt
   list of email addresses to sign to

 Output:
  Exit code of gpg.  (0 on success)

  $self->{last_message} => any errors from gpg

  The provided $entity will be encrypted.  (i.e. it _will_ be modified.)

=cut

sub mime_encrypt {
  my $self = shift;
  $self->_mime_encrypt(0,@_);
}

lib/Mail/GnuPG.pm  view on Meta::CPAN

# interleave reads and writes
# input parameters: 
#  $rhandles - array ref with a list of file handles for reading
#  $whandles - array ref with a list of file handles for writing
#  $wbuf_of  - hash ref indexed by the stringified handles
#              containing the data to write
# return value:
#  $rbuf_of  - hash ref indexed by the stringified handles
#              containing the data that has been read
#
# read and write errors due to EPIPE (gpg exit) are skipped silently on the
# assumption that gpg will explain the problem on the error handle
#
# other errors cause a non-fatal warning, processing continues on the rest
# of the file handles
#
# NOTE: all the handles get closed inside this function

sub _communicate {
    my $blocksize = 2048;
    my ($rhandles, $whandles, $wbuf_of) = @_;
    my $rbuf_of = {};

lib/Mail/GnuPG.pm  view on Meta::CPAN

        if (@$eready) {
            die("select returned an unexpected exception handle, this shouldn't happen");
        }
        for my $rhandle (@$rready) {
            my $n = fileno($rhandle);
            my $count = sysread($rhandle, $rbuf_of->{$rhandle},
                                $blocksize, length($rbuf_of->{$rhandle}));
            warn("read $count bytes from handle $n") if $DEBUG;
            if (!defined $count) { # read error
                if ($!{EPIPE}) {
                    warn("read failure (gpg exited?) from handle $n: $!")
                        if $DEBUG;
                } else {
                    warn("read failure from handle $n: $!");
                }
                $reader->remove($rhandle);
                close $rhandle;
                next;
            }
            if ($count == 0) { # EOF
                warn("read done from handle $n") if $DEBUG;

lib/Mail/GnuPG.pm  view on Meta::CPAN

                next;
            }
        }
        for my $whandle (@$wready) {
            my $n = fileno($whandle);
            $woffset_of->{$whandle} = 0 if !exists $woffset_of->{$whandle};
            my $count = syswrite($whandle, $wbuf_of->{$whandle},
                                 $blocksize, $woffset_of->{$whandle});
            if (!defined $count) {
                if ($!{EPIPE}) { # write error
                    warn("write failure (gpg exited?) from handle $n: $!")
                        if $DEBUG;
                } else {
                    warn("write failure from handle $n: $!");
                }
                $writer->remove($whandle);
                close $whandle;
                next;
            }
            warn("wrote $count bytes to handle $n") if $DEBUG;
            $woffset_of->{$whandle} += $count;

t/20.inline-verify.t  view on Meta::CPAN

# -*- perl -*-

use Test::More;
use Mail::GnuPG;
use MIME::Entity;
use strict;



require('t/import_keys.pl');
my $gpghome=import_keys('t/pubkeys.asc');
unless (defined($gpghome)){
  plan skip_all => "failed to import GPG keys for testing";
  goto end;
}

plan tests => 5;

# Main program
my $parser = new MIME::Parser;
$parser->output_to_core(1);

my $entity= $parser->parse_open("t/msg/inline-signed-qp.eml") ;
isa_ok($entity,"MIME::Entity");

my $mg = new Mail::GnuPG( keydir =>$gpghome );

isa_ok($mg,"Mail::GnuPG");

my ($return,$keyid,$uid) = $mg->verify($entity);
is($return,0,"verify success");
is($keyid,'4526F399',"verify keyid");
is($uid,'David Bremner <bremner@debian.org>',"verify uid");

end:

t/25.multipart-verify.t  view on Meta::CPAN

# -*- perl -*-

use Test::More;
use Mail::GnuPG;
use MIME::Entity;
use strict;


require('t/import_keys.pl');
my $gpghome=import_keys('t/pubkeys.asc');
unless (defined($gpghome)){
  plan skip_all => "failed to import GPG keys for testing";
  goto end;
}

plan tests => 5;

# Main program
my $parser = new MIME::Parser;
$parser->output_to_core(1);
$parser->decode_bodies(0);

my $entity= $parser->parse_open("t/msg/multipart-signed-qp.eml") ;
isa_ok($entity,"MIME::Entity");

my $mg = new Mail::GnuPG( keydir=>$gpghome);

isa_ok($mg,"Mail::GnuPG");

my ($return,$keyid,$uid) = $mg->verify($entity);
is($return,0,"verify success");
is($keyid,'9456D16A',"verify keyid");
is($uid,'Mauricio Campiglia <mauricio@campiglia.org>',"verify uid");

end:

t/30.inline-decrypt.t  view on Meta::CPAN

# Main program
my $parser = new MIME::Parser;
$parser->output_to_core(1);

my $entity= $parser->parse_open("t/msg/inline-encrypted-qp.eml") ;
isa_ok($entity,"MIME::Entity");

my $KEY = "EFEA4EAD"; # 49539D60EFEA4EAD
my $WHO = "Mail::GnuPG Test Key <mail\@gnupg.dom>";

unless ( 0 == system("gpg --version 2>&1 >/dev/null") ) {
  plan skip_all => "gpg in path required for testing round-trip";
  goto end;
}

my $tmpdir = tempdir( "mgtXXXXX", CLEANUP => 1);

unless ( 0 == system("gpg --homedir $tmpdir --trusted-key 0x49539D60EFEA4EAD --import t/test-key.pgp 2>&1 >/dev/null")) {
  plan skip_all => "unable to import testing keys";
  goto end;
}


my $mg = new Mail::GnuPG( key => '49539D60EFEA4EAD',
			  keydir => $tmpdir,
			  passphrase => 'passphrase');

isa_ok($mg,"Mail::GnuPG");

t/35.has-public-key.t  view on Meta::CPAN

# -*- perl -*-

use Test::More;
use Mail::GnuPG;
use strict;

require('t/import_keys.pl');
my $gpghome=import_keys('t/test-key.pgp');
unless (defined($gpghome)){
  plan skip_all => "failed to import GPG keys for testing";
  goto end;
}

plan tests => 3;

my $mg = new Mail::GnuPG( keydir => $gpghome );
isa_ok($mg, 'Mail::GnuPG');

is($mg->has_public_key('mail@gnupg.dom'), 1, 'public key exists');
is($mg->has_public_key('bogus@email.example.com'), 0, "bogus key doesn't exist");

end:

t/agent.t  view on Meta::CPAN

use strict;
no warnings 'redefine';         # fix this later

TODO: {
  local $TODO = "agent test unreliable with pre 2.11 gnupg";

my $KEY = "EFEA4EAD"; # 49539D60EFEA4EAD
my $WHO = "Mail::GnuPG Test Key <mail\@gnupg.dom>";

my $GPG;
# if gpg2 exists, use that. Mixing versions causes problems.
if (0 == system ("gpg2 --version  2>&1 >/dev/null")) {
  $GPG="gpg2";
} elsif (0 == system ("gpg --version  2>&1 >/dev/null")) {
  $GPG="gpg";
} else {
  plan skip_all => "gpg2 or gpg in path required for testing agent";
  goto end;
}

unless ( 0 == system("gpg-agent --version 2>&1 >/dev/null")) {
  plan skip_all => "gpg-agent in path required for testing agent";
  goto end;
}

my $tmpdir = tempdir( "/tmp/mgtXXXXX", CLEANUP => 1);

unless (open AGENT, "gpg-agent  --homedir $tmpdir --batch --quiet --disable-scdaemon --allow-preset --daemon|") {
  plan skip_all =>"unable to start gpg-agent";
  goto end;
}

my ($agent_pid,$agent_info);
while (<AGENT>){
  if (m/GPG_AGENT_INFO=([^;]*);/){
    $agent_info=$1;
    $ENV{'GPG_AGENT_INFO'}=$agent_info;
    my @parts=split(':',$agent_info);
    $agent_pid=$parts[1];
  }
}

unless ($agent_info) {
  # is it running on the standard (as of 2.1) socket?
  if (0 == system("gpg-agent --homedir $tmpdir 2>&1 >/dev/null")) {
    $ENV{'GPG_AGENT_INFO'}="$tmpdir/S.gpg-agent:0:1";
  } else {
    plan skip_all => "unable to find gpg agent";
  }
}

my $preset=$ENV{GPG_PRESET_PASSPHRASE} || "/usr/lib/gnupg2/gpg-preset-passphrase";

unless (0 == system("$preset --version 2>&1 >/dev/null")) {
  plan skip_all => "gpg-preset-passphrase not found; set GPG_PRESET_PASSPHRASE in environment to location of binary";
  goto end;
}


unless ( 0 == system("${GPG} --homedir $tmpdir --use-agent --batch --quiet --trusted-key 0x49539D60EFEA4EAD --import t/test-key.pgp 2>&1 >/dev/null")) {
  plan skip_all => "unable to import testing keys";
  goto end;
}

# gpg-preset-passphrase uses the keygrip of the subkey, rather than the id/fingerprint.
unless ( 0 == system ("$preset --homedir $tmpdir --preset -P passphrase " .
		      "AC4FAFD3DC861700DB6109591BAD5F37DB2801A1")
	 && 0 == system ("$preset --homedir $tmpdir --preset -P passphrase " .
		      "1230AEE1345EC41ED8E183011176AC9C74A99513")    ){
  plan skip_all =>"unable to cache passphrase";
  goto end;
}

plan tests => 20;


my $mg = new Mail::GnuPG( key => '49539D60EFEA4EAD',
			  keydir => $tmpdir,
			  use_agent => 1,
			  gpg_path => ${GPG});

isa_ok($mg,"Mail::GnuPG");

my $line = "x\n";
my $string = $line x 100000;

my $copy;
my $me =  MIME::Entity->build(From    => 'me@myhost.com',
			      To      => 'you@yourhost.com',
			      Subject => "Hello, nurse!",

t/import_keys.pl  view on Meta::CPAN

sub import_keys($){
  my $filename=shift;

  my $trusted =  scalar(@_) ? "--trusted-key 0x".shift : "";

  use File::Temp qw(tempdir);

  unless ( 0 == system("gpg --version 2>&1 >/dev/null") ) {
    return undef;
  }

  my $gpghome = tempdir( "mgtXXXXX", CLEANUP => 1);
  unless ( 0 == system("gpg --homedir $gpghome $trusted --import $filename 2>&1 >/dev/null")) {
    return undef;
  }
  return $gpghome;
}

1;

t/pubkeys.asc  view on Meta::CPAN

NhOG07dxKz6JmJD0pESfO4kCHAQQAQIABgUCSq5cVAAKCRD4YxFDPX1fD2xED/9C
XWXiI0miXOxLMhxi/BP3KahEzW6Oo7mEcctPPPVvNjomwyBrrB2GcGDJJETOQWIp
h+HMPaRGzHCHluAxVLmulsejQt40tdxymoRnLIiwAhsr+y2SyotzgDeU5qzPRbwJ
2n0zfuXxpn2atGVFjBn5jsu3l2fK5rdF45F9MRC/2RQrb2SX6oJErG7DJDuVMoab
AdMhHZEzWUEz/sJeZjHXi9a18+gEX8YW4C5qsmL0ttUo0cb39nN+d6u83Ns9Tv3k
EsQo9cAFmhJ0pE/h0mELdOouAqdmbdjeGfx25CWYCYLsPfkJ5IbcOeGOaSA3EVKZ
1bBT05bbVXnrsUnkvDIRd+sWTNXgZqziLA6EavN4aAEsH8aIMf/YpQMolXuamJ2M
85nFLDFEw4oACZCW7GLGpMLqhDHaOqzUuX9VFJUCpO/F7mYjn5SiiC5xO8aszjeS
lS12mUAtDdwx8HlVApUxoDDfQrdKz8BekmgogDYHSlnn8lJdEY5iX4wSSPGBO028
Jqi3Ihol0YBou0lWUcN8FceKgkOC4/AeRIavhYbbdz77vGBZfJMtsN4EL1i2mx2h
SgvYsmdSEgwARFBQPazwb6uCTp1bPfVYm1cXwTzKICLwE7jLnWgpgSIiHp0NKEA+
iuwm+i118rYbs8Sg85FPt95tbubU6gvOr8hBBd8tOIkCHAQQAQIABgUCTFxCQgAK
CRCfD+WHN0u+gd0tD/0ShMBT4T1me+UKJq+7YMhpHPBtX4GWc8N225icF+5qWzwO
gJdDaqZ8ZOEhOGycHks0mL8SNPLjnWJZjIyWW+1J8NCWX3B5ShKURU2stOvuhqJB
sCDzUkNal2pHF7DdagiMKvhNntx9/Zl8u4WJl7p99fdkdMVoO8Uxq2VqNjuSKbeB
YatdbGqRiurXqtf1k2z4INjxcIJS7OWjamSNx3O1rd1U2iJ/3/G1wxB7Ph4R5n7F
GagduRwq39hBXXj9t5IWvLS1amwo0su+pIrKoI4bjGajQzT/doac6c5ScRj8yGpK
l9//rCXbKcCCtzd2zVn+oJnzvPBdJyQWLBUuSrPsgLyUR+O+ysSyIFiRQ7Jjia75
h/jLEof0OYdM1Tpv3cvwsGHA9juffm/hTeHaJAUpiUDTErWMOqrBhVhGiOWXTNJn
+cMI91ZQjeiokmfVn2h7EbJSa6B3Uvw4L9FqYjYfCxPkfU5BpyuwCH/HjJlCBMl/
/f9ONrhGGVLKPgNZejY6Bzos5qHNy0+9tYfDJhT9PUf2EjLvYPTdV/r1BVTJqxqh

t/pubkeys.asc  view on Meta::CPAN

qLDaSaR4jzKgPZNMXtZjZS9B5FW4Loo1JFuKwcWVMXf4NZ5xsXoO3xkxAUa72nuV
HAQt8+8ObgOCjQzxrn4+MiuE74rJAHq8eVzfKiuJ5/V6fpf4yZRMtOC16pqP1Drd
byQYpQPLhjQA+mYk7qGp8W0OZ77cupGn9ks1DOw3xrpYf+4Rs2yyxSn5fhzbIujY
9okCHAQTAQIABgUCUbtbtAAKCRCRGmz5j0rS04gMD/9RGrldlC5P6q+qcDiKzWK8
KdtdK6XxYaxwQtPwi2kDeK5R2McSv3rziFgLTMTI1v958UHTfd8HlRWIgDmMOoPA
8DgoUsKKyBv4L/Ljmta9u/uhTPXrOUcM5tyQbQ9QcTPM6/Ic5yDzu3uCvNgZD9V+
lMIopZZKIInX17lyST9XcHAVT47NU0CiRhTx2iR6s9DeGDOiLQZKd2ZtC704oTmp
3/hj+eNwm45OwZKsyZdJ+LAWd3l0138bYf13cz16cC/+TUtwRxnnecsXueXCPltm
sE+biI2EafRMyPuoF6k6sFFfDOpp0j6brQwjAfTcXbs6NwPJXSTMaJIgXj0zRphP
Wv5XyKIKd1WXyZuX5+CjU0bV8GudKmlaSanR/31QIYDG6Hbamr8Y5YkZSoFqISEl
sYX1namMHZNR2zm9Wjsc7ko43+qZuVf5JDd59Haz40nDvt7x9KElVdZgpgTsBduA
JvxLmxR/x+ITDkwHFedCqlWmimwB0/AMIXFPw1KroN13sZj24YAbZNzB1xaNZW30
5ElgbV9dv7trKApD1VrVlQIaenWpenIRb4e3UxW6qxSMtZTAkTFBpFEd4o3hFWvj
L1YP4mgiWbK/2U9zYNvhB8Dz8H/N46ek0sgFrzMHMcOgXy77C9j0+EzCciqzVxlm
KOFVig4OJWdhnGDTgcciuIkCNgQwAQIAIAUCT4xRERkdAE5vdCB2ZXJpZmllZCBp
biBwZXJzb24uAAoJENWoUwh+Fmdxfr4QAKorLszA7U2P7pNgPc+uvehCxeXsA97h
VHnby5SqJfuourPaIfaQgOpQFxOY7JSh8/Lx5f+/q4dN7OuXtOZ/7JQQSXgW4cd6
Dlg7oALi8ZCRRz1EJq2KGb7jquDsdNt9aMMAC5BOLJOltWmk9SXnRwczKCmXmpqY
cYJtTimk+29SvyJFCVsjvczt1I1OZ60xbH6i4725MA1eA1MARQYug9Z3HzoKuzoV
AhwTFNpbm1ffb+cIR9/nfG8BhHErjTe3gUoHliiK/3oKtmhXrsGkxVp7w7KHVzvf
0QFPJKtnhkTNeHf2uz3JLXfFCQkT0ED0K28KfJd53WJbMK80X6zIzA2k5KjaAcgp

t/pubkeys.asc  view on Meta::CPAN

K1e7eEIGrcDdIAQZAQgABgUCUfebcgAKCRAcw7iHjvA7wPSEDACK12SX3qvZgTZ8
ZRBHq/DNSpjJANAF8EcHHKEUXlwAEKk8v/wX5AS/TadFCQ1szKKy8rLhcG8a135A
aDuqBLDDBUYmPaVxmk7l/XfjfAIbcHbU2IeJROscrccCQhdUyKpKXdIsbd0IvcPH
rZirWTGyQJSWJVRrG/m81yrQmSKMyrBg29coSCkQ6qUn+uVcrTLPE6445rK3fkF4
GVNnIeNAuL88ND+iTYk2UINrUouF/zc3eIQ98g4fCFYxyAe7UrBmDYNHsfRMq3eT
iElgE3AFLJUVXtp2oEzsQ15d+U0kK7t5sKTus7JsLoCBkFQla/p/RnRP86opkvUg
Mt/8AUgS+FmcOW4w1TutRo3lb/oN9WGv+Kxu2WXkD0MB5B8ggm3AtWLUjdJwmhqU
Ri2efGO7cUtW1AsUgF/GGCA2NixLZDm6SuqdKIYl/RYBpxP/FcaAM4Gl7eo5IWlF
Df9JcdVTzMne96kYwXRp/0T+xrdehtMb7eS3NtYtGQ2KMbtUIgfv2hAAnnuLcCJ9
uJj32H2T7J1k7I3da8S1zj6KT9kl2G1vYmts61rvnsM9PPbQiGPOhotXCy+6HptI
E+DKby2u1OnetYoQCGh45SLTmG9qXQjGl8GCgpgQGSIU2XA5D5ttjcPlaL/eF+Gr
KwnWq3rT/mO9SaRjwPjdJzX9eVcOsZiGuuC+Ix64GyLNmuAqkhO2ixWZFE6sYEhC
AE3eObpZl4JRsyo/qAoORhJ5NX6o3hsof8qammz3nGsBt+pcRljN3e1sf7JtDKgt
zOf8XDfj+A7mN3YW9J6UKb9gURqAqhMI0ezhiUeuC5n2lA+ja0sDl2225uQ7dxM5
bnekKvPtabyUtZskUxZHAnMBvSa9RDz/68DgBQk6PSxpeTFDu046fJvwRoWMflWE
oQ1ItgjiswyYr23eh+bjbpWqJJT4bFlB9lcbjyD2e2IcClIwflRVsGkW4VdhNoG6
5ACk121Osh3I8QaGxfNes1hjPPLpNG/IZXsD3IVkfr0l4bM7s8AHzXWAoGnekww9
npgPk96o/JTtVqaUOL8PmdnFSpcx93FEPDbWv71sJU/IUZf9wcAU3TbcYSKIq50T
g/dAENpiaiDORKtMgIswH4KRzXYc7l4iVLtVwCyS3RSelVMQHIEHd9vZEW+NHMbw
xOL6DsLivWMktra0JCY8Q//CKqy1ahv2lUqZAaIER0B5dREEALf0CTzcJ2BRQseh
G+6wh2nu+MphqCzdk6pAJrU1yLuUpO+2AVjaxXgOVvtzF3daKAWznkMrM2+hixqW

t/round-trip.t  view on Meta::CPAN

use Mail::GnuPG;
use MIME::Entity;
use strict;

my $FULL_KEY = "49539D60EFEA4EAD";
my $KEY = substr($FULL_KEY,-8,8);

my $WHO = "Mail::GnuPG Test Key <mail\@gnupg.dom>";

require('t/import_keys.pl');
my $gpghome=import_keys('t/test-key.pgp',$FULL_KEY);
unless (defined($gpghome)){
  plan skip_all => "failed to import GPG keys for testing";
  goto end;
}

plan tests => 20;


my $mg = new Mail::GnuPG( key => '49539D60EFEA4EAD',
			  keydir => $gpghome,
			  passphrase => 'passphrase');

isa_ok($mg,"Mail::GnuPG");

my $line = "x\n";
my $string = $line x 100000;

my $copy;
my $me =  MIME::Entity->build(From    => 'me@myhost.com',
			      To      => 'you@yourhost.com',

t/test-key.pgp  view on Meta::CPAN

gpg -a --export EFEA4EAD > test-key.pgp 
gpg -a --export-secret-keys   EFEA4EAD >> test-key.pgp 

passcode is passcode

-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: Encryption is Good

lQHhBD+ODYcRBACk5d777JxX4unmJLjy+SeexH1xYdDmcqH8VL125tyfpm9zIOtm
bzCcur7c+WM6am7jsdVV7udX8RuYWnlpj3f0rtodjXsaxGUQSt3VN2/oec0Hr/PE
6T+64cHBCLsijgeYBFIP4Zoq2sK0vO9CIjqxveHbrfZx3UdpzofUTodKewCgzX4P
KJjYzBfZQ+Y2C1kXWXOqGrkD/3INRfhmsZOUgQeJzcZLIi9vVeaJls4KV2LEpONv



( run in 0.891 second using v1.01-cache-2.11-cpan-df04353d9ac )