Package: libgnupg-interface-perl Tags: security patch One of the primary reasons one might want to use GnuPG::Interface is to examine the cryptographically-valid OpenPGP certifications that bind User IDs and subkeys to primary keys.
However, GnuPG::Signature has no information about whether a given signature is in fact cryptographically valid. Given that it is trivial to create invalid OpenPGP signatures "from" any key you like and inject them into keyservers (and from there into local keyrings), this seems like a potential security vulnerability in any application which uses GnuPG::Interface to examine a list of OpenPGP certifications. Attached is a patch which adds new functionality to GnuPG::Signature to report whether a signature has been computed by GnuPG to be cryptographically valid or not. Given that no existing code which relies on GnuPG::Signature currently uses this functionality, it may be safer to go even further: another possible patch on top of this would be to only store valid signatures in the signatures() arrayref of the GnuPG::UserID and GnuPG::SubKey classes. (perhaps an "invalid_signatures" arrayref could be added to these classes if users for some reason wanted access to this kind of questionable material). This patch applies after the recent series of patches i've submitted. --dkg PS i can create and publish an invalid certification from any key to any key if it would be a useful demonstration. Please let me know if that is desired as proof of the security concerns around this bug report.
--- a/lib/GnuPG/Interface.pm +++ b/lib/GnuPG/Interface.pm @@ -365,7 +365,7 @@ my ( $self, @key_ids ) = @_; return $self->get_keys( - commands => ['--list-sigs'], + commands => ['--check-sigs'], command_args => [...@key_ids], ); } @@ -464,11 +464,12 @@ } elsif ( $record_type eq 'sig' ) { my ( + $validity, $algo_num, $hex_key_id, $signature_date, $expiration_date, $user_id_string - ) = @fields[ 3 .. 6, 9 ]; + ) = @fields[ 1, 3 .. 6, 9 ]; my $expiration_date_string; if ($expiration_date eq '') { @@ -479,6 +480,7 @@ my $signature_date_string = $self->_downrez_date($signature_date); my $signature = GnuPG::Signature->new( + validity => $validity, algo_num => $algo_num, hex_id => $hex_key_id, date => $signature_date, --- a/lib/GnuPG/Signature.pm +++ b/lib/GnuPG/Signature.pm @@ -16,11 +16,23 @@ package GnuPG::Signature; use Any::Moose; -has [qw( algo_num hex_id user_id_string date date_string expiration_date expiration_date_string )] => ( +has [qw( validity + algo_num + hex_id + user_id_string + date + date_string + expiration_date + expiration_date_string )] => ( isa => 'Any', is => 'rw', ); +sub is_valid { + my $self = shift; + return $self->validity eq '!'; +} + __PACKAGE__->meta->make_immutable; 1; @@ -51,12 +63,26 @@ This methods creates a new object. The optional arguments are initialization of data members. +=item is_valid() + +Returns 1 if GnuPG was able to cryptographically verify the signature, +otherwise 0. + =back =head1 OBJECT DATA MEMBERS =over 4 +=item validity + +A character indicating the cryptographic validity of the key. GnuPG +uses at least the following characters: "!" means valid, "-" means not +valid, "?" means unknown (e.g. if the supposed signing key is not +present in the local keyring), and "%" means an error occurred (e.g. a +non-supported algorithm). See the documentation for --check-sigs in +gpg(1). + =item algo_num The number of the algorithm used for the signature. --- a/t/GnuPG/ComparableSignature.pm +++ b/t/GnuPG/ComparableSignature.pm @@ -23,7 +23,7 @@ { my ( $self, $other ) = @_; - my @compared_fields = qw( algo_num hex_id date date_string ); + my @compared_fields = qw( validity algo_num hex_id date date_string ); foreach my $field ( @compared_fields ) { --- a/t/get_public_keys.t +++ b/t/get_public_keys.t @@ -43,7 +43,8 @@ ); my $subkey_signature = GnuPG::ComparableSignature->new - ( algo_num => 17, + ( validity => '!', + algo_num => 17, hex_id => '53AE596EF950DA9C', date => 1177086380, date_string => '2007-04-20', @@ -51,14 +52,16 @@ ); my $uid2_signature = GnuPG::Signature->new - ( algo_num => 17, + ( validity => '!', + algo_num => 17, hex_id => '53AE596EF950DA9C', date => 953179891, date_string => '2000-03-16', ); my $ftobin_signature = GnuPG::Signature->new - ( algo_num => 17, + ( validity => '!', + algo_num => 17, hex_id => '56FFD10A260C4FA3', date => 953180097, date_string => '2000-03-16',
signature.asc
Description: OpenPGP digital signature