[elbe-devel] [PATCH 04/10] gpg: gpg2 requires passphrases for private keys

Manuel Traut manut at linutronix.de
Wed Apr 3 12:34:52 CEST 2019


The keys inside the initvm are for temperory repo signing.
To do this automatically it's best to have no passphrase at
all. However having no passphrase for private keys is not
allowed in gpg2.

Therefore set a pseudo passphrase and unlock the keys in the
gpg-agent before usage.

Signed-off-by: Manuel Traut <manut at linutronix.de>
---
 elbepack/egpg.py        | 19 ++++++++++++++++++-
 elbepack/finetuning.py  |  2 ++
 elbepack/repomanager.py | 22 +++++++++++++++-------
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/elbepack/egpg.py b/elbepack/egpg.py
index 6d9072e2..6b66b004 100644
--- a/elbepack/egpg.py
+++ b/elbepack/egpg.py
@@ -12,6 +12,11 @@ import os
 from gpg import core
 from gpg.constants import sigsum, sig
 
+try:
+    from subprocess import run
+except ImportError:
+    from subprocess import call as run
+
 from elbepack.filesystem import hostfs
 
 elbe_internal_key_param = """
@@ -23,6 +28,7 @@ elbe_internal_key_param = """
   Name-Comment: Automatically generated
   Name-Email: root at elbe-daemon.de
   Expire-Date: 0
+  Passphrase: requiredToAvoidUserInput
 </GnupgKeyParms>
 """
 
@@ -146,6 +152,14 @@ def unsign_file(fname):
 
     return None
 
+def unlock_key(fingerprint):
+    os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
+    ctx = core.Context()
+    key = ctx.get_key(fingerprint, secret=True)
+    keygrip = key.subkeys[0].keygrip
+    run(["/usr/lib/gnupg2/gpg-preset-passphrase",
+         "--preset", "-P", "requiredToAvoidUserInput", str(keygrip)],
+        env={"GNUPGHOME": "/var/cache/elbe/gnupg"})
 
 def sign(infile, outfile, fingerprint):
 
@@ -158,6 +172,7 @@ def sign(infile, outfile, fingerprint):
     except Exception as ex:
         print("no key with fingerprint %s: %s" % (fingerprint, ex.message))
 
+    unlock_key(key.fpr)
     ctx.signers_add(key)
     ctx.set_armor(False)
 
@@ -194,6 +209,8 @@ def get_fingerprints():
 
 def generate_elbe_internal_key():
     hostfs.mkdir_p("/var/cache/elbe/gnupg")
+    hostfs.write_file("/var/cache/elbe/gnupg/gpg-agent.conf", 0o600,
+                      "allow-preset-passphrase")
     os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
     ctx = core.Context()
     ctx.op_genkey(elbe_internal_key_param, None, None)
@@ -216,4 +233,4 @@ def export_key(fingerprint, outfile):
     except Exception:
         print("Error exporting key %s" % (fingerprint))
 
-    return '/var/cache/elbe/gnupg/pubring.gpg'
+    return '/var/cache/elbe/gnupg/pubring.kbx'
diff --git a/elbepack/finetuning.py b/elbepack/finetuning.py
index 5f2b0010..8e2fc4a0 100644
--- a/elbepack/finetuning.py
+++ b/elbepack/finetuning.py
@@ -19,6 +19,7 @@ from elbepack.rpcaptcache import get_rpcaptcache
 from elbepack.shellhelper import CommandError
 from elbepack.filesystem import ImgMountFilesystem
 from elbepack.packers import default_packer, packers
+from elbepack.egpg import unlock_key
 
 
 class FinetuningException(Exception):
@@ -421,6 +422,7 @@ class UpdatedAction(FinetuningAction):
             gpgdata = core.Data()
             ctx = core.Context()
             ctx.set_armor(True)
+            unlock_key(fp)
             ctx.op_export(fp, 0, gpgdata)
             gpgdata.seek(0, os.SEEK_SET)
             key = gpgdata.read()
diff --git a/elbepack/repomanager.py b/elbepack/repomanager.py
index 9719a1ea..19a481ab 100644
--- a/elbepack/repomanager.py
+++ b/elbepack/repomanager.py
@@ -15,7 +15,7 @@ from debian.deb822 import Deb822
 from elbepack.debianreleases import codename2suite
 from elbepack.filesystem import Filesystem
 from elbepack.pkgutils import get_dsc_size
-from elbepack.egpg import generate_elbe_internal_key, export_key
+from elbepack.egpg import generate_elbe_internal_key, export_key, unlock_key
 from elbepack.shellhelper import CommandError
 
 
@@ -84,11 +84,17 @@ class RepoBase(object):
         self.maxsize = maxsize
         self.fs = self.get_volume_fs(self.volume_count)
 
-        # check whether the repository already exists
-        # if this is the case, we dont generate a new
-        # key, and dont touch den repository config
-        if not self.fs.isdir("/"):
+        # if repo exists retrive the keyid otherwise
+        # generate a new key and generate repository config
+        if self.fs.isdir("/"):
+            repo_conf = self.fs.read_file("conf/distributions")
+            for l in repo_conf:
+                if l.startswith("SignWith"):
+                    self.keyid = l.split(" ")[1]
+                    unlock_key(self.keyid)
+        else:
             self.keyid = generate_elbe_internal_key()
+            unlock_key(self.keyid)
             self.gen_repo_conf()
 
     def get_volume_fs(self, volume):
@@ -163,14 +169,16 @@ class RepoBase(object):
             self.log.do(
                 'reprepro --export=force --basedir "' +
                 self.fs.path +
-                '" update')
+                '" update',
+                env_add={'GNUPGHOME': "/var/cache/elbe/gnupg"})
         else:
             for att in self.attrs:
                 self.log.do(
                     'reprepro --basedir "' +
                     self.fs.path +
                     '" export ' +
-                    att.codename)
+                    att.codename,
+                    env_add={'GNUPGHOME': "/var/cache/elbe/gnupg"})
 
     def finalize(self):
         os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg"
-- 
2.20.1




More information about the elbe-devel mailing list