NAME

PGP::Sign - Create detached PGP signatures for data, securely

SYNOPSIS

use PGP::Sign;
($signature, $version) = pgp_sign ($keyid, $passphrase, @data);
$signer = pgp_verify ($signature, $version, @data);
@errors = PGP::Sign::pgp_error;

DESCRIPTION

This module is designed to do one and only one thing securely and well; namely, generate and check detached PGP signatures for some arbitrary data. It doesn't do encryption, it doesn't manage keyrings, it doesn't verify signatures, it just signs things. This is ideal for applications like PGPMoose or control message generation that just need a fast signing mechanism.

The interface is very simple; just call pgp_sign() with a key ID, a pass phrase, and some data, or call pgp_verify() with a signature (in the form generated by pgp_sign()), a version number (which can be undef if you don't want to give a version), and some data. The data can be specified in pretty much any form you can possibly consider data and a few you might not. Scalars and arrays are passed along to PGP; references to arrays are walked and passed one element at a time (to avoid making a copy of the array); file handles, globs, or references to globs are read a line at a time and passed to PGP; and references to code are even supported (see below). About the only thing that we don't handle are references to references (which are just printed to PGP, which probably isn't what you wanted) and hashes (which are treated like arrays, which doesn't make a lot of sense).

If you give either function a reference to a sub, it will repeatedly call that sub, sending the results to PGP to be signed, until the sub returns undef. What this lets you do is pass the function an anonymous sub that walks your internal data and performs some manipulations on it a line at a time, thus allowing you to sign a slightly modified form of your data (with initial dashes escaped, for example) without having to use up memory to make an internal copy of it.

In a scalar context, pgp_sign() returns the signature as an ASCII armored block with embedded newlines (but no trailing newline). In a list context, it returns a two-element list consisting of the signature as above and the PGP version that signed it. pgp_sign() will return undef in the event of any sort of error.

pgp_verify() returns the signer of the message in the case of a good signature, the empty string in the case of a bad signature, and undef in the event of some error.

pgp_error() (which isn't exported by default) returns the error encountered by the last pgp_sign() or pgp_verify(), or undef if there was no error. In a list context, a list of lines is returned; in a scalar context, a long string with embedded newlines is returned.

Two global variables can be modified:

$PGP::Sign::PGP

The path to PGP. This defaults to /usr/local/bin/pgp, but may have been fixed to point at the right place by the module installer during installation.

$PGP::Sign::TMPDIR

The directory in which temporary files are created. Defaults to TMPDIR if set, and /tmp if not.

$PGP::Sign::MUNGE

If this variable is set to a true value, PGP::Sign will automatically strip trailing spaces when signing or verifying signatures. This will make the resulting signatures and verification compatible with programs that generate attached signatures (since PGP ignores trailing spaces when generating or checking attached signatures).

ENVIRONMENT

TMPDIR

The directory in which to create temporary files. Can be overridden by changing $PGP::Sign::TMPDIR. If not set, defaults to /tmp.

DIAGNOSTICS

Mostly the contents of @PGP::Sign::ERROR (returned by pgp_error()) are completely determined by PGP. The only thing that this module may stick in there is "Execution of PGP failed" if we couldn't fork off a PGP process and "PGP returned exit status %d" in the event of a non-zero exit status from PGP.

BUGS

The implementation of pgp_verify() uses temporary files. Unfortunately, given the current implementation of PGP, there isn't any way to avoid this, since we want to generate detached signatures. It would be possible to do everything through pipes if we generated attached signatures, but then we would have to deal with PGP data munging, which is ugly and underdocumented. We also wouldn't be able to work with applications that want detached signatures, and since we are returning a signature that's logically detached from the signed data, it doesn't make any sense to have the signature be of the form used for attached signatures.

CAVEATS

This module uses a pipe and the environment variable PGPPASSFD to give the pass phrase to PGP, since this is the only secure method (both command line switches and environment variables can potentially be read by other users on the same machine using ps). This requires a version of PGP that supports that feature, however. I know for certain that PGP 2.6.2 does, but I can't be sure about other versions.

This module forks, uses a pipe, and relies on the ability to pass an open pipe to an exec()ed subprocess. This may cause portability problems to certain substandard operating systems.

The signature generated is a detached signature. If you intend to pass it to an application that will attempt to verify it by creating a signed document (the way pgpverify does), you'll need to set $PGP::Sign::MUNGE before creating the signature.

AUTHOR

Russ Allbery <rra@stanford.edu>

HISTORY

Based heavily on work by Andrew Gierth <andrew@erlenstar.demon.co.uk> and benefitting greatly from input, comments, suggestions, and help from him, this module came about in the process of implementing PGPMoose signatures and control message signatures for Usenet. PGPMoose is the idea of Greg Rose <ggr@usenix.org>, and signcontrol and pgpverify are the idea of David Lawrence <tale@isc.org>.