Crypt-OpenPGP

 view release on metacpan or  search on metacpan

lib/Crypt/OpenPGP.pm  view on Meta::CPAN

        if (exists $ENV{$dir}) { for (@_) { push @paths, "$ENV{$dir}/$_" } }
        return @paths ? @paths : ();
    };

    my $home = sub {
        my( @path ) = @_;
        my $home_dir = File::HomeDir->my_home or return;
        return File::Spec->catfile( $home_dir, @path );
    };

    %COMPAT = (
        PGP2 => {
              'sign'    => { Digest => 'MD5', Version => 3 },
              'encrypt' => { Cipher => 'IDEA', Compress => 'ZIP' },
              'keygen'  => { Type => 'RSA', Cipher => 'IDEA',
                             Version => 3, Digest => 'MD5' },
              'PubRing' => [
                     $env->('PGPPATH','pubring.pgp'),
                     $home->( '.pgp', 'pubring.pgp' ),
              ],
              'SecRing' => [
                     $env->('PGPPATH','secring.pgp'),
                     $home->( '.pgp', 'secring.pgp' ),
              ],
              'Config'  => [
                     $env->('PGPPATH', 'config.txt'),
                     $home->( '.pgp', 'config.txt' ),
              ],
        },

        PGP5 => {
              'sign'    => { Digest => 'SHA1', Version => 3 },
              'encrypt' => { Cipher => 'DES3', Compress => 'ZIP' },
              'keygen'  => { Type => 'DSA', Cipher => 'DES3',
                             Version => 4, Digest => 'SHA1' },
              'PubRing' => [
                     $env->('PGPPATH','pubring.pkr'),
                     $home->( '.pgp', 'pubring.pkr' ),
              ],
              'SecRing' => [
                     $env->('PGPPATH','secring.skr'),
                     $home->( '.pgp', 'secring.skr' ),
              ],
              'Config'  => [
                     $env->('PGPPATH', 'pgp.cfg'),
                     $home->( '.pgp', 'pgp.cfg' ),
              ],
        },

        GnuPG => {
              'sign'    => { Digest => 'SHA256', Version => 4 },
              'encrypt' => { Cipher => 'Rijndael', Compress => 'Zlib',
                             MDC => 1 },
              'keygen'  => { Type => 'RSA', Cipher => 'Rijndael',
                             Version => 4, Digest => 'SHA256' },
              'Config'  => [
                     $env->('GNUPGHOME', 'options'),
                     $home->( '.gnupg', 'options' ),
              ],
              'PubRing' => [
                     $env->('GNUPGHOME', 'pubring.gpg'),
                     $home->( '.gnupg', 'pubring.gpg' ),
              ],
              'SecRing' => [
                     $env->('GNUPGHOME', 'secring.gpg'),
                     $home->( '.gnupg', 'secring.gpg' ),
              ],
        },
    );
}

sub version_string {
    no warnings 'uninitialized';
    __PACKAGE__ . ' ' . __PACKAGE__->VERSION;
}

sub pubrings { $_[0]->{pubrings} }
sub secrings { $_[0]->{secrings} }

use constant PUBLIC => 1;
use constant SECRET => 2;

sub add_ring {
    my $pgp = shift;
    my($type, $ring) = @_;
    unless (ref($ring) eq 'Crypt::OpenPGP::KeyRing') {
        $ring = Crypt::OpenPGP::KeyRing->new( Filename => $ring )
            or return Crypt::OpenPGP::KeyRing->errstr;
    }
    if ($type == SECRET) {
        push @{ $pgp->{secrings} }, $ring;
    } else {
        push @{ $pgp->{pubrings} }, $ring;
    }
    $ring;
}

sub new {
    my $class = shift;
    my $pgp = bless { }, $class;
    $pgp->init(@_);
}

sub _first_exists {
    my($list) = @_;
    for my $f (@$list) {
        next unless $f;
        return $f if -e $f;
    }
}

sub init {
    my $pgp = shift;
    $pgp->{pubrings} = [];
    $pgp->{secrings} = [];
    my %param = @_;
    my $cfg_file = delete $param{ConfigFile};
    my $cfg = $pgp->{cfg} = Crypt::OpenPGP::Config->new(%param) or
        return Crypt::OpenPGP::Config->errstr;
    if (!$cfg_file && (my $compat = $cfg->get('Compat'))) {
        $cfg_file = _first_exists($COMPAT{$compat}{Config});
    }
    if ($cfg_file) {
        $cfg->read_config($param{Compat}, $cfg_file);
    }
    ## Load public and secret keyrings.

lib/Crypt/OpenPGP.pm  view on Meta::CPAN

Signing: digest = C<MD5>, packet format = version 3

=item * PGP5

Encryption: symmetric cipher = C<3DES>, compression = C<ZIP>,
modification detection code (MDC) = C<0>

Signing: digest = C<SHA-1>, packet format = version 3

=item * GnuPG

Encryption: symmetric cipher = C<Rijndael>, compression = C<Zlib>,
modification detection code (MDC) = C<1>

Signing: digest = C<RIPE-MD/160>, packet format = version 4

=back

If the compatibility setting is unspecified (that is, if no I<Compat>
argument is supplied), the settings (ciphers, digests, etc.) fall
back to their default settings.

=head1 USAGE

I<Crypt::OpenPGP> has the following high-level interface. On failure,
all methods will return C<undef> and set the I<errstr> for the object;
look below at the I<ERROR HANDLING> section for more information.

=head1 RANDOM SOURCE

I<Crypt::OpenPGP> requires a Random source.  I<Bytes::Random::Secure> is
now specified as a dependency, as some installations failed to have one
installed.

I<Crypt::Random>, if installed, is used instead.

=head2 Crypt::OpenPGP->new( %args )

Constructs a new I<Crypt::OpenPGP> instance and returns that object.
Returns C<undef> on failure.

I<%args> can contain:

=over 4

=item * Compat

The compatibility mode for this I<Crypt::OpenPGP> object. This value will
propagate down into method calls upon this object, meaning that it will be
applied for all method calls invoked on this object. For example, if you set
I<Compat> here, you do not have to set it again when calling I<encrypt>
or I<sign> (below), unless, of course, you want to set I<Compat> to a
different value for those methods.

I<Compat> influences several factors upon object creation, unless otherwise
overridden in the constructor arguments: if you have a configuration file
for this compatibility mode (eg. F<~/.gnupg/options> for GnuPG), it will
be automatically read in, and I<Crypt::OpenPGP> will set any options
relevant to its execution (symmetric cipher algorithm, etc.); I<PubRing>
and I<SecRing> (below) are set according to the default values for this
compatibility mode (eg. F<~/.gnupg/pubring.gpg> for the GnuPG public
keyring).

=item * SecRing

Path to your secret keyring. If unspecified, I<Crypt::OpenPGP> will look
for your keyring in a number of default places.

As an alternative to passing in a path to the keyring file, you can pass in
a I<Crypt::OpenPGP::KeyRing> object representing a secret keyring.

=item * PubRing

Path to your public keyring. If unspecified, I<Crypt::OpenPGP> will look
for your keyring in a number of default places.

As an alternative to passing in a path to the keyring file, you can pass in
a I<Crypt::OpenPGP::KeyRing> object representing a public keyring.

=item * ConfigFile

Path to a PGP/GnuPG config file. If specified, you must also pass in a
value for the I<Compat> parameter, stating what format config file you are
passing in. For example, if you are passing in the path to a GnuPG config
file, you should give a value of C<GnuPG> for the I<Compat> flag.

If you leave I<ConfigFile> unspecified, but you have specified a value for
I<Compat>, I<Crypt::OpenPGP> will try to find your config file, based on
the value of I<Compat> that you pass in (eg. F<~/.gnupg/options> if
I<Compat> is C<GnuPG>).

NOTE: if you do not specify a I<Compat> flag, I<Crypt::OpenPGP> cannot read
any configuration files, even if you I<have> specified a value for the
I<ConfigFile> parameter, because it will not be able to determine the proper
config file format.

=item * KeyServer

The hostname of the HKP keyserver. You can get a list of keyservers through

    % host -l pgp.net | grep wwwkeys

If I<AutoKeyRetrieve> is set to a true value,
keys will be automatically retrieved from the keyserver if they are not found
in your local keyring.

=item * AutoKeyRetrieve

If set to a true value, and if I<KeyServer> is set to a keyserver name,
I<encrypt> and I<verify> will automatically try to fetch public keys from
the keyserver if they are not found in your local keyring.

=back

=head2 $pgp->handle( %args )

A do-what-I-mean wrapper around I<decrypt> and I<verify>. Given either a
filename or a block of data--for example, data from an incoming email
message--I<handle> "handles" it as appropriate for whatever encryption or
signing the message contains. For example, if the data is encrypted, I<handle>
will return the decrypted data (after prompting you for the passphrase). If

lib/Crypt/OpenPGP.pm  view on Meta::CPAN

    Foo Bar <foo@bar.com>

The I<Identity> is used to build a User ID packet that is stored in
each of the returned keyblocks.

This is a required argument.

=item * Passphrase

String with which the secret key will be encrypted. When read in from
disk, the key can then only be unlocked using this string.

This is a required argument.

=item * Version

Specifies the key version; defaults to version C<4> keys. You should
only set this to version C<3> if you know why you are doing so (for
backwards compatibility, most likely). Version C<3> keys only support
RSA.

=item * Verbosity

Set to a true value to enable a status display during key generation;
since key generation is a relatively lengthy process, it is helpful
to have an indication that some action is occurring.

I<Verbosity> is 0 by default.

=back

=head1 ERROR HANDLING

If an error occurs in any of the above methods, the method will return
C<undef>. You should then call the method I<errstr> to determine the
source of the error:

    $pgp->errstr

In the case that you do not yet have a I<Crypt::OpenPGP> object (that
is, if an error occurs while creating a I<Crypt::OpenPGP> object),
the error can be obtained as a class method:

    Crypt::OpenPGP->errstr

For example, if you try to decrypt some encrypted text, and you do
not give a passphrase to unlock your secret key:

    my $pt = $pgp->decrypt( Filename => "encrypted_data" )
        or die "Decryption failed: ", $pgp->errstr;

=head1 SAMPLES/TUTORIALS

Take a look at F<bin/pgplet> for an example of usage of I<Crypt::OpenPGP>.
It gives you an example of using the four main major methods (I<encrypt>,
I<sign>, I<decrypt>, and I<verify>), as well as the various parameters to
those methods. It also demonstrates usage of the callback parameters (eg.
I<PassphraseCallback>).

F<bin/pgplet> currently does not have any documentation, but its interface
mirrors that of I<gpg>.

=head1 LICENSE

Crypt::OpenPGP is free software; you may redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHOR & COPYRIGHT

Except where otherwise noted, Crypt::OpenPGP is Copyright 2001 Benjamin
Trott, cpan@stupidfool.org. All rights reserved.

=head1 REFERENCES

=over 4

=item 1 RFC4880 - OpenPGP Message Format (2007). http://www.faqs.org/rfcs/rfc4880.html

=back 

=cut



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