view release on metacpan or search on metacpan
/MANIFEST.bak
/MYMETA.json
/MYMETA.json.lock
/MYMETA.yml
/PGP-Sign-*/
/PGP-Sign-*.tar.gz
/_build/
/blib/
/cover_db/
/pm_to_blib
/t/data/gnupg1/pubring.gpg~
/t/data/gnupg1/random_seed
/t/data/gnupg1/trustdb.gpg
/t/data/gnupg2/trustdb.gpg
use Module::Build;
# Basic package configuration.
my $build = Module::Build->new(
module_name => 'PGP::Sign',
dist_author => 'Russ Allbery <rra@cpan.org>',
license => 'perl',
recursive_test_files => 1,
add_to_cleanup =>
[qw(MANIFEST.bak cover_db t/data/random_seed t/data/trustdb.gpg)],
# Add additional package metadata.
meta_merge => {
'meta-spec' => { version => '2' },
resources => {
bugtracker => {
mailto => 'bug-PGP-Sign@rt.cpan.org',
web => 'https://rt.cpan.org/Dist/Display.html?Name=PGP-Sign',
},
homepage => 'https://www.eyrie.org/~eagle/software/pgp-sign',
Document that GnuPG 2.1.23 or GnuPG 1.4.20 or later is required and
skip tests on platforms that do not meet those version requirements.
The alternative would be auto-discovery of which command-line flags to
use and these version requirements are met by Debian stable (and
Debian oldstable with backports), so hopefully this restriction will
not cause too much hardship.
PGP::Sign 1.02 (2020-08-29)
On systems where gpg is GnuPG v1, override the path to the gpg binary
in the test suite. Some tests were still incorrectly looking for a
gpg1 binary.
On systems where gpg as found on the PATH is GnuPG v2 but is older
than 2.1.12 and therefore doesn't support the command-line arguments
PGP::Sign uses, skip the relevant tests. Tests are skipped rather
than failed because this doesn't represent a problem with the module
and the module can still be used with explicit configuration pointing
to a different version of GnuPG.
PGP::Sign 1.01 (2020-07-18)
Fix test suite to pass on systems where gpg is GnuPG v1. This is
apparently still common among many CPAN tester machines, and thus
probably other systems in the wild. This does not change the module's
default behavior; systems using GnuPG v1 still need to pass an
explicit style => 'GPG1' argument to the PGP::Sign constructor.
Update to rra-c-util 8.3:
* Fix style issues caught by Perl::Critic::Freenode.
* Ignore debian/changelog when checking for obsolete strings.
chooses by default. It can stll be overridden by setting the tmpdir
constructor parameter or $PGP::Sign::TMPDIR.
Rewrite the build system to use Module::Build. This eliminates the
spurious VERSION.pm "module" at the top level, which was a hack for
setting the distribution version in old versions of
ExtUtils::MakeMaker and should improve the indexing of the module.
Move the module into a lib structure and the test suite data into
t/data. Eliminate all of the prompting and command-line parameters to
set the PGP style and path to programs; instead, PGP::Sign will
default to using gpg1 from the user's PATH.
Rewrite ChangeLog into a more conventional Changes file.
PGP::Sign 0.20 (2007-04-27)
Unbuffer output when building the module since there is an interactive
prompt.
PGP::Sign 0.19 (2004-08-08)
Replace verification code for GnuPG with code that uses --status-fd,
so that it will work independent of locale.
Document limitations in the error reporting and recommended setting
TMPDIR.
PGP::Sign 0.18 (2004-08-04)
Remove trustdb.gpg from the distribution and add it to the files
cleaned by make clean.
PGP::Sign 0.17 (2002-06-28)
Skip the test for verification of data with trailing whitespace when
run under GnuPG, since the whitespace behavior changes fromr elease to
release. GnuPG 1.0.2 is back to the previous behavior of releases
before GnuPG 1.0.1.
Update CAVEATS to be slightly less optimistic about the chances of a
docs/metadata/requirements
docs/metadata/test/suffix
lib/PGP/Sign.pm
LICENSE
MANIFEST This list of files
MANIFEST.SKIP
README
README.md
t/api/basic.t
t/api/errors.t
t/api/gpg1.t
t/api/large-data.t
t/api/whitespace.t
t/data/gnupg1/pubring.gpg
t/data/gnupg1/secring.gpg
t/data/gnupg2/private-keys-v1.d/142395EC50F842F0638500914F0B8C925B12200C.key
t/data/gnupg2/private-keys-v1.d/B02AE5E841A818DC0BBC38F0773CB504F5BF4B00.key
t/data/gnupg2/pubring.kbx
t/data/message
t/data/message.dsa-v3.asc
t/data/message.dsa-v4.asc
t/data/message.rsa-pgp.sig
t/data/message.rsa-v3.asc
t/data/message.rsa-v4.asc
t/data/perl.conf
MANIFEST.SKIP view on Meta::CPAN
\bcovered\b
# Avoid MYMETA files
^MYMETA\.
# Avoid archives of this distribution
\bPGP-Sign-[\d\.\_]+
# Ignore data generated by the test suite.
^t/data/gnupg1/random_seed$
^t/data/gnupg1/trustdb\.gpg$
^t/data/gnupg2/trustdb\.gpg$
PGP::Sign comes with a test suite, which you can run after building
with:
./Build test
If a test fails, you can run a single test with verbose output via:
./Build test --test_files <path-to-test>
If the gpg binary found first on the PATH is too old, the tests will be
skipped rather than fail. This may not always be desirable, since the
module is not usable on such a system without configuration, but the
module can still be configured to use a GnuPG binary found elsewhere and
therefore this doesn't represent an error in the module itself.
The following additional Perl modules will be used by the test suite if
present:
* Devel::Cover
* Perl::Critic::Freenode
```
./Build test
```
If a test fails, you can run a single test with verbose output via:
```
./Build test --test_files <path-to-test>
```
If the gpg binary found first on the PATH is too old, the tests will be
skipped rather than fail. This may not always be desirable, since the
module is not usable on such a system without configuration, but the
module can still be configured to use a GnuPG binary found elsewhere and
therefore this doesn't represent an error in the module itself.
The following additional Perl modules will be used by the test suite if
present:
* Devel::Cover
* Perl::Critic::Freenode
docs/metadata/metadata.json view on Meta::CPAN
"broken": true,
},
"distribution": {
"section": "perl",
"tarname": "PGP-Sign",
"version": "pgp-sign",
"cpan": "PGP-Sign",
"ignore": [
"^\\.github/",
"^t/data/gnupg1/random_seed$",
"^t/data/gnupg./trustdb\\.gpg$",
],
},
"packaging": {
"debian": "libpgp-sign-perl",
},
"docs": {
"user": [
{
"name": "docs",
"title": "Module documentation",
docs/metadata/test/suffix view on Meta::CPAN
If the gpg binary found first on the PATH is too old, the tests will be
skipped rather than fail. This may not always be desirable, since the
module is not usable on such a system without configuration, but the
module can still be configured to use a GnuPG binary found elsewhere and
therefore this doesn't represent an error in the module itself.
The following additional Perl modules will be used by the test suite if
present:
* Devel::Cover
* Perl::Critic::Freenode
lib/PGP/Sign.pm view on Meta::CPAN
# Make sure the module returns true.
1;
__DATA__
=for stopwords
Allbery DSS GNUPGHOME GPG GPG1 Gierth Mitzelfelt OpenPGP PGPMoose PGPPATH
TMPDIR canonicalized d'Itri egd keyrings pgpverify ps signcontrol
KEYID --force-v3-sigs --allow-weak-digest-algos --homedir --textmode cleartext
cryptographic gpg gpg1 gpgv homedir interoperable tmpdir
=head1 NAME
PGP::Sign - Create detached PGP signatures for data, securely
=head1 SYNOPSIS
use PGP::Sign;
my $keyid = '<some-key-id>';
my $passphrase = '<passphrase-for-key>';
lib/PGP/Sign.pm view on Meta::CPAN
If set to a true value, PGP::Sign will strip trailing spaces (only spaces, not
arbitrary whitespace) when signing or verifying signatures. This will make
the resulting signatures and verification compatible with programs that
generate or verify cleartext signatures, since OpenPGP implementations ignore
trailing spaces when generating or checking cleartext signatures.
=item path
The path to the GnuPG binary to use. If not set, PGP::Sign defaults to
running B<gpg> (as found on the user's PATH) for a C<style> setting of "GPG"
and B<gpg1> (as found on the user's PATH) for a C<style> setting of "GPG1".
PGP::Sign does not support B<gpgv> (it passes options that it does not
understand). This parameter should point to a full GnuPG implementation.
=item style
The style of OpenPGP backend to use, chosen from "GPG" for GnuPG v2 (the
default) and "GPG1" for GnuPG v1.
If set to "GPG1", PGP::Sign will pass the command-line flags for maximum
backwards compatibility, including forcing v3 signatures instead of the
current version. This is interoperable with PGP 2.6.2, at the cost of using
lib/PGP/Sign.pm view on Meta::CPAN
be either "GPG" for GnuPG v2 or "GPG1" for GnuPG v1. The default is "GPG".
If set to "GPG1", PGP::Sign will pass the command-line flags for maximum
backwards compatibility, including forcing v3 signatures instead of the
current version. This is interoperable with PGP 2.6.2, at the cost of using
deprecated protocols and cryptographic algorithms with known weaknesses.
=item $PGP::Sign::PGPS
The path to the program used by pgp_sign(). If not set, PGP::Sign defaults to
running B<gpg> (as found on the user's PATH) if $PGP::Sign::PGPSTYLE is set to
"GPG" and B<gpg1> (as found on the user's PATH) if $PGP::Sign::PGPSTYLE is set
to "GPG1".
=item $PGP::Sign::PGPV
The path to the program used by pgp_verify(). If not set, PGP::Sign defaults
to running B<gpg> (as found on the user's PATH) if $PGP::Sign::PGPSTYLE is set
to "GPG" and B<gpg1> (as found on the user's PATH) if $PGP::Sign::PGPSTYLE is
set to "GPG1".
PGP::Sign does not support B<gpgv> (it passes options that it does not
understand). This variable should point to a full GnuPG implementation.
=item $PGP::Sign::TMPDIR
The directory in which temporary files are created. Defaults to whatever
directory File::Temp chooses to use by default.
=back
=head1 ENVIRONMENT
lib/PGP/Sign.pm view on Meta::CPAN
=head1 COPYRIGHT AND LICENSE
Copyright 1997-2000, 2002, 2004, 2018, 2020 Russ Allbery <rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
gpg(1), gpg1(1), L<File::Temp>
L<RFC 4880|https://tools.ietf.org/html/rfc4880>, which is the current
specification for the OpenPGP message format.
The current version of PGP::Sign is available from CPAN, or directly from its
web site at L<https://www.eyrie.org/~eagle/software/pgp-sign/>.
=cut
# Local Variables:
t/api/basic.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IO::File;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (gpg_is_gpg1()) {
plan skip_all => 'gpg binary is GnuPG v1';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 2.1.23';
} else {
plan tests => 7;
use_ok('PGP::Sign');
}
}
# Locate our test data directory for later use.
my $data = 't/data';
# Open and load our data file. This is the sample data that we'll be signing
t/api/errors.t view on Meta::CPAN
# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
} else {
plan tests => 4;
use_ok('PGP::Sign');
}
}
# Locate our test data directory for later use.
my $data = 't/data';
# Open and load our data file. This is the sample data that we'll be signing
t/api/errors.t view on Meta::CPAN
# A path to a nonexistent binary.
$signer = PGP::Sign->new({ path => '/nonexistent/binary' });
undef $@;
my $signature = eval { $signer->sign($keyid, $passphrase, @data) };
ok($@, 'Bad path to GnuPG binary');
# Verification of a completely invalid signature.
$signer = PGP::Sign->new();
undef $@;
eval { $signer->verify('adfasdfasdf', @data) };
like($@, qr{Execution [ ] of [ ] gpg [ ] failed}xms, 'Invalid signature');
t/api/gpg1.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IO::File;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Path to GnuPG v1.
my $PATH;
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
$PATH = 'gpg1';
if (!can_run('gpg1')) {
if (gpg_is_gpg1()) {
$PATH = 'gpg';
} else {
plan skip_all => 'gpg1 binary not available';
}
}
if (!gpg_is_new_enough($PATH)) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
}
plan tests => 7;
use_ok('PGP::Sign');
}
# Locate our test data directory for later use.
my $data = 't/data';
# Open and load our data file. This is the sample data that we'll be signing
# and checking signatures against.
t/api/large-data.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
} else {
plan tests => 3;
use_ok('PGP::Sign');
}
}
# The key ID and pass phrase to use for testing.
my $keyid = 'testing';
my $passphrase = 'testing';
# Create the object to use for testing.
my $signer;
if (gpg_is_gpg1()) {
my $home = File::Spec->catdir('t', 'data', 'gnupg1');
$signer = PGP::Sign->new(
{
home => $home,
path => 'gpg',
style => 'GPG1',
},
);
} else {
my $home = File::Spec->catdir('t', 'data', 'gnupg2');
$signer = PGP::Sign->new({ home => $home });
}
# Create a long message to sign. This is about 1MB.
my $message = ('a' x 76 . "\n") x 13618;
t/api/whitespace.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IO::File;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
} else {
plan tests => 10;
use_ok('PGP::Sign');
}
}
# The key ID and pass phrase to use for testing.
my $keyid = 'testing';
my $passphrase = 'testing';
# Create the objects to use for tests, one without munging enabled and one
# with.
my ($home, $signer, $munged);
if (gpg_is_gpg1()) {
$home = File::Spec->catdir('t', 'data', 'gnupg1');
$signer = PGP::Sign->new(
{
home => $home,
path => 'gpg',
style => 'GPG1',
},
);
$munged = PGP::Sign->new(
{
home => $home,
path => 'gpg',
munge => 1,
style => 'GPG1',
},
);
} else {
$home = File::Spec->catdir('t', 'data', 'gnupg2');
$signer = PGP::Sign->new({ home => $home });
$munged = PGP::Sign->new({ home => $home, munge => 1 });
}
t/docs/spdx-license.t view on Meta::CPAN
qr{ \A [.] / [.] pc/ }xms, # quilt metadata files
qr{ \A [.] /_build/ }xms, # Module::Build metadata
qr{ \A [.] /blib/ }xms, # Perl build system artifacts
qr{ \A [.] /cover_db/ }xms, # Artifacts from coverage testing
qr{ \A [.] /debian/ }xms, # Found in debian/* branches
qr{ \A [.] /docs/metadata/ }xms, # Package license should be fine
qr{ \A [.] /README ( [.] .* )? \z }xms, # Package license should be fine
qr{ \A [.] /share/ }xms, # Package license should be fine
qr{ \A [.] /t/data .* /metadata/ }xms, # Test metadata
qr{ \A [.] /t/data .* /output/ }xms, # Test output
qr{ \A [.] /t/data .* [.] gpg \z }xms, # Test GnuPG files
qr{ \A [.] /t/data .* [.] json \z }xms, # Test metadata
);
## use critic
# Only run this test during automated testing, since failure doesn't indicate
# any user-noticable flaw in the package itself.
skip_unless_automated('SPDX identifier tests');
# Check a single file for an occurrence of the string.
#
t/legacy/basic.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IO::File;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
} else {
use_ok('PGP::Sign');
}
}
# Locate our test data directory for later use.
my $data = 't/data';
# Open and load our data file. This is the sample data that we'll be signing
# and checking signatures against.
open(my $fh, '<', "$data/message");
my @data = <$fh>;
close($fh);
# The key ID and pass phrase to use for testing.
my $keyid = 'testing';
my $passphrase = 'testing';
# There are three possibilities: gpg is GnuPG v1, gpg is GnuPG v2 and v1 is
# not available, or gpg is GnuPG v2 and gpg1 is GnuPG v1. We ideally want to
# test both styles, but we'll take what we can get.
my @styles;
if (gpg_is_gpg1()) {
@styles = qw(GPG1);
} elsif (!can_run('gpg1')) {
@styles = qw(GPG);
} else {
@styles = qw(GPG GPG1);
}
# Run all the tests twice, once with GnuPG v2 and then with GnuPG v1.
for my $style (@styles) {
note("Testing PGPSTYLE $style");
local $PGP::Sign::PGPSTYLE = $style;
my $pgpdir = ($style eq 'GPG') ? 'gnupg2' : 'gnupg1';
local $PGP::Sign::PGPPATH = File::Spec->catdir($data, $pgpdir);
if ($style eq 'GPG1' && gpg_is_gpg1()) {
$PGP::Sign::PGPS = 'gpg';
$PGP::Sign::PGPV = 'gpg';
}
# Generate a signature.
my ($signature, $version) = pgp_sign($keyid, $passphrase, @data);
ok($signature, 'Sign');
is(PGP::Sign::pgp_error(), q{}, '...with no errors');
isnt($signature, undef, 'Signature');
is(PGP::Sign::pgp_error(), q{}, '...with no errors');
# Check signature.
t/legacy/basic.t view on Meta::CPAN
is(pgp_verify($signature, $version, q{ }),
$keyid, '...and does match munged');
}
# Test error handling.
is(pgp_verify('asfasdfasf', undef, @data), undef, 'Invalid signature');
my @errors = PGP::Sign::pgp_error();
my $errors = PGP::Sign::pgp_error();
like(
$errors[-1],
qr{^ Execution [ ] of [ ] gpg.? [ ] failed}xms,
'Invalid signature',
);
like(
$errors,
qr{\n Execution [ ] of [ ] gpg.? [ ] failed}xms,
'Errors contain newlines',
);
is($errors, join(q{}, @errors), 'Two presentations of errors match');
}
# Report the end of testing.
done_testing(21 * scalar(@styles) + 1);
t/legacy/locale.t view on Meta::CPAN
use 5.020;
use autodie;
use warnings;
use lib 't/lib';
use File::Spec;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);
# Check that GnuPG is available. If so, load the module and set the plan.
BEGIN {
if (!can_run('gpg')) {
plan skip_all => 'gpg binary not available';
} elsif (!gpg_is_new_enough('gpg')) {
plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
} else {
plan tests => 5;
use_ok('PGP::Sign', qw(pgp_sign pgp_verify pgp_error));
}
}
# Set the locale. I use French for testing; this won't be a proper test
# unless the locale is available on the local system, so hopefully this will
# be a common one.
local $ENV{LC_ALL} = 'fr_FR';
# Locate our test data directory for later use.
my $data = 't/data';
if (gpg_is_gpg1()) {
$PGP::Sign::PGPSTYLE = 'GPG1';
$PGP::Sign::PGPPATH = File::Spec->catdir($data, 'gnupg1');
$PGP::Sign::PGPS = 'gpg';
$PGP::Sign::PGPV = 'gpg';
} else {
$PGP::Sign::PGPPATH = File::Spec->catdir($data, 'gnupg2');
}
# Open and load our data file. This is the sample data that we'll be signing
# and checking signatures against.
open(my $fh, '<', "$data/message");
my @data = <$fh>;
close($fh);
t/lib/Test/PGP.pm view on Meta::CPAN
package Test::PGP 1.00;
use 5.020;
use autodie;
use version;
use warnings;
use Exporter qw(import);
use IPC::Cmd qw(run);
our @EXPORT_OK = qw(gpg_is_gpg1 gpg_is_new_enough);
# Test if the gpg binary found first on PATH is actually gpg1.
#
# Returns: 1 if so, undef if not or on any errors
sub gpg_is_gpg1 {
my $output;
if (!run(command => ['gpg', '--version'], buffer => \$output)) {
return;
}
return $output =~ m{ ^ gpg [^\n]* \s 1 [.] }xms;
}
# Test if the GnuPG binary is new enough to have the flags we expect.
#
# $path - Path to the GnuPG binary to test
#
# Returns: 1 if so, undef if not or on any errors
sub gpg_is_new_enough {
my ($path) = @_;
my $output;
if (!run(command => [$path, '--version'], buffer => \$output)) {
return;
}
if ($output =~ m{ ^ gpg [^\n]* \s (2 [.\d]+) }xms) {
my $version = $1;
return version->parse($version) >= version->parse('2.1.23');
} elsif ($output =~ m{ ^ gpg [^\n]* \s (1 [.\d]+) }xms) {
my $version = $1;
return version->parse($version) >= version->parse('1.4.20');
} else {
warn "Cannot determine version of $path\n";
return;
}
}
1;