summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalvatore Bonaccorso <carnil@debian.org>2020-05-15 21:43:28 +0200
committerSalvatore Bonaccorso <carnil@debian.org>2020-05-15 21:43:28 +0200
commita9d620f12037ecc62bc18915e2eb7e5b81c43afb (patch)
treefa8020b0b261d879cb76d3ae7f4104be79e23689
parentb528cc9c9bb8a277708ef8f5420c89baa437f067 (diff)
New upstream version 1.00
-rw-r--r--Changes11
-rw-r--r--MANIFEST14
-rw-r--r--META.yml6
-rw-r--r--Makefile.PL3
-rw-r--r--README82
-rw-r--r--SIGNATURE162
-rw-r--r--inc/Module/Install.pm35
-rw-r--r--inc/Module/Install/Base.pm2
-rw-r--r--inc/Module/Install/Can.pm13
-rw-r--r--inc/Module/Install/Fetch.pm2
-rw-r--r--inc/Module/Install/Makefile.pm2
-rw-r--r--inc/Module/Install/Metadata.pm2
-rw-r--r--inc/Module/Install/ReadmeFromPod.pm76
-rw-r--r--inc/Module/Install/Win32.pm2
-rw-r--r--inc/Module/Install/WriteAll.pm2
-rw-r--r--lib/GnuPG/Fingerprint.pm2
-rw-r--r--lib/GnuPG/Handles.pm2
-rw-r--r--lib/GnuPG/Interface.pm158
-rw-r--r--lib/GnuPG/Key.pm10
-rw-r--r--lib/GnuPG/Options.pm17
-rw-r--r--lib/GnuPG/PrimaryKey.pm2
-rw-r--r--t/000_setup.t54
-rw-r--r--t/MyTestSpecific.pm53
-rw-r--r--t/decrypt.t31
-rw-r--r--t/encrypt.t6
-rw-r--r--t/export_keys.t4
-rw-r--r--t/get_public_keys.t71
-rw-r--r--t/get_secret_keys.t68
-rw-r--r--t/list_public_keys.t4
-rw-r--r--t/list_secret_keys.t31
-rw-r--r--t/list_sigs.t4
-rw-r--r--t/sign_and_encrypt.t2
-rw-r--r--t/zzz_cleanup.t27
-rw-r--r--test/encrypted.2.gpg12
-rwxr-xr-xtest/fake-pinentry.pl28
-rw-r--r--test/gpg.conf (renamed from test/options)0
-rw-r--r--test/new_secret.pgp58
-rw-r--r--test/plain.2.txt1
-rw-r--r--test/public_keys.pgp (renamed from test/pubring.gpg)bin3418 -> 3418 bytes
-rw-r--r--test/secret-keys/1.0.test8
-rw-r--r--test/secret-keys/1.1.test11
-rw-r--r--test/secret-keys/1.2.test13
-rw-r--r--test/secret_keys.pgp (renamed from test/secring.gpg)bin1241 -> 1241 bytes
43 files changed, 844 insertions, 247 deletions
diff --git a/Changes b/Changes
index b42fd07..55e1ec6 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,16 @@
Revision history for GnuPG-Interface
+1.0 - 2020-05-13
+ - Limit support to GnuPG 2.2+ and 1.4
+ - Additional information from keys when using GnuPG 2.2 or higher
+ - Add support for use of agent/pinentry
+ - Updated options to add ignore_mdc_error and logging
+ - Improvements to tests
+ - Update pubkey_data documentation
+ - Special thanks to dkg on Github for a large PR with updates for GnuPG 2
+ - Thanks also to ntyni on Github for a pointer to test updates also dealing
+ with version changes
+
0.52 - 2016-02-16
- Skip "grp" records, generated by GPG 2.1; this suppresses "unknown
record type" warnings
diff --git a/MANIFEST b/MANIFEST
index d331caf..7c04bb9 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -28,6 +28,7 @@ MANIFEST.SKIP
META.yml
README
SIGNATURE
+t/000_setup.t
t/clearsign.t
t/decrypt.t
t/detach_sign.t
@@ -50,11 +51,16 @@ t/sign_and_encrypt.t
t/UserId.t
t/verify.t
t/wrap_call.t
+t/zzz_cleanup.t
test/encrypted.1.gpg
+test/encrypted.2.gpg
+test/fake-pinentry.pl
+test/gpg.conf
test/key.1.asc
-test/options
+test/new_secret.pgp
test/passphrase
test/plain.1.txt
+test/plain.2.txt
test/public-keys-sigs/1.0.test
test/public-keys-sigs/1.1.test
test/public-keys-sigs/2.0.test
@@ -63,8 +69,10 @@ test/public-keys/1.0.test
test/public-keys/1.1.test
test/public-keys/2.0.test
test/public-keys/2.1.test
-test/pubring.gpg
+test/public_keys.pgp
test/secret-keys/1.0.test
+test/secret-keys/1.1.test
+test/secret-keys/1.2.test
test/secret-keys/2.0.test
-test/secring.gpg
+test/secret_keys.pgp
test/signed.1.asc
diff --git a/META.yml b/META.yml
index c009b47..9c183c6 100644
--- a/META.yml
+++ b/META.yml
@@ -1,14 +1,14 @@
---
abstract: 'supply object methods for interacting with GnuPG'
author:
- - 'Frank J. Tobin'
+ - BPS
build_requires:
ExtUtils::MakeMaker: 6.36
configure_requires:
ExtUtils::MakeMaker: 6.36
distribution_type: module
dynamic_config: 1
-generated_by: 'Module::Install version 1.14'
+generated_by: 'Module::Install version 1.19'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -27,4 +27,4 @@ requires:
MooX::late: '0.014'
resources:
license: http://dev.perl.org/licenses/
-version: '0.52'
+version: '1.00'
diff --git a/Makefile.PL b/Makefile.PL
index 38aca27..7066a69 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,3 +1,4 @@
+BEGIN{push @INC, '.';}
use strict;
use warnings;
use inc::Module::Install;
@@ -12,7 +13,7 @@ die "Can't determine gpg version"
die "gpg (GnuPG) 1.4 or later is required" unless $1 >= 1.4;
-author 'Frank J. Tobin';
+author 'BPS';
abstract 'supply object methods for interacting with GnuPG';
name 'GnuPG-Interface';
version_from 'lib/GnuPG/Interface.pm';
diff --git a/README b/README
index fcb982a..2ef6dd4 100644
--- a/README
+++ b/README
@@ -5,8 +5,8 @@ SYNOPSIS
# A simple example
use IO::Handle;
use GnuPG::Interface;
-
- # settting up the situation
+
+ # setting up the situation
my $gnupg = GnuPG::Interface->new();
$gnupg->options->hash_init( armor => 1,
homedir => '/home/foobar' );
@@ -24,7 +24,7 @@ SYNOPSIS
# Now we'll go about encrypting with the options already set
my @plaintext = ( 'foobar' );
my $pid = $gnupg->encrypt( handles => $handles );
-
+
# Now we write to the input of GnuPG
print $input @plaintext;
close $input;
@@ -67,6 +67,18 @@ DESCRIPTION
handles appropriately, as described in "Bidirectional Communication with
Another Process" in perlipc.
+GnuPG Versions
+ As of this version of GnuPG::Interface, there are two supported versions
+ of GnuPG: 1.4.x and 2.2.x. The GnuPG download page
+ <https://gnupg.org/download/index.html> has updated information on the
+ currently supported versions.
+
+ GnuPG released 2.0 and 2.1 versions in the past and some packaging
+ systems may still provide these if you install the default "gpg",
+ "gnupg", "gnupg2", etc. packages. This modules supports only version
+ 2.2.x, so you may need to find additional package repositories or build
+ from source to get the updated version.
+
OBJECT METHODS
Initialization Methods
new( *%initialization_args* )
@@ -140,13 +152,26 @@ OBJECT METHODS
standard error, standard output, or standard error. If the status or
logger handle is not defined, this channel of communication is never
established with GnuPG, and so this information is not generated and
- does not come into play. If the passphrase data member handle of the
- handles object is not defined, but the the passphrase data member
- handle of GnuPG::Interface object is, GnuPG::Interface will handle
- passing this information into GnuPG for the user as a convience.
- Note that this will result in GnuPG::Interface storing the
- passphrase in memory, instead of having it simply 'pass-through' to
- GnuPG via a handle.
+ does not come into play.
+
+ If the passphrase data member handle of the handles object is not
+ defined, but the the passphrase data member handle of
+ GnuPG::Interface object is, GnuPG::Interface will handle passing
+ this information into GnuPG for the user as a convenience. Note that
+ this will result in GnuPG::Interface storing the passphrase in
+ memory, instead of having it simply 'pass-through' to GnuPG via a
+ handle.
+
+ If neither the passphrase data member of the GnuPG::Interface nor
+ the passphrase data member of the handles object is defined, then
+ GnuPG::Interface assumes that access and control over the secret key
+ will be handled by the running gpg-agent process. This represents
+ the simplest mode of operation with the GnuPG "stable" suite
+ (version 2.2 and later). It is also the preferred mode for tools
+ intended to be user-facing, since the user will be prompted directly
+ by gpg-agent for use of the secret key material. Note that for
+ programmatic use, this mode requires the gpg-agent and pinentry to
+ already be correctly configured.
Other Methods
get_public_keys( @search_strings )
@@ -228,10 +253,14 @@ EXAMPLES
$gnupg->options->hash_init( armor => 1,
recipients => [ 'ftobin@uiuc.edu',
- '0xABCD1234' ],
+ '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ],
meta_interactive => 0 ,
);
+ $gnupg->options->debug_level(4);
+
+ $gnupg->options->logger_file("/tmp/gnupg-$$-decrypt-".time().".log");
+
Encrypting
# We'll let the standard error of GnuPG pass through
# to our own standard error, by not creating
@@ -241,7 +270,7 @@ EXAMPLES
my $handles = GnuPG::Handles->new( stdin => $input,
stdout => $output );
-
+
# this sets up the communication
# Note that the recipients were specified earlier
# in the 'options' data member of the $gnupg object.
@@ -271,7 +300,7 @@ EXAMPLES
);
# indicate our pasphrase through the
- # convience method
+ # convenience method
$gnupg->passphrase( $passphrase );
# this sets up the communication
@@ -315,7 +344,7 @@ EXAMPLES
# a file written to disk
# Make sure you "use IO::File" if you use this module!
my $cipher_file = IO::File->new( 'encrypted.gpg' );
-
+
# this sets up the communication
my $pid = $gnupg->decrypt( handles => $handles );
@@ -346,19 +375,19 @@ EXAMPLES
# This time we'll just let GnuPG print to our own output
# and read from our input, because no input is needed!
my $handles = GnuPG::Handles->new();
-
- my @ids = ( 'ftobin', '0xABCD1234' );
+
+ my @ids = ( 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' );
# this time we need to specify something for
# command_args because --list-public-keys takes
# search ids as arguments
my $pid = $gnupg->list_public_keys( handles => $handles,
command_args => [ @ids ] );
-
+
waitpid $pid, 0;
Creating GnuPG::PublicKey Objects
- my @ids = [ 'ftobin', '0xABCD1234' ];
+ my @ids = [ 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ];
my @keys = $gnupg->get_public_keys( @ids );
@@ -372,7 +401,7 @@ EXAMPLES
command_args => [ qw( test/key.1.asc ) ],
handles => $handles,
);
-
+
my @out = <$handles->stdout()>;
waitpid $pid, 0;
@@ -411,12 +440,21 @@ NOTES
the process table.
BUGS
+ Large Amounts of Data
Currently there are problems when transmitting large quantities of
information over handles; I'm guessing this is due to buffering issues.
This bug does not seem specific to this package; IPC::Open3 also appears
affected.
- I don't know yet how well this modules handles parsing OpenPGP v3 keys.
+ OpenPGP v3 Keys
+ I don't know yet how well this module handles parsing OpenPGP v3 keys.
+
+ RHEL 7 Test Failures
+ Testing with the updates for version 1.00 we saw intermittent test
+ failures on RHEL 7 with GnuPG version 2.2.20. In some cases the tests
+ would all pass for several runs, then one would fail. We're unable to
+ reliably reproduce this so we would be interested in feedback from other
+ users.
SEE ALSO
GnuPG::Options, GnuPG::Handles, GnuPG::PublicKey, GnuPG::SecretKey, gpg,
@@ -427,8 +465,8 @@ LICENSE
under the same terms as Perl itself.
AUTHOR
- GnuPg::Interface is currently maintained by Jesse Vincent
- <jesse@cpan.org>.
+ GnuPG::Interface is currently maintained by Best Practical Solutions
+ <BPS@cpan.org>.
Frank J. Tobin, ftobin@cpan.org was the original author of the package.
diff --git a/SIGNATURE b/SIGNATURE
index 8875d2b..de01497 100644
--- a/SIGNATURE
+++ b/SIGNATURE
@@ -1,5 +1,5 @@
This file contains message digests of all files listed in MANIFEST,
-signed via the Module::Signature module, version 0.73.
+signed via the Module::Signature module, version 0.83.
To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:
@@ -12,81 +12,93 @@ the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.
-----BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
+Hash: SHA256
-SHA1 e890ff9e89a43f20c7bbe6501ca9eee9e0a34cc5 Changes
-SHA1 53b4359060763a93e39261003c33f21ee78ca263 MANIFEST
-SHA1 01aaeb25c70093c04dd0b27f8619332393830652 MANIFEST.SKIP
-SHA1 045613a39cbe7175a8aed8aea6442e7bfce202c1 META.yml
-SHA1 86643cffc4d799993109646b1d7e2e9bac64cdf7 Makefile.PL
-SHA1 429370a90369dce9cc5e1ba9f820406f0f0ca8d4 README
-SHA1 d2664c57b65686abbfbbe1e71229761625be4922 inc/Module/Install.pm
-SHA1 da41a8d9904f7b409b49a5f6c338d3eb305a2b4b inc/Module/Install/Base.pm
-SHA1 0db0afe19cd298abba248fa089e5525bd5ab3ab6 inc/Module/Install/Can.pm
-SHA1 e7152bfd5ca67d0e33f96d09c59d600bca5c1f15 inc/Module/Install/Fetch.pm
-SHA1 29ee1cb0dc262b00983e3a2f5cf00b538dff5069 inc/Module/Install/Makefile.pm
-SHA1 e963f80cfe255f16e55067d1feb6841cff3ed2fe inc/Module/Install/Metadata.pm
-SHA1 79f5b4199f622e8b05aac266b0c39f6a85bb303f inc/Module/Install/ReadmeFromPod.pm
-SHA1 65a1f09af1f4f9e47a98b6b45667c328b1b2f9c0 inc/Module/Install/Win32.pm
-SHA1 f191c49475b3f51775180cd4f7e41e3bdab7f85a inc/Module/Install/WriteAll.pm
-SHA1 d1cf614274e3b01254379758123b75034e1d2e80 lib/GnuPG/Fingerprint.pm
-SHA1 9508207dbd2a4b36a38e08b72f39fc4d26c49615 lib/GnuPG/Handles.pm
-SHA1 b2fe771ca9a1d719b222013e08b93ab57f7452e8 lib/GnuPG/HashInit.pm
-SHA1 1258ef1ec5e9586d48809ba53139c58373289d66 lib/GnuPG/Interface.pm
-SHA1 41cc5278e62c3298248cefbd27179d0322e65011 lib/GnuPG/Key.pm
-SHA1 c5a7cc8c23f009fee6f615c2e5966c4d0336ab5c lib/GnuPG/Options.pm
-SHA1 c6a1f74f35c4f2ea0dfc163202fa1c650acf6d2d lib/GnuPG/PrimaryKey.pm
-SHA1 a38e294729aac733fafcf9d7e4b7ef5fcb50e685 lib/GnuPG/PublicKey.pm
-SHA1 4b917013b36c4e66bdf3ae27cc8e056c9bd6be64 lib/GnuPG/Revoker.pm
-SHA1 3dbf6667b73b61dff5bc8db30b6dd81415297c09 lib/GnuPG/SecretKey.pm
-SHA1 f19dfa77fd83fcc520aa2246318b359c0ba844cd lib/GnuPG/Signature.pm
-SHA1 3267654e96c0fbe6805c466f193e92c5cd8a5e5b lib/GnuPG/SubKey.pm
-SHA1 acfec9fd5e879711280d5ac8ebfd667fde8d4f1e lib/GnuPG/UserAttribute.pm
-SHA1 d70a9e4c89b2fe445c733dc9c177d62cc9f44826 lib/GnuPG/UserId.pm
-SHA1 367fdb308292a9c005afffef49ff9096a20a4da3 t/Fingerprint.t
-SHA1 8791d014e4efd4cf11998386e1651cc4eb16dd26 t/Interface.t
-SHA1 980fcd5a1d302e65cc2414be96d5f3a4266e8308 t/MyTest.pm
-SHA1 e12da2a4da6d98e80d91278790eca9dc82e610ee t/MyTestSpecific.pm
-SHA1 ccd942d9f00627253d7eb9c011116dc5671639b8 t/UserId.t
-SHA1 e2e53ab9458c61d32b973a16d32573a954e13769 t/clearsign.t
-SHA1 6808b2b88bb2f1aa9398d7bb32993ae679cf869c t/decrypt.t
-SHA1 b828dfb74321c117264b4418cf57d2da3d96f7c4 t/detach_sign.t
-SHA1 194562685ecfe0ba09b8238bbd6b86f0bd6f9d7d t/encrypt.t
-SHA1 2d8d00e2bd767c658c2a795ec970398af3c87ebe t/encrypt_symmetrically.t
-SHA1 8d3cf3e7433e59c393193ae7df4ef16b094e3f96 t/export_keys.t
-SHA1 02f4685776d8556fafc88644ff51677ce6b4b4c6 t/get_public_keys.t
-SHA1 a0c8a3a1b653593b96ad511d2b348acf84411501 t/get_secret_keys.t
-SHA1 5a4cbcdac983766a60f5f25db20bf81f251c9b3a t/import_keys.t
-SHA1 7d4b60343a07ab530adbfc02acc3212463a46190 t/list_public_keys.t
-SHA1 489784ddcc8c1baf5857bb535394935f0472c7f5 t/list_secret_keys.t
-SHA1 10b57083d7767a6d13285e18449bb37333cd9676 t/list_sigs.t
-SHA1 07a602cbb5a78518cd4cccfb7007e80564a19e1e t/passphrase_handling.t
-SHA1 99c53aa0a919cbf16cba74be84c6cff3af0cd097 t/sign.t
-SHA1 8b6aec0a94d6ac5a0d40dffc52cc2a21a9c934e8 t/sign_and_encrypt.t
-SHA1 cabbf4e667027f9bb7958673bc9b8be2d1577e29 t/verify.t
-SHA1 8fd17bc4ad8ac4c4357503edfe2d1a952a44c28b t/wrap_call.t
-SHA1 58f58338a2922798c59c5e852bd0110541f27e2d test/encrypted.1.gpg
-SHA1 b012a47f295ee9dcc955560b9a78c0ad3a61e137 test/key.1.asc
-SHA1 1290379acadab2cc713d659c7c3feff2b0923f75 test/options
-SHA1 4e1243bd22c66e76c2ba9eddc1f91394e57f9f83 test/passphrase
-SHA1 59c0e6436b38645144d17ce11ac4aabfdd43e960 test/plain.1.txt
-SHA1 7d94ea032bdbb0104c1dc73583ec64ade6294495 test/public-keys-sigs/1.0.test
-SHA1 63d93054decf9ff6c2dc99eb03f131b55af4ee43 test/public-keys-sigs/1.1.test
-SHA1 bd9892a93f802c68109b11b756f79f6b0292eb1a test/public-keys-sigs/2.0.test
-SHA1 73d90696020a01753cda984262a2831dcc6ac0d7 test/public-keys-sigs/2.1.test
-SHA1 82d483adc6d203c79856a70dd259370f6efdeef7 test/public-keys/1.0.test
-SHA1 86056ad37b8bb67d55ac61b5d5a27ac4bbd1cceb test/public-keys/1.1.test
-SHA1 a8e97a2439671dae0dd29a2404c321ccb686ba7a test/public-keys/2.0.test
-SHA1 54d2c13bf3b73b7582edef091175dfe3763ddf59 test/public-keys/2.1.test
-SHA1 4349906c08f65af3b13e7b441ac4dd2e637bfeae test/pubring.gpg
-SHA1 e740841597775e3da265ec14e411ed0432bae5e2 test/secret-keys/1.0.test
-SHA1 3bd6135279f9ae23e32680707c6170910421e5de test/secret-keys/2.0.test
-SHA1 9ce5508cd8cefadc4c9bf2842864b52e87b1826e test/secring.gpg
-SHA1 981418a80bf7dab91b63608cfd1ddf5091f89ad7 test/signed.1.asc
+SHA256 40fd03ca91f8ff428c8dbe217c646e7d8c6777b2016d95b5a4003dce0ce30143 Changes
+SHA256 a88d644002b8f00f1c369da77144fc79cb289ca2c7912eadd44c246ee08c2d1c MANIFEST
+SHA256 93d50f37fd222dbe3a8590a019f39d7a79ba725227b53ea6f9dd195830e2fb77 MANIFEST.SKIP
+SHA256 8bd01c7a116d2cbd561e0d56199e95967e5b1ca9b24f0fac15a9b39486295088 META.yml
+SHA256 898ed6f95b1700265f483d0fad3fe337438ac022c597bdfe904a9bf987410655 Makefile.PL
+SHA256 c0d74f2b2987828dc66017694f36454f429b5be29ca235db1e626f12d67cc1b2 README
+SHA256 67d139199c03b8bf8447a5a62f0d0b6dc1bd5bf6dbe04de6d21998c577823ed6 inc/Module/Install.pm
+SHA256 6ebcc53a161dd5dc0aae69e4704575f2b00181901d768a82e26722a309cfdbe4 inc/Module/Install/Base.pm
+SHA256 d3f8c839d03fd21c197d05362dbb277cd7cadb15da6390d124b61e851f15146e inc/Module/Install/Can.pm
+SHA256 e9e72e18921c10c87bc4ea4c20af83e52015b9f5775d00ac64073042403717ca inc/Module/Install/Fetch.pm
+SHA256 a7a681bf2c9eee58a372cb642ffe42b0301d1200432ba8de9f7791cd1ecc9827 inc/Module/Install/Makefile.pm
+SHA256 aa887fa65a5eb6bbd1805706ce298b3f3cd55b353ecfd37aa7d35ae419331a49 inc/Module/Install/Metadata.pm
+SHA256 53825bc78e4c910b888160bc148c8bc211be58e02b99c8edcbf4854f95faa049 inc/Module/Install/ReadmeFromPod.pm
+SHA256 26b166ff62aacdb55317d1659f160aa4935097eea9810ea980e6d747206b5dc0 inc/Module/Install/Win32.pm
+SHA256 5f73a6851a91ea44e65b924f918743ad6e860620ad7a38a39d0295e0c5652a9f inc/Module/Install/WriteAll.pm
+SHA256 21170a181c773923aa779477d62eed6357f44c9ab27b2abd216f097d78901c9e lib/GnuPG/Fingerprint.pm
+SHA256 341fe948514a63dc081708c3a5356e0237ef1f333d964d99e9829a9e956f82d9 lib/GnuPG/Handles.pm
+SHA256 fa9fca26659ef2baba11543b4cbcb141dc6d66191cea9bc07140a8cb3bccec9f lib/GnuPG/HashInit.pm
+SHA256 64cfdfa5cd59c60cbbb36cd4c7c9a8cd87a39049f5ba690155910508005324e7 lib/GnuPG/Interface.pm
+SHA256 f53d8e10107713b8c72d1e0ae13021964344ed205e412fb49621ada6fd32bf3e lib/GnuPG/Key.pm
+SHA256 729f79dfaf58ba9d7321a8005f90a9dea1614b61556c50120bc323fe753e0022 lib/GnuPG/Options.pm
+SHA256 de1dbcd19ece6fd939367f1132f08afdede2553e4c20028d08c186d10ec0d9c8 lib/GnuPG/PrimaryKey.pm
+SHA256 21e7704eb1b290470661c8d256b5391941203ce42df10ef87862307a18f3a5e8 lib/GnuPG/PublicKey.pm
+SHA256 797d9e9abebb03aa15e8f4de9285216febbc608e41f099002f6160268d087de5 lib/GnuPG/Revoker.pm
+SHA256 9e899d4cd41d95203dcfca7041c8ae1dc9c01fa828b11ca09529dc4f0503d999 lib/GnuPG/SecretKey.pm
+SHA256 8238221e3300ea420ebd92eec784a8d4c8e32ca91a104d854dcb72e42cfd2158 lib/GnuPG/Signature.pm
+SHA256 879000dc23cbce49d8b6ecb179afa45ea3a91ee8c5272dc3c953fd2253d53c31 lib/GnuPG/SubKey.pm
+SHA256 89c853903cc9220a8e2ae05483b5b295ef0d100fe91066ab955addf720b26249 lib/GnuPG/UserAttribute.pm
+SHA256 57892e62bf1291be5dbf56f75691022f344ef3850524e1d65051bdd6dc4797c8 lib/GnuPG/UserId.pm
+SHA256 dae227d6b1c5dfc5fa0e404c747ed3258a221dea7ab773927bd199530c299b38 t/000_setup.t
+SHA256 2ba7457456a05dc99a4ad7240127c0fa04655c7bcefd41ca40bf8cc89e72fd0c t/Fingerprint.t
+SHA256 4e3d72d1d66cde3777a1aaa43b482edfab79845e76570f5fab09532761f47cc5 t/Interface.t
+SHA256 13a39c1c8e9ef2335b01c194caa83b48fd15bee9bc35723df2532fac6cbcb204 t/MyTest.pm
+SHA256 96050358ec301df2c456a4216817bfd6cb359fae4348a717c4a56325de522fcc t/MyTestSpecific.pm
+SHA256 ecc3d7593ee9580b2a247a8bbe8384e51f4659d21d21878d0e8925d8520d55a1 t/UserId.t
+SHA256 1c1105851a3a35632b09fa3f09efb0bbfee788fba38f124e732acc7c18cce0c9 t/clearsign.t
+SHA256 e06f37b7379b8e970aef4f1b1e0e6d7c0b12fcd15a8890db990dc56fa1dbc4e1 t/decrypt.t
+SHA256 5dadb07fda0101d02e9a7bcd81142d5f3c79ff0746cc2ec3d02db0056adc2e79 t/detach_sign.t
+SHA256 d2cd3e45ddcafc924573c675d9613203633fc37c1deeba0f4338781b550a9ab9 t/encrypt.t
+SHA256 2f9d931effb1b8bfdb20c250ae7ad0cdfac1b9546408e2b1c722b8559f7d57f6 t/encrypt_symmetrically.t
+SHA256 5bad9360f0e5cfe956c7aed6691da13a233eaf869d6b9c89d8717970f450035d t/export_keys.t
+SHA256 8f31e088ceb6dac7b61b23b5e6f2857ff377f371945df68e6f48bff443ca9588 t/get_public_keys.t
+SHA256 b1a0059daf0f74eb56a6bf644db37f50b0fb9fd8a0a4460b3b61b8a6e698e448 t/get_secret_keys.t
+SHA256 e6551cf8c9b417e97ad7ae0ba17cba696420d0fd82f6dbfed906ba95c990a3ce t/import_keys.t
+SHA256 3d1a6a667e365bcfe4fe21af2d13dfb0aced9077bf140cfa859b955ba9def388 t/list_public_keys.t
+SHA256 bc59185d9c1634eca69c08b9541556902f81cde96fc74ee898472abf05ff61b4 t/list_secret_keys.t
+SHA256 233a3438cadd21602d821271e4f4d117e131b7d09098543c556689f3a00bb840 t/list_sigs.t
+SHA256 998f85987922a9f55895b696808c677b036e199ba6054773cc0318ab55f21150 t/passphrase_handling.t
+SHA256 dbba8768ec668f5963cda97b50ebf0bd4759cf53c7d584afe724e05f2e3ecc32 t/sign.t
+SHA256 58dd4921945ed7347ba028f52c87fe5ea43487ec3c4765afb73e97686e277a15 t/sign_and_encrypt.t
+SHA256 845140735d2be4acc0ae4c3459ef06646d26843584d370b18f49fcc17d27ccae t/verify.t
+SHA256 4fe916000a3a23c7a06386252ae5731ffb5c08d2f03c07826908529844cc3c27 t/wrap_call.t
+SHA256 a38c6762ac3bc3fe324a3e2a729259f780cb6d5d1f5fec24a2b362010be475e0 t/zzz_cleanup.t
+SHA256 5a829fe0270a33d5157563fe555f395aae1c0fa6ed0aaf68308af50f880fa259 test/encrypted.1.gpg
+SHA256 d595ad88a2af6192660ef386fb36ac90d55088e5a9e55294fb54c06d9260fd97 test/encrypted.2.gpg
+SHA256 90de0e214326e6cc05c49813836ebc9f0b67805b8d8d37bd160dd34c02334b12 test/fake-pinentry.pl
+SHA256 73e66c46bb07993b2df8b785c90737dc4cd708a3c6ae50a8721d4a20434cd62f test/gpg.conf
+SHA256 d51ec60087f52f6f4e7dfc2cd2eca5b2130c06051fadaf99994eeb14954d80a5 test/key.1.asc
+SHA256 b9d3444cdd0a8bee742dccf550d090a8ad36415fc5e96831fd3ec82dc1c574d3 test/new_secret.pgp
+SHA256 f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2 test/passphrase
+SHA256 369c75d88ce40c4f2440cc3e0b1149990eed0702f1ea7d613489eb48adfa42ea test/plain.1.txt
+SHA256 a6e9c6e238daf6212dfc51a42dc5c6809b3100a68d2323b6a598995e81a4a100 test/plain.2.txt
+SHA256 fda2ddcbe111a6e41f5a0866e93174d6517941c1ca67c84e62d8a576ee02dada test/public-keys-sigs/1.0.test
+SHA256 ac786cf67af312cc69070cbef261616cc6dde6b4a01ea82cbf3258ed6ee5bb6d test/public-keys-sigs/1.1.test
+SHA256 ff749cc7df40c450355d411e1e21b525836dd65d3b6f63d2924cbf3cdd5dba15 test/public-keys-sigs/2.0.test
+SHA256 db9438e4c0c6cbcb9c6484c1b09ba332609631fe2966ba553821a526c96e0d2d test/public-keys-sigs/2.1.test
+SHA256 384b4f167fe72745bb69e1e987fc927bd92677d3d51276198b43b1b6d10873df test/public-keys/1.0.test
+SHA256 11287dcbac0d9c62a2796ce7d5e26bf3f301a5db8e5ff00c8d69a0c627dab376 test/public-keys/1.1.test
+SHA256 06a81da24c9a2860b411188577068dd285ba469c5023eb1bac6d3cc489e6bf2c test/public-keys/2.0.test
+SHA256 ba075f34630a38dcc9d368f23ccfe0d6116d9eb05190bdb01337f76dffe96acd test/public-keys/2.1.test
+SHA256 6b3ef18f32c501a3cfdd94644594055796271ac2634b21cb82c5126c60454de0 test/public_keys.pgp
+SHA256 f37f6448e73bdb18977c459e949fa30e59e1d6abb3a0533005191112c8dd0e34 test/secret-keys/1.0.test
+SHA256 53100dae1939540999ee2dea39e46077fdaa905870dea5e426eb5add32290619 test/secret-keys/1.1.test
+SHA256 8eb233c6c122e84cb3ccd758c1787300e93aeb38b16e986761a03455e2ed1f8c test/secret-keys/1.2.test
+SHA256 83c081e123ec2453b42388865b8948e8bbc5276c739ee6087aad4cdc98f127a5 test/secret-keys/2.0.test
+SHA256 b84cf371c144ae5bdb201c7a8fa0461562ac7d87395c94406b8611bc855d5bb3 test/secret_keys.pgp
+SHA256 1fb329b56306f80d4c23398f2f8076b8f7fffa19fcda7193be24c8792807ea80 test/signed.1.asc
-----BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.22 (GNU/Linux)
-iEYEARECAAYFAlTioEQACgkQMflWJZZAbqAlGwCcDi0uU+q3nG9DQqg/1nQLdUxa
-BVsAn1DqJdBvYqKtHr/XWn6T0Km0dLBp
-=6yHK
+iQEzBAEBCAAdFiEExJs3Lyv4ShkBFmAnDfCig/6sgLIFAl68Uk8ACgkQDfCig/6s
+gLJp7gf/Ys444GmW0i6k+NhnW/kpFqn+P8seuGMfIoxFm04nr5AWhtmac5rkjk0k
+FGyoxL8NX3Zzxt55o4mN3+edDRsWRummFqa1clpHl3FSMye/GRXQUsavTLVnjCNX
+DyE8/38cdaGcOQccLisS0Hud+C4HEXK/zW9EKyr6shGkMSkx8sKwe7ghN8yYAoMr
+JnS8Bp1q1/BUpc9PosNsC6dEmPrHkhN5fj01APvNm2SbR7ipk0Njn9Xwtip+8yKY
+vZRnC4lzDn5Og0VVGyUCYjpocQkzFWc0X7UMO7bhEqmH3eyYgh+z8OT7/hO3tw/K
+MnbjDHaYcmmnDhN3gwldobM6/Akb6Q==
+=ClL/
-----END PGP SIGNATURE-----
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index ff767fa..7ba98c2 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -31,7 +31,7 @@ BEGIN {
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
- $VERSION = '1.14';
+ $VERSION = '1.19';
# Storage for the pseudo-singleton
$MAIN = undef;
@@ -244,6 +244,8 @@ sub new {
}
return $args{_self} if $args{_self};
+ $base_path = VMS::Filespec::unixify($base_path) if $^O eq 'VMS';
+
$args{dispatch} ||= 'Admin';
$args{prefix} ||= 'inc';
$args{author} ||= ($^O eq 'VMS' ? '_author' : '.author');
@@ -322,7 +324,7 @@ sub find_extensions {
my ($self, $path) = @_;
my @found;
- File::Find::find( sub {
+ File::Find::find( {no_chdir => 1, wanted => sub {
my $file = $File::Find::name;
return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
my $subpath = $1;
@@ -336,7 +338,7 @@ sub find_extensions {
# correctly. Otherwise, root through the file to locate the case-preserved
# version of the package name.
if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
- my $content = Module::Install::_read($subpath . '.pm');
+ my $content = Module::Install::_read($File::Find::name);
my $in_pod = 0;
foreach ( split /\n/, $content ) {
$in_pod = 1 if /^=\w/;
@@ -351,7 +353,7 @@ sub find_extensions {
}
push @found, [ $file, $pkg ];
- }, $path ) if -d $path;
+ }}, $path ) if -d $path;
@found;
}
@@ -373,8 +375,6 @@ sub _caller {
return $call;
}
-# Done in evals to avoid confusing Perl::MinimumVersion
-eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _read {
local *FH;
open( FH, '<', $_[0] ) or die "open($_[0]): $!";
@@ -383,16 +383,6 @@ sub _read {
close FH or die "close($_[0]): $!";
return $string;
}
-END_NEW
-sub _read {
- local *FH;
- open( FH, "< $_[0]" ) or die "open($_[0]): $!";
- binmode FH;
- my $string = do { local $/; <FH> };
- close FH or die "close($_[0]): $!";
- return $string;
-}
-END_OLD
sub _readperl {
my $string = Module::Install::_read($_[0]);
@@ -413,8 +403,6 @@ sub _readpod {
return $string;
}
-# Done in evals to avoid confusing Perl::MinimumVersion
-eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _write {
local *FH;
open( FH, '>', $_[0] ) or die "open($_[0]): $!";
@@ -424,17 +412,6 @@ sub _write {
}
close FH or die "close($_[0]): $!";
}
-END_NEW
-sub _write {
- local *FH;
- open( FH, "> $_[0]" ) or die "open($_[0]): $!";
- binmode FH;
- foreach ( 1 .. $#_ ) {
- print FH $_[$_] or die "print($_[0]): $!";
- }
- close FH or die "close($_[0]): $!";
-}
-END_OLD
# _version is for processing module versions (eg, 1.03_05) not
# Perl versions (eg, 5.8.1).
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 4206347..9fa42c2 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
use strict 'vars';
use vars qw{$VERSION};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
}
# Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 9929b1b..d65c753 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -121,6 +121,15 @@ END_C
# Can we locate a (the) C compiler
sub can_cc {
my $self = shift;
+
+ if ($^O eq 'VMS') {
+ require ExtUtils::CBuilder;
+ my $builder = ExtUtils::CBuilder->new(
+ quiet => 1,
+ );
+ return $builder->have_compiler;
+ }
+
my @chunks = split(/ /, $Config::Config{cc}) or return;
# $Config{cc} may contain args; try to find out the program part
@@ -151,4 +160,4 @@ if ( $^O eq 'cygwin' ) {
__END__
-#line 236
+#line 245
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index 3d8de76..3072b08 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 66993af..13a4464 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index e547fa0..11bf971 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
diff --git a/inc/Module/Install/ReadmeFromPod.pm b/inc/Module/Install/ReadmeFromPod.pm
index b5e03c3..3738232 100644
--- a/inc/Module/Install/ReadmeFromPod.pm
+++ b/inc/Module/Install/ReadmeFromPod.pm
@@ -7,12 +7,41 @@ use warnings;
use base qw(Module::Install::Base);
use vars qw($VERSION);
-$VERSION = '0.22';
+$VERSION = '0.30';
+
+{
+
+ # these aren't defined until after _require_admin is run, so
+ # define them so prototypes are available during compilation.
+ sub io;
+ sub capture(&;@);
+
+#line 28
+
+ my $done = 0;
+
+ sub _require_admin {
+
+ # do this once to avoid redefinition warnings from IO::All
+ return if $done;
+
+ require IO::All;
+ IO::All->import( '-binary' );
+
+ require Capture::Tiny;
+ Capture::Tiny->import ( 'capture' );
+
+ return;
+ }
+
+}
sub readme_from {
my $self = shift;
return unless $self->is_admin;
+ _require_admin;
+
# Input file
my $in_file = shift || $self->_all_from
or die "Can't determine file to make readme_from";
@@ -50,6 +79,8 @@ sub readme_from {
$out_file = $self->_readme_htm($in_file, $out_file, $options);
} elsif ($format eq 'man') {
$out_file = $self->_readme_man($in_file, $out_file, $options);
+ } elsif ($format eq 'md') {
+ $out_file = $self->_readme_md($in_file, $out_file, $options);
} elsif ($format eq 'pdf') {
$out_file = $self->_readme_pdf($in_file, $out_file, $options);
}
@@ -67,10 +98,10 @@ sub _readme_txt {
$out_file ||= 'README';
require Pod::Text;
my $parser = Pod::Text->new( @$options );
- open my $out_fh, '>', $out_file or die "Could not write file $out_file:\n$!\n";
+ my $io = io->file($out_file)->open(">");
+ my $out_fh = $io->io_handle;
$parser->output_fh( *$out_fh );
$parser->parse_file( $in_file );
- close $out_fh;
return $out_file;
}
@@ -79,11 +110,14 @@ sub _readme_htm {
my ($self, $in_file, $out_file, $options) = @_;
$out_file ||= 'README.htm';
require Pod::Html;
- Pod::Html::pod2html(
- "--infile=$in_file",
- "--outfile=$out_file",
- @$options,
- );
+ my ($o) = capture {
+ Pod::Html::pod2html(
+ "--infile=$in_file",
+ "--outfile=-",
+ @$options,
+ );
+ };
+ io->file($out_file)->print($o);
# Remove temporary files if needed
for my $file ('pod2htmd.tmp', 'pod2htmi.tmp') {
if (-e $file) {
@@ -99,7 +133,10 @@ sub _readme_man {
$out_file ||= 'README.1';
require Pod::Man;
my $parser = Pod::Man->new( @$options );
- $parser->parse_from_file($in_file, $out_file);
+ my $io = io->file($out_file)->open(">");
+ my $out_fh = $io->io_handle;
+ $parser->output_fh( *$out_fh );
+ $parser->parse_file( $in_file );
return $out_file;
}
@@ -111,11 +148,20 @@ sub _readme_pdf {
or die "Could not generate $out_file because pod2pdf could not be found\n";
my $parser = App::pod2pdf->new( @$options );
$parser->parse_from_file($in_file);
- open my $out_fh, '>', $out_file or die "Could not write file $out_file:\n$!\n";
- select $out_fh;
- $parser->output;
- select STDOUT;
- close $out_fh;
+ my ($o) = capture { $parser->output };
+ io->file($out_file)->print($o);
+ return $out_file;
+}
+
+sub _readme_md {
+ my ($self, $in_file, $out_file, $options) = @_;
+ $out_file ||= 'README.md';
+ require Pod::Markdown;
+ my $parser = Pod::Markdown->new( @$options );
+ my $io = io->file($out_file)->open(">");
+ my $out_fh = $io->io_handle;
+ $parser->output_fh( *$out_fh );
+ $parser->parse_file( $in_file );
return $out_file;
}
@@ -134,5 +180,5 @@ sub _all_from {
__END__
-#line 254
+#line 316
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index 9706e5f..f7aa615 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index dbedc00..2db861a 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '1.14';
+ $VERSION = '1.19';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
diff --git a/lib/GnuPG/Fingerprint.pm b/lib/GnuPG/Fingerprint.pm
index fcb1028..81c38a7 100644
--- a/lib/GnuPG/Fingerprint.pm
+++ b/lib/GnuPG/Fingerprint.pm
@@ -20,7 +20,7 @@ with qw(GnuPG::HashInit);
has as_hex_string => (
isa => 'Any',
- is => 'rw',
+ is => 'rw',
);
sub compare {
diff --git a/lib/GnuPG/Handles.pm b/lib/GnuPG/Handles.pm
index b30ca57..3eee0e3 100644
--- a/lib/GnuPG/Handles.pm
+++ b/lib/GnuPG/Handles.pm
@@ -73,7 +73,7 @@ GnuPG::Handles - GnuPG handles bundle
= ( IO::Handle->new(), IO::Handle->new(), IO::Handle->new(),
IO::Handle->new(), IO::Handle->new(), IO::Handle->new(),
);
-
+
my $handles = GnuPG::Handles->new
( stdin => $stdin,
stdout => $stdout,
diff --git a/lib/GnuPG/Interface.pm b/lib/GnuPG/Interface.pm
index f952f3e..b11e4d2 100644
--- a/lib/GnuPG/Interface.pm
+++ b/lib/GnuPG/Interface.pm
@@ -28,7 +28,7 @@ use Math::BigInt try => 'GMP';
use GnuPG::Options;
use GnuPG::Handles;
-$VERSION = '0.52';
+$VERSION = '1.00';
has $_ => (
isa => 'Any',
@@ -36,6 +36,25 @@ has $_ => (
clearer => 'clear_' . $_,
) for qw(call passphrase);
+# NB: GnuPG versions
+#
+# There are now two supported versions of GnuPG: legacy 1.4 and stable 2.2
+# They are detected and each behave slightly differently.
+#
+# When using features specific to branches, check that the system's
+# version of gpg corresponds to the branch.
+#
+# legacy: 1.4
+# stable: >= 2.2
+#
+# You can find examples of version comparison in the tests.
+has version => (
+ isa => 'Str',
+ is => 'ro',
+ reader => 'version',
+ writer => '_set_version',
+);
+
has options => (
isa => 'GnuPG::Options',
is => 'rw',
@@ -52,6 +71,7 @@ sub BUILD {
$self->hash_init( call => 'gpg' );
$self->hash_init(%$args);
+ $self->_set_version($self->_version());
}
struct(
@@ -77,17 +97,18 @@ sub wrap_call( $% ) {
$handles->stdout('>&STDOUT') unless $handles->stdout();
$handles->stderr('>&STDERR') unless $handles->stderr();
- # so call me sexist; English just doen't cope well
- my $needs_passphrase_handled_for_him
- = ( $self->passphrase() and not $handles->passphrase() ) ? 1 : 0;
+ $self->passphrase("\n") unless $self->passphrase();
+
+ my $needs_passphrase_handled
+ = ( $self->passphrase() =~ m/\S/ and not $handles->passphrase() ) ? 1 : 0;
- if ($needs_passphrase_handled_for_him) {
+ if ($needs_passphrase_handled) {
$handles->passphrase( IO::Handle->new() );
}
my $pid = $self->fork_attach_exec(%args);
- if ($needs_passphrase_handled_for_him) {
+ if ($needs_passphrase_handled) {
my $passphrase_handle = $handles->passphrase();
print $passphrase_handle $self->passphrase();
close $passphrase_handle;
@@ -106,6 +127,16 @@ sub fork_attach_exec( $% ) {
my ( $self, %args ) = @_;
my $handles = $args{handles} or croak 'no GnuPG::Handles passed';
+ my $use_loopback_pinentry = 0;
+
+ # Don't use loopback pintentry for legacy (1.4) GPG
+ #
+ # Check that $version is populated before running cmp_version. If
+ # we are invoked as part of BUILD to populate $version, then any
+ # methods that depend on $version will fail. We don't care about
+ # loopback when we're called just to check gpg version.
+ $use_loopback_pinentry = 1
+ if ($handles->passphrase() && $self->version && $self->cmp_version($self->version, '2.2') > 0 );
# deprecation support
$args{commands} ||= $args{gnupg_commands};
@@ -293,8 +324,12 @@ sub fork_attach_exec( $% ) {
$self->options->$option($fileno);
}
+ my @args = $self->options->get_args();
+ push @args, '--pinentry-mode', 'loopback'
+ if $use_loopback_pinentry;
+
my @command = (
- $self->call(), $self->options->get_args(),
+ $self->call(), @args,
@commands, @command_args
);
@@ -659,15 +694,16 @@ sub encrypt( $% ) {
sub encrypt_symmetrically( $% ) {
my ( $self, %args ) = @_;
- # Strip the homedir and put it back after encrypting; gpg 2.0.x
- # fails symmetric encryption when one is passed.
+ # Strip the homedir and put it back after encrypting;
my $homedir = $self->options->homedir;
- $self->options->clear_homedir;
+ $self->options->clear_homedir
+ unless $self->cmp_version($self->version, '2.2') >= 0;
my $pid = $self->wrap_call(
%args,
commands => ['--symmetric']
);
- $self->options->homedir($homedir);
+ $self->options->homedir($homedir)
+ unless $self->cmp_version($self->version, '2.2') >= 0;
return $pid;
}
@@ -762,15 +798,36 @@ sub search_keys( $% ) {
);
}
-sub version {
+sub _version {
my ( $self ) = @_;
my $out = IO::Handle->new;
my $handles = GnuPG::Handles->new( stdout => $out );
- $self->wrap_call( commands => [ '--version' ], handles => $handles );
+ my $pid = $self->wrap_call( commands => [ '--no-options', '--version' ], handles => $handles );
my $line = $out->getline;
$line =~ /(\d+\.\d+\.\d+)/;
- return $1;
+
+ my $version = $1;
+ unless ($self->cmp_version($version, '2.2') >= 0 or
+ ($self->cmp_version($version, '1.4') >= 0 and $self->cmp_version($version, '1.5') < 0 )) {
+ croak "GnuPG Version 1.4 or 2.2+ required";
+ }
+ waitpid $pid, 0;
+
+ return $version;
+}
+
+sub cmp_version($$) {
+ my ( $self, $a, $b ) = (@_);
+ my @a = split '\.', $a;
+ my @b = split '\.', $b;
+ @a > @b
+ ? push @b, (0) x (@a-@b)
+ : push @a, (0) x (@b-@a);
+ for ( my $i = 0; $i < @a; $i++ ) {
+ return $a[$i] <=> $b[$i] if $a[$i] <=> $b[$i];
+ }
+ return 0;
}
sub test_default_key_passphrase() {
@@ -808,7 +865,7 @@ sub test_default_key_passphrase() {
# all we realy want to check is the status fh
while (<$status>) {
- if (/^\[GNUPG:\]\s*GOOD_PASSPHRASE/) {
+ if (/^\[GNUPG:\]\s*(GOOD_PASSPHRASE|SIG_CREATED)/) {
waitpid $pid, 0;
return 1;
}
@@ -833,8 +890,8 @@ GnuPG::Interface - Perl interface to GnuPG
# A simple example
use IO::Handle;
use GnuPG::Interface;
-
- # settting up the situation
+
+ # setting up the situation
my $gnupg = GnuPG::Interface->new();
$gnupg->options->hash_init( armor => 1,
homedir => '/home/foobar' );
@@ -852,7 +909,7 @@ GnuPG::Interface - Perl interface to GnuPG
# Now we'll go about encrypting with the options already set
my @plaintext = ( 'foobar' );
my $pid = $gnupg->encrypt( handles => $handles );
-
+
# Now we write to the input of GnuPG
print $input @plaintext;
close $input;
@@ -906,6 +963,19 @@ B<clearsign>. One then interacts with with the handles
appropriately, as described in
L<perlipc/"Bidirectional Communication with Another Process">.
+=head1 GnuPG Versions
+
+As of this version of GnuPG::Interface, there are two supported
+versions of GnuPG: 1.4.x and 2.2.x. The
+L<GnuPG download page|https://gnupg.org/download/index.html> has
+updated information on the currently supported versions.
+
+GnuPG released 2.0 and 2.1 versions in the past and some packaging
+systems may still provide these if you install the default C<gpg>,
+C<gnupg>, C<gnupg2>, etc. packages. This modules supports only
+version 2.2.x, so you may need to find additional package
+repositories or build from source to get the updated version.
+
=head1 OBJECT METHODS
=head2 Initialization Methods
@@ -1005,13 +1075,25 @@ and standard error will be tied to the running program's standard error,
standard output, or standard error. If the B<status> or B<logger> handle
is not defined, this channel of communication is never established with GnuPG,
and so this information is not generated and does not come into play.
+
If the B<passphrase> data member handle of the B<handles> object
is not defined, but the the B<passphrase> data member handle of GnuPG::Interface
object is, GnuPG::Interface will handle passing this information into GnuPG
-for the user as a convience. Note that this will result in
+for the user as a convenience. Note that this will result in
GnuPG::Interface storing the passphrase in memory, instead of having
it simply 'pass-through' to GnuPG via a handle.
+If neither the B<passphrase> data member of the GnuPG::Interface nor
+the B<passphrase> data member of the B<handles> object is defined,
+then GnuPG::Interface assumes that access and control over the secret
+key will be handled by the running gpg-agent process. This represents
+the simplest mode of operation with the GnuPG "stable" suite (version
+2.2 and later). It is also the preferred mode for tools intended to
+be user-facing, since the user will be prompted directly by gpg-agent
+for use of the secret key material. Note that for programmatic use,
+this mode requires the gpg-agent and pinentry to already be correctly
+configured.
+
=back
=head2 Other Methods
@@ -1130,10 +1212,15 @@ The following setup can be done before any of the following examples:
$gnupg->options->hash_init( armor => 1,
recipients => [ 'ftobin@uiuc.edu',
- '0xABCD1234' ],
+ '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ],
meta_interactive => 0 ,
);
+ $gnupg->options->debug_level(4);
+
+ $gnupg->options->logger_file("/tmp/gnupg-$$-decrypt-".time().".log");
+
+
=head2 Encrypting
# We'll let the standard error of GnuPG pass through
@@ -1144,7 +1231,7 @@ The following setup can be done before any of the following examples:
my $handles = GnuPG::Handles->new( stdin => $input,
stdout => $output );
-
+
# this sets up the communication
# Note that the recipients were specified earlier
# in the 'options' data member of the $gnupg object.
@@ -1175,7 +1262,7 @@ The following setup can be done before any of the following examples:
);
# indicate our pasphrase through the
- # convience method
+ # convenience method
$gnupg->passphrase( $passphrase );
# this sets up the communication
@@ -1220,7 +1307,7 @@ The following setup can be done before any of the following examples:
# a file written to disk
# Make sure you "use IO::File" if you use this module!
my $cipher_file = IO::File->new( 'encrypted.gpg' );
-
+
# this sets up the communication
my $pid = $gnupg->decrypt( handles => $handles );
@@ -1252,20 +1339,20 @@ The following setup can be done before any of the following examples:
# This time we'll just let GnuPG print to our own output
# and read from our input, because no input is needed!
my $handles = GnuPG::Handles->new();
-
- my @ids = ( 'ftobin', '0xABCD1234' );
+
+ my @ids = ( 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' );
# this time we need to specify something for
# command_args because --list-public-keys takes
# search ids as arguments
my $pid = $gnupg->list_public_keys( handles => $handles,
command_args => [ @ids ] );
-
+
waitpid $pid, 0;
=head2 Creating GnuPG::PublicKey Objects
- my @ids = [ 'ftobin', '0xABCD1234' ];
+ my @ids = [ 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ];
my @keys = $gnupg->get_public_keys( @ids );
@@ -1280,7 +1367,7 @@ The following setup can be done before any of the following examples:
command_args => [ qw( test/key.1.asc ) ],
handles => $handles,
);
-
+
my @out = <$handles->stdout()>;
waitpid $pid, 0;
@@ -1334,12 +1421,23 @@ one should all B<wait> to clean up GnuPG from the process table.
=head1 BUGS
+=head2 Large Amounts of Data
+
Currently there are problems when transmitting large quantities
of information over handles; I'm guessing this is due
to buffering issues. This bug does not seem specific to this package;
IPC::Open3 also appears affected.
-I don't know yet how well this modules handles parsing OpenPGP v3 keys.
+=head2 OpenPGP v3 Keys
+
+I don't know yet how well this module handles parsing OpenPGP v3 keys.
+
+=head2 RHEL 7 Test Failures
+
+Testing with the updates for version 1.00 we saw intermittent test failures
+on RHEL 7 with GnuPG version 2.2.20. In some cases the tests would all pass
+for several runs, then one would fail. We're unable to reliably reproduce
+this so we would be interested in feedback from other users.
=head1 SEE ALSO
@@ -1357,7 +1455,7 @@ under the same terms as Perl itself.
=head1 AUTHOR
-GnuPg::Interface is currently maintained by Jesse Vincent <jesse@cpan.org>.
+GnuPG::Interface is currently maintained by Best Practical Solutions <BPS@cpan.org>.
Frank J. Tobin, ftobin@cpan.org was the original author of the package.
diff --git a/lib/GnuPG/Key.pm b/lib/GnuPG/Key.pm
index 8f98f85..e8d743b 100644
--- a/lib/GnuPG/Key.pm
+++ b/lib/GnuPG/Key.pm
@@ -88,11 +88,12 @@ sub compare {
hex_data
expiration_date
expiration_date_string
+ local_id
);
foreach $field (@can_be_undef) {
- return 0 unless (defined $self->$field) == (defined $other->$field);
- if (defined $self->$field) {
- return 0 unless $self->$field eq $other->$field;
+ return 0 unless ((defined $self->$field && ( $self->$field ne '') ) == (defined $other->$field && ( $other->$field ne '')));
+ if (defined $self->$field && ( $self->$field ne '') ) {
+ return 0 unless ($self->$field eq $other->$field);
}
}
my @objs = qw(
@@ -207,7 +208,8 @@ instantiated, and should always be undef.
=item pubkey_data
A list of Math::BigInt objects that correspond to the public key
-material for the given key (this member is empty on secret keys).
+material for the given key. This member is empty on secret keys in
+GnuPG 1.4. It is populated on secret keys In GnuPG >= 2.2.0.
For DSA keys, the values are: prime (p), group order (q), group generator (g), y
diff --git a/lib/GnuPG/Options.pm b/lib/GnuPG/Options.pm
index 86261a0..9b94653 100644
--- a/lib/GnuPG/Options.pm
+++ b/lib/GnuPG/Options.pm
@@ -35,6 +35,9 @@ use constant BOOLEANS => qw(
meta_pgp_5_compatible
meta_pgp_2_compatible
meta_interactive
+ ignore_mdc_error
+ keyring
+ no_default_keyring
);
use constant SCALARS => qw(
@@ -49,6 +52,8 @@ use constant SCALARS => qw(
options
meta_signing_key
meta_signing_key_id
+ debug_level
+ logger_file
);
use constant LISTS => qw(
@@ -93,6 +98,9 @@ for my $list (LISTS) {
sub BUILD {
my ( $self, $args ) = @_;
+ # Newer GnuPG will force failure for old ciphertext unless set
+ $args->{ignore_mdc_error} //= 1;
+
$self->hash_init( meta_interactive => 1 );
$self->hash_init(%$args);
}
@@ -157,6 +165,13 @@ sub get_option_args {
push @args, map { ( '--recipient', $_ ) } $self->recipients();
push @args, map { ( '--encrypt-to', $_ ) } $self->encrypt_to();
+ push @args, '--debug-level', $self->debug_level() if ($self->debug_level);
+ push @args, '--logger-file', $self->logger_file() if ($self->logger_file());
+
+ push @args, '--ignore-mdc-error' if ($self->ignore_mdc_error());
+ push @args, '--keyring' if ( $self->keyring() );
+ push @args, '--no-default-keyring' if ( $self->no_default_keyring() );
+
return @args;
}
@@ -198,7 +213,7 @@ GnuPG::Options - GnuPG options embodiment
# assuming $gnupg is a GnuPG::Interface object
$gnupg->options->armor( 1 );
- $gnupg->options->push_recipients( 'ftobin', '0xABCD1234' );
+ $gnupg->options->push_recipients( 'ftobin', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' );
=head1 DESCRIPTION
diff --git a/lib/GnuPG/PrimaryKey.pm b/lib/GnuPG/PrimaryKey.pm
index 3776588..e26cdc7 100644
--- a/lib/GnuPG/PrimaryKey.pm
+++ b/lib/GnuPG/PrimaryKey.pm
@@ -48,8 +48,6 @@ has $_ => (
sub compare {
my ($self, $other, $deep) = @_;
- # not comparing local_id because it is meaningless in modern
- # versions of GnuPG.
my @comparison_fields = qw (
owner_trust
);
diff --git a/t/000_setup.t b/t/000_setup.t
new file mode 100644
index 0000000..8e3235a
--- /dev/null
+++ b/t/000_setup.t
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+use strict;
+use English qw( -no_match_vars );
+
+use lib './t';
+use MyTest;
+use MyTestSpecific;
+use Cwd;
+use File::Path qw (make_path);
+use File::Copy;
+
+TEST
+{
+ my $homedir = $gnupg->options->homedir();
+ make_path($homedir, { mode => 0700 });
+
+ copy('test/gpg.conf', $homedir . '/gpg.conf');
+
+ if ($gnupg->cmp_version($gnupg->version, '2.2') >= 0) {
+ my $agentconf = IO::File->new( "> " . $homedir . "/gpg-agent.conf" );
+ # Classic gpg can't use loopback pinentry programs like fake-pinentry.pl.
+ $agentconf->write(
+ "allow-preset-passphrase\n".
+ "allow-loopback-pinentry\n".
+ "pinentry-program " . getcwd() . "/test/fake-pinentry.pl\n"
+ );
+ $agentconf->close();
+
+ my $error = system("gpg-connect-agent", "--homedir", "$homedir", '/bye');
+ if ($error) {
+ warn "gpg-connect-agent returned error : $error";
+ }
+
+ $error = system('gpg-connect-agent', "--homedir", "$homedir", 'reloadagent', '/bye');
+ if ($error) {
+ warn "gpg-connect-agent returned error : $error";
+ }
+
+ $error = system("gpg-agent", '--homedir', "$homedir");
+ if ($error) {
+ warn "gpg-agent returned error : $error";
+ }
+
+ }
+ reset_handles();
+
+ my $pid = $gnupg->import_keys(command_args => [ 'test/public_keys.pgp', 'test/secret_keys.pgp', 'test/new_secret.pgp' ],
+ options => [ 'batch'],
+ handles => $handles);
+ waitpid $pid, 0;
+
+ return $CHILD_ERROR == 0;
+};
diff --git a/t/MyTestSpecific.pm b/t/MyTestSpecific.pm
index 053b749..c335d62 100644
--- a/t/MyTestSpecific.pm
+++ b/t/MyTestSpecific.pm
@@ -22,6 +22,7 @@ use IO::Seekable;
use File::Compare;
use Exporter;
use Class::Struct;
+use File::Temp qw (tempdir);
use GnuPG::Interface;
use GnuPG::Handles;
@@ -38,12 +39,25 @@ use vars qw( @ISA @EXPORT
texts file_match
);
-$gnupg = GnuPG::Interface->new( passphrase => 'test' );
+my $homedir;
+if (-f "test/gnupghome") {
+ my $record = IO::File->new( "< test/gnupghome" );
+ $homedir = <$record>;
+ $record->close();
+} else {
+ $homedir = tempdir( DIR => '/tmp');
+ my $record = IO::File->new( "> test/gnupghome" );
+ $record->write($homedir);
+ $record->close();
+}
+
+$ENV{'GNUPGHOME'} = $homedir;
-$gnupg->options->hash_init( homedir => 'test',
+$gnupg = GnuPG::Interface->new( passphrase => 'test' );
+$gnupg->options->hash_init( homedir => $homedir,
armor => 1,
meta_interactive => 0,
- meta_signing_key_id => '0xF950DA9C',
+ meta_signing_key_id => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C',
always_trust => 1,
);
@@ -52,9 +66,15 @@ struct( Text => { fn => "\$", fh => "\$", data => "\$" } );
$texts{plain} = Text->new();
$texts{plain}->fn( 'test/plain.1.txt' );
+$texts{alt_plain} = Text->new();
+$texts{alt_plain}->fn( 'test/plain.2.txt' );
+
$texts{encrypted} = Text->new();
$texts{encrypted}->fn( 'test/encrypted.1.gpg' );
+$texts{alt_encrypted} = Text->new();
+$texts{alt_encrypted}->fn( 'test/encrypted.2.gpg' );
+
$texts{signed} = Text->new();
$texts{signed}->fn( 'test/signed.1.asc' );
@@ -65,7 +85,7 @@ $texts{temp} = Text->new();
$texts{temp}->fn( 'test/temp' );
-foreach my $name ( qw( plain encrypted signed key ) )
+foreach my $name ( qw( plain alt_plain encrypted alt_encrypted signed key ) )
{
my $entry = $texts{$name};
my $filename = $entry->fn();
@@ -87,7 +107,7 @@ sub reset_handles
stderr => $stderr
);
- foreach my $name ( qw( plain encrypted signed key ) )
+ foreach my $name ( qw( plain alt_plain encrypted alt_encrypted signed key ) )
{
my $entry = $texts{$name};
my $filename = $entry->fn();
@@ -124,4 +144,27 @@ sub file_match
+# blank user_id_string and different validity for expired sig in GPG 2.2.x vs 1.x, 2.1
+sub get_expired_test_sig_params {
+ my $gnupg = shift;
+ my $version = $gnupg->version;
+
+ my %sig_params = (
+ date_string => '2000-03-16',
+ hex_id => '56FFD10A260C4FA3',
+ sig_class => 0x10,
+ algo_num => 17,
+ is_exportable => 1,
+ );
+ if ($gnupg->cmp_version($gnupg->version, '2.2') > 0) {
+ $sig_params{user_id_string} = '';
+ $sig_params{validity} = '?';
+ }
+ else {
+ $sig_params{user_id_string} = 'Frank J. Tobin <ftobin@neverending.org>',
+ $sig_params{validity} = '!';
+ }
+ return %sig_params
+}
+
1;
diff --git a/t/decrypt.t b/t/decrypt.t
index b2639ed..5bb35da 100644
--- a/t/decrypt.t
+++ b/t/decrypt.t
@@ -58,3 +58,34 @@ TEST
{
return compare( $texts{plain}->fn(), $texts{temp}->fn() ) == 0;
};
+
+
+# test without default_passphrase (that is, by using the agent, if ENV flag set)
+TEST
+{
+ return 1 unless ($gnupg->cmp_version($gnupg->version, '2.2') >= 0);
+
+ reset_handles();
+
+ $handles->stdin( $texts{alt_encrypted}->fh() );
+ $handles->options( 'stdin' )->{direct} = 1;
+
+ $handles->stdout( $texts{temp}->fh() );
+ $handles->options( 'stdout' )->{direct} = 1;
+
+ $handles->clear_passphrase();
+ $gnupg->clear_passphrase();
+
+ my $pid = $gnupg->decrypt( handles => $handles );
+
+ waitpid $pid, 0;
+
+ return $CHILD_ERROR == 0;
+};
+
+
+TEST
+{
+ return 1 unless ($gnupg->cmp_version($gnupg->version, '2.2') >= 0);
+ return compare( $texts{alt_plain}->fn(), $texts{temp}->fn() ) == 0;
+};
diff --git a/t/encrypt.t b/t/encrypt.t
index 3183ac4..e6bdc08 100644
--- a/t/encrypt.t
+++ b/t/encrypt.t
@@ -27,7 +27,7 @@ TEST
$gnupg->options->clear_recipients();
$gnupg->options->clear_meta_recipients_keys();
- $gnupg->options->push_recipients( '0x2E854A6B' );
+ $gnupg->options->push_recipients( '0x7466B7E98C4CCB64C2CE738BADB99D9C2E854A6B' );
my $pid = $gnupg->encrypt( handles => $handles );
@@ -43,7 +43,7 @@ TEST
{
reset_handles();
- my @keys = $gnupg->get_public_keys( '0xF950DA9C' );
+ my @keys = $gnupg->get_public_keys( '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
$gnupg->options->clear_recipients();
$gnupg->options->clear_meta_recipients_keys();
$gnupg->options->push_meta_recipients_keys( @keys );
@@ -64,7 +64,7 @@ TEST
$gnupg->options->clear_recipients();
$gnupg->options->clear_meta_recipients_keys();
- $gnupg->options->push_recipients( '0x2E854A6B' );
+ $gnupg->options->push_recipients( '0x7466B7E98C4CCB64C2CE738BADB99D9C2E854A6B' );
$handles->stdin( $texts{plain}->fh() );
$handles->options( 'stdin' )->{direct} = 1;
diff --git a/t/export_keys.t b/t/export_keys.t
index cf5c82b..5add064 100644
--- a/t/export_keys.t
+++ b/t/export_keys.t
@@ -15,7 +15,7 @@ TEST
reset_handles();
my $pid = $gnupg->export_keys( handles => $handles,
- command_args => '0xF950DA9C' );
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
close $stdin;
waitpid $pid, 0;
@@ -31,7 +31,7 @@ TEST
$handles->options( 'stdout' )->{direct} = 1;
my $pid = $gnupg->export_keys( handles => $handles,
- command_args => '0xF950DA9C' );
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
waitpid $pid, 0;
return $CHILD_ERROR == 0;
};
diff --git a/t/get_public_keys.t b/t/get_public_keys.t
index 53db021..300c81c 100644
--- a/t/get_public_keys.t
+++ b/t/get_public_keys.t
@@ -19,7 +19,7 @@ TEST
{
reset_handles();
- my @returned_keys = $gnupg->get_public_keys_with_sigs( '0xF950DA9C' );
+ my @returned_keys = $gnupg->get_public_keys_with_sigs( '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
return 0 unless @returned_keys == 1;
@@ -54,6 +54,7 @@ TEST
);
+ # Note, blank user_id_string and different validity for expired sig in GPG 2.2.x
my $uid0 = GnuPG::UserId->new( as_string => 'GnuPG test key (for testing purposes only)',
validity => '-');
$uid0->push_signatures(
@@ -67,24 +68,30 @@ TEST
sig_class => 0x13,
validity => '!'),
GnuPG::Signature->new(
+ get_expired_test_sig_params($gnupg),
date => 953180097,
+ ),
+ GnuPG::Signature->new(
+ date => 949813093,
algo_num => 17,
is_exportable => 1,
- user_id_string => 'Frank J. Tobin <ftobin@neverending.org>',
- date_string => '2000-03-16',
- hex_id => '56FFD10A260C4FA3',
- sig_class => 0x10,
+ user_id_string => 'GnuPG test key (for testing purposes only)',
+ date_string => '2000-02-06',
+ hex_id => '53AE596EF950DA9C',
+ sig_class => 0x13,
validity => '!'),
GnuPG::Signature->new(
- date => 949813093,
+ date => 1177086329,
algo_num => 17,
is_exportable => 1,
user_id_string => 'GnuPG test key (for testing purposes only)',
- date_string => '2000-02-06',
+ date_string => '2007-04-20',
hex_id => '53AE596EF950DA9C',
sig_class => 0x13,
- validity => '!'));
+ validity => '!'),
+ );
+ # Note, blank user_id_string and different validity for expired sig in GPG 2.2.x
my $uid1 = GnuPG::UserId->new( as_string => 'Foo Bar (1)',
validity => '-');
$uid1->push_signatures(
@@ -98,14 +105,9 @@ TEST
sig_class => 0x13,
validity => '!'),
GnuPG::Signature->new(
+ get_expired_test_sig_params($gnupg),
date => 953180103,
- algo_num => 17,
- is_exportable => 1,
- user_id_string => 'Frank J. Tobin <ftobin@neverending.org>',
- date_string => '2000-03-16',
- hex_id => '56FFD10A260C4FA3',
- sig_class => 0x10,
- validity => '!'),
+ ),
GnuPG::Signature->new(
date => 953179891,
algo_num => 17,
@@ -116,8 +118,6 @@ TEST
sig_class => 0x13,
validity => '!'));
-
-
$handmade_key->push_user_ids($uid0, $uid1);
my $subkey_signature = GnuPG::Signature->new
@@ -175,7 +175,7 @@ TEST
];
my $subkey = GnuPG::SubKey->new
- ( validity => 'u',
+ ( validity => '-',
length => 768,
algo_num => 16,
hex_id => 'ADB99D9C2E854A6B',
@@ -218,5 +218,40 @@ TEST
TEST
{
+ # Some versions of GnuPG 2.2.x give same user_id and validity for expired sig as 1.4
+ # this forces them to be consistent and still test them with 2.2 codepath
+ no warnings qw(redefine once);
+ local *GnuPG::Signature::compare = sub {
+ my ($self, $other) = @_;
+ if ($gnupg->cmp_version($gnupg->version, '2.2') > 0) {
+ if ( defined $self->user_id_string and
+ $self->user_id_string eq 'Frank J. Tobin <ftobin@neverending.org>') {
+ $self->user_id_string('');
+ $self->validity('?');
+ }
+ }
+
+ my @compared_fields = qw(
+ validity
+ algo_num
+ hex_id
+ date
+ date_string
+ sig_class
+ is_exportable
+ );
+
+ foreach my $field ( @compared_fields ) {
+ return 0 unless $self->$field eq $other->$field;
+ }
+ # check for expiration if present?
+ return 0 unless (defined $self->expiration_date) == (defined $other->expiration_date);
+ if (defined $self->expiration_date) {
+ return 0 unless (($self->expiration_date == $other->expiration_date) ||
+ ($self->expiration_date_string eq $other->expiration_date_string));
+ }
+ return 1;
+ };
+
$handmade_key->compare( $given_key, 1 );
};
diff --git a/t/get_secret_keys.t b/t/get_secret_keys.t
index 3a1d99f..5b4f97e 100644
--- a/t/get_secret_keys.t
+++ b/t/get_secret_keys.t
@@ -18,21 +18,39 @@ TEST
{
reset_handles();
- my @returned_keys = $gnupg->get_secret_keys( '0xF950DA9C' );
+ my @returned_keys = $gnupg->get_secret_keys( '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
return 0 unless @returned_keys == 1;
$given_key = shift @returned_keys;
-
- $handmade_key = GnuPG::PrimaryKey->new
- ( length => 1024,
+ my $pubkey_data = [
+ Math::BigInt->from_hex('0x'.
+ '88FCAAA5BCDCD52084D46143F44ED1715A339794641158DE03AA2092AFD3174E3DCA2CB7DF2DDC6FEDF7C3620F5A8BDAD06713E6153F8748DD76CB97305F30CBA8F8801DB47FAC11EED725F55672CB9BDAD629178A677CBB089B3E8AE0D9A9AD7741697A35F2868C62D25670994A92D810480173DC24263EEA0F103A43C0B64B'),
+ Math::BigInt->from_hex('0x'.
+ '8F2A3842C70FF17660CBB78C78FC93F534AB9A17'),
+ Math::BigInt->from_hex('0x'.
+ '83E348C2AA65F56DE84E8FDCE6DA7B0991B1C75EC8CA446FA85869A43350907BFF36BE512385E8E7E095578BB2138C04E318495873218286DE2B8C86F36EA670135434967AC798EBA28581F709F0C6B696EB512D3E561E381A06E4B5239BCC655015F9A926C74E4B859B26EAD604F208A556511A76A40EDCD9C38E6BD82CCCB4'),
+ Math::BigInt->from_hex('0x'.
+ '80DE04C85E30C9D62C13F90CFF927A84A5A59D0900B3533D4D6193FEF8C5DAEF9FF8A7D5F76B244FBC17644F50D524E0B19CD3A4B5FC2D78DAECA3FE58FA1C1A64E6C7B96C4EE618173543163A72EF954DFD593E84342699096E9CA76578AC1DE3D893BCCD0BF470CEF625FAF816A0F503EF75C18C6173E35C8675AF919E5704')
+ ];
+
+
+ my $args = {
+ length => 1024,
algo_num => 17,
hex_id => '53AE596EF950DA9C',
creation_date => 949813093,
creation_date_string => '2000-02-06',
- owner_trust => '', # secret keys do not report ownertrust?
+ owner_trust => '-',
usage_flags => 'scaESCA',
- );
+ pubkey_data => $pubkey_data,
+ };
+ if ($gnupg->cmp_version($gnupg->version, '2.1') < 0) {
+ # older versions don't report ownertrust or pubkey_data for secret keys:
+ delete $args->{pubkey_data};
+ $args->{owner_trust} = '';
+ }
+ $handmade_key = GnuPG::PrimaryKey->new($args);
$handmade_key->fingerprint
( GnuPG::Fingerprint->new( as_hex_string =>
@@ -42,20 +60,42 @@ TEST
$handmade_key->push_user_ids(
GnuPG::UserId->new( as_string => 'GnuPG test key (for testing purposes only)',
- validity => ''), # secret keys do not report uid validity?
+ validity => $args->{owner_trust}),
GnuPG::UserId->new( as_string => 'Foo Bar (1)',
- validity => '')); # secret keys do not report uid validity?
-
-
- my $subkey = GnuPG::SubKey->new
- ( validity => 'u',
+ validity => $args->{owner_trust}));
+
+ my $revoker = GnuPG::Revoker->new
+ ( algo_num => 17,
+ class => 0x80,
+ fingerprint => GnuPG::Fingerprint->new( as_hex_string =>
+ '4F863BBBA8166F0A340F600356FFD10A260C4FA3'),
+ );
+
+ my $subkey_pub_data = [
+ Math::BigInt->from_hex('0x'.
+ '8831982DADC4C5D05CBB01D9EAF612131DDC9C24CEA7246557679423FB0BA42F74D10D8E7F5564F6A4FB8837F8DC4A46571C19B122E6DF4B443D15197A6A22688863D0685FADB6E402316DAA9B560D1F915475364580A67E6DF0A727778A5CF3'),
+ Math::BigInt->from_hex('0x'.
+ '6'),
+ Math::BigInt->from_hex('0x'.
+ '2F3850FF130C6AC9AA0962720E86539626FAA9B67B33A74DFC0DE843FF3E90E43E2F379EE0182D914FA539CCCF5C83A20DB3A7C45E365B8A2A092E799A3DFF4AD8274EB977BAAF5B1AFB2ACB8D6F92454F01682F555565E73E56793C46EF7C3E')
+ ];
+
+ my $sub_args = {
+ validity => '-',
length => 768,
algo_num => 16,
hex_id => 'ADB99D9C2E854A6B',
creation_date => 949813119,
creation_date_string => '2000-02-06',
usage_flags => 'e',
- );
+ pubkey_data => $subkey_pub_data,
+ };
+
+ if ($gnupg->cmp_version($gnupg->version, '2.1') < 0) {
+ # older versions do not report pubkey data for secret keys
+ delete $sub_args->{pubkey_data};
+ }
+ my $subkey = GnuPG::SubKey->new($sub_args);
$subkey->fingerprint
( GnuPG::Fingerprint->new( as_hex_string =>
@@ -64,6 +104,8 @@ TEST
);
$handmade_key->push_subkeys( $subkey );
+ # older versions do not report designated revokers for secret keys
+ $handmade_key->push_revokers( $revoker ) if ($gnupg->cmp_version($gnupg->version, '2.1') >= 0);
$handmade_key->compare( $given_key );
};
diff --git a/t/list_public_keys.t b/t/list_public_keys.t
index 7e563c1..622b092 100644
--- a/t/list_public_keys.t
+++ b/t/list_public_keys.t
@@ -38,7 +38,7 @@ TEST
reset_handles();
my $pid = $gnupg->list_public_keys( handles => $handles,
- ommand_args => '0xF950DA9C'
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C'
);
close $stdin;
@@ -64,7 +64,7 @@ TEST
$handles->options( 'stdout' )->{direct} = 1;
my $pid = $gnupg->list_public_keys( handles => $handles,
- command_args => '0xF950DA9C',
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C',
);
waitpid $pid, 0;
diff --git a/t/list_secret_keys.t b/t/list_secret_keys.t
index 1fe9b7e..13a7ae2 100644
--- a/t/list_secret_keys.t
+++ b/t/list_secret_keys.t
@@ -16,13 +16,24 @@ TEST
{
reset_handles();
+ $ENV{LC_MESSAGES} = 'C';
my $pid = $gnupg->list_secret_keys( handles => $handles );
close $stdin;
$outfile = 'test/secret-keys/1.out';
my $out = IO::File->new( "> $outfile" )
or die "cannot open $outfile for writing: $ERRNO";
- $out->print( <$stdout> );
+ my $seckey_file = $gnupg->cmp_version($gnupg->version, '2.1') >= 0 ? 'pubring.kbx' : 'secring.gpg';
+ my $pubring_line = $gnupg->options->homedir() . '/' . $seckey_file . "\n";
+ while (<$stdout>) {
+ if ($_ eq $pubring_line) {
+ $out->print('test/gnupghome/'.$seckey_file."\n");
+ } elsif (/^--*$/) {
+ $out->print("--------------------------\n");
+ } else {
+ $out->print( $_ );
+ }
+ }
close $stdout;
$out->close();
waitpid $pid, 0;
@@ -33,7 +44,19 @@ TEST
TEST
{
- my @files_to_test = ( 'test/secret-keys/1.0.test' );
+ my $keylist;
+ if ($gnupg->cmp_version($gnupg->version, '2.1') < 0) {
+ $keylist = '0';
+ }
+ else {
+ if ($gnupg->cmp_version($gnupg->version, '2.1.11') <= 0) {
+ $keylist = '1';
+ }
+ else {
+ $keylist = '2';
+ }
+ }
+ my @files_to_test = ( 'test/secret-keys/1.'.$keylist.'.test' );
return file_match( $outfile, @files_to_test );
};
@@ -44,7 +67,7 @@ TEST
reset_handles();
my $pid = $gnupg->list_secret_keys( handles => $handles,
- command_args => '0xF950DA9C' );
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
close $stdin;
$outfile = 'test/secret-keys/2.out';
@@ -69,7 +92,7 @@ TEST
$handles->options( 'stdout' )->{direct} = 1;
my $pid = $gnupg->list_secret_keys( handles => $handles,
- command_args => '0xF950DA9C' );
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C' );
waitpid $pid, 0;
diff --git a/t/list_sigs.t b/t/list_sigs.t
index 16cfa6a..1301fb2 100644
--- a/t/list_sigs.t
+++ b/t/list_sigs.t
@@ -36,7 +36,7 @@ TEST
reset_handles();
my $pid = $gnupg->list_sigs( handles => $handles,
- command_args => '0xF950DA9C',
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C',
);
close $stdin;
@@ -60,7 +60,7 @@ TEST
$handles->options( 'stdout' )->{direct} = 1;
my $pid = $gnupg->list_sigs( handles => $handles,
- command_args => '0xF950DA9C',
+ command_args => '0x93AFC4B1B0288A104996B44253AE596EF950DA9C',
);
waitpid $pid, 0;
diff --git a/t/sign_and_encrypt.t b/t/sign_and_encrypt.t
index 5dc1c08..df0fc75 100644
--- a/t/sign_and_encrypt.t
+++ b/t/sign_and_encrypt.t
@@ -14,7 +14,7 @@ TEST
{
reset_handles();
- $gnupg->options->push_recipients( '0x2E854A6B' );
+ $gnupg->options->push_recipients( '0x7466B7E98C4CCB64C2CE738BADB99D9C2E854A6B' );
my $pid = $gnupg->sign_and_encrypt( handles => $handles );
print $stdin @{ $texts{plain}->data() };
diff --git a/t/zzz_cleanup.t b/t/zzz_cleanup.t
new file mode 100644
index 0000000..9c4d806
--- /dev/null
+++ b/t/zzz_cleanup.t
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+
+use strict;
+use English qw( -no_match_vars );
+
+use lib './t';
+use MyTest;
+use MyTestSpecific;
+use File::Path qw (remove_tree);
+
+# this is actually no test, just cleanup.
+TEST
+{
+ my $homedir = $gnupg->options->homedir();
+ my $err = [];
+ # kill off any long-lived gpg-agent, ignoring errors.
+ # gpgconf versions < 2.1.11 do not support '--homedir', but still
+ # respect the GNUPGHOME environment variable
+ if ($gnupg->cmp_version($gnupg->version, '2.1') >= 0) {
+ $ENV{'GNUPGHOME'} = $homedir;
+ system('gpgconf', '--homedir', $homedir, '--quiet', '--kill', 'gpg-agent');
+ delete $ENV{'GNUPGHOME'};
+ }
+ remove_tree($homedir, {error => \$err});
+ unlink('test/gnupghome');
+ return ! @$err;
+};
diff --git a/test/encrypted.2.gpg b/test/encrypted.2.gpg
new file mode 100644
index 0000000..105cbb3
--- /dev/null
+++ b/test/encrypted.2.gpg
@@ -0,0 +1,12 @@
+-----BEGIN PGP MESSAGE-----
+
+hQEMAw3NS2KuRB0PAQgAuCMQO6blPRIJZib+kDa51gac+BYPl8caXYTLqIHtiz2/
+YRVqePJON4lNAqT6qUksIzQHtejFO6tb1SLqgX9Ti+fKAMLrQw9VGOYaJFoRrTJs
++X33S4GHVVikRTu0dydAsekbfPSc2nRmTFUlSEV3psgAmg9xy8KA6cZroK9Xfcuh
+xW7KLE0hLP+2NZ7zNmJMdu6LDGzvlQsnm1UeElXK8XdMGf8kA3R+GgeeOnR/oEQc
+Uep77k/fLc+UV4fp9Dk1OBeg3Ko/irSaefk4mU7F4HmS8jIERHRvXBTiur1Zx8Nx
+9U3fcQuc+P9+JC89iS4PJPF1Hr0MlezAghZYJrhOrtJIAe5Uaft5KMGRfy0VQnAs
+MHqGnGtzzVWK6GK83ibgG4tTfPEHHIgNFsJf3rM4cWklUmCS9TeeDJJZfhnRA6+/
+X82e6OI7QNbO
+=DlGE
+-----END PGP MESSAGE-----
diff --git a/test/fake-pinentry.pl b/test/fake-pinentry.pl
new file mode 100755
index 0000000..40b8b08
--- /dev/null
+++ b/test/fake-pinentry.pl
@@ -0,0 +1,28 @@
+#!/usr/bin/perl -w
+# Use this for your test suites when a perl interpreter is available.
+#
+# The encrypted keys in your test suite that you expect to work must
+# be locked with a passphrase of "test"
+#
+# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+#
+# License: This trivial work is hereby explicitly placed into the
+# public domain. Anyone may reuse it, modify it, redistribute it for
+# any purpose.
+
+use strict;
+use warnings;
+
+# turn off buffering
+$| = 1;
+
+print "OK This is only for test suites, and should never be used in production\n";
+while (<STDIN>) {
+ chomp;
+ next if (/^$/);
+ next if (/^#/);
+ print ("D supercalifragilisticexpialidocious\n") if (/^getpin/i);
+ print "OK\n";
+ exit if (/^bye/i);
+}
+1;
diff --git a/test/options b/test/gpg.conf
index 1f319a6..1f319a6 100644
--- a/test/options
+++ b/test/gpg.conf
diff --git a/test/new_secret.pgp b/test/new_secret.pgp
new file mode 100644
index 0000000..5feb72c
--- /dev/null
+++ b/test/new_secret.pgp
@@ -0,0 +1,58 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+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
+=ftgB
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/test/plain.2.txt b/test/plain.2.txt
new file mode 100644
index 0000000..da5a1d5
--- /dev/null
+++ b/test/plain.2.txt
@@ -0,0 +1 @@
+test message
diff --git a/test/pubring.gpg b/test/public_keys.pgp
index 60b008a..60b008a 100644
--- a/test/pubring.gpg
+++ b/test/public_keys.pgp
Binary files differ
diff --git a/test/secret-keys/1.0.test b/test/secret-keys/1.0.test
index 5999484..f8239a9 100644
--- a/test/secret-keys/1.0.test
+++ b/test/secret-keys/1.0.test
@@ -1,7 +1,11 @@
-test/secring.gpg
-----------------
+test/gnupghome/secring.gpg
+--------------------------
sec 1024D/F950DA9C 2000-02-06
uid GnuPG test key (for testing purposes only)
uid Foo Bar (1)
ssb 768g/2E854A6B 2000-02-06
+sec 2048R/B6747DDC 2016-10-12
+uid GnuPG::Interface Test key <test@example.org>
+ssb 2048R/AE441D0F 2016-10-12
+
diff --git a/test/secret-keys/1.1.test b/test/secret-keys/1.1.test
new file mode 100644
index 0000000..2fa6ceb
--- /dev/null
+++ b/test/secret-keys/1.1.test
@@ -0,0 +1,11 @@
+test/gnupghome/pubring.kbx
+--------------------------
+sec dsa1024/F950DA9C 2000-02-06 [SCA]
+uid [ unknown] GnuPG test key (for testing purposes only)
+uid [ unknown] Foo Bar (1)
+ssb elg768/2E854A6B 2000-02-06 [E]
+
+sec rsa2048/B6747DDC 2016-10-12 [SC]
+uid [ unknown] GnuPG::Interface Test key <test@example.org>
+ssb rsa2048/AE441D0F 2016-10-12 [E]
+
diff --git a/test/secret-keys/1.2.test b/test/secret-keys/1.2.test
new file mode 100644
index 0000000..42b27a1
--- /dev/null
+++ b/test/secret-keys/1.2.test
@@ -0,0 +1,13 @@
+test/gnupghome/pubring.kbx
+--------------------------
+sec dsa1024 2000-02-06 [SCA]
+ 93AFC4B1B0288A104996B44253AE596EF950DA9C
+uid [ unknown] GnuPG test key (for testing purposes only)
+uid [ unknown] Foo Bar (1)
+ssb elg768 2000-02-06 [E]
+
+sec rsa2048 2016-10-12 [SC]
+ 278F850AA702911F1318F0A61B913CE9B6747DDC
+uid [ unknown] GnuPG::Interface Test key <test@example.org>
+ssb rsa2048 2016-10-12 [E]
+
diff --git a/test/secring.gpg b/test/secret_keys.pgp
index aa34674..aa34674 100644
--- a/test/secring.gpg
+++ b/test/secret_keys.pgp
Binary files differ