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=a8614ed38265c4bbe52a8bb4ab1b86d636dd6aac

commit a8614ed38265c4bbe52a8bb4ab1b86d636dd6aac
Author: Guillem Jover <[email protected]>
AuthorDate: Thu Oct 27 04:33:25 2022 +0200

    dpkg-buildpackage: Add --sign-keyfile and DEB_SIGN_KEYFILE support
    
    We need to be able to pass the secret key file to use for signing both
    for the test suite and for OpenPGP implementations that do not (yet or
    won't ever) have a keystore.
---
 man/dpkg-buildpackage.pod         | 13 +++++++++++++
 scripts/Dpkg/OpenPGP.pm           | 24 ++++++++++++++++++++++--
 scripts/Dpkg/OpenPGP/KeyHandle.pm | 16 ++++++++++++----
 scripts/dpkg-buildpackage.pl      | 10 +++++++++-
 4 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/man/dpkg-buildpackage.pod b/man/dpkg-buildpackage.pod
index aa51ec9b9..b5b2f33a4 100644
--- a/man/dpkg-buildpackage.pod
+++ b/man/dpkg-buildpackage.pod
@@ -535,6 +535,13 @@ Specify an OpenPGP key-ID (either a fingerprint or a 
user-ID) for the
 secret key to use when signing packages (B<--sign-key> since dpkg 1.18.8,
 B<--sign-keyid> since dpkg 1.21.10).
 
+=item B<--sign-keyfile=>I<key-file>
+
+Specify an OpenPGP I<key-file> containing the secret key to use when signing
+packages (since dpkg 1.21.10).
+
+Note: For security reasons the I<key-file> is best kept locked with a password.
+
 =item B<-us>, B<--unsigned-source>
 
 Do not sign the source package (long option since dpkg 1.18.8).
@@ -638,6 +645,12 @@ If set, it will be used to sign the B<.changes>, 
B<.buildinfo> and B<.dsc>
 files (since dpkg 1.17.2).
 Overridden by the B<--sign-key> option.
 
+=item B<DEB_SIGN_KEYFILE>
+
+If set, it will be used to sign the B<.changes>, B<.buildinfo> and B<.dsc>
+files (since dpkg 1.21.10).
+Overridden by the B<--sign-keyfile> option.
+
 =item B<DEB_BUILD_OPTIONS>
 
 If set, it will contain a space-separated list of options that might
diff --git a/scripts/Dpkg/OpenPGP.pm b/scripts/Dpkg/OpenPGP.pm
index be358ab66..005d6d7eb 100644
--- a/scripts/Dpkg/OpenPGP.pm
+++ b/scripts/Dpkg/OpenPGP.pm
@@ -66,7 +66,15 @@ sub can_use_secrets {
     my ($self, $key) = @_;
 
     return 0 unless $self->{cmd};
-    return $self->_gpg_has_keystore();
+    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->_gpg_has_keystore();
+    }
+    return 0;
 }
 
 sub get_trusted_keyrings {
@@ -254,7 +262,19 @@ sub _gpg_inline_sign {
     my @exec = ($self->{cmd});
     push @exec, _gpg_options_weak_digests();
     push @exec, qw(--utf8-strings --textmode --armor);
-    push @exec, '--local-user', $key->handle;
+    if ($key->type eq 'keyfile') {
+        # Promote the keyfile keyhandle to a keystore, this way we share the
+        # same gpg-agent and can get any password cached.
+        my $gpg_home = File::Temp->newdir('dpkg-sign.XXXXXXXX', TMPDIR => 1);
+
+        push @exec, '--homedir', $gpg_home;
+        $self->_gpg_exec(@exec, qw(--quiet --no-tty --batch --import), 
$key->handle);
+        $key->set('keystore', $gpg_home);
+    } elsif ($key->type eq 'keystore') {
+        push @exec, '--homedir', $key->handle;
+    } else {
+        push @exec, '--local-user', $key->handle;
+    }
     push @exec, '--output', $inlinesigned;
 
     my $rc = $self->_gpg_exec(@exec, '--clearsign', $data);
diff --git a/scripts/Dpkg/OpenPGP/KeyHandle.pm 
b/scripts/Dpkg/OpenPGP/KeyHandle.pm
index e193290a5..89ae44820 100644
--- a/scripts/Dpkg/OpenPGP/KeyHandle.pm
+++ b/scripts/Dpkg/OpenPGP/KeyHandle.pm
@@ -21,7 +21,7 @@ use warnings;
 our $VERSION = '0.01';
 
 use Carp;
-use List::Util qw(none);
+use List::Util qw(any none);
 
 sub new {
     my ($this, %opts) = @_;
@@ -44,7 +44,15 @@ sub _sanitize {
     my ($self) = shift;
 
     my $type = $self->{type};
-    if ($type eq 'auto' or $type eq 'autoid') {
+    if ($type eq 'auto') {
+        if (-e $self->{handle}) {
+            $type = 'keyfile';
+        } else {
+            $type = 'autoid';
+        }
+    }
+
+    if ($type eq 'autoid') {
         if ($self->{handle} =~ m/$keyid_regex/) {
             $self->{handle} = $1;
             $type = 'keyid';
@@ -58,7 +66,7 @@ sub _sanitize {
         }
     }
 
-    if (none { $type eq $_ } qw(userid keyid)) {
+    if (none { $type eq $_ } qw(userid keyid keyfile keystore)) {
         croak "unknown type parameter value $type";
     }
 
@@ -68,7 +76,7 @@ sub _sanitize {
 sub needs_keystore {
     my $self = shift;
 
-    return 1;
+    return any { $self->{type} eq $_ } qw(keyid userid);
 }
 
 sub set {
diff --git a/scripts/dpkg-buildpackage.pl b/scripts/dpkg-buildpackage.pl
index 329408417..2c204b8ef 100755
--- a/scripts/dpkg-buildpackage.pl
+++ b/scripts/dpkg-buildpackage.pl
@@ -26,6 +26,7 @@ use warnings;
 use File::Temp qw(tempdir);
 use File::Basename;
 use File::Copy;
+use File::Glob qw(bsd_glob GLOB_TILDE GLOB_NOCHECK);
 use POSIX qw(:sys_wait_h);
 
 use Dpkg ();
@@ -111,6 +112,7 @@ sub usage {
   -p, --sign-command=<command>
                               command to sign .dsc and/or .changes files
                                 (default is gpg).
+      --sign-keyfile=<file>   the key file to use for signing.
   -k, --sign-keyid=<keyid>    the key id to use for signing.
       --sign-key=<keyid>      alias for -k, --sign-keyid.
   -ap, --sign-pause           add pause before starting signature process.
@@ -170,6 +172,7 @@ my @source_opts;
 my $check_command = $ENV{DEB_CHECK_COMMAND};
 my @check_opts;
 my $signpause;
+my $signkeyfile = $ENV{DEB_SIGN_KEYFILE};
 my $signkeyid = $ENV{DEB_SIGN_KEYID};
 my $signforce = 0;
 my $signreleased = 1;
@@ -288,6 +291,8 @@ while (@ARGV) {
        warning(g_('%s is deprecated; it is without effect'), $1);
     } elsif (/^(?:-p|--sign-command=)(.*)$/) {
        $signcommand = $1;
+    } elsif (/^--sign-keyfile=(.*)$/) {
+       $signkeyfile = $1;
     } elsif (/^(?:-k|--sign-keyid=|--sign-key=)(.*)$/) {
        $signkeyid = $1;
     } elsif (/^--(no-)?check-builddeps$/) {
@@ -522,7 +527,10 @@ my $pva = "${pkg}_${sversion}_$arch";
 
 my $signkeytype;
 my $signkeyhandle;
-if (defined $signkeyid) {
+if (defined $signkeyfile) {
+    $signkeytype = 'keyfile';
+    $signkeyhandle = bsd_glob($signkeyfile, GLOB_TILDE | GLOB_NOCHECK);
+} elsif (defined $signkeyid) {
     $signkeytype = 'autoid';
     $signkeyhandle = $signkeyid;
 } else {

-- 
Dpkg.Org's dpkg

Reply via email to