summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/gpg_sign.py
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2016-01-25 14:21:34 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-26 22:31:58 +0000
commitbb971577ab308caf7177d4bda290d1fe5ab842db (patch)
tree49c1811106a9b58717dcfd3c6fe4e4810341c1b3 /meta/lib/oe/gpg_sign.py
parentaadb879e5b302e405e05443f56611c17868d10b6 (diff)
downloadpoky-bb971577ab308caf7177d4bda290d1fe5ab842db.tar.gz
meta/lib: new module for handling GPG signing
Add a new Python module (oe.gpg_sign) for handling GPG signing operations, i.e. currently package and package feed signing. The purpose is to be able to more easily support various signing backends and to be able to centralise signing functionality into one place (e.g. package signing and sstate signing). Currently, only local signing with gpg is implemented. [YOCTO #8755] (From OE-Core rev: 9b3dc1bd4b8336423a3f8f7db0ab5fa6fa0e7257) Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oe/gpg_sign.py')
-rw-r--r--meta/lib/oe/gpg_sign.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py
new file mode 100644
index 0000000000..55abad8ffc
--- /dev/null
+++ b/meta/lib/oe/gpg_sign.py
@@ -0,0 +1,76 @@
1"""Helper module for GPG signing"""
2import os
3
4import bb
5import oe.utils
6
7class LocalSigner(object):
8 """Class for handling local (on the build host) signing"""
9 def __init__(self, d, keyid, passphrase_file):
10 self.keyid = keyid
11 self.passphrase_file = passphrase_file
12 self.gpg_bin = d.getVar('GPG_BIN', True) or \
13 bb.utils.which(os.getenv('PATH'), 'gpg')
14 self.gpg_path = d.getVar('GPG_PATH', True)
15 self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm")
16
17 def export_pubkey(self, output_file):
18 """Export GPG public key to a file"""
19 cmd = '%s --batch --yes --export --armor -o %s ' % \
20 (self.gpg_bin, output_file)
21 if self.gpg_path:
22 cmd += "--homedir %s " % self.gpg_path
23 cmd += self.keyid
24 status, output = oe.utils.getstatusoutput(cmd)
25 if status:
26 raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' %
27 (self.keyid, output))
28
29 def sign_rpms(self, files):
30 """Sign RPM files"""
31 import pexpect
32
33 cmd = self.rpm_bin + " --addsign --define '_gpg_name %s' " % self.keyid
34 if self.gpg_bin:
35 cmd += "--define '%%__gpg %s' " % self.gpg_bin
36 if self.gpg_path:
37 cmd += "--define '_gpg_path %s' " % self.gpg_path
38 cmd += ' '.join(files)
39
40 # Need to use pexpect for feeding the passphrase
41 proc = pexpect.spawn(cmd)
42 try:
43 proc.expect_exact('Enter pass phrase:', timeout=15)
44 with open(self.passphrase_file) as fobj:
45 proc.sendline(fobj.readline().rstrip('\n'))
46 proc.expect(pexpect.EOF, timeout=900)
47 proc.close()
48 except pexpect.TIMEOUT as err:
49 bb.error('rpmsign timeout: %s' % err)
50 proc.terminate()
51 if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status):
52 bb.error('rpmsign failed: %s' % proc.before.strip())
53 raise bb.build.FuncFailed("Failed to sign RPM packages")
54
55 def detach_sign(self, input_file):
56 """Create a detached signature of a file"""
57 cmd = "%s --detach-sign --armor --batch --no-tty --yes " \
58 "--passphrase-file '%s' -u '%s' " % \
59 (self.gpg_bin, self.passphrase_file, self.keyid)
60 if self.gpg_path:
61 gpg_cmd += "--homedir %s " % self.gpg_path
62 cmd += input_file
63 status, output = oe.utils.getstatusoutput(cmd)
64 if status:
65 raise bb.build.FuncFailed("Failed to create signature for '%s': %s" %
66 (input_file, output))
67
68
69def get_signer(d, backend, keyid, passphrase_file):
70 """Get signer object for the specified backend"""
71 # Use local signing by default
72 if backend == 'local':
73 return LocalSigner(d, keyid, passphrase_file)
74 else:
75 bb.fatal("Unsupported signing backend '%s'" % backend)
76