[elbe-devel] [PATCH v2] gpg: gpg2 requires passphrases for private keys

Manuel Traut manut at linutronix.de
Thu Apr 4 09:26:57 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>
---

changes since v1: use shellhelper

 elbepack/egpg.py        | 15 ++++++++++++++-
 elbepack/finetuning.py  |  2 ++
 elbepack/repomanager.py | 22 +++++++++++++++-------
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/elbepack/egpg.py b/elbepack/egpg.py
index 6d9072e2..7c3827cf 100644
--- a/elbepack/egpg.py
+++ b/elbepack/egpg.py
@@ -13,6 +13,7 @@ from gpg import core
 from gpg.constants import sigsum, sig
 
 from elbepack.filesystem import hostfs
+from elbepack.shellhelper import system
 
 elbe_internal_key_param = """
 <GnupgKeyParms format="internal">
@@ -23,6 +24,7 @@ elbe_internal_key_param = """
   Name-Comment: Automatically generated
   Name-Email: root at elbe-daemon.de
   Expire-Date: 0
+  Passphrase: requiredToAvoidUserInput
 </GnupgKeyParms>
 """
 
@@ -146,6 +148,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
+    system("/usr/lib/gnupg2/gpg-preset-passphrase "
+           "--preset -P requiredToAvoidUserInput %s" % str(keygrip),
+           env_add={"GNUPGHOME": "/var/cache/elbe/gnupg"})
 
 def sign(infile, outfile, fingerprint):
 
@@ -158,6 +168,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 +205,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 +229,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