Package: libgnupg-interface-perl Tags: patch GnuPG::SubKey currently reports a single signature object. However, it should have a list of signatures. RFC 4880 permits multiple binding signatures to exist on a subkey.
For example: * primary key X has subkey Y, with an initial binding signature A. * This bundle is uploaded to the public keyservers. * the keyholder then decides to set (or modify) the expiration date for subkey Y, generating a new subkey binding signature. * the new binding signature is uploaded to the keyservers, which now have two signatures over the subkey. * another user downloading the key from the keyservers (or importing it from a file) will find two 'sig' lines after the 'sub' line. The attached patch deprecates the signature() function of GnuPG::SubKey (code that calls this function will carp()) and introduces two functions: signatures() and push_signatures(). It also updates the test suite and the documentation. Regards, --dkg
--- a/lib/GnuPG/Interface.pm +++ b/lib/GnuPG/Interface.pm @@ -488,12 +488,10 @@ user_id_string => unescape_string($user_id_string), ); - if ( $current_signed_item->isa('GnuPG::UserId') ) { + if ( $current_signed_item->isa('GnuPG::UserId') || + $current_signed_item->isa('GnuPG::SubKey') ) { $current_signed_item->push_signatures($signature); } - elsif ( $current_signed_item->isa('GnuPG::SubKey') ) { - $current_signed_item->signature($signature); - } else { warn "do not know how to handle signature line: $line\n"; } --- a/lib/GnuPG/SubKey.pm +++ b/lib/GnuPG/SubKey.pm @@ -15,13 +15,46 @@ package GnuPG::SubKey; use Any::Moose; +use Carp; BEGIN { extends qw( GnuPG::Key ) } -has [qw( validity owner_trust local_id signature )] => ( +has [qw( validity owner_trust local_id )] => ( isa => 'Any', is => 'rw', ); +has signatures => ( + isa => 'ArrayRef', + is => 'rw', + default => sub { [] }, +); + +sub push_signatures { + my $self = shift; + push @{ $self->signatures }, @_; +} + +# DEPRECATED! +# return the last signature, if present. Or push in a new signature, +# if one is supplied. +sub signature { + my $self = shift; + my $argcount = @_; + + if ($argcount) { + carp("Please do not use GnuPG::SubKey::signature(). Use GnuPG::SubKey::push_signatures() instead, since subkeys can have more than one signature."); + $self->push_signatures(@_); + } else { + carp("Please do not use GnuPG::SubKey::signature. Use GnuPG::SubKey::signatures instead, since subkeys can have more than one signature."); + my $sigcount = @{$self->signatures}; + if ($sigcount) { + return $self->signatures->[$sigcount-1]; + } else { + return undef; + } + } +} + __PACKAGE__->meta->make_immutable; 1; @@ -70,8 +103,17 @@ =item signature -A GnuPG::Signature object holding the representation of the -signature on this key. +* DEPRECATED* + +A GnuPG::Signature object holding the representation of the signature +on this key. Please use signatures (see below) instead of signature. +Using signature, you will get an arbitrary signature from the set of +available signatures. + +=item signatures + +A list of GnuPG::Signature objects embodying the binding signatures on +this subkey. =back --- a/t/GnuPG/ComparableSubKey.pm +++ b/t/GnuPG/ComparableSubKey.pm @@ -27,12 +27,24 @@ if ( $deep ) { - bless $self->signature, 'GnuPG::ComparableSignature' - if $self->signature(); + + my @self_signatures = @{$self->signatures()}; + my @other_signatures = @{$other->signatures()}; + + return 0 unless @self_signatures == @other_signatures; + + my $num_sigs = @self_signatures; + + for ( my $i = 0; $i < $num_sigs; $i++ ) + { + return 0 + unless $self_signatures[$i]->compare( $other_signatures[$i], 1 ); + } + bless $self->fingerprint, 'GnuPG::ComparableFingerprint' if $self->fingerprint(); - foreach my $field ( qw( signature fingerprint ) ) + foreach my $field ( qw( fingerprint ) ) { my $f1 = $self->$field(); my $f2 = $other->$field(); --- a/t/get_public_keys.t +++ b/t/get_public_keys.t @@ -42,11 +42,12 @@ ) ); - my $initial_self_signature = GnuPG::Signature->new + my $subkey_signature = GnuPG::ComparableSignature->new ( algo_num => 17, hex_id => '53AE596EF950DA9C', - date => 949813093, - date_string => '2000-02-06', + date => 1177086380, + date_string => '2007-04-20', + user_id_string => 'GnuPG test key (for testing purposes only)', ); my $uid2_signature = GnuPG::Signature->new @@ -80,7 +81,7 @@ ) ); - $subkey->signature( $initial_self_signature ); + $subkey->push_signatures( $subkey_signature ); $handmade_key->push_subkeys( $subkey ); --- a/t/GnuPG/ComparableSignature.pm +++ b/t/GnuPG/ComparableSignature.pm @@ -29,7 +29,6 @@ { my $f1 = $self->$field(); my $f2 = $other->$field(); - # don't test for definedness because # all fields should be defined return 0 unless $self->$field() eq $other->$field();
signature.asc
Description: OpenPGP digital signature