This is an automated email from the git hooks/post-receive script. guillem pushed a commit to branch main in repository dpkg.
View the commit online: https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=823df15d72d7956f6f159ae61e348840125541df The following commit(s) were added to refs/heads/main by this push: new 823df15d7 Dpkg::OpenPGP: Handle backend requiring a keystore daemon for signing 823df15d7 is described below commit 823df15d72d7956f6f159ae61e348840125541df (HEAD -> main) Author: Guillem Jover <[email protected]> AuthorDate: Sat Nov 19 00:44:30 2022 +0100 Dpkg::OpenPGP: Handle backend requiring a keystore daemon for signing The OpenPGP backends might need a keystore command or daemon, so we need to detect and take that into account when deciding whether we can perform the signing operation. Add a new cmdstore command to detect, and a new can_use_key() method in the Dpkg::OpenPGP::Backend class. --- scripts/Dpkg/OpenPGP.pm | 14 ++++---------- scripts/Dpkg/OpenPGP/Backend.pm | 12 ++++++++++++ scripts/Dpkg/OpenPGP/Backend/GnuPG.pm | 20 +++++++++++++++++++- scripts/t/Dpkg_OpenPGP.t | 12 ++++++++---- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/scripts/Dpkg/OpenPGP.pm b/scripts/Dpkg/OpenPGP.pm index 74b1674b2..dea37b645 100644 --- a/scripts/Dpkg/OpenPGP.pm +++ b/scripts/Dpkg/OpenPGP.pm @@ -108,16 +108,10 @@ sub can_use_secrets { my ($self, $key) = @_; return 0 unless $self->{backend}->has_backend_cmd(); - - if ($key->type eq 'keyfile') { - return 1 if -f $key->handle; - } elsif ($key->type eq 'keystore') { - return 1 if -e $key->handle; - } else { - # For IDs we need a keystore. - return $self->{backend}->has_keystore(); - } - return 0; + return 0 if $key->type eq 'keyfile' && ! -f $key->handle; + return 0 if $key->type eq 'keystore' && ! -e $key->handle; + return 0 unless $self->{backend}->can_use_key($key); + return 1; } sub get_trusted_keyrings { diff --git a/scripts/Dpkg/OpenPGP/Backend.pm b/scripts/Dpkg/OpenPGP/Backend.pm index c654f830b..48cfd2267 100644 --- a/scripts/Dpkg/OpenPGP/Backend.pm +++ b/scripts/Dpkg/OpenPGP/Backend.pm @@ -29,6 +29,10 @@ sub DEFAULT_CMDV { return []; } +sub DEFAULT_CMDSTORE { + return []; +} + sub DEFAULT_CMD { return []; } @@ -53,6 +57,7 @@ sub new { bless $self, $class; $self->{cmdv} = _detect_cmd($opts{cmdv}, $self->DEFAULT_CMDV()); + $self->{cmdstore} = _detect_cmd($opts{cmdstore}, $self->DEFAULT_CMDSTORE()); $self->{cmd} = _detect_cmd($opts{cmd}, $self->DEFAULT_CMD()); return $self; @@ -76,6 +81,13 @@ sub has_keystore { return 0; } +sub can_use_key { + my ($self, $key) = @_; + + return $self->has_keystore() if $key->needs_keystore(); + return 1; +} + sub get_trusted_keyrings { my $self = shift; diff --git a/scripts/Dpkg/OpenPGP/Backend/GnuPG.pm b/scripts/Dpkg/OpenPGP/Backend/GnuPG.pm index f5ba0ac87..b35dfc5ae 100644 --- a/scripts/Dpkg/OpenPGP/Backend/GnuPG.pm +++ b/scripts/Dpkg/OpenPGP/Backend/GnuPG.pm @@ -36,18 +36,36 @@ sub DEFAULT_CMDV { return [ qw(gpgv) ]; } +sub DEFAULT_CMDSTORE { + return [ qw(gpg-agent) ]; +} + sub DEFAULT_CMD { return [ qw(gpg) ]; } +sub has_backend_cmd { + my $self = shift; + + return defined $self->{cmd} && defined $self->{cmdstore}; +} + sub has_keystore { my $self = shift; + return 0 if not defined $self->{cmdstore}; return 1 if ($ENV{GNUPGHOME} && -e $ENV{GNUPGHOME}) || ($ENV{HOME} && -e "$ENV{HOME}/.gnupg"); return 0; } +sub can_use_key { + my ($self, $key) = @_; + + # With gpg, a secret key always requires gpg-agent (the key store). + return $self->has_keystore(); +} + sub has_verify_cmd { my $self = shift; @@ -234,7 +252,7 @@ sub verify { sub inline_sign { my ($self, $data, $inlinesigned, $key) = @_; - return OPENPGP_MISSING_CMD if ! $self->{cmd}; + return OPENPGP_MISSING_CMD if ! $self->has_backend_cmd(); my @exec = ($self->{cmd}); push @exec, _gpg_options_weak_digests(); diff --git a/scripts/t/Dpkg_OpenPGP.t b/scripts/t/Dpkg_OpenPGP.t index c7d045d1d..fc4085820 100644 --- a/scripts/t/Dpkg_OpenPGP.t +++ b/scripts/t/Dpkg_OpenPGP.t @@ -107,10 +107,14 @@ foreach my $cmd (@cmds) { handle => "$datadir/dpkg-test-sec.asc", ); - ok($openpgp->inline_sign("$datadir/sign-file", "$tempdir/sign-file-inline.asc", $key) == OPENPGP_OK(), - "($backend:$cmd) inline OpenPGP sign"); - ok($openpgp->inline_verify("$tempdir/sign-file-inline.asc", undef, $cert) == OPENPGP_OK(), - "($backend:$cmd) verify generated inline OpenPGP signature"); + SKIP: { + skip 'cannot use secrets', 2 unless $openpgp->can_use_secrets($key); + + ok($openpgp->inline_sign("$datadir/sign-file", "$tempdir/sign-file-inline.asc", $key) == OPENPGP_OK(), + "($backend:$cmd) inline OpenPGP sign"); + ok($openpgp->inline_verify("$tempdir/sign-file-inline.asc", undef, $cert) == OPENPGP_OK(), + "($backend:$cmd) verify generated inline OpenPGP signature"); + }; # TODO: Add more test cases. } -- Dpkg.Org's dpkg

