summaryrefslogtreecommitdiff
path: root/README
diff options
context:
space:
mode:
Diffstat (limited to 'README')
-rw-r--r--README472
1 files changed, 472 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..2ef6dd4
--- /dev/null
+++ b/README
@@ -0,0 +1,472 @@
+NAME
+ GnuPG::Interface - Perl interface to GnuPG
+
+SYNOPSIS
+ # A simple example
+ use IO::Handle;
+ use GnuPG::Interface;
+
+ # setting up the situation
+ my $gnupg = GnuPG::Interface->new();
+ $gnupg->options->hash_init( armor => 1,
+ homedir => '/home/foobar' );
+
+ # Note you can set the recipients even if you aren't encrypting!
+ $gnupg->options->push_recipients( 'ftobin@cpan.org' );
+ $gnupg->options->meta_interactive( 0 );
+
+ # how we create some handles to interact with GnuPG
+ my $input = IO::Handle->new();
+ my $output = IO::Handle->new();
+ my $handles = GnuPG::Handles->new( stdin => $input,
+ stdout => $output );
+
+ # 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;
+
+ # now we read the output
+ my @ciphertext = <$output>;
+ close $output;
+
+ waitpid $pid, 0;
+
+DESCRIPTION
+ GnuPG::Interface and its associated modules are designed to provide an
+ object-oriented method for interacting with GnuPG, being able to perform
+ functions such as but not limited to encrypting, signing, decryption,
+ verification, and key-listing parsing.
+
+ How Data Member Accessor Methods are Created
+ Each module in the GnuPG::Interface bundle relies on Moo to generate the
+ get/set methods used to set the object's data members. *This is very
+ important to realize.* This means that any data member which is a list
+ has special methods assigned to it for pushing, popping, and clearing
+ the list.
+
+ Understanding Bidirectional Communication
+ It is also imperative to realize that this package uses interprocess
+ communication methods similar to those used in IPC::Open3 and
+ "Bidirectional Communication with Another Process" in perlipc, and that
+ users of this package need to understand how to use this method because
+ this package does not abstract these methods for the user greatly. This
+ package is not designed to abstract this away entirely (partly for
+ security purposes), but rather to simply help create 'proper', clean
+ calls to GnuPG, and to implement key-listing parsing. Please see
+ "Bidirectional Communication with Another Process" in perlipc to learn
+ how to deal with these methods.
+
+ Using this package to do message processing generally invovlves creating
+ a GnuPG::Interface object, creating a GnuPG::Handles object, setting
+ some options in its options data member, and then calling a method which
+ invokes GnuPG, such as clearsign. One then interacts with with the
+ 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* )
+ This methods creates a new object. The optional arguments are
+ initialization of data members.
+
+ hash_init( *%args* ).
+
+ Object Methods which use a GnuPG::Handles Object
+ list_public_keys( % )
+ list_sigs( % )
+ list_secret_keys( % )
+ encrypt( % )
+ encrypt_symmetrically( % )
+ sign( % )
+ clearsign( % )
+ detach_sign( % )
+ sign_and_encrypt( % )
+ decrypt( % )
+ verify( % )
+ import_keys( % )
+ export_keys( % )
+ recv_keys( % )
+ send_keys( % )
+ search_keys( % )
+ These methods each correspond directly to or are very similar to a
+ GnuPG command described in gpg. Each of these methods takes a hash,
+ which currently must contain a key of handles which has the value of
+ a GnuPG::Handles object. Another optional key is command_args which
+ should have the value of an array reference; these arguments will be
+ passed to GnuPG as command arguments. These command arguments are
+ used for such things as determining the keys to list in the
+ export_keys method. *Please note that GnuPG command arguments are
+ not the same as GnuPG options*. To understand what are options and
+ what are command arguments please read "COMMANDS" in gpg and
+ "OPTIONS" in gpg.
+
+ Each of these calls returns the PID for the resulting GnuPG process.
+ One can use this PID in a "waitpid" call instead of a "wait" call if
+ more precise process reaping is needed.
+
+ These methods will attach the handles specified in the handles
+ object to the running GnuPG object, so that bidirectional
+ communication can be established. That is, the optionally-defined
+ stdin, stdout, stderr, status, logger, and passphrase handles will
+ be attached to GnuPG's input, output, standard error, the handle
+ created by setting status-fd, the handle created by setting
+ logger-fd, and the handle created by setting passphrase-fd
+ respectively. This tying of handles of similar to the process done
+ in *IPC::Open3*.
+
+ If you want the GnuPG process to read or write directly to an
+ already-opened filehandle, you cannot do this via the normal
+ *IPC::Open3* mechanisms. In order to accomplish this, set the
+ appropriate handles data member to the already-opened filehandle,
+ and then set the option direct to be true for that handle, as
+ described in "options" in GnuPG::Handles. For example, to have GnuPG
+ read from the file input.txt and write to output.txt, the following
+ snippet may do:
+
+ my $infile = IO::File->new( 'input.txt' );
+ my $outfile = IO::File->new( '>output.txt' );
+ my $handles = GnuPG::Handles->new( stdin => $infile,
+ stdout => $outfile,
+ );
+ $handles->options( 'stdin' )->{direct} = 1;
+ $handles->options( 'stdout' )->{direct} = 1;
+
+ If any handle in the handles object is not defined, GnuPG's input,
+ output, and standard error will be tied to the running program's
+ 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 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 )
+ get_secret_keys( @search_strings )
+ get_public_keys_with_sigs( @search_strings )
+ These methods create and return objects of the type GnuPG::PublicKey
+ or GnuPG::SecretKey respectively. This is done by parsing the output
+ of GnuPG with the option with-colons enabled. The objects created do
+ or do not have signature information stored in them, depending if
+ the method ends in *_sigs*; this separation of functionality is
+ there because of performance hits when listing information with
+ signatures.
+
+ test_default_key_passphrase()
+ This method will return a true or false value, depending on whether
+ GnuPG reports a good passphrase was entered while signing a short
+ message using the values of the passphrase data member, and the
+ default key specified in the options data member.
+
+ version()
+ Returns the version of GnuPG that GnuPG::Interface is running.
+
+Invoking GnuPG with a custom call
+ GnuPG::Interface attempts to cover a lot of the commands of GnuPG that
+ one would want to perform; however, there may be a lot more calls that
+ GnuPG is and will be capable of, so a generic command interface is
+ provided, "wrap_call".
+
+ wrap_call( %args )
+ Call GnuPG with a custom command. The %args hash must contain at
+ least the following keys:
+
+ commands
+ The value of this key in the hash must be a reference to a a
+ list of commands for GnuPG, such as "[ qw( --encrypt --sign )
+ ]".
+
+ handles
+ As with most other GnuPG::Interface methods, handles must be a
+ GnuPG::Handles object.
+
+ The following keys are optional.
+
+ command_args
+ As with other GnuPG::Interface methods, the value in hash for
+ this key must be a reference to a list of arguments to be passed
+ to the GnuPG command, such as which keys to list in a
+ key-listing.
+
+OBJECT DATA MEMBERS
+ call
+ This defines the call made to invoke GnuPG. Defaults to 'gpg'; this
+ should be changed if 'gpg' is not in your path, or there is a
+ different name for the binary on your system.
+
+ passphrase
+ In order to lessen the burden of using handles by the user of this
+ package, setting this option to one's passphrase for a secret key
+ will allow the package to enter the passphrase via a handle to GnuPG
+ by itself instead of leaving this to the user. See also "passphrase"
+ in GnuPG::Handles.
+
+ options
+ This data member, of the type GnuPG::Options; the setting stored in
+ this data member are used to determine the options used when calling
+ GnuPG via *any* of the object methods described in this package. See
+ GnuPG::Options for more information.
+
+EXAMPLES
+ The following setup can be done before any of the following examples:
+
+ use IO::Handle;
+ use GnuPG::Interface;
+
+ my @original_plaintext = ( "How do you doo?" );
+ my $passphrase = "Three Little Pigs";
+
+ my $gnupg = GnuPG::Interface->new();
+
+ $gnupg->options->hash_init( armor => 1,
+ recipients => [ 'ftobin@uiuc.edu',
+ '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
+ # a stderr-part of the $handles object.
+ my ( $input, $output ) = ( IO::Handle->new(),
+ IO::Handle->new() );
+
+ 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.
+ my $pid = $gnupg->encrypt( handles => $handles );
+
+ # this passes in the plaintext
+ print $input @original_plaintext;
+
+ # this closes the communication channel,
+ # indicating we are done
+ close $input;
+
+ my @ciphertext = <$output>; # reading the output
+
+ waitpid $pid, 0; # clean up the finished GnuPG process
+
+ Signing
+ # This time we'll catch the standard error for our perusing
+ my ( $input, $output, $error ) = ( IO::Handle->new(),
+ IO::Handle->new(),
+ IO::Handle->new(),
+ );
+
+ my $handles = GnuPG::Handles->new( stdin => $input,
+ stdout => $output,
+ stderr => $error,
+ );
+
+ # indicate our pasphrase through the
+ # convenience method
+ $gnupg->passphrase( $passphrase );
+
+ # this sets up the communication
+ my $pid = $gnupg->sign( handles => $handles );
+
+ # this passes in the plaintext
+ print $input @original_plaintext;
+
+ # this closes the communication channel,
+ # indicating we are done
+ close $input;
+
+ my @ciphertext = <$output>; # reading the output
+ my @error_output = <$error>; # reading the error
+
+ close $output;
+ close $error;
+
+ waitpid $pid, 0; # clean up the finished GnuPG process
+
+ Decryption
+ # This time we'll catch the standard error for our perusing
+ # as well as passing in the passphrase manually
+ # as well as the status information given by GnuPG
+ my ( $input, $output, $error, $passphrase_fh, $status_fh )
+ = ( IO::Handle->new(),
+ IO::Handle->new(),
+ IO::Handle->new(),
+ IO::Handle->new(),
+ IO::Handle->new(),
+ );
+
+ my $handles = GnuPG::Handles->new( stdin => $input,
+ stdout => $output,
+ stderr => $error,
+ passphrase => $passphrase_fh,
+ status => $status_fh,
+ );
+
+ # this time we'll also demonstrate decrypting
+ # 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 );
+
+ # This passes in the passphrase
+ print $passphrase_fh $passphrase;
+ close $passphrase_fh;
+
+ # this passes in the plaintext
+ print $input $_ while <$cipher_file>;
+
+ # this closes the communication channel,
+ # indicating we are done
+ close $input;
+ close $cipher_file;
+
+ my @plaintext = <$output>; # reading the output
+ my @error_output = <$error>; # reading the error
+ my @status_info = <$status_fh>; # read the status info
+
+ # clean up...
+ close $output;
+ close $error;
+ close $status_fh;
+
+ waitpid $pid, 0; # clean up the finished GnuPG process
+
+ Printing Keys
+ # 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', '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', '0xABCD1234ABCD1234ABCD1234ABCD1234ABCD1234' ];
+
+ my @keys = $gnupg->get_public_keys( @ids );
+
+ # no wait is required this time; it's handled internally
+ # since the entire call is encapsulated
+
+ Custom GnuPG call
+ # assuming $handles is a GnuPG::Handles object
+ my $pid = $gnupg->wrap_call
+ ( commands => [ qw( --list-packets ) ],
+ command_args => [ qw( test/key.1.asc ) ],
+ handles => $handles,
+ );
+
+ my @out = <$handles->stdout()>;
+ waitpid $pid, 0;
+
+FAQ
+ How do I get GnuPG::Interface to read/write directly from a filehandle?
+ You need to set GnuPG::Handles direct option to be true for the
+ filehandles in concern. See "options" in GnuPG::Handles and "Object
+ Methods which use a GnuPG::Handles Object" for more information.
+
+ Why do you make it so difficult to get GnuPG to write/read from a
+ filehandle? In the shell, I can just call GnuPG with the --outfile
+ option!
+ There are lots of issues when trying to tell GnuPG to read/write
+ directly from a file, such as if the file isn't there, or there is a
+ file, and you want to write over it! What do you want to happen
+ then? Having the user of this module handle these questions
+ beforehand by opening up filehandles to GnuPG lets the user know
+ fully what is going to happen in these circumstances, and makes the
+ module less error-prone.
+
+ When having GnuPG process a large message, sometimes it just hanges
+ there.
+ Your problem may be due to buffering issues; when GnuPG reads/writes
+ to non-direct filehandles (those that are sent to filehandles which
+ you read to from into memory, not that those access the disk),
+ buffering issues can mess things up. I recommend looking into
+ "options" in GnuPG::Handles.
+
+NOTES
+ This package is the successor to PGP::GPG::MessageProcessor, which I
+ found to be too inextensible to carry on further. A total redesign was
+ needed, and this is the resulting work.
+
+ After any call to a GnuPG-command method of GnuPG::Interface in which
+ one passes in the handles, one should all wait to clean up GnuPG from
+ 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.
+
+ 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,
+ "Bidirectional Communication with Another Process" in perlipc
+
+LICENSE
+ This module is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
+AUTHOR
+ 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.
+