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

