* [PATCH 0/3] Support remote RPM signing
@ 2016-01-11 16:13 Markus Lehtonen
2016-01-11 16:13 ` [PATCH 1/3] sign_rpm.bbclass: fix task dependencies Markus Lehtonen
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Markus Lehtonen @ 2016-01-11 16:13 UTC (permalink / raw)
To: openembedded-core
This patchset enables remote signing of RPM packages and package feeds using
the obs-signd signing server from openSUSE.
https://github.com/openSUSE/obs-sign
https://en.opensuse.org/openSUSE:Build_Service_Signer
Other remote signing methods should be easy to add, later.
The first patch of the series is a generic task dependency bugfix for rpm
signing.
The following changes since commit 95fced137a46dc98863fe5af7be5cbce708602f2:
udev-extraconf: introduce multiple blacklist files for more complex setups (2016-01-05 17:55:05 +0000)
are available in the git repository at:
git://git.openembedded.org/openembedded-core-contrib marquiz/rpmsign
for you to fetch changes up to 3ac8c3e5ab0dd6cab1438efd4484e0e313e55d8d:
oe.gpg_sign: support obs-signd (2016-01-11 18:00:19 +0200)
Markus Lehtonen (3):
sign_rpm.bbclass: fix task dependencies
New lib module for handling GPG signing
oe.gpg_sign: support obs-signd
meta/classes/sign_package_feed.bbclass | 11 ++-
meta/classes/sign_rpm.bbclass | 53 +++++---------
meta/lib/oe/gpg_sign.py | 124 +++++++++++++++++++++++++++++++++
meta/lib/oe/package_manager.py | 31 +++------
meta/recipes-core/meta/signing-keys.bb | 26 ++++---
5 files changed, 173 insertions(+), 72 deletions(-)
create mode 100644 meta/lib/oe/gpg_sign.py
--
2.1.4
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 1/3] sign_rpm.bbclass: fix task dependencies 2016-01-11 16:13 [PATCH 0/3] Support remote RPM signing Markus Lehtonen @ 2016-01-11 16:13 ` Markus Lehtonen 2016-01-11 16:13 ` [PATCH 2/3] New lib module for handling GPG signing Markus Lehtonen 2016-01-11 16:13 ` [PATCH 3/3] oe.gpg_sign: support obs-signd Markus Lehtonen 2 siblings, 0 replies; 12+ messages in thread From: Markus Lehtonen @ 2016-01-11 16:13 UTC (permalink / raw) To: openembedded-core do_rootfs task needs to depend on signing-keys:do_export_public_keys. The rpm signing public key needs to be present in order to prevent a crash because it is imported into the rootfs rpmdb before rootfs creation starts. Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> --- meta/classes/sign_rpm.bbclass | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass index bc916a7..7906b64 100644 --- a/meta/classes/sign_rpm.bbclass +++ b/meta/classes/sign_rpm.bbclass @@ -71,3 +71,4 @@ python sign_rpm () { } do_package_index[depends] += "signing-keys:do_export_public_keys" +do_rootfs[depends] += "signing-keys:do_export_public_keys" -- 2.1.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/3] New lib module for handling GPG signing 2016-01-11 16:13 [PATCH 0/3] Support remote RPM signing Markus Lehtonen 2016-01-11 16:13 ` [PATCH 1/3] sign_rpm.bbclass: fix task dependencies Markus Lehtonen @ 2016-01-11 16:13 ` Markus Lehtonen 2016-01-11 16:13 ` [PATCH 3/3] oe.gpg_sign: support obs-signd Markus Lehtonen 2 siblings, 0 replies; 12+ messages in thread From: Markus Lehtonen @ 2016-01-11 16:13 UTC (permalink / raw) To: openembedded-core 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. Currently, only local on-the-build-host signing is implemented. [YOCTO #8755] Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> --- meta/classes/sign_package_feed.bbclass | 6 +++ meta/classes/sign_rpm.bbclass | 47 +++++---------------- meta/lib/oe/gpg_sign.py | 76 ++++++++++++++++++++++++++++++++++ meta/lib/oe/package_manager.py | 31 +++++--------- meta/recipes-core/meta/signing-keys.bb | 26 ++++++------ 5 files changed, 116 insertions(+), 70 deletions(-) create mode 100644 meta/lib/oe/gpg_sign.py diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass index d89bc0b..d5df8af 100644 --- a/meta/classes/sign_package_feed.bbclass +++ b/meta/classes/sign_package_feed.bbclass @@ -6,6 +6,10 @@ # Path to a file containing the passphrase of the signing key. # PACKAGE_FEED_GPG_NAME # Name of the key to sign with. May be key id or key name. +# PACKAGE_FEED_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. # GPG_BIN # Optional variable for specifying the gpg binary/wrapper to use for # signing. @@ -15,6 +19,8 @@ inherit sanity PACKAGE_FEED_SIGN = '1' +PACKAGE_FEED_GPG_BACKEND ?= 'local' + python () { # Check sanity of configuration diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass index 7906b64..8bcabee 100644 --- a/meta/classes/sign_rpm.bbclass +++ b/meta/classes/sign_rpm.bbclass @@ -5,6 +5,10 @@ # Path to a file containing the passphrase of the signing key. # RPM_GPG_NAME # Name of the key to sign with. May be key id or key name. +# RPM_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. # GPG_BIN # Optional variable for specifying the gpg binary/wrapper to use for # signing. @@ -14,6 +18,7 @@ inherit sanity RPM_SIGN_PACKAGES='1' +RPM_GPG_BACKEND ?= 'local' python () { @@ -27,47 +32,17 @@ python () { 'RPM-GPG-PUBKEY')) } - -def rpmsign_wrapper(d, files, passphrase, gpg_name=None): - import pexpect - - # Find the correct rpm binary - rpm_bin_path = d.getVar('STAGING_BINDIR_NATIVE', True) + '/rpm' - cmd = rpm_bin_path + " --addsign --define '_gpg_name %s' " % gpg_name - if d.getVar('GPG_BIN', True): - cmd += "--define '%%__gpg %s' " % d.getVar('GPG_BIN', True) - if d.getVar('GPG_PATH', True): - cmd += "--define '_gpg_path %s' " % d.getVar('GPG_PATH', True) - cmd += ' '.join(files) - - # Need to use pexpect for feeding the passphrase - proc = pexpect.spawn(cmd) - try: - proc.expect_exact('Enter pass phrase:', timeout=15) - proc.sendline(passphrase) - proc.expect(pexpect.EOF, timeout=900) - proc.close() - except pexpect.TIMEOUT as err: - bb.warn('rpmsign timeout: %s' % err) - proc.terminate() - else: - if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status): - bb.warn('rpmsign failed: %s' % proc.before.strip()) - return proc.exitstatus - - python sign_rpm () { import glob + from oe.gpg_sign import get_signer - with open(d.getVar("RPM_GPG_PASSPHRASE_FILE", True)) as fobj: - rpm_gpg_passphrase = fobj.readlines()[0].rstrip('\n') - - rpm_gpg_name = (d.getVar("RPM_GPG_NAME", True) or "") - + signer = get_signer(d, + d.getVar('RPM_GPG_BACKEND', True), + d.getVar('RPM_GPG_NAME', True), + d.getVar('RPM_GPG_PASSPHRASE_FILE', True)) rpms = glob.glob(d.getVar('RPM_PKGWRITEDIR', True) + '/*') - if rpmsign_wrapper(d, rpms, rpm_gpg_passphrase, rpm_gpg_name) != 0: - raise bb.build.FuncFailed("RPM signing failed") + signer.sign_rpms(rpms) } do_package_index[depends] += "signing-keys:do_export_public_keys" diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py new file mode 100644 index 0000000..55abad8 --- /dev/null +++ b/meta/lib/oe/gpg_sign.py @@ -0,0 +1,76 @@ +"""Helper module for GPG signing""" +import os + +import bb +import oe.utils + +class LocalSigner(object): + """Class for handling local (on the build host) signing""" + def __init__(self, d, keyid, passphrase_file): + self.keyid = keyid + self.passphrase_file = passphrase_file + self.gpg_bin = d.getVar('GPG_BIN', True) or \ + bb.utils.which(os.getenv('PATH'), 'gpg') + self.gpg_path = d.getVar('GPG_PATH', True) + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") + + def export_pubkey(self, output_file): + """Export GPG public key to a file""" + cmd = '%s --batch --yes --export --armor -o %s ' % \ + (self.gpg_bin, output_file) + if self.gpg_path: + cmd += "--homedir %s " % self.gpg_path + cmd += self.keyid + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % + (self.keyid, output)) + + def sign_rpms(self, files): + """Sign RPM files""" + import pexpect + + cmd = self.rpm_bin + " --addsign --define '_gpg_name %s' " % self.keyid + if self.gpg_bin: + cmd += "--define '%%__gpg %s' " % self.gpg_bin + if self.gpg_path: + cmd += "--define '_gpg_path %s' " % self.gpg_path + cmd += ' '.join(files) + + # Need to use pexpect for feeding the passphrase + proc = pexpect.spawn(cmd) + try: + proc.expect_exact('Enter pass phrase:', timeout=15) + with open(self.passphrase_file) as fobj: + proc.sendline(fobj.readline().rstrip('\n')) + proc.expect(pexpect.EOF, timeout=900) + proc.close() + except pexpect.TIMEOUT as err: + bb.error('rpmsign timeout: %s' % err) + proc.terminate() + if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status): + bb.error('rpmsign failed: %s' % proc.before.strip()) + raise bb.build.FuncFailed("Failed to sign RPM packages") + + def detach_sign(self, input_file): + """Create a detached signature of a file""" + cmd = "%s --detach-sign --armor --batch --no-tty --yes " \ + "--passphrase-file '%s' -u '%s' " % \ + (self.gpg_bin, self.passphrase_file, self.keyid) + if self.gpg_path: + gpg_cmd += "--homedir %s " % self.gpg_path + cmd += input_file + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed("Failed to create signature for '%s': %s" % + (input_file, output)) + + +def get_signer(d, backend, keyid, passphrase_file): + """Get signer object for the specified backend""" + # Use local signing by default + if backend == 'local': + return LocalSigner(d, keyid, passphrase_file) + else: + bb.fatal("Unsupported signing backend '%s'" % backend) + diff --git a/meta/lib/oe/package_manager.py b/meta/lib/oe/package_manager.py index 32afeaf..c7df4bc 100644 --- a/meta/lib/oe/package_manager.py +++ b/meta/lib/oe/package_manager.py @@ -9,6 +9,7 @@ import bb import tempfile import oe.utils import string +from oe.gpg_sign import get_signer # this can be used by all PM backends to create the index files in parallel def create_index(arg): @@ -109,16 +110,14 @@ class RpmIndexer(Indexer): rpm_createrepo = bb.utils.which(os.getenv('PATH'), "createrepo") if self.d.getVar('PACKAGE_FEED_SIGN', True) == '1': - pkgfeed_gpg_name = self.d.getVar('PACKAGE_FEED_GPG_NAME', True) - pkgfeed_gpg_pass = self.d.getVar('PACKAGE_FEED_GPG_PASSPHRASE_FILE', True) + signer = get_signer(self.d, + self.d.getVar('PACKAGE_FEED_GPG_BACKEND', True), + self.d.getVar('PACKAGE_FEED_GPG_NAME', True), + self.d.getVar('PACKAGE_FEED_GPG_PASSPHRASE_FILE', True)) else: - pkgfeed_gpg_name = None - pkgfeed_gpg_pass = None - gpg_bin = self.d.getVar('GPG_BIN', True) or \ - bb.utils.which(os.getenv('PATH'), "gpg") - + signer = None index_cmds = [] - repo_sign_cmds = [] + repomd_files = [] rpm_dirs_found = False for arch in archs: dbpath = os.path.join(self.d.getVar('WORKDIR', True), 'rpmdb', arch) @@ -130,15 +129,7 @@ class RpmIndexer(Indexer): index_cmds.append("%s --dbpath %s --update -q %s" % \ (rpm_createrepo, dbpath, arch_dir)) - if pkgfeed_gpg_name: - repomd_file = os.path.join(arch_dir, 'repodata', 'repomd.xml') - gpg_cmd = "%s --detach-sign --armor --batch --no-tty --yes " \ - "--passphrase-file '%s' -u '%s' " % \ - (gpg_bin, pkgfeed_gpg_pass, pkgfeed_gpg_name) - if self.d.getVar('GPG_PATH', True): - gpg_cmd += "--homedir %s " % self.d.getVar('GPG_PATH', True) - gpg_cmd += repomd_file - repo_sign_cmds.append(gpg_cmd) + repomd_files.append(os.path.join(arch_dir, 'repodata', 'repomd.xml')) rpm_dirs_found = True @@ -151,9 +142,9 @@ class RpmIndexer(Indexer): if result: bb.fatal('%s' % ('\n'.join(result))) # Sign repomd - result = oe.utils.multiprocess_exec(repo_sign_cmds, create_index) - if result: - bb.fatal('%s' % ('\n'.join(result))) + if signer: + for repomd in repomd_files: + signer.detach_sign(repomd) # Copy pubkey(s) to repo distro_version = self.d.getVar('DISTRO_VERSION', True) or "oe.0" if self.d.getVar('RPM_SIGN_PACKAGES', True) == '1': diff --git a/meta/recipes-core/meta/signing-keys.bb b/meta/recipes-core/meta/signing-keys.bb index cc401f3..d7aa79d 100644 --- a/meta/recipes-core/meta/signing-keys.bb +++ b/meta/recipes-core/meta/signing-keys.bb @@ -20,26 +20,24 @@ do_populate_sysroot[noexec] = "1" EXCLUDE_FROM_WORLD = "1" -def export_gpg_pubkey(d, keyid, path): - import bb - gpg_bin = d.getVar('GPG_BIN', True) or \ - bb.utils.which(os.getenv('PATH'), "gpg") - cmd = '%s --batch --yes --export --armor -o %s %s' % \ - (gpg_bin, path, keyid) - status, output = oe.utils.getstatusoutput(cmd) - if status: - raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % - (keyid, output)) python do_export_public_keys () { + from oe.gpg_sign import get_signer + if d.getVar("RPM_SIGN_PACKAGES", True): # Export public key of the rpm signing key - export_gpg_pubkey(d, d.getVar("RPM_GPG_NAME", True), - d.getVar('RPM_GPG_PUBKEY', True)) + signer = get_signer(d, + d.getVar('RPM_GPG_BACKEND', True), + d.getVar('RPM_GPG_NAME', True), + d.getVar('RPM_GPG_PASSPHRASE_FILE', True)) + signer.export_pubkey(d.getVar('RPM_GPG_PUBKEY', True)) if d.getVar('PACKAGE_FEED_SIGN', True) == '1': # Export public key of the feed signing key - export_gpg_pubkey(d, d.getVar("PACKAGE_FEED_GPG_NAME", True), - d.getVar('PACKAGE_FEED_GPG_PUBKEY', True)) + signer = get_signer(d, + d.getVar('PACKAGE_FEED_GPG_BACKEND', True), + d.getVar('PACKAGE_FEED_GPG_NAME', True), + d.getVar('PACKAGE_FEED_GPG_PASSPHRASE_FILE', True)) + signer.export_pubkey(d.getVar('PACKAGE_FEED_GPG_PUBKEY', True)) } addtask do_export_public_keys before do_build -- 2.1.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-11 16:13 [PATCH 0/3] Support remote RPM signing Markus Lehtonen 2016-01-11 16:13 ` [PATCH 1/3] sign_rpm.bbclass: fix task dependencies Markus Lehtonen 2016-01-11 16:13 ` [PATCH 2/3] New lib module for handling GPG signing Markus Lehtonen @ 2016-01-11 16:13 ` Markus Lehtonen 2016-01-11 16:33 ` Mark Hatle 2 siblings, 1 reply; 12+ messages in thread From: Markus Lehtonen @ 2016-01-11 16:13 UTC (permalink / raw) To: openembedded-core Implement support for remote signing using obs-signd. It is now possible to sign both RPM packages and package feeds with this method. The user just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND variables to 'obssign' in the bitbake config. Of course, in addition, one needs to setup the signing server and the configure the 'sign' client command on the build host. The *_PASSPHRASE_FILE settings are not used when the obssign backend is enabled. [YOCTO #8755] Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> --- meta/classes/sign_package_feed.bbclass | 5 +++- meta/classes/sign_rpm.bbclass | 5 +++- meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass index d5df8af..953fa85 100644 --- a/meta/classes/sign_package_feed.bbclass +++ b/meta/classes/sign_package_feed.bbclass @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' python () { # Check sanity of configuration - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): + required = ['PACKAGE_FEED_GPG_NAME'] + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') + for var in required: if not d.getVar(var, True): raise_sanity_error("You need to define %s in the config" % var, d) diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass index 8bcabee..8be1c35 100644 --- a/meta/classes/sign_rpm.bbclass +++ b/meta/classes/sign_rpm.bbclass @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' python () { # Check configuration - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): + required = ['RPM_GPG_NAME'] + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': + required.append('RPM_GPG_PASSPHRASE_FILE') + for var in required: if not d.getVar(var, True): raise_sanity_error("You need to define %s in the config" % var, d) diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py index 55abad8..d8ab816 100644 --- a/meta/lib/oe/gpg_sign.py +++ b/meta/lib/oe/gpg_sign.py @@ -66,11 +66,59 @@ class LocalSigner(object): (input_file, output)) +class ObsSigner(object): + """Class for handling signing with obs-signd""" + def __init__(self, keyid): + self.keyid = keyid + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") + + def export_pubkey(self, output_file): + """Export GPG public key to a file""" + cmd = "sign -u '%s' -p" % self.keyid + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % + (self.keyid, output)) + with open(output_file, 'w') as fobj: + fobj.write(output) + fobj.write('\n') + + def sign_rpms(self, files): + """Sign RPM files""" + import pexpect + + # Remove existing signatures + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed("Failed to remove RPM signatures: %s" % + output) + # Sign packages + cmd = "sign -u '%s' -r %s" % (self.keyid, ' '.join(files)) + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % + output) + + def detach_sign(self, input_file): + """Create a detached signature of a file""" + cmd = "sign -u '%s' -d %s" % (self.keyid, input_file) + status, output = oe.utils.getstatusoutput(cmd) + if status: + raise bb.build.FuncFailed("Failed to create signature for '%s': %s" % + (input_file, output)) + + def get_signer(d, backend, keyid, passphrase_file): """Get signer object for the specified backend""" # Use local signing by default if backend == 'local': return LocalSigner(d, keyid, passphrase_file) + elif backend == 'obssign': + if passphrase_file: + bb.note("GPG passphrase file setting not used when 'obssign' " + "backend is used.") + return ObsSigner(keyid) else: bb.fatal("Unsupported signing backend '%s'" % backend) -- 2.1.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-11 16:13 ` [PATCH 3/3] oe.gpg_sign: support obs-signd Markus Lehtonen @ 2016-01-11 16:33 ` Mark Hatle 2016-01-12 16:24 ` Markus Lehtonen 0 siblings, 1 reply; 12+ messages in thread From: Mark Hatle @ 2016-01-11 16:33 UTC (permalink / raw) To: Markus Lehtonen, openembedded-core On 1/11/16 10:13 AM, Markus Lehtonen wrote: > Implement support for remote signing using obs-signd. It is now possible > to sign both RPM packages and package feeds with this method. The user > just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND > variables to 'obssign' in the bitbake config. Of course, in addition, > one needs to setup the signing server and the configure the 'sign' > client command on the build host. The *_PASSPHRASE_FILE settings are not > used when the obssign backend is enabled. > > [YOCTO #8755] > > Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> > --- > meta/classes/sign_package_feed.bbclass | 5 +++- > meta/classes/sign_rpm.bbclass | 5 +++- > meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ > 3 files changed, 56 insertions(+), 2 deletions(-) > > diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass > index d5df8af..953fa85 100644 > --- a/meta/classes/sign_package_feed.bbclass > +++ b/meta/classes/sign_package_feed.bbclass > @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' > > python () { > # Check sanity of configuration > - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): > + required = ['PACKAGE_FEED_GPG_NAME'] > + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': > + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') > + for var in required: > if not d.getVar(var, True): > raise_sanity_error("You need to define %s in the config" % var, d) > > diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass > index 8bcabee..8be1c35 100644 > --- a/meta/classes/sign_rpm.bbclass > +++ b/meta/classes/sign_rpm.bbclass > @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' > > python () { > # Check configuration > - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): > + required = ['RPM_GPG_NAME'] > + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': > + required.append('RPM_GPG_PASSPHRASE_FILE') > + for var in required: > if not d.getVar(var, True): > raise_sanity_error("You need to define %s in the config" % var, d) > > diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py > index 55abad8..d8ab816 100644 > --- a/meta/lib/oe/gpg_sign.py > +++ b/meta/lib/oe/gpg_sign.py > @@ -66,11 +66,59 @@ class LocalSigner(object): > (input_file, output)) > > > +class ObsSigner(object): > + """Class for handling signing with obs-signd""" > + def __init__(self, keyid): > + self.keyid = keyid > + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") > + > + def export_pubkey(self, output_file): > + """Export GPG public key to a file""" > + cmd = "sign -u '%s' -p" % self.keyid > + status, output = oe.utils.getstatusoutput(cmd) > + if status: > + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % > + (self.keyid, output)) > + with open(output_file, 'w') as fobj: > + fobj.write(output) > + fobj.write('\n') > + > + def sign_rpms(self, files): > + """Sign RPM files""" > + import pexpect > + > + # Remove existing signatures > + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) Why are you removing existing signatures? I believe for many cases this is actually incorrect. RPM (5) has the ability to have an endless number of signatures within a given package. The package SHOULD included the internal non-repudiable signature... (to refresh memory) all RPM 5 packages include an internal non-repudiable signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't change that a package is 'authentic' in any way (often the purpose of signatures like what this code is doing), but instead keeps a high reliability way to sign and verify the package is signed properly. This is used for validation if the system doing the install does not have the public key that the package was signed with. ... as well as one or more repudiable signatures that can be used to verify that it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV keys install on them. You can program RPM in such a way that it will refused to install packages with unknown authentication keys or the non-repudiable key as well. So, I believe running delsign is wrong. If the obs-signd can't handle ADDING signatures to packages, then I'd say it is broken and should be fixed in some way -- or at least the signature deletion code should be optional. > + status, output = oe.utils.getstatusoutput(cmd) > + if status: > + raise bb.build.FuncFailed("Failed to remove RPM signatures: %s" % > + output) > + # Sign packages > + cmd = "sign -u '%s' -r %s" % (self.keyid, ' '.join(files)) > + status, output = oe.utils.getstatusoutput(cmd) > + if status: > + raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % > + output) > + > + def detach_sign(self, input_file): > + """Create a detached signature of a file""" > + cmd = "sign -u '%s' -d %s" % (self.keyid, input_file) > + status, output = oe.utils.getstatusoutput(cmd) > + if status: > + raise bb.build.FuncFailed("Failed to create signature for '%s': %s" % > + (input_file, output)) > + > + > def get_signer(d, backend, keyid, passphrase_file): > """Get signer object for the specified backend""" > # Use local signing by default > if backend == 'local': > return LocalSigner(d, keyid, passphrase_file) > + elif backend == 'obssign': > + if passphrase_file: > + bb.note("GPG passphrase file setting not used when 'obssign' " > + "backend is used.") > + return ObsSigner(keyid) > else: > bb.fatal("Unsupported signing backend '%s'" % backend) > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-11 16:33 ` Mark Hatle @ 2016-01-12 16:24 ` Markus Lehtonen 2016-01-13 10:28 ` Markus Lehtonen 0 siblings, 1 reply; 12+ messages in thread From: Markus Lehtonen @ 2016-01-12 16:24 UTC (permalink / raw) To: Mark Hatle; +Cc: openembedded-core Hi Mark, Thank you for your review! Comments below. On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: > On 1/11/16 10:13 AM, Markus Lehtonen wrote: > > Implement support for remote signing using obs-signd. It is now possible > > to sign both RPM packages and package feeds with this method. The user > > just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND > > variables to 'obssign' in the bitbake config. Of course, in addition, > > one needs to setup the signing server and the configure the 'sign' > > client command on the build host. The *_PASSPHRASE_FILE settings are not > > used when the obssign backend is enabled. > > > > [YOCTO #8755] > > > > Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> > > --- > > meta/classes/sign_package_feed.bbclass | 5 +++- > > meta/classes/sign_rpm.bbclass | 5 +++- > > meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ > > 3 files changed, 56 insertions(+), 2 deletions(-) > > > > diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass > > index d5df8af..953fa85 100644 > > --- a/meta/classes/sign_package_feed.bbclass > > +++ b/meta/classes/sign_package_feed.bbclass > > @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' > > > > python () { > > # Check sanity of configuration > > - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): > > + required = ['PACKAGE_FEED_GPG_NAME'] > > + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': > > + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') > > + for var in required: > > if not d.getVar(var, True): > > raise_sanity_error("You need to define %s in the config" % var, d) > > > > diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass > > index 8bcabee..8be1c35 100644 > > --- a/meta/classes/sign_rpm.bbclass > > +++ b/meta/classes/sign_rpm.bbclass > > @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' > > > > python () { > > # Check configuration > > - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): > > + required = ['RPM_GPG_NAME'] > > + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': > > + required.append('RPM_GPG_PASSPHRASE_FILE') > > + for var in required: > > if not d.getVar(var, True): > > raise_sanity_error("You need to define %s in the config" % var, d) > > > > diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py > > index 55abad8..d8ab816 100644 > > --- a/meta/lib/oe/gpg_sign.py > > +++ b/meta/lib/oe/gpg_sign.py > > @@ -66,11 +66,59 @@ class LocalSigner(object): > > (input_file, output)) > > > > > > +class ObsSigner(object): > > + """Class for handling signing with obs-signd""" > > + def __init__(self, keyid): > > + self.keyid = keyid > > + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") > > + > > + def export_pubkey(self, output_file): > > + """Export GPG public key to a file""" > > + cmd = "sign -u '%s' -p" % self.keyid > > + status, output = oe.utils.getstatusoutput(cmd) > > + if status: > > + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % > > + (self.keyid, output)) > > + with open(output_file, 'w') as fobj: > > + fobj.write(output) > > + fobj.write('\n') > > + > > + def sign_rpms(self, files): > > + """Sign RPM files""" > > + import pexpect > > + > > + # Remove existing signatures > > + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) > > Why are you removing existing signatures? I believe for many cases this is > actually incorrect. > > RPM (5) has the ability to have an endless number of signatures within a given > package. The package SHOULD included the internal non-repudiable signature... > > (to refresh memory) all RPM 5 packages include an internal non-repudiable > signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't > change that a package is 'authentic' in any way (often the purpose of signatures > like what this code is doing), but instead keeps a high reliability way to sign > and verify the package is signed properly. > > This is used for validation if the system doing the install does not have the > public key that the package was signed with. > > ... as well as one or more repudiable signatures that can be used to verify that > it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV > keys install on them. You can program RPM in such a way that it will refused to > install packages with unknown authentication keys or the non-repudiable key as well. > > So, I believe running delsign is wrong. If the obs-signd can't handle ADDING > signatures to packages, then I'd say it is broken and should be fixed in some > way -- or at least the signature deletion code should be optional. Yes, unfortunately this is currently the limitation of obs-signd. It refuses to sign if there are signatures present in the rpm package. Using --delsign is "unfortunate" consequence of this and that should've probably been described in a comment. Making signature deletion a configurable setting is hopefully a decent resolution for now. I will send a new version of the patchset later. Thanks, Markus > > + status, output = oe.utils.getstatusoutput(cmd) > > + if status: > > + raise bb.build.FuncFailed("Failed to remove RPM signatures: %s" % > > + output) > > + # Sign packages > > + cmd = "sign -u '%s' -r %s" % (self.keyid, ' '.join(files)) > > + status, output = oe.utils.getstatusoutput(cmd) > > + if status: > > + raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % > > + output) > > + > > + def detach_sign(self, input_file): > > + """Create a detached signature of a file""" > > + cmd = "sign -u '%s' -d %s" % (self.keyid, input_file) > > + status, output = oe.utils.getstatusoutput(cmd) > > + if status: > > + raise bb.build.FuncFailed("Failed to create signature for '%s': %s" % > > + (input_file, output)) > > + > > + > > def get_signer(d, backend, keyid, passphrase_file): > > """Get signer object for the specified backend""" > > # Use local signing by default > > if backend == 'local': > > return LocalSigner(d, keyid, passphrase_file) > > + elif backend == 'obssign': > > + if passphrase_file: > > + bb.note("GPG passphrase file setting not used when 'obssign' " > > + "backend is used.") > > + return ObsSigner(keyid) > > else: > > bb.fatal("Unsupported signing backend '%s'" % backend) > > > > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-12 16:24 ` Markus Lehtonen @ 2016-01-13 10:28 ` Markus Lehtonen 2016-01-13 14:56 ` Mark Hatle [not found] ` <1453375237.13987.27.camel@linux.intel.com> 0 siblings, 2 replies; 12+ messages in thread From: Markus Lehtonen @ 2016-01-13 10:28 UTC (permalink / raw) To: Mark Hatle; +Cc: openembedded-core Hi, On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: > Hi Mark, > > Thank you for your review! Comments below. > > On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: > > On 1/11/16 10:13 AM, Markus Lehtonen wrote: > > > Implement support for remote signing using obs-signd. It is now possible > > > to sign both RPM packages and package feeds with this method. The user > > > just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND > > > variables to 'obssign' in the bitbake config. Of course, in addition, > > > one needs to setup the signing server and the configure the 'sign' > > > client command on the build host. The *_PASSPHRASE_FILE settings are not > > > used when the obssign backend is enabled. > > > > > > [YOCTO #8755] > > > > > > Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> > > > --- > > > meta/classes/sign_package_feed.bbclass | 5 +++- > > > meta/classes/sign_rpm.bbclass | 5 +++- > > > meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ > > > 3 files changed, 56 insertions(+), 2 deletions(-) > > > > > > diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass > > > index d5df8af..953fa85 100644 > > > --- a/meta/classes/sign_package_feed.bbclass > > > +++ b/meta/classes/sign_package_feed.bbclass > > > @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' > > > > > > python () { > > > # Check sanity of configuration > > > - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): > > > + required = ['PACKAGE_FEED_GPG_NAME'] > > > + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': > > > + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') > > > + for var in required: > > > if not d.getVar(var, True): > > > raise_sanity_error("You need to define %s in the config" % var, d) > > > > > > diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass > > > index 8bcabee..8be1c35 100644 > > > --- a/meta/classes/sign_rpm.bbclass > > > +++ b/meta/classes/sign_rpm.bbclass > > > @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' > > > > > > python () { > > > # Check configuration > > > - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): > > > + required = ['RPM_GPG_NAME'] > > > + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': > > > + required.append('RPM_GPG_PASSPHRASE_FILE') > > > + for var in required: > > > if not d.getVar(var, True): > > > raise_sanity_error("You need to define %s in the config" % var, d) > > > > > > diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py > > > index 55abad8..d8ab816 100644 > > > --- a/meta/lib/oe/gpg_sign.py > > > +++ b/meta/lib/oe/gpg_sign.py > > > @@ -66,11 +66,59 @@ class LocalSigner(object): > > > (input_file, output)) > > > > > > > > > +class ObsSigner(object): > > > + """Class for handling signing with obs-signd""" > > > + def __init__(self, keyid): > > > + self.keyid = keyid > > > + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") > > > + > > > + def export_pubkey(self, output_file): > > > + """Export GPG public key to a file""" > > > + cmd = "sign -u '%s' -p" % self.keyid > > > + status, output = oe.utils.getstatusoutput(cmd) > > > + if status: > > > + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % > > > + (self.keyid, output)) > > > + with open(output_file, 'w') as fobj: > > > + fobj.write(output) > > > + fobj.write('\n') > > > + > > > + def sign_rpms(self, files): > > > + """Sign RPM files""" > > > + import pexpect > > > + > > > + # Remove existing signatures > > > + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) > > > > Why are you removing existing signatures? I believe for many cases this is > > actually incorrect. > > > > RPM (5) has the ability to have an endless number of signatures within a given > > package. The package SHOULD included the internal non-repudiable signature... > > > > (to refresh memory) all RPM 5 packages include an internal non-repudiable > > signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't > > change that a package is 'authentic' in any way (often the purpose of signatures > > like what this code is doing), but instead keeps a high reliability way to sign > > and verify the package is signed properly. > > > > This is used for validation if the system doing the install does not have the > > public key that the package was signed with. > > > > ... as well as one or more repudiable signatures that can be used to verify that > > it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV > > keys install on them. You can program RPM in such a way that it will refused to > > install packages with unknown authentication keys or the non-repudiable key as well. > > > > So, I believe running delsign is wrong. If the obs-signd can't handle ADDING > > signatures to packages, then I'd say it is broken and should be fixed in some > > way -- or at least the signature deletion code should be optional. > > Yes, unfortunately this is currently the limitation of obs-signd. It > refuses to sign if there are signatures present in the rpm package. > Using --delsign is "unfortunate" consequence of this and that should've > probably been described in a comment. Making signature deletion a > configurable setting is hopefully a decent resolution for now. I will > send a new version of the patchset later. Backing up a bit here. I did some quick testing and it seems that RPM5 does not support multiple signatures (anymore?). Doing --addsign seems to overwrite the existing signatures similarly to --resign. Support for multiple signatures were removed from RPM4 years ago. In this light, doing --delsign should be ok. What do you think? Thanks, Markus ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-13 10:28 ` Markus Lehtonen @ 2016-01-13 14:56 ` Mark Hatle 2016-01-13 21:47 ` Mark Hatle [not found] ` <1453375237.13987.27.camel@linux.intel.com> 1 sibling, 1 reply; 12+ messages in thread From: Mark Hatle @ 2016-01-13 14:56 UTC (permalink / raw) To: Markus Lehtonen; +Cc: openembedded-core On 1/13/16 4:28 AM, Markus Lehtonen wrote: > Hi, > > On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: >> Hi Mark, >> >> Thank you for your review! Comments below. >> >> On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: >>> On 1/11/16 10:13 AM, Markus Lehtonen wrote: >>>> Implement support for remote signing using obs-signd. It is now possible >>>> to sign both RPM packages and package feeds with this method. The user >>>> just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND >>>> variables to 'obssign' in the bitbake config. Of course, in addition, >>>> one needs to setup the signing server and the configure the 'sign' >>>> client command on the build host. The *_PASSPHRASE_FILE settings are not >>>> used when the obssign backend is enabled. >>>> >>>> [YOCTO #8755] >>>> >>>> Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> >>>> --- >>>> meta/classes/sign_package_feed.bbclass | 5 +++- >>>> meta/classes/sign_rpm.bbclass | 5 +++- >>>> meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ >>>> 3 files changed, 56 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass >>>> index d5df8af..953fa85 100644 >>>> --- a/meta/classes/sign_package_feed.bbclass >>>> +++ b/meta/classes/sign_package_feed.bbclass >>>> @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' >>>> >>>> python () { >>>> # Check sanity of configuration >>>> - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): >>>> + required = ['PACKAGE_FEED_GPG_NAME'] >>>> + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': >>>> + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') >>>> + for var in required: >>>> if not d.getVar(var, True): >>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>> >>>> diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass >>>> index 8bcabee..8be1c35 100644 >>>> --- a/meta/classes/sign_rpm.bbclass >>>> +++ b/meta/classes/sign_rpm.bbclass >>>> @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' >>>> >>>> python () { >>>> # Check configuration >>>> - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): >>>> + required = ['RPM_GPG_NAME'] >>>> + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': >>>> + required.append('RPM_GPG_PASSPHRASE_FILE') >>>> + for var in required: >>>> if not d.getVar(var, True): >>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>> >>>> diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py >>>> index 55abad8..d8ab816 100644 >>>> --- a/meta/lib/oe/gpg_sign.py >>>> +++ b/meta/lib/oe/gpg_sign.py >>>> @@ -66,11 +66,59 @@ class LocalSigner(object): >>>> (input_file, output)) >>>> >>>> >>>> +class ObsSigner(object): >>>> + """Class for handling signing with obs-signd""" >>>> + def __init__(self, keyid): >>>> + self.keyid = keyid >>>> + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") >>>> + >>>> + def export_pubkey(self, output_file): >>>> + """Export GPG public key to a file""" >>>> + cmd = "sign -u '%s' -p" % self.keyid >>>> + status, output = oe.utils.getstatusoutput(cmd) >>>> + if status: >>>> + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % >>>> + (self.keyid, output)) >>>> + with open(output_file, 'w') as fobj: >>>> + fobj.write(output) >>>> + fobj.write('\n') >>>> + >>>> + def sign_rpms(self, files): >>>> + """Sign RPM files""" >>>> + import pexpect >>>> + >>>> + # Remove existing signatures >>>> + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) >>> >>> Why are you removing existing signatures? I believe for many cases this is >>> actually incorrect. >>> >>> RPM (5) has the ability to have an endless number of signatures within a given >>> package. The package SHOULD included the internal non-repudiable signature... >>> >>> (to refresh memory) all RPM 5 packages include an internal non-repudiable >>> signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't >>> change that a package is 'authentic' in any way (often the purpose of signatures >>> like what this code is doing), but instead keeps a high reliability way to sign >>> and verify the package is signed properly. >>> >>> This is used for validation if the system doing the install does not have the >>> public key that the package was signed with. >>> >>> ... as well as one or more repudiable signatures that can be used to verify that >>> it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV >>> keys install on them. You can program RPM in such a way that it will refused to >>> install packages with unknown authentication keys or the non-repudiable key as well. >>> >>> So, I believe running delsign is wrong. If the obs-signd can't handle ADDING >>> signatures to packages, then I'd say it is broken and should be fixed in some >>> way -- or at least the signature deletion code should be optional. >> >> Yes, unfortunately this is currently the limitation of obs-signd. It >> refuses to sign if there are signatures present in the rpm package. >> Using --delsign is "unfortunate" consequence of this and that should've >> probably been described in a comment. Making signature deletion a >> configurable setting is hopefully a decent resolution for now. I will >> send a new version of the patchset later. > > Backing up a bit here. I did some quick testing and it seems that RPM5 > does not support multiple signatures (anymore?). Doing --addsign seems > to overwrite the existing signatures similarly to --resign. Support for > multiple signatures were removed from RPM4 years ago. > > In this light, doing --delsign should be ok. What do you think? I'll have to double check, but I used multiple signature support about 6 months ago with the YP 2.0 (still current oe version) version of RPM. Are you using the correct rpm signing tool? If you sign using RPM4's tool, then you can get the behavior you are talking about. (The easiest way to verify the signing is 'multiple' was via a debug flag, I don't remember if rpm -K -vvvv <package> was the right approach of if it was a more specific one, but the debugging clearly showed it loading multiple signatures.) --Mark > > Thanks, > Markus > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-13 14:56 ` Mark Hatle @ 2016-01-13 21:47 ` Mark Hatle 2016-01-21 15:28 ` Mark Hatle 0 siblings, 1 reply; 12+ messages in thread From: Mark Hatle @ 2016-01-13 21:47 UTC (permalink / raw) To: Markus Lehtonen; +Cc: openembedded-core On 1/13/16 8:56 AM, Mark Hatle wrote: > On 1/13/16 4:28 AM, Markus Lehtonen wrote: >> Hi, >> >> On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: >>> Hi Mark, >>> >>> Thank you for your review! Comments below. >>> >>> On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: >>>> On 1/11/16 10:13 AM, Markus Lehtonen wrote: >>>>> Implement support for remote signing using obs-signd. It is now possible >>>>> to sign both RPM packages and package feeds with this method. The user >>>>> just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND >>>>> variables to 'obssign' in the bitbake config. Of course, in addition, >>>>> one needs to setup the signing server and the configure the 'sign' >>>>> client command on the build host. The *_PASSPHRASE_FILE settings are not >>>>> used when the obssign backend is enabled. >>>>> >>>>> [YOCTO #8755] >>>>> >>>>> Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> >>>>> --- >>>>> meta/classes/sign_package_feed.bbclass | 5 +++- >>>>> meta/classes/sign_rpm.bbclass | 5 +++- >>>>> meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ >>>>> 3 files changed, 56 insertions(+), 2 deletions(-) >>>>> >>>>> diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass >>>>> index d5df8af..953fa85 100644 >>>>> --- a/meta/classes/sign_package_feed.bbclass >>>>> +++ b/meta/classes/sign_package_feed.bbclass >>>>> @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' >>>>> >>>>> python () { >>>>> # Check sanity of configuration >>>>> - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): >>>>> + required = ['PACKAGE_FEED_GPG_NAME'] >>>>> + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': >>>>> + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') >>>>> + for var in required: >>>>> if not d.getVar(var, True): >>>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>>> >>>>> diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass >>>>> index 8bcabee..8be1c35 100644 >>>>> --- a/meta/classes/sign_rpm.bbclass >>>>> +++ b/meta/classes/sign_rpm.bbclass >>>>> @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' >>>>> >>>>> python () { >>>>> # Check configuration >>>>> - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): >>>>> + required = ['RPM_GPG_NAME'] >>>>> + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': >>>>> + required.append('RPM_GPG_PASSPHRASE_FILE') >>>>> + for var in required: >>>>> if not d.getVar(var, True): >>>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>>> >>>>> diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py >>>>> index 55abad8..d8ab816 100644 >>>>> --- a/meta/lib/oe/gpg_sign.py >>>>> +++ b/meta/lib/oe/gpg_sign.py >>>>> @@ -66,11 +66,59 @@ class LocalSigner(object): >>>>> (input_file, output)) >>>>> >>>>> >>>>> +class ObsSigner(object): >>>>> + """Class for handling signing with obs-signd""" >>>>> + def __init__(self, keyid): >>>>> + self.keyid = keyid >>>>> + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") >>>>> + >>>>> + def export_pubkey(self, output_file): >>>>> + """Export GPG public key to a file""" >>>>> + cmd = "sign -u '%s' -p" % self.keyid >>>>> + status, output = oe.utils.getstatusoutput(cmd) >>>>> + if status: >>>>> + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % >>>>> + (self.keyid, output)) >>>>> + with open(output_file, 'w') as fobj: >>>>> + fobj.write(output) >>>>> + fobj.write('\n') >>>>> + >>>>> + def sign_rpms(self, files): >>>>> + """Sign RPM files""" >>>>> + import pexpect >>>>> + >>>>> + # Remove existing signatures >>>>> + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) >>>> >>>> Why are you removing existing signatures? I believe for many cases this is >>>> actually incorrect. >>>> >>>> RPM (5) has the ability to have an endless number of signatures within a given >>>> package. The package SHOULD included the internal non-repudiable signature... >>>> >>>> (to refresh memory) all RPM 5 packages include an internal non-repudiable >>>> signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't >>>> change that a package is 'authentic' in any way (often the purpose of signatures >>>> like what this code is doing), but instead keeps a high reliability way to sign >>>> and verify the package is signed properly. >>>> >>>> This is used for validation if the system doing the install does not have the >>>> public key that the package was signed with. >>>> >>>> ... as well as one or more repudiable signatures that can be used to verify that >>>> it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV >>>> keys install on them. You can program RPM in such a way that it will refused to >>>> install packages with unknown authentication keys or the non-repudiable key as well. >>>> >>>> So, I believe running delsign is wrong. If the obs-signd can't handle ADDING >>>> signatures to packages, then I'd say it is broken and should be fixed in some >>>> way -- or at least the signature deletion code should be optional. >>> >>> Yes, unfortunately this is currently the limitation of obs-signd. It >>> refuses to sign if there are signatures present in the rpm package. >>> Using --delsign is "unfortunate" consequence of this and that should've >>> probably been described in a comment. Making signature deletion a >>> configurable setting is hopefully a decent resolution for now. I will >>> send a new version of the patchset later. >> >> Backing up a bit here. I did some quick testing and it seems that RPM5 >> does not support multiple signatures (anymore?). Doing --addsign seems >> to overwrite the existing signatures similarly to --resign. Support for >> multiple signatures were removed from RPM4 years ago. >> >> In this light, doing --delsign should be ok. What do you think? > > I'll have to double check, but I used multiple signature support about 6 months > ago with the YP 2.0 (still current oe version) version of RPM. > > Are you using the correct rpm signing tool? If you sign using RPM4's tool, then > you can get the behavior you are talking about. > > (The easiest way to verify the signing is 'multiple' was via a debug flag, I > don't remember if rpm -K -vvvv <package> was the right approach of if it was a > more specific one, but the debugging clearly showed it loading multiple signatures.) I got clarification from the RPM5 maintainer. More or less there are slots for up to 3 signatures to be added. Signatures may include the ECDSA non-repudiable, RSA/DSA and another. If the default signature is already RSA/DSA it may be replaced -- from what I understand newer versions of RPM5 default to an ECDSA non-repudiable signature. The order of signature verification is first found. So the -K behavior will likely not quite match what is actually verified during a package installation. So comparing rpm -Kvv and rpm -qvvp will show the various signatures a package has loaded and will verify. (RPM5 should -always- have at least one signature that has a matching key known to RPM. This is used for validation purposes of the header.) So short answer. We still should avoid 'delsign' in the RPM5 case. Let RPM decide which slot to use and ensure that each package has either a repudiable or non-repudiable signature (and included pubkey). --Mark > --Mark > >> >> Thanks, >> Markus >> > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-13 21:47 ` Mark Hatle @ 2016-01-21 15:28 ` Mark Hatle 0 siblings, 0 replies; 12+ messages in thread From: Mark Hatle @ 2016-01-21 15:28 UTC (permalink / raw) To: Markus Lehtonen; +Cc: openembedded-core On 1/13/16 3:47 PM, Mark Hatle wrote: > On 1/13/16 8:56 AM, Mark Hatle wrote: >> On 1/13/16 4:28 AM, Markus Lehtonen wrote: >>> Hi, >>> >>> On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: >>>> Hi Mark, >>>> >>>> Thank you for your review! Comments below. >>>> >>>> On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: >>>>> On 1/11/16 10:13 AM, Markus Lehtonen wrote: >>>>>> Implement support for remote signing using obs-signd. It is now possible >>>>>> to sign both RPM packages and package feeds with this method. The user >>>>>> just needs to set RPM_GPG_BACKEND and/or PACKAGE_FEED_GPG_BACKEND >>>>>> variables to 'obssign' in the bitbake config. Of course, in addition, >>>>>> one needs to setup the signing server and the configure the 'sign' >>>>>> client command on the build host. The *_PASSPHRASE_FILE settings are not >>>>>> used when the obssign backend is enabled. >>>>>> >>>>>> [YOCTO #8755] >>>>>> >>>>>> Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com> >>>>>> --- >>>>>> meta/classes/sign_package_feed.bbclass | 5 +++- >>>>>> meta/classes/sign_rpm.bbclass | 5 +++- >>>>>> meta/lib/oe/gpg_sign.py | 48 ++++++++++++++++++++++++++++++++++ >>>>>> 3 files changed, 56 insertions(+), 2 deletions(-) >>>>>> >>>>>> diff --git a/meta/classes/sign_package_feed.bbclass b/meta/classes/sign_package_feed.bbclass >>>>>> index d5df8af..953fa85 100644 >>>>>> --- a/meta/classes/sign_package_feed.bbclass >>>>>> +++ b/meta/classes/sign_package_feed.bbclass >>>>>> @@ -24,7 +24,10 @@ PACKAGE_FEED_GPG_BACKEND ?= 'local' >>>>>> >>>>>> python () { >>>>>> # Check sanity of configuration >>>>>> - for var in ('PACKAGE_FEED_GPG_NAME', 'PACKAGE_FEED_GPG_PASSPHRASE_FILE'): >>>>>> + required = ['PACKAGE_FEED_GPG_NAME'] >>>>>> + if d.getVar('PACKAGE_FEED_GPG_BACKEND', True) != 'obssign': >>>>>> + required.append('PACKAGE_FEED_GPG_PASSPHRASE_FILE') >>>>>> + for var in required: >>>>>> if not d.getVar(var, True): >>>>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>>>> >>>>>> diff --git a/meta/classes/sign_rpm.bbclass b/meta/classes/sign_rpm.bbclass >>>>>> index 8bcabee..8be1c35 100644 >>>>>> --- a/meta/classes/sign_rpm.bbclass >>>>>> +++ b/meta/classes/sign_rpm.bbclass >>>>>> @@ -23,7 +23,10 @@ RPM_GPG_BACKEND ?= 'local' >>>>>> >>>>>> python () { >>>>>> # Check configuration >>>>>> - for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): >>>>>> + required = ['RPM_GPG_NAME'] >>>>>> + if d.getVar('RPM_GPG_BACKEND', True) != 'obssign': >>>>>> + required.append('RPM_GPG_PASSPHRASE_FILE') >>>>>> + for var in required: >>>>>> if not d.getVar(var, True): >>>>>> raise_sanity_error("You need to define %s in the config" % var, d) >>>>>> >>>>>> diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py >>>>>> index 55abad8..d8ab816 100644 >>>>>> --- a/meta/lib/oe/gpg_sign.py >>>>>> +++ b/meta/lib/oe/gpg_sign.py >>>>>> @@ -66,11 +66,59 @@ class LocalSigner(object): >>>>>> (input_file, output)) >>>>>> >>>>>> >>>>>> +class ObsSigner(object): >>>>>> + """Class for handling signing with obs-signd""" >>>>>> + def __init__(self, keyid): >>>>>> + self.keyid = keyid >>>>>> + self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm") >>>>>> + >>>>>> + def export_pubkey(self, output_file): >>>>>> + """Export GPG public key to a file""" >>>>>> + cmd = "sign -u '%s' -p" % self.keyid >>>>>> + status, output = oe.utils.getstatusoutput(cmd) >>>>>> + if status: >>>>>> + raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' % >>>>>> + (self.keyid, output)) >>>>>> + with open(output_file, 'w') as fobj: >>>>>> + fobj.write(output) >>>>>> + fobj.write('\n') >>>>>> + >>>>>> + def sign_rpms(self, files): >>>>>> + """Sign RPM files""" >>>>>> + import pexpect >>>>>> + >>>>>> + # Remove existing signatures >>>>>> + cmd = "%s --delsign %s" % (self.rpm_bin, ' '.join(files)) >>>>> >>>>> Why are you removing existing signatures? I believe for many cases this is >>>>> actually incorrect. >>>>> >>>>> RPM (5) has the ability to have an endless number of signatures within a given >>>>> package. The package SHOULD included the internal non-repudiable signature... >>>>> >>>>> (to refresh memory) all RPM 5 packages include an internal non-repudiable >>>>> signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't >>>>> change that a package is 'authentic' in any way (often the purpose of signatures >>>>> like what this code is doing), but instead keeps a high reliability way to sign >>>>> and verify the package is signed properly. >>>>> >>>>> This is used for validation if the system doing the install does not have the >>>>> public key that the package was signed with. >>>>> >>>>> ... as well as one or more repudiable signatures that can be used to verify that >>>>> it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV >>>>> keys install on them. You can program RPM in such a way that it will refused to >>>>> install packages with unknown authentication keys or the non-repudiable key as well. >>>>> >>>>> So, I believe running delsign is wrong. If the obs-signd can't handle ADDING >>>>> signatures to packages, then I'd say it is broken and should be fixed in some >>>>> way -- or at least the signature deletion code should be optional. >>>> >>>> Yes, unfortunately this is currently the limitation of obs-signd. It >>>> refuses to sign if there are signatures present in the rpm package. >>>> Using --delsign is "unfortunate" consequence of this and that should've >>>> probably been described in a comment. Making signature deletion a >>>> configurable setting is hopefully a decent resolution for now. I will >>>> send a new version of the patchset later. >>> >>> Backing up a bit here. I did some quick testing and it seems that RPM5 >>> does not support multiple signatures (anymore?). Doing --addsign seems >>> to overwrite the existing signatures similarly to --resign. Support for >>> multiple signatures were removed from RPM4 years ago. >>> >>> In this light, doing --delsign should be ok. What do you think? >> >> I'll have to double check, but I used multiple signature support about 6 months >> ago with the YP 2.0 (still current oe version) version of RPM. >> >> Are you using the correct rpm signing tool? If you sign using RPM4's tool, then >> you can get the behavior you are talking about. >> >> (The easiest way to verify the signing is 'multiple' was via a debug flag, I >> don't remember if rpm -K -vvvv <package> was the right approach of if it was a >> more specific one, but the debugging clearly showed it loading multiple signatures.) > > I got clarification from the RPM5 maintainer. > > More or less there are slots for up to 3 signatures to be added. Signatures may > include the ECDSA non-repudiable, RSA/DSA and another. If the default signature > is already RSA/DSA it may be replaced -- from what I understand newer versions > of RPM5 default to an ECDSA non-repudiable signature. > > The order of signature verification is first found. So the -K behavior will > likely not quite match what is actually verified during a package installation. > So comparing rpm -Kvv and rpm -qvvp will show the various signatures a package > has loaded and will verify. > > (RPM5 should -always- have at least one signature that has a matching key known > to RPM. This is used for validation purposes of the header.) > > So short answer. We still should avoid 'delsign' in the RPM5 case. Let RPM > decide which slot to use and ensure that each package has either a repudiable or > non-repudiable signature (and included pubkey). Following up on this again. I'm wondering if the best approach would be to remove the RPM specific actions in this code. Rename it away from 'obsigner' as well as the existing. And just invoke a script that can be provided with OE itself. In the scripts directory provide two versions of the signer script. One that does the traditional signing and one that can do the --delsign and call the obs-sign program. If we did it that way it would simplify the 'bbclass' and other functions, and should not adversely affect performance. It would also support the two use-cases you have, as well as easily permit new ones without having to further change the functionality. The only thing we'd need to do is come up with a reasonable set of inputs for the 'script', so that it knew the right versions of GPG, the correct set of options, and other special behaviors that may be required to perform a signing operation. Exporting these through the environment or as command line arguments would likely make it easy to extend it if necessary in the future. You might even be able to do something like: RPM_PACKAGE_SIGNING_SCRIPT = "my-custom-sign.sh '${RPM_GPG_NAME}' '${RPM_GPG_PASSPHRASE_FILE}'" Simplifying the code further in that the RPM_PACKAGE_SIGNING_SCRIPT value would contain all of the arguments necessary avoiding further special processing in the bbclass... The default behavior could be made compatible with the current implementation, while secondary (OBS) behaviors could be added as documentation how to change what happens. --Mark > --Mark > >> --Mark >> >>> >>> Thanks, >>> Markus >>> >> > ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <1453375237.13987.27.camel@linux.intel.com>]
[parent not found: <56A0F794.7060603@windriver.com>]
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd [not found] ` <56A0F794.7060603@windriver.com> @ 2016-01-22 10:43 ` Markus Lehtonen 2016-01-22 14:09 ` Mark Hatle 0 siblings, 1 reply; 12+ messages in thread From: Markus Lehtonen @ 2016-01-22 10:43 UTC (permalink / raw) To: Mark Hatle; +Cc: openembedded-core@lists.openembedded.org Hi Mark, (CC'd the mailing list which was accidentally dropped from my previous email) On 21/01/16 17:21, "Mark Hatle" <mark.hatle@windriver.com> wrote: >On 1/21/16 5:20 AM, Markus Lehtonen wrote: >> On Wed, 2016-01-13 at 12:28 +0200, Markus Lehtonen wrote: >>> On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: >>>> Hi Mark, >>>> >>>> Thank you for your review! Comments below. >>>> >>>> On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: >> >> [...SNIP...] >> >>>>> >>>>> Why are you removing existing signatures? I believe for many cases this is >>>>> actually incorrect. >>>>> >>>>> RPM (5) has the ability to have an endless number of signatures within a given >>>>> package. The package SHOULD included the internal non-repudiable signature... >>>>> >>>>> (to refresh memory) all RPM 5 packages include an internal non-repudiable >>>>> signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't >>>>> change that a package is 'authentic' in any way (often the purpose of signatures >>>>> like what this code is doing), but instead keeps a high reliability way to sign >>>>> and verify the package is signed properly. >>>>> >>>>> This is used for validation if the system doing the install does not have the >>>>> public key that the package was signed with. >>>>> >>>>> ... as well as one or more repudiable signatures that can be used to verify that >>>>> it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV >>>>> keys install on them. You can program RPM in such a way that it will refused to >>>>> install packages with unknown authentication keys or the non-repudiable key as well. >>>>> >>>>> So, I believe running delsign is wrong. If the obs-signd can't handle ADDING >>>>> signatures to packages, then I'd say it is broken and should be fixed in some >>>>> way -- or at least the signature deletion code should be optional. >>>> >>>> Yes, unfortunately this is currently the limitation of obs-signd. It >>>> refuses to sign if there are signatures present in the rpm package. >>>> Using --delsign is "unfortunate" consequence of this and that should've >>>> probably been described in a comment. Making signature deletion a >>>> configurable setting is hopefully a decent resolution for now. I will >>>> send a new version of the patchset later. >>> >>> Backing up a bit here. I did some quick testing and it seems that RPM5 >>> does not support multiple signatures (anymore?). Doing --addsign seems >>> to overwrite the existing signatures similarly to --resign. Support for >>> multiple signatures were removed from RPM4 years ago. >>> >>> In this light, doing --delsign should be ok. What do you think? >> >> Hi Mark. Do you have any comments to the above? I'd like to get this >> patchset out of my hands :) > >RPM5 does have multiple signatures, but only allows one of each of the three >types to be installed. The delsign shouldn't be used as it might remove the >wrong signature. AFAIU, rpm only allows one signature so be present. The file format allows that, but, the rpm tool does not (anymore). For example, rpm --addsign will remove an existing DSA signature when adding an RSA signature. The SHA1 / MD5 digests are not touched by --delsign. >(Three types are DSA/RSA, ECDSA, and simple SHA256 or similar.) I didn't know that rpm(5?) supports ECDSA signatures. >But making the --delsign optional I think is the best approach. (It would be >better to move it to the obs-sign script itself -- but I can live with doing it >on the OE side since people are trying to use their owns systems.) I still believe that making it optional is just worthless and complicates things because doing rpm --addsign has exactly the same effect. >The alternative would be to not call the script 'obs-sign', but instead call an >arbitrarily named (and defined in a bitbake variable) script.. Then THAT script >can do the del and call the obs-sign.) Hmm, I probably don't like this idea that much. This user-written script would need to be a bit more complex as a it needs to support multiple operations (signrpm, detach sign, export pubkey). Of course, I could write a default script and put it under scripts/ but somehow feels more complex than needed. Thanks, Markus ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] oe.gpg_sign: support obs-signd 2016-01-22 10:43 ` Markus Lehtonen @ 2016-01-22 14:09 ` Mark Hatle 0 siblings, 0 replies; 12+ messages in thread From: Mark Hatle @ 2016-01-22 14:09 UTC (permalink / raw) To: Markus Lehtonen; +Cc: openembedded-core@lists.openembedded.org On 1/22/16 4:43 AM, Markus Lehtonen wrote: > Hi Mark, > > > > (CC'd the mailing list which was accidentally dropped from my previous email) > > On 21/01/16 17:21, "Mark Hatle" <mark.hatle@windriver.com> wrote: > >> On 1/21/16 5:20 AM, Markus Lehtonen wrote: >>> On Wed, 2016-01-13 at 12:28 +0200, Markus Lehtonen wrote: >>>> On Tue, 2016-01-12 at 18:24 +0200, Markus Lehtonen wrote: >>>>> Hi Mark, >>>>> >>>>> Thank you for your review! Comments below. >>>>> >>>>> On Mon, 2016-01-11 at 10:33 -0600, Mark Hatle wrote: >>> >>> [...SNIP...] >>> >>>>>> >>>>>> Why are you removing existing signatures? I believe for many cases this is >>>>>> actually incorrect. >>>>>> >>>>>> RPM (5) has the ability to have an endless number of signatures within a given >>>>>> package. The package SHOULD included the internal non-repudiable signature... >>>>>> >>>>>> (to refresh memory) all RPM 5 packages include an internal non-repudiable >>>>>> signature. Think of this as an extended md5sum, sha256sum, etc. It doesn't >>>>>> change that a package is 'authentic' in any way (often the purpose of signatures >>>>>> like what this code is doing), but instead keeps a high reliability way to sign >>>>>> and verify the package is signed properly. >>>>>> >>>>>> This is used for validation if the system doing the install does not have the >>>>>> public key that the package was signed with. >>>>>> >>>>>> ... as well as one or more repudiable signatures that can be used to verify that >>>>>> it's "authentic" in some way. A system could very easily have OSV, OEM, and ISV >>>>>> keys install on them. You can program RPM in such a way that it will refused to >>>>>> install packages with unknown authentication keys or the non-repudiable key as well. >>>>>> >>>>>> So, I believe running delsign is wrong. If the obs-signd can't handle ADDING >>>>>> signatures to packages, then I'd say it is broken and should be fixed in some >>>>>> way -- or at least the signature deletion code should be optional. >>>>> >>>>> Yes, unfortunately this is currently the limitation of obs-signd. It >>>>> refuses to sign if there are signatures present in the rpm package. >>>>> Using --delsign is "unfortunate" consequence of this and that should've >>>>> probably been described in a comment. Making signature deletion a >>>>> configurable setting is hopefully a decent resolution for now. I will >>>>> send a new version of the patchset later. >>>> >>>> Backing up a bit here. I did some quick testing and it seems that RPM5 >>>> does not support multiple signatures (anymore?). Doing --addsign seems >>>> to overwrite the existing signatures similarly to --resign. Support for >>>> multiple signatures were removed from RPM4 years ago. >>>> >>>> In this light, doing --delsign should be ok. What do you think? >>> >>> Hi Mark. Do you have any comments to the above? I'd like to get this >>> patchset out of my hands :) >> >> RPM5 does have multiple signatures, but only allows one of each of the three >> types to be installed. The delsign shouldn't be used as it might remove the >> wrong signature. > > AFAIU, rpm only allows one signature so be present. The file format allows that, but, the rpm tool does not (anymore). For example, rpm --addsign will remove an existing DSA signature when adding an RSA signature. The SHA1 / MD5 digests are not touched by --delsign. > > >> (Three types are DSA/RSA, ECDSA, and simple SHA256 or similar.) > > I didn't know that rpm(5?) supports ECDSA signatures. > > >> But making the --delsign optional I think is the best approach. (It would be >> better to move it to the obs-sign script itself -- but I can live with doing it >> on the OE side since people are trying to use their owns systems.) > > I still believe that making it optional is just worthless and complicates things because doing rpm --addsign has exactly the same effect. > > >> The alternative would be to not call the script 'obs-sign', but instead call an >> arbitrarily named (and defined in a bitbake variable) script.. Then THAT script >> can do the del and call the obs-sign.) > > Hmm, I probably don't like this idea that much. This user-written script would need to be a bit more complex as a it needs to support multiple operations (signrpm, detach sign, export pubkey). Of course, I could write a default script and put it under scripts/ but somehow feels more complex than needed. The more I look at this, the more I think that makes sense. I've had some of my (WR Linux) release guys look at this, and the obs-sign mechanism will not work for us. So we're going to have to write some custom signing code anyway. It will be much easier if there is a generic interface. The previous thought was to use the obs-sign "interface", but write our own... but at that point OBS has nothing to do with it.. It's just really being used as a signing interface. I'm assuming at this point that we're not alone in this need. I've talked to a variety of commercial people and they all have slightly different signing policies and mechanisms. Everything from, we don't sign the packages but check separate checksums -- to we sign locally with a local keyring key -- to we sign locally with a special in-memory key -- to after every package is built we have to upload the package to an (internal password protected) FTP/HTTP site and trigger it to be signed, then once signed we download it. (And of course OBS specific signing...) I think in this case an external script makes this all much easier for someone to implement their specific policy and procedures, especially with a defined API. Including default scripts with this as useful runners or examples would definitely be a part of the work in my mind. --Mark > > Thanks, > Markus > > ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-01-22 14:09 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-11 16:13 [PATCH 0/3] Support remote RPM signing Markus Lehtonen
2016-01-11 16:13 ` [PATCH 1/3] sign_rpm.bbclass: fix task dependencies Markus Lehtonen
2016-01-11 16:13 ` [PATCH 2/3] New lib module for handling GPG signing Markus Lehtonen
2016-01-11 16:13 ` [PATCH 3/3] oe.gpg_sign: support obs-signd Markus Lehtonen
2016-01-11 16:33 ` Mark Hatle
2016-01-12 16:24 ` Markus Lehtonen
2016-01-13 10:28 ` Markus Lehtonen
2016-01-13 14:56 ` Mark Hatle
2016-01-13 21:47 ` Mark Hatle
2016-01-21 15:28 ` Mark Hatle
[not found] ` <1453375237.13987.27.camel@linux.intel.com>
[not found] ` <56A0F794.7060603@windriver.com>
2016-01-22 10:43 ` Markus Lehtonen
2016-01-22 14:09 ` Mark Hatle
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox