NAME

Crypt::OpenPGP - Pure-Perl OpenPGP implementation

SYNOPSIS

my $pgp = Crypt::OpenPGP->new;

        # Given an input stream (could be a signature, ciphertext, etc),
        # do the "right thing" to it.
        my $message_body; $message_body .= $ while <STDIN>;
        my $result = $pgp->handle( Data => $messagebody );

        # Create a detached, ASCII-armoured signature of $file using the
        # secret key $key_id, protected with the passphrase $pass. 
        my $file = 'really-from-me.txt';
        my $key_id = '...';
        my $pass = 'foo bar';
        my $signature = $pgp->sign(
            Filename   => $file,
            KeyID      => $key_id,
            Passphrase => $pass,
            Detach     => 1,
            Armour     => 1,
        );

        # Verify the detached signature $signature, which should be of the
        # source file $file.
        my $is_valid = $pgp->verify(
            Signature  => $signature,
            Files      => [ $file ],
        );

        # Using the public key associated with $key_id, encrypt the contents
        # of the file $file, and ASCII-armour the ciphertext.
        my $ciphertext = $pgp->encrypt(
            Filename   => $file,
            Recipients => $key_id,
            Armour     => 1,
        );

        # Decrypt $ciphertext using the secret key used to encrypt it,
        # which key is protected with the passphrase $pass.
        my $plaintext = $pgp->decrypt(
            Data       => $ciphertext,
            Passphrase => $pass,
        );

DESCRIPTION

Crypt::OpenPGP is a pure-Perl implementation of the OpenPGP standard[1]. In addition to support for the standard itself, Crypt::OpenPGP claims compatibility with many other PGP implementations, both those that support the standard and those that preceded it.

Crypt::OpenPGP provides signing/verification, encryption/decryption, keyring management, and key-pair generation; in short it should provide you with everything you need to PGP-enable yourself. Alternatively it can be used as part of a larger system; for example, perhaps you have a web-form-to-email generator written in Perl, and you'd like to encrypt outgoing messages, because they contain sensitive information. Crypt::OpenPGP can be plugged into such a scenario, given your public key, and told to encrypt all messages; they will then be readable only by you.

This module currently supports "RSA" and "DSA" for digital signatures, and "RSA" and "ElGamal" for encryption/decryption. It supports the symmetric ciphers "3DES", "Blowfish", "IDEA", "Twofish", "CAST5", and "Rijndael" ("AES"). "Rijndael" is supported for key sizes of 128, 192, and 256 bits. Crypt::OpenPGP supports the digest algorithms "MD5", "SHA-1", and "RIPE-MD/160". And it supports "ZIP" and "Zlib" compression.

COMPATIBILITY

One of the highest priorities for Crypt::OpenPGP is compatibility with other PGP implementations, including PGP implementations that existed before the OpenPGP standard.

As a means towards that end, some of the high-level Crypt::OpenPGP methods can be used in compatibility mode; given an argument Compat and a PGP implementation with which they should be compatible, these method will do their best to choose ciphers, digest algorithms, etc. that are compatible with that implementation. For example, PGP2 only supports "IDEA" encryption, "MD5" digests, and version 3 signature formats; if you tell Crypt::OpenPGP that it must be compatible with PGP2, it will only use these algorithms/formats when encrypting and signing data.

To use this feature, supply either sign or encrypt with the Compat parameter, giving it one of the values from the list below. For example:

        my $ct = $pgp->encrypt(
                      Compat     => 'PGP2',
                      Filename   => 'foo.pl',
                      Recipients => $key_id,
                 );

Because PGP2 was specified, the data will automatically be encrypted using the "IDEA" cipher, and will be compressed using "ZIP".

Here is a list of the current compatibility sets and the algorithms and formats they support.

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

USAGE

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

Crypt::OpenPGP->new( %args )
Constructs a new Crypt::OpenPGP instance and returns that object. Returns "undef" on failure.

%args can contain:

% host -l pgp.net | grep wwwkeys

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

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

The return value is a reference to a hash, which may contain the following keys, depending on the data passed to the method:

If an error occurs, the return value will be "undef", and the error message can be obtained by calling errstr on the Crypt::OpenPGP object.

%args can contain:

            sub defaultpassphrase_cb {
                my($cert) = @;
                my $prompt;
                if ($cert) {
                    $prompt = sprintf qq(
            You need a passphrase to unlock the secret key for
            user "%s".
            %d-bit %s key, ID %s
    
            Enter passphrase: ), $cert->uid,
                                 $cert->key->size,
                                 $cert->key->alg,
                                 substr($cert->keyid_hex, -8, 8);
                } else {
                    $prompt = "Enter passphrase: ";
                }
                _prompt($prompt, '', 1);
            }

        If you do specify this parameter, make sure that your callback
        function can handle both asymmetric and symmetric encryption.

        See the PassphraseCallback parameter for decrypt, below.

$pgp->encrypt( %args )
Encrypts a block of data. The encryption is actually done with a symmetric cipher; the key for the symmetric cipher is then encrypted with either the public key of the recipient or using a passphrase that you enter. The former case is using public-key cryptography, the latter, standard symmetric ciphers. In the first case, the session key can only be unlocked by someone with the corresponding secret key; in the second, it can only be unlocked by someone who knows the passphrase.

Given the parameter SignKeyID (see below), encrypt will first sign the message before encrypting it, adding a Signature packet to the encrypted plaintext.

Returns a block of data containing two PGP packets: the encrypted symmetric key and the encrypted data.

On failure returns "undef".

%args can contain:

            8-digit hex key ID: 123ABC45
            16-digit hex key ID: 678DEF90123ABC45
            (Part of) User ID: foo@bar

        Note that the 8-digit hex key ID is the last 8 digits of the (long)
        16-digit hex key ID.

        If you wish to encrypt the message for multiple recipients, the
        value of Recipients should be a reference to a list of recipients
        (as defined above). For each recipient in the list, the public key
        will be looked up in your public keyring, and an encrypted session
        key packet will be added to the encrypted message.

        This argument is optional; if not provided you should provide the
        Passphrase option (below) to perform symmetric-key encryption when
        encrypting the session key.
            my %BAD_KEYS = (
                ABCDEF1234567890 => 1,
                1234567890ABCDEF => 1,
            );
            my $cb = sub {
                my $keys = shift;
                my @return;
                for my $cert (@$keys) {
                    push @return, $cert unless $BAD_KEYS{ $cert->key_id_hex };
                }
                \@returns;
            };
            my $ct = $pgp->encrypt( ..., RecipientsCallback => $cb, ... );

$pgp->decrypt( %args )
Decrypts a block of ciphertext. The ciphertext should be of the sort returned from encrypt, in either armoured or non-armoured form. This is compatible with all other implementations of PGP: the output of their encryption should serves as the input to this method.

When called in scalar context, returns the plaintext (that is, the decrypted ciphertext), or "undef" on failure. When called in list context, returns a three-element list containing the plaintext and the result of signature verification (see next paragraph), or the empty list on failure. Either of the failure conditions listed here indicates that decryption failed.

If decrypt is called in list context, and the encrypted text contains a signature over the plaintext, decrypt will attempt to verify the signature and will return the result of that verification as the second element in the return list, and the actual Crypt::OpenPGP::Signature object as the third element in the return list. If you call decrypt in list context and the ciphertext does not contain a signature, that second element will be "undef", and the errstr will be set to the string "No Signature\n". The second element in the return list can have one of three possible values: "undef", meaning that either an error occurred in verifying the signature, or the ciphertext did not contain a signature; 0, meaning that the signature is invalid; or a true value of either the signer's user ID or 1, if the user ID cannot be determined. Note that these are the same values returned from verify (below).

For example, to decrypt a message that may contain a signature that you want verified, you might use code like this:

        my($pt, $valid, $sig) = $pgp->decrypt( ... );
        die "Decryption failed: ", $pgp->errstr unless $pt;
        die "Signature verification failed: ", $pgp->errstr
            unless defined $valid || $pgp->errstr !~ /^No Signature/;
        print "Signature created at ", $sig->timestamp, "\n";

This checks for errors in decryption, as well as errors in signature verification, excluding the error denoting that the plaintext was not signed.

%args can contain:

            sub passphrase_cb {
                if (my $cert = $[0]) {
                    printf "Enter passphrase for secret key %s: ",
                        $cert->keyid_hex;
                } else {
                    print "Enter passphrase: ";
                }
            }

        This argument is optional if your secret key is protected; if not
        provided you should supply the Passphrase parameter (above).

$pgp->sign( %args )
Creates and returns a digital signature on a block of data.

On failure returns "undef".

%args can contain:

$pgp->verify( %args )
Verifies a digital signature. Returns true for a valid signature, 0 for an invalid signature, and "undef" if an error occurs (in which case you should call errstr to determine the source of the error). The 'true' value returned for a successful signature will be, if available, the PGP User ID of the person who created the signature. If that value is unavailable, the return value will be 1.

If called in list context, the second element returned in the return list will be the Crypt::OpenPGP::Signature object representing the actual signature.

%args can contain:

$pgp->keygen( %args )
NOTE: this interface is alpha and could change in future releases!

Generates a public/secret PGP keypair. Returns two keyblocks (objects of type Crypt::OpenPGP::KeyBlock), a public and a secret keyblock, respectively. A keyblock is essentially a block of keys, subkeys, signatures, and user ID PGP packets.

%args can contain:

Foo Bar <foo@bar.com>

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

        This is a required argument.

ERROR HANDLING

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

$pgp->errstr

In the case that you do not yet have a Crypt::OpenPGP object (that is, if an error occurs while creating a 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;

SAMPLES/TUTORIALS

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

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

LICENSE

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

AUTHOR & COPYRIGHT

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

REFERENCES

1 RFC2440 - OpenPGP Message Format (1998). http://www.faqs.org/rfcs/rfc2440.html