* [PATCH v6 0/4] IPK signing for the gpg_sign module
@ 2016-02-19 15:45 Ioan-Adrian Ratiu
2016-02-19 15:45 ` [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality Ioan-Adrian Ratiu
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Ioan-Adrian Ratiu @ 2016-02-19 15:45 UTC (permalink / raw)
To: openembedded-core
This patch series extends the gpg_sign module to support ipk signing.
v6 implements Markus' feedback. The most notable change is the sign_ipk
and detach_sign merger, as they were almost identical in functionality.
This also meant a refactoring for detach_sign and a bug fix for the
STDIN file descriptor introduced in gpg > 2.1.
Technically that STDIN bug is a feature (meh) of gpg >2.1 which breaks
existing behaviour so we have to work around it i.e. check the gpg
version and use the loopback interface. This means that gpg-agent to
which gpg >2.1 always connects needs to be running permanently.
Ioan-Adrian Ratiu (4):
gpg_sign: add local ipk package signing functionality
gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor
gpg_sign: export_pubkey: add signature type support
package_manager: sign IPK package feeds
meta/classes/package_ipk.bbclass | 5 +++
meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++
meta/classes/sign_package_feed.bbclass | 12 +++++-
meta/lib/oe/gpg_sign.py | 74 +++++++++++++++++++++++++++-------
meta/lib/oe/package_manager.py | 17 +++++++-
5 files changed, 143 insertions(+), 17 deletions(-)
create mode 100644 meta/classes/sign_ipk.bbclass
--
2.7.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu @ 2016-02-19 15:45 ` Ioan-Adrian Ratiu 2016-02-23 10:25 ` Markus Lehtonen 2016-02-19 15:45 ` [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor Ioan-Adrian Ratiu ` (3 subsequent siblings) 4 siblings, 1 reply; 8+ messages in thread From: Ioan-Adrian Ratiu @ 2016-02-19 15:45 UTC (permalink / raw) To: openembedded-core Implement ipk signing inside the sign_ipk bbclass using the gpg_sign module and configure signing similar to how rpm does it. sign_ipk uses gpg_sign's detach_sign because its functionality is identical to package feed signing. IPK signing process is a bit different from rpm: - Signatures are stored outside ipk files; opkg connects to a feed server and downloads them to verify a package. - Signatures are of two types (both supported by opkg): binary or ascii armoured. By default we sign using ascii armoured. - Public keys are stored on targets to verify ipks using the opkg-keyrings recipe. Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> --- meta/classes/package_ipk.bbclass | 5 ++++ meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++++++++++++++++++ meta/lib/oe/gpg_sign.py | 50 ++++++++++++++++++++++++++++---------- 3 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 meta/classes/sign_ipk.bbclass diff --git a/meta/classes/package_ipk.bbclass b/meta/classes/package_ipk.bbclass index 51bee28..f64837a 100644 --- a/meta/classes/package_ipk.bbclass +++ b/meta/classes/package_ipk.bbclass @@ -246,6 +246,11 @@ python do_package_ipk () { bb.utils.unlockfile(lf) raise bb.build.FuncFailed("opkg-build execution failed") + if d.getVar('IPK_SIGN_PACKAGES', True) == '1': + ipkver = "%s-%s" % (d.getVar('PKGV'), d.getVar('PKGR')) + ipk_to_sign = "%s/%s_%s_%s.ipk" % (pkgoutdir, pkgname, ipkver, d.getVar('PACKAGE_ARCH', True)) + sign_ipk(d, ipk_to_sign) + cleanupcontrol(root) bb.utils.unlockfile(lf) diff --git a/meta/classes/sign_ipk.bbclass b/meta/classes/sign_ipk.bbclass new file mode 100644 index 0000000..a481f6d --- /dev/null +++ b/meta/classes/sign_ipk.bbclass @@ -0,0 +1,52 @@ +# Class for generating signed IPK packages. +# +# Configuration variables used by this class: +# IPK_GPG_PASSPHRASE_FILE +# Path to a file containing the passphrase of the signing key. +# IPK_GPG_NAME +# Name of the key to sign with. +# IPK_GPG_BACKEND +# Optional variable for specifying the backend to use for signing. +# Currently the only available option is 'local', i.e. local signing +# on the build host. +# IPK_GPG_SIGNATURE_TYPE +# Optional variable for specifying the type of gpg signatures, can be: +# 1. Ascii armored (ASC), default if not set +# 2. Binary (BIN) +# GPG_BIN +# Optional variable for specifying the gpg binary/wrapper to use for +# signing. +# GPG_PATH +# Optional variable for specifying the gnupg "home" directory: +# + +inherit sanity + +IPK_SIGN_PACKAGES = '1' +IPK_GPG_BACKEND ?= 'local' +IPK_GPG_SIGNATURE_TYPE ?= 'ASC' + +python () { + # Check configuration + for var in ('IPK_GPG_NAME', 'IPK_GPG_PASSPHRASE_FILE'): + if not d.getVar(var, True): + raise_sanity_error("You need to define %s in the config" % var, d) + + sigtype = d.getVar("IPK_GPG_SIGNATURE_TYPE", True) + if sigtype.upper() != "ASC" and sigtype.upper() != "BIN": + raise_sanity_error("Bad value for IPK_GPG_SIGNATURE_TYPE (%s), use either ASC or BIN" % sigtype) +} + +def sign_ipk(d, ipk_to_sign): + from oe.gpg_sign import get_signer + + bb.debug(1, 'Signing ipk: %s' % ipk_to_sign) + + signer = get_signer(d, d.getVar('IPK_GPG_BACKEND', True)) + sig_type = d.getVar('IPK_GPG_SIGNATURE_TYPE', True) + is_ascii_sig = (sig_type.upper() != "BIN") + + signer.detach_sign(ipk_to_sign, + d.getVar('IPK_GPG_NAME', True), + d.getVar('IPK_GPG_PASSPHRASE_FILE', True), + armor=is_ascii_sig) diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py index ada1b2f..ef47d1a 100644 --- a/meta/lib/oe/gpg_sign.py +++ b/meta/lib/oe/gpg_sign.py @@ -1,5 +1,6 @@ """Helper module for GPG signing""" import os +import sys import bb import oe.utils @@ -50,6 +51,7 @@ class LocalSigner(object): bb.error('rpmsign failed: %s' % proc.before.strip()) raise bb.build.FuncFailed("Failed to sign RPM packages") + def detach_sign(self, input_file, keyid, passphrase_file, passphrase=None, armor=True): """Create a detached signature of a file""" import subprocess @@ -57,23 +59,45 @@ class LocalSigner(object): if passphrase_file and passphrase: raise Exception("You should use either passphrase_file of passphrase, not both") - cmd = [self.gpg_bin, '--detach-sign', '--batch', '--no-tty', '--yes', - '-u', keyid] - if passphrase_file: - cmd += ['--passphrase-file', passphrase_file] - else: - cmd += ['--passphrase-fd', '0'] + cmd = [self.gpg_bin, '--detach-sign', '--batch', '--no-tty', '--yes', '-u', keyid] + if self.gpg_path: cmd += ['--homedir', self.gpg_path] if armor: cmd += ['--armor'] - cmd.append(input_file) - job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, stderr = job.communicate(passphrase) - if job.returncode: - raise bb.build.FuncFailed("Failed to create signature for '%s': %s" % - (input_file, stderr)) + + try: + keypipe = os.pipe() + + if passphrase_file: + with open(passphrase_file) as fobj: + os.write(keypipe[1], fobj.readline()); + else: + os.write(keypipe[1], passphrase) + + cmd += ["--passphrase-fd", str(keypipe[0])] + cmd += [input_file] + + job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + (_, stderr) = job.communicate(passphrase) + + os.close(keypipe[1]) + os.close(keypipe[0]) + + if job.returncode: + raise bb.build.FuncFailed("GPG exited with code %d: %s" % + (job.returncode, stderr)) + + except IOError as e: + bb.error("IO error (%s): %s" % (e.errno, e.strerror)) + raise Exception("Failed to sign '%s'" % input_file) + except OSError as e: + bb.error("OS error (%s): %s" % (e.errno, e.strerror)) + raise Exception("Failed to sign '%s" % input_file) + except: + bb.error("Unexpected error (%s): %s" % (sys.exc_info()[0], sys.exc_info()[1])) + raise Exception("Failed to sign '%s'" % input_file) + def verify(self, sig_file): """Verify signature""" -- 2.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality 2016-02-19 15:45 ` [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality Ioan-Adrian Ratiu @ 2016-02-23 10:25 ` Markus Lehtonen 0 siblings, 0 replies; 8+ messages in thread From: Markus Lehtonen @ 2016-02-23 10:25 UTC (permalink / raw) To: Ioan-Adrian Ratiu, openembedded-core Hi, Resending as my I got a strange "Only members may post to the list." error yesterday... On Fri, 2016-02-19 at 17:43 +0200, Ioan-Adrian Ratiu wrote: > Implement ipk signing inside the sign_ipk bbclass using the gpg_sign > module and configure signing similar to how rpm does it. sign_ipk > uses > gpg_sign's detach_sign because its functionality is identical to > package > feed signing. > > IPK signing process is a bit different from rpm: > - Signatures are stored outside ipk files; opkg connects to a > feed > server and downloads them to verify a package. > - Signatures are of two types (both supported by opkg): binary or > ascii armoured. By default we sign using ascii armoured. > - Public keys are stored on targets to verify ipks using the > opkg-keyrings recipe. > > Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> > --- > meta/classes/package_ipk.bbclass | 5 ++++ > meta/classes/sign_ipk.bbclass | 52 > ++++++++++++++++++++++++++++++++++++++++ > meta/lib/oe/gpg_sign.py | 50 ++++++++++++++++++++++++++++-- > -------- > 3 files changed, 94 insertions(+), 13 deletions(-) > create mode 100644 meta/classes/sign_ipk.bbclass > > diff --git a/meta/classes/package_ipk.bbclass > b/meta/classes/package_ipk.bbclass > index 51bee28..f64837a 100644 > --- a/meta/classes/package_ipk.bbclass > +++ b/meta/classes/package_ipk.bbclass > @@ -246,6 +246,11 @@ python do_package_ipk () { > bb.utils.unlockfile(lf) > raise bb.build.FuncFailed("opkg-build execution failed") > > + if d.getVar('IPK_SIGN_PACKAGES', True) == '1': > + ipkver = "%s-%s" % (d.getVar('PKGV'), d.getVar('PKGR')) > + ipk_to_sign = "%s/%s_%s_%s.ipk" % (pkgoutdir, pkgname, > ipkver, d.getVar('PACKAGE_ARCH', True)) > + sign_ipk(d, ipk_to_sign) > + > cleanupcontrol(root) > bb.utils.unlockfile(lf) > > diff --git a/meta/classes/sign_ipk.bbclass > b/meta/classes/sign_ipk.bbclass > new file mode 100644 > index 0000000..a481f6d > --- /dev/null > +++ b/meta/classes/sign_ipk.bbclass > @@ -0,0 +1,52 @@ > +# Class for generating signed IPK packages. > +# > +# Configuration variables used by this class: > +# IPK_GPG_PASSPHRASE_FILE > +# Path to a file containing the passphrase of the signing > key. > +# IPK_GPG_NAME > +# Name of the key to sign with. > +# IPK_GPG_BACKEND > +# Optional variable for specifying the backend to use for > signing. > +# Currently the only available option is 'local', i.e. > local signing > +# on the build host. > +# IPK_GPG_SIGNATURE_TYPE > +# Optional variable for specifying the type of gpg > signatures, can be: > +# 1. Ascii armored (ASC), default if not set > +# 2. Binary (BIN) > +# GPG_BIN > +# Optional variable for specifying the gpg binary/wrapper > to use for > +# signing. > +# GPG_PATH > +# Optional variable for specifying the gnupg "home" > directory: > +# > + > +inherit sanity > + > +IPK_SIGN_PACKAGES = '1' > +IPK_GPG_BACKEND ?= 'local' > +IPK_GPG_SIGNATURE_TYPE ?= 'ASC' > + > +python () { > + # Check configuration > + for var in ('IPK_GPG_NAME', 'IPK_GPG_PASSPHRASE_FILE'): > + if not d.getVar(var, True): > + raise_sanity_error("You need to define %s in the config" > % var, d) > + > + sigtype = d.getVar("IPK_GPG_SIGNATURE_TYPE", True) > + if sigtype.upper() != "ASC" and sigtype.upper() != "BIN": > + raise_sanity_error("Bad value for IPK_GPG_SIGNATURE_TYPE > (%s), use either ASC or BIN" % sigtype) > +} > + > +def sign_ipk(d, ipk_to_sign): > + from oe.gpg_sign import get_signer > + > + bb.debug(1, 'Signing ipk: %s' % ipk_to_sign) > + > + signer = get_signer(d, d.getVar('IPK_GPG_BACKEND', True)) > + sig_type = d.getVar('IPK_GPG_SIGNATURE_TYPE', True) > + is_ascii_sig = (sig_type.upper() != "BIN") > + > + signer.detach_sign(ipk_to_sign, > + d.getVar('IPK_GPG_NAME', True), > + d.getVar('IPK_GPG_PASSPHRASE_FILE', True), > + armor=is_ascii_sig) > diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py > index ada1b2f..ef47d1a 100644 > --- a/meta/lib/oe/gpg_sign.py > +++ b/meta/lib/oe/gpg_sign.py > @@ -1,5 +1,6 @@ > """Helper module for GPG signing""" > import os > +import sys > > import bb > import oe.utils > @@ -50,6 +51,7 @@ class LocalSigner(object): > bb.error('rpmsign failed: %s' % proc.before.strip()) > raise bb.build.FuncFailed("Failed to sign RPM packages") > > + > def detach_sign(self, input_file, keyid, passphrase_file, > passphrase=None, armor=True): > """Create a detached signature of a file""" > import subprocess > @@ -57,23 +59,45 @@ class LocalSigner(object): > if passphrase_file and passphrase: > raise Exception("You should use either passphrase_file > of passphrase, not both") > > - cmd = [self.gpg_bin, '--detach-sign', '--batch', '--no-tty', > '--yes', > - '-u', keyid] > - if passphrase_file: > - cmd += ['--passphrase-file', passphrase_file] > - else: > - cmd += ['--passphrase-fd', '0'] > + cmd = [self.gpg_bin, '--detach-sign', '--batch', '--no-tty', > '--yes', '-u', keyid] > + > if self.gpg_path: > cmd += ['--homedir', self.gpg_path] > if armor: > cmd += ['--armor'] > - cmd.append(input_file) > - job = subprocess.Popen(cmd, stdin=subprocess.PIPE, > stdout=subprocess.PIPE, > - stderr=subprocess.PIPE) > - _, stderr = job.communicate(passphrase) > - if job.returncode: > - raise bb.build.FuncFailed("Failed to create signature > for '%s': %s" % > - (input_file, stderr)) > + > + try: > + keypipe = os.pipe() > + > + if passphrase_file: > + with open(passphrase_file) as fobj: > + os.write(keypipe[1], fobj.readline()); > + else: > + os.write(keypipe[1], passphrase) > + > + cmd += ["--passphrase-fd", str(keypipe[0])] > + cmd += [input_file] > + > + job = subprocess.Popen(cmd, stdin=subprocess.PIPE, > stderr=subprocess.PIPE) > + (_, stderr) = job.communicate(passphrase) > + > + os.close(keypipe[1]) > + os.close(keypipe[0]) I still fail to see why you want to complicate the code with os.pipe. Why not ditch pipe and just do something like: if passphrase_file: with open(passphrase_file) as fobj: _, stderr = job.communicate(fobj.readline()) Thanks, Markus > + > + if job.returncode: > + raise bb.build.FuncFailed("GPG exited with code %d: > %s" % > + (job.returncode, stderr)) > + > + except IOError as e: > + bb.error("IO error (%s): %s" % (e.errno, e.strerror)) > + raise Exception("Failed to sign '%s'" % input_file) > + except OSError as e: > + bb.error("OS error (%s): %s" % (e.errno, e.strerror)) > + raise Exception("Failed to sign '%s" % input_file) > + except: > + bb.error("Unexpected error (%s): %s" % > (sys.exc_info()[0], sys.exc_info()[1])) > + raise Exception("Failed to sign '%s'" % input_file) > + > > def verify(self, sig_file): > """Verify signature""" ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality Ioan-Adrian Ratiu @ 2016-02-19 15:45 ` Ioan-Adrian Ratiu 2016-02-23 10:26 ` Markus Lehtonen 2016-02-19 15:45 ` [PATCH v6 3/4] gpg_sign: export_pubkey: add signature type support Ioan-Adrian Ratiu ` (2 subsequent siblings) 4 siblings, 1 reply; 8+ messages in thread From: Ioan-Adrian Ratiu @ 2016-02-19 15:45 UTC (permalink / raw) To: openembedded-core Starting from v2.1 passing passwords directly to gpg does not work anymore [1], instead a loopback interface must be used otherwise gpg >2.1 will error out with: "gpg: signing failed: Inappropriate ioctl for device" gpg <2.1 does not work with the new --pinentry-mode arg and gives an invalid option error, so we detect what is the running version of gpg and pass it accordingly. [1] https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> --- meta/lib/oe/gpg_sign.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py index ef47d1a..9f6b0f0 100644 --- a/meta/lib/oe/gpg_sign.py +++ b/meta/lib/oe/gpg_sign.py @@ -66,6 +66,12 @@ class LocalSigner(object): if armor: cmd += ['--armor'] + #gpg > 2.1 supports password pipes only through the loopback interface + #gpg < 2.1 errors out if given unknown parameters + gpg_ver = self.get_gpg_version() + if gpg_ver > 2.1: + cmd += ['--pinentry-mode', 'loopback'] + try: keypipe = os.pipe() @@ -99,6 +105,20 @@ class LocalSigner(object): raise Exception("Failed to sign '%s'" % input_file) + def get_gpg_version(self): + """Return the gpg version""" + import subprocess + + job = subprocess.Popen([self.gpg_bin, "--version"], stdout=subprocess.PIPE) + (stdout, _) = job.communicate() + + if job.returncode: + raise bb.build.FuncFailed("Could not get gpg version (is %s installed?)" % + self.gpg_bin) + + return stdout.split()[2] + + def verify(self, sig_file): """Verify signature""" cmd = self.gpg_bin + " --verify " -- 2.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor 2016-02-19 15:45 ` [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor Ioan-Adrian Ratiu @ 2016-02-23 10:26 ` Markus Lehtonen 0 siblings, 0 replies; 8+ messages in thread From: Markus Lehtonen @ 2016-02-23 10:26 UTC (permalink / raw) To: Ioan-Adrian Ratiu, openembedded-core Hi, Resending as my I got a strange "Only members may post to the list." error yesterday... On Fri, 2016-02-19 at 17:43 +0200, Ioan-Adrian Ratiu wrote: > Starting from v2.1 passing passwords directly to gpg does not work > anymore [1], instead a loopback interface must be used otherwise > gpg >2.1 will error out with: > "gpg: signing failed: Inappropriate ioctl for device" > > gpg <2.1 does not work with the new --pinentry-mode arg and gives an > invalid option error, so we detect what is the running version of gpg > and pass it accordingly. > > [1] https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase > > Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> > --- > meta/lib/oe/gpg_sign.py | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py > index ef47d1a..9f6b0f0 100644 > --- a/meta/lib/oe/gpg_sign.py > +++ b/meta/lib/oe/gpg_sign.py > @@ -66,6 +66,12 @@ class LocalSigner(object): > if armor: > cmd += ['--armor'] > > + #gpg > 2.1 supports password pipes only through the loopback > interface > + #gpg < 2.1 errors out if given unknown parameters > + gpg_ver = self.get_gpg_version() > + if gpg_ver > 2.1: > + cmd += ['--pinentry-mode', 'loopback'] > + As far as I can tell get_gpg_version returns a string. However, you compare that with a float. This should give more correct behavior: + if gpg_ver > "2.1": Thanks, Markus > try: > keypipe = os.pipe() > > @@ -99,6 +105,20 @@ class LocalSigner(object): > raise Exception("Failed to sign '%s'" % input_file) > > > + def get_gpg_version(self): > + """Return the gpg version""" > + import subprocess > + > + job = subprocess.Popen([self.gpg_bin, "--version"], > stdout=subprocess.PIPE) > + (stdout, _) = job.communicate() > + > + if job.returncode: > + raise bb.build.FuncFailed("Could not get gpg version (is > %s installed?)" % > + self.gpg_bin) > + > + return stdout.split()[2] > + > + > def verify(self, sig_file): > """Verify signature""" > cmd = self.gpg_bin + " --verify " ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v6 3/4] gpg_sign: export_pubkey: add signature type support 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor Ioan-Adrian Ratiu @ 2016-02-19 15:45 ` Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 4/4] package_manager: sign IPK package feeds Ioan-Adrian Ratiu 2016-02-23 10:28 ` [PATCH v6 0/4] IPK signing for the gpg_sign module Markus Lehtonen 4 siblings, 0 replies; 8+ messages in thread From: Ioan-Adrian Ratiu @ 2016-02-19 15:45 UTC (permalink / raw) To: openembedded-core Add support for multiple types of signatures (binary or ascii) in export_pubkey(). There is no change in behaviour for the function, the previous implicit default is the new parameter "armor" default. Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> --- meta/lib/oe/gpg_sign.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py index 9f6b0f0..9b3864a 100644 --- a/meta/lib/oe/gpg_sign.py +++ b/meta/lib/oe/gpg_sign.py @@ -13,12 +13,14 @@ class LocalSigner(object): self.gpg_path = d.getVar('GPG_PATH', True) self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") - def export_pubkey(self, output_file, keyid): + def export_pubkey(self, output_file, keyid, armor=True): """Export GPG public key to a file""" - cmd = '%s --batch --yes --export --armor -o %s ' % \ + cmd = '%s --batch --yes --export -o %s ' % \ (self.gpg_bin, output_file) if self.gpg_path: cmd += "--homedir %s " % self.gpg_path + if armor: + cmd += "--armor " cmd += keyid status, output = oe.utils.getstatusoutput(cmd) if status: -- 2.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 4/4] package_manager: sign IPK package feeds 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu ` (2 preceding siblings ...) 2016-02-19 15:45 ` [PATCH v6 3/4] gpg_sign: export_pubkey: add signature type support Ioan-Adrian Ratiu @ 2016-02-19 15:45 ` Ioan-Adrian Ratiu 2016-02-23 10:28 ` [PATCH v6 0/4] IPK signing for the gpg_sign module Markus Lehtonen 4 siblings, 0 replies; 8+ messages in thread From: Ioan-Adrian Ratiu @ 2016-02-19 15:45 UTC (permalink / raw) To: openembedded-core Create gpg signed ipk package feeds using the gpg backend if configured. Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> --- meta/classes/sign_package_feed.bbclass | 12 +++++++++++- meta/lib/oe/package_manager.py | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass index 63ca02f..85c37f3 100644 --- a/meta/classes/sign_package_feed.bbclass +++ b/meta/classes/sign_package_feed.bbclass @@ -10,6 +10,12 @@ # Optional variable for specifying the backend to use for signing. # Currently the only available option is 'local', i.e. local signing # on the build host. +# PACKAGE_FEED_GPG_SIGNATURE_TYPE +# Optional variable for specifying the type of gpg signature, can be: +# 1. Ascii armored (ASC), default if not set +# 2. Binary (BIN) +# This variable is only available for IPK feeds. It is ignored on +# other packaging backends. # GPG_BIN # Optional variable for specifying the gpg binary/wrapper to use for # signing. @@ -20,7 +26,7 @@ inherit sanity PACKAGE_FEED_SIGN = '1' PACKAGE_FEED_GPG_BACKEND ?= 'local' - +PACKAGE_FEED_GPG_SIGNATURE_TYPE ?= 'ASC' python () { # Check sanity of configuration @@ -28,6 +34,10 @@ python () { if not d.getVar(var, True): raise_sanity_error("You need to define %s in the config" % var, d) + sigtype = d.getVar("PACKAGE_FEED_GPG_SIGNATURE_TYPE", True) + if sigtype.upper() != "ASC" and sigtype.upper() != "BIN": + raise_sanity_error("Bad value for PACKAGE_FEED_GPG_SIGNATURE_TYPE (%s), use either ASC or BIN" % sigtype) + # Set expected location of the public key d.setVar('PACKAGE_FEED_GPG_PUBKEY', os.path.join(d.getVar('STAGING_ETCDIR_NATIVE', False), diff --git a/meta/lib/oe/package_manager.py b/meta/lib/oe/package_manager.py index b30a4da..606ba24 100644 --- a/meta/lib/oe/package_manager.py +++ b/meta/lib/oe/package_manager.py @@ -163,11 +163,16 @@ class OpkgIndexer(Indexer): "MULTILIB_ARCHS"] opkg_index_cmd = bb.utils.which(os.getenv('PATH'), "opkg-make-index") + if self.d.getVar('PACKAGE_FEED_SIGN', True) == '1': + signer = get_signer(self.d, self.d.getVar('PACKAGE_FEED_GPG_BACKEND', True)) + else: + signer = None if not os.path.exists(os.path.join(self.deploy_dir, "Packages")): open(os.path.join(self.deploy_dir, "Packages"), "w").close() index_cmds = [] + index_sign_files = [] for arch_var in arch_vars: archs = self.d.getVar(arch_var, True) if archs is None: @@ -186,6 +191,8 @@ class OpkgIndexer(Indexer): index_cmds.append('%s -r %s -p %s -m %s' % (opkg_index_cmd, pkgs_file, pkgs_file, pkgs_dir)) + index_sign_files.append(pkgs_file) + if len(index_cmds) == 0: bb.note("There are no packages in %s!" % self.deploy_dir) return @@ -193,9 +200,15 @@ class OpkgIndexer(Indexer): result = oe.utils.multiprocess_exec(index_cmds, create_index) if result: bb.fatal('%s' % ('\n'.join(result))) - if self.d.getVar('PACKAGE_FEED_SIGN', True) == '1': - raise NotImplementedError('Package feed signing not implementd for ipk') + if signer: + feed_sig_type = self.d.getVar('PACKAGE_FEED_GPG_SIGNATURE_TYPE', True) + is_ascii_sig = (feed_sig_type.upper() != "BIN") + for f in index_sign_files: + signer.detach_sign(f, + self.d.getVar('PACKAGE_FEED_GPG_NAME', True), + self.d.getVar('PACKAGE_FEED_GPG_PASSPHRASE_FILE', True), + armor=is_ascii_sig) class DpkgIndexer(Indexer): -- 2.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 0/4] IPK signing for the gpg_sign module 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu ` (3 preceding siblings ...) 2016-02-19 15:45 ` [PATCH v6 4/4] package_manager: sign IPK package feeds Ioan-Adrian Ratiu @ 2016-02-23 10:28 ` Markus Lehtonen 4 siblings, 0 replies; 8+ messages in thread From: Markus Lehtonen @ 2016-02-23 10:28 UTC (permalink / raw) To: Ioan-Adrian Ratiu, openembedded-core Hi, Resending as my I got a strange "Only members may post to the list." error yesterday... On Fri, 2016-02-19 at 17:45 +0200, Ioan-Adrian Ratiu wrote: > This patch series extends the gpg_sign module to support ipk signing. > > v6 implements Markus' feedback. The most notable change is the > sign_ipk > and detach_sign merger, as they were almost identical in > functionality. > This also meant a refactoring for detach_sign and a bug fix for the > STDIN file descriptor introduced in gpg > 2.1. > > Technically that STDIN bug is a feature (meh) of gpg >2.1 which > breaks > existing behaviour so we have to work around it i.e. check the gpg > version and use the loopback interface. This means that gpg-agent to > which gpg >2.1 always connects needs to be running permanently. > > Ioan-Adrian Ratiu (4): > gpg_sign: add local ipk package signing functionality > gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor > gpg_sign: export_pubkey: add signature type support > package_manager: sign IPK package feeds > > meta/classes/package_ipk.bbclass | 5 +++ > meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++ > meta/classes/sign_package_feed.bbclass | 12 +++++- > meta/lib/oe/gpg_sign.py | 74 > +++++++++++++++++++++++++++------- > meta/lib/oe/package_manager.py | 17 +++++++- > 5 files changed, 143 insertions(+), 17 deletions(-) > create mode 100644 meta/classes/sign_ipk.bbclass I just realized that it would be good to add the ipk signing key to the signing_keys.bb recipe. However, it'd probably be good to write it on top of Randy Witt's rework: http://lists.openembedded.org/pipermail/openembedded-core/2016-February /117791.html Thanks, Markus ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-02-23 10:28 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-02-19 15:45 [PATCH v6 0/4] IPK signing for the gpg_sign module Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 1/4] gpg_sign: add local ipk package signing functionality Ioan-Adrian Ratiu 2016-02-23 10:25 ` Markus Lehtonen 2016-02-19 15:45 ` [PATCH v6 2/4] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor Ioan-Adrian Ratiu 2016-02-23 10:26 ` Markus Lehtonen 2016-02-19 15:45 ` [PATCH v6 3/4] gpg_sign: export_pubkey: add signature type support Ioan-Adrian Ratiu 2016-02-19 15:45 ` [PATCH v6 4/4] package_manager: sign IPK package feeds Ioan-Adrian Ratiu 2016-02-23 10:28 ` [PATCH v6 0/4] IPK signing for the gpg_sign module Markus Lehtonen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox