IPK signing for the gpg_sign module
v7 cover IPK signing for the gpg_sign module
This patch series extends the gpg_sign module to support ipk signing.
Changes since v6:
* Added pubkey to signing_keys.bb and rebased on top of Randy's work
* Made gpg version detection logic more robust
* Simplified detach_sign() gpg communication (no more os.pipe)
Ioan-Adrian Ratiu (5):
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
signing-keys: create ipk package
package_manager: sign IPK package feeds
meta/classes/package_ipk.bbclass | 5 +++ meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++++++ meta/classes/sign_package_feed.bbclass | 17 ++++++++- meta/lib/oe/gpg_sign.py | 63 ++++++++++++++++++++++++++-------- meta/lib/oe/package_manager.py | 17 +++++++-- meta/recipes-core/meta/signing-keys.bb | 15 +++++++- 6 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 meta/classes/sign_ipk.bbclass
Signature · 1 line
2.7.1
PATCH v7 1/5 gpg_sign: add local ipk package signing functionality
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.
--- meta/classes/package_ipk.bbclass | 5 ++++ meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++++++++++++++++++ meta/lib/oe/gpg_sign.py | 41 +++++++++++++++++++++---------- 3 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 meta/classes/sign_ipk.bbclass
meta/classes/package_ipk.bbclass +5 -0
@@ -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', True), d.getVar('PKGR', True)) + 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)
meta/classes/sign_ipk.bbclass new file +52 -0
52 lines not on this page · raw message
meta/lib/oe/gpg_sign.py +29 -12
62 lines not on this page · raw message
Signature · 1 line
2.7.1
Re: [PATCH v7 1/5] gpg_sign: add local ipk package signing functionality
Quoted 150 lines · Ioan-Adrian Ratiu
Implement ipk signing inside the
sign_ipkbbclass using thegpg_signmodule and configure signing similar to how rpm does it.sign_ipkuses gpg_sign'sdetach_signbecause 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 <[email protected]>---
meta/classes/package_ipk.bbclass | 5 ++++ meta/classes/sign_ipk.bbclass | 52 ++++++++++++++++++++++++++++++++++++++++ meta/lib/oe/gpg_sign.py | 41 +++++++++++++++++++++---------- 3 files changed, 86 insertions(+), 12 deletions(-)create mode 100644 meta/classes/sign_ipk.bbclass
meta/classes/package_ipk.bbclass +5
-0@@ -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', True), d.getVar('PKGR', True)) + 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)meta/classes/sign_ipk.bbclass new file +52
-0@@ -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)meta/lib/oe/gpg_sign.py +0
-0@@ -1,5 +1,6 @@"""Helper module for GPG signing"""
import os
+import sysimport bb
import oe.utilsmeta/lib/oe/gpg_sign.py +17
-12@@ -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@@ -58,22 +60,37 @@ class LocalSigner(object): 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'] + '--passphrase-fd', '0', '-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)) + + cmd += [input_file] + + try: + if passphrase_file: + with open(passphrase_file) as fobj: + passphrase = fobj.readline(); + + job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + (_, stderr) = job.communicate(passphrase) + + if job.returncode: + raise bb.build.FuncFailed("GPG exited with code %d: %s" % + (job.returncode, stderr))
meta/lib/oe/gpg_sign.py class LocalSigner(object): · line 92
Quoted 10 lines
meta/lib/oe/gpg_sign.py +10
-0+ + 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)
Still one nitpick :) I would move the except clauses before the if statement. Otherwise the general "except:" is masking the bb.build.FuncFailed exception.
Thanks,
Markus
Quoted 4 lines
meta/lib/oe/gpg_sign.py +1
-0+ def verify(self, sig_file): """Verify signature"""
PATCH v7 2/5 gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor
In reply to Ioan-Adrian RatiuStarting 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
--- meta/lib/oe/gpg_sign.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
meta/lib/oe/gpg_sign.py +16 -0
@@ -67,6 +67,13 @@ 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 + dots = self.get_gpg_version().split('.') + assert len(dots) >= 2 + if int(dots[0]) >= 2 and int(dots[1]) >= 1: + cmd += ['--pinentry-mode', 'loopback'] + cmd += [input_file] try:
@@ -92,6 +99,15 @@ class LocalSigner(object): raise Exception("Failed to sign '%s'" % input_file) + def get_gpg_version(self): + """Return the gpg version""" + import subprocess + try: + return subprocess.check_output((self.gpg_bin, "--version")).split()[2] + except subprocess.CalledProcessError as e: + raise bb.build.FuncFailed("Could not get gpg version: %s" % e) + + def verify(self, sig_file): """Verify signature""" cmd = self.gpg_bin + " --verify "
Signature · 1 line
2.7.1
Re: [PATCH v7 2/5] gpg_sign: detach_sign: fix gpg > 2.1 STDIN file descriptor
Quoted 35 lines · Ioan-Adrian Ratiu
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 <[email protected]>---
meta/lib/oe/gpg_sign.py| 16 ++++++++++++++++1 file changed, 16 insertions(+)meta/lib/oe/gpg_sign.py +7
-0@@ -67,6 +67,13 @@ 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 + dots = self.get_gpg_version().split('.') + assert len(dots) >= 2 + if int(dots[0]) >= 2 and int(dots[1]) >= 1: + cmd += ['--pinentry-mode', 'loopback'] + cmd += [input_file] try:
meta/lib/oe/gpg_sign.py class LocalSigner(object): · line 99
Quoted 1 line
meta/lib/oe/gpg_sign.py +0
-0@@ -92,6 +99,15 @@ class LocalSigner(object): raise Exception("Failed to sign '%s'" % input_file)
Another nitpick: missing a line feed here(?)
Thanks,
Markus
Quoted 17 lines
meta/lib/oe/gpg_sign.py +9
-0+ def get_gpg_version(self): + """Return the gpg version""" + import subprocess + try: + return subprocess.check_output((self.gpg_bin, "--version")).split()[2] + except subprocess.CalledProcessError as e: + raise bb.build.FuncFailed("Could not get gpg version: %s" % e) + + def verify(self, sig_file): """Verify signature""" cmd = self.gpg_bin + " --verify "Signature · 1 line
2.7.1
PATCH v7 3/5 gpg_sign: export_pubkey: add signature type support
In reply to Ioan-Adrian RatiuAdd 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.
--- meta/lib/oe/gpg_sign.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
meta/lib/oe/gpg_sign.py +4 -2
@@ -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:
Signature · 1 line
2.7.1
PATCH v7 4/5 signing-keys: create ipk package
In reply to Ioan-Adrian RatiuStore the ascii armored pubkey generated using gpg_sign.export_pubkey() in its own package.
--- meta/recipes-core/meta/signing-keys.bb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
meta/recipes-core/meta/signing-keys.bb +14 -1
@@ -12,9 +12,10 @@ inherit allarch deploy EXCLUDE_FROM_WORLD = "1" INHIBIT_DEFAULT_DEPS = "1" -PACKAGES =+ "${PN}-rpm ${PN}-packagefeed" +PACKAGES =+ "${PN}-ipk ${PN}-rpm ${PN}-packagefeed" FILES_${PN}-rpm = "${sysconfdir}/pki/rpm-gpg" +FILES_${PN}-ipk = "${sysconfdir}/pki/ipk-gpg" FILES_${PN}-packagefeed = "${sysconfdir}/pki/packagefeed-gpg" python do_get_public_keys () {
@@ -26,6 +27,12 @@ python do_get_public_keys () { signer.export_pubkey(os.path.join(d.expand('${B}'), 'rpm-key'), d.getVar('RPM_GPG_NAME', True)) + if d.getVar("IPK_SIGN_PACKAGES", True): + # Export public key of the ipk signing key + signer = get_signer(d, d.getVar('IPK_GPG_BACKEND', True)) + signer.export_pubkey(os.path.join(d.expand('${B}'), 'ipk-key'), + d.getVar('IPK_GPG_NAME', True)) + if d.getVar('PACKAGE_FEED_SIGN', True) == '1': # Export public key of the feed signing key signer = get_signer(d, d.getVar('PACKAGE_FEED_GPG_BACKEND', True))
@@ -39,6 +46,9 @@ do_install () { if [ -f "${B}/rpm-key" ]; then install -D -m 0644 "${B}/rpm-key" "${D}${sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-${DISTRO_VERSION}" fi + if [ -f "${B}/ipk-key" ]; then + install -D -m 0644 "${B}/ipk-key" "${D}${sysconfdir}/pki/ipk-gpg/IPK-GPG-KEY-${DISTRO_VERSION}" + fi if [ -f "${B}/pf-key" ]; then install -D -m 0644 "${B}/pf-key" "${D}${sysconfdir}/pki/packagefeed-gpg/PACKAGEFEED-GPG-KEY-${DISTRO_VERSION}" fi
@@ -52,6 +62,9 @@ do_deploy () { if [ -f "${B}/rpm-key" ]; then install -D -m 0644 "${B}/rpm-key" "${DEPLOYDIR}/RPM-GPG-KEY-${DISTRO_VERSION}" fi + if [ -f "${B}/ipk-key" ]; then + install -D -m 0644 "${B}/ipk-key" "${DEPLOYDIR}/IPK-GPG-KEY-${DISTRO_VERSION}" + fi if [ -f "${B}/pf-key" ]; then install -D -m 0644 "${B}/pf-key" "${DEPLOYDIR}/PACKAGEFEED-GPG-KEY-${DISTRO_VERSION}" fi
Signature · 1 line
2.7.1
PATCH v7 5/5 package_manager: sign IPK package feeds
In reply to Ioan-Adrian RatiuCreate gpg signed ipk package feeds using the gpg backend if configured.
--- meta/classes/sign_package_feed.bbclass | 17 ++++++++++++++++- meta/lib/oe/package_manager.py | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-)
meta/classes/sign_package_feed.bbclass +16 -1
@@ -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,13 +26,22 @@ inherit sanity PACKAGE_FEED_SIGN = '1' PACKAGE_FEED_GPG_BACKEND ?= 'local' - +PACKAGE_FEED_GPG_SIGNATURE_TYPE ?= 'ASC' python () { # Check sanity of configuration for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_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("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), + 'PACKAGE-FEED-GPG-PUBKEY')) } do_package_index[depends] += "signing-keys:do_deploy"
meta/lib/oe/package_manager.py +15 -2
@@ -153,11 +153,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:
@@ -176,6 +181,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
@@ -183,9 +190,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):
Signature · 1 line
2.7.1
Re: [PATCH v7 5/5] package_manager: sign IPK package feeds
Quoted 37 lines · Ioan-Adrian Ratiu
Create gpg signed ipk package feeds using the gpg backend if configured.
Signed-off-by Ioan-Adrian Ratiu <[email protected]>---
meta/classes/sign_package_feed.bbclass | 17 ++++++++++++++++-meta/lib/oe/package_manager.py| 17 +++++++++++++++--2 files changed, 31 insertions(+), 3 deletions(-)meta/classes/sign_package_feed.bbclass +6
-0@@ -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,13 +26,22 @@ inherit sanity
PACKAGE_FEED_SIGN= '1'PACKAGE_FEED_GPG_BACKEND?= 'local'meta/classes/sign_package_feed.bbclass +1
-1- +PACKAGE_FEED_GPG_SIGNATURE_TYPE ?= 'ASC'python () {
# Check sanity of configuration
for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'):
if notd.getVar(var, True):
raise_sanity_error("You need to define %s in the config" % var, d)
meta/classes/sign_package_feed.bbclass inherit sanity · line 44
Quoted 9 lines
meta/classes/sign_package_feed.bbclass +9
-0+ + 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), + 'PACKAGE-FEED-GPG-PUBKEY'))
We just got rid of the PACKAGE_FEED_GPG_PUBKEY variable in a recent patch from Randy Witt. There should be no reason to re-introduce it.
Thanks,
Markus
Quoted 54 lines
}
do_package_index[depends] += "signing-keys:do_deploy"
meta/lib/oe/package_manager.py +15
-2@@ -153,11 +153,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:@@ -176,6 +181,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@@ -183,9 +190,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):
Signature · 1 line
2.7.1