diff options
Diffstat (limited to 'meta-oe/classes')
-rw-r--r-- | meta-oe/classes/breakpad.bbclass | 2 | ||||
-rw-r--r-- | meta-oe/classes/gitpkgv.bbclass | 43 | ||||
-rw-r--r-- | meta-oe/classes/gitver.bbclass | 2 | ||||
-rw-r--r-- | meta-oe/classes/gpe.bbclass | 4 | ||||
-rw-r--r-- | meta-oe/classes/image_types_sparse.bbclass | 17 | ||||
-rw-r--r-- | meta-oe/classes/itstool.bbclass | 5 | ||||
-rw-r--r-- | meta-oe/classes/signing.bbclass | 316 | ||||
-rw-r--r-- | meta-oe/classes/socorro-syms.bbclass | 2 |
8 files changed, 366 insertions, 25 deletions
diff --git a/meta-oe/classes/breakpad.bbclass b/meta-oe/classes/breakpad.bbclass index cebe559a7f..96b8f42e97 100644 --- a/meta-oe/classes/breakpad.bbclass +++ b/meta-oe/classes/breakpad.bbclass @@ -32,5 +32,5 @@ breakpad_package_preprocess () { PACKAGES =+ "${PN}-breakpad" -FILES_${PN}-breakpad = "/usr/share/breakpad-syms" +FILES:${PN}-breakpad = "/usr/share/breakpad-syms" diff --git a/meta-oe/classes/gitpkgv.bbclass b/meta-oe/classes/gitpkgv.bbclass index 2d9680a35c..5ab507969c 100644 --- a/meta-oe/classes/gitpkgv.bbclass +++ b/meta-oe/classes/gitpkgv.bbclass @@ -7,8 +7,8 @@ # NN equals the total number of revs up to SRCREV # GITHASH is SRCREV's (full) hash # -# - GITPKGVTAG which is the output of 'git describe' allowing for -# automatic versioning +# - GITPKGVTAG which is the output of 'git describe --tags --exact-match' +# allowing for automatic versioning # # gitpkgv.bbclass assumes the git repository has been cloned, and # contains SRCREV. So ${GITPKGV} and ${GITPKGVTAG} should never be @@ -25,32 +25,38 @@ # # inherit gitpkgv # -# PV = "1.0+gitr${SRCPV}" # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b -# PKGV = "1.0+gitr${GITPKGV}" # expands also to something like 1.0+gitr31337+4c1c21d7d +# PV = "1.0+git" # expands to 1.0+git +# PKGV = "1.0+git${GITPKGV}" # expands also to something like 1.0+git31337+4c1c21d7d # # or # # inherit gitpkgv # -# PV = "1.0+gitr${SRCPV}" # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b -# PKGV = "${GITPKGVTAG}" # expands to something like 1.0-31337+g4c1c21d -# if there is tag v1.0 before this revision or -# ver1.0-31337+g4c1c21d if there is tag ver1.0 +# PV = "1.0+git" # expands to 1.0+git +# PKGV = "${GITPKGVTAG}" # expands to something like 1.0-31337+g4c1c21d +# if there is tag v1.0 before this revision or +# ver1.0-31337+g4c1c21d if there is tag ver1.0 GITPKGV = "${@get_git_pkgv(d, False)}" GITPKGVTAG = "${@get_git_pkgv(d, True)}" -def gitpkgv_drop_tag_prefix(version): +# This regexp is used to drop unwanted parts of the found tags. Any matching +# groups will be concatenated to yield the final version. +GITPKGV_TAG_REGEXP ??= "v(\d.*)" + +def gitpkgv_drop_tag_prefix(d, version): import re - if re.match("v\d", version): - return version[1:] + + m = re.match(d.getVar('GITPKGV_TAG_REGEXP'), version) + if m: + return ''.join(group for group in m.groups() if group) else: return version def get_git_pkgv(d, use_tags): import os import bb - from pipes import quote + from shlex import quote src_uri = d.getVar('SRC_URI').split() fetcher = bb.fetch2.Fetch(src_uri, d) @@ -87,10 +93,8 @@ def get_git_pkgv(d, use_tags): if not os.path.exists(rev_file) or os.path.getsize(rev_file)==0: commits = bb.fetch2.runfetchcmd( - "cd %(repodir)s && " - "git rev-list %(rev)s -- 2> /dev/null " - "| wc -l" % vars, - d, quiet=True).strip().lstrip('0') + "git --git-dir=%(repodir)s rev-list %(rev)s -- 2>/dev/null | wc -l" + % vars, d, quiet=True).strip().lstrip('0') if commits != "": oe.path.remove(rev_file, recurse=False) @@ -105,10 +109,9 @@ def get_git_pkgv(d, use_tags): if use_tags: try: output = bb.fetch2.runfetchcmd( - "cd %(repodir)s && " - "git describe %(rev)s 2>/dev/null" % vars, - d, quiet=True).strip() - ver = gitpkgv_drop_tag_prefix(output) + "git --git-dir=%(repodir)s describe %(rev)s --tags --exact-match 2>/dev/null" + % vars, d, quiet=True).strip() + ver = gitpkgv_drop_tag_prefix(d, output) except Exception: ver = "0.0-%s-g%s" % (commits, vars['rev'][:7]) else: diff --git a/meta-oe/classes/gitver.bbclass b/meta-oe/classes/gitver.bbclass index 07f44c34b4..cab850c7ac 100644 --- a/meta-oe/classes/gitver.bbclass +++ b/meta-oe/classes/gitver.bbclass @@ -48,7 +48,7 @@ def get_git_hash(d): srcdir = d.getVar("EXTERNALSRC") or d.getVar("S") gitdir = os.path.abspath(os.path.join(srcdir, ".git")) try: - rev = gitrev_run("git rev-list HEAD -1") + rev = gitrev_run("git rev-list HEAD -1", gitdir) return rev[:7] except Exception as exc: bb.fatal(str(exc)) diff --git a/meta-oe/classes/gpe.bbclass b/meta-oe/classes/gpe.bbclass index 9fc136590a..a9b1cd5a90 100644 --- a/meta-oe/classes/gpe.bbclass +++ b/meta-oe/classes/gpe.bbclass @@ -1,7 +1,7 @@ -DEPENDS_prepend = "virtual/libintl intltool-native " +DEPENDS:prepend = "virtual/libintl intltool-native " GPE_TARBALL_SUFFIX ?= "gz" SRC_URI = "${GPE_MIRROR}/${BP}.tar.${GPE_TARBALL_SUFFIX}" -FILES_${PN} += "${datadir}/gpe ${datadir}/application-registry" +FILES:${PN} += "${datadir}/gpe ${datadir}/application-registry" SECTION ?= "gpe" inherit gettext diff --git a/meta-oe/classes/image_types_sparse.bbclass b/meta-oe/classes/image_types_sparse.bbclass new file mode 100644 index 0000000000..d6ea68968e --- /dev/null +++ b/meta-oe/classes/image_types_sparse.bbclass @@ -0,0 +1,17 @@ +inherit image_types + +# This sets the granularity of the sparse image conversion. Chunk sizes will be +# specified in units of this value. Setting this value smaller than the +# underlying image's block size will not result in any further space saving. +# However, there is no loss in correctness if this value is larger or smaller +# than optimal. This value should be a power of two. +SPARSE_BLOCK_SIZE ??= "4096" + +CONVERSIONTYPES += "sparse" + +CONVERSION_CMD:sparse = " \ + truncate --no-create --size=%${SPARSE_BLOCK_SIZE} "${IMAGE_NAME}.${type}"; \ + img2simg -s "${IMAGE_NAME}.${type}" "${IMAGE_NAME}.${type}.sparse" ${SPARSE_BLOCK_SIZE}; \ + " + +CONVERSION_DEPENDS_sparse = "android-tools-native" diff --git a/meta-oe/classes/itstool.bbclass b/meta-oe/classes/itstool.bbclass new file mode 100644 index 0000000000..962461f205 --- /dev/null +++ b/meta-oe/classes/itstool.bbclass @@ -0,0 +1,5 @@ +# helper class to prepare correct environment for native itstool + +inherit python3native + +DEPENDS:append = " itstool-native" diff --git a/meta-oe/classes/signing.bbclass b/meta-oe/classes/signing.bbclass new file mode 100644 index 0000000000..f52d861b76 --- /dev/null +++ b/meta-oe/classes/signing.bbclass @@ -0,0 +1,316 @@ +# +# Copyright Jan Luebbe <jlu@pengutronix.de> +# +# SPDX-License-Identifier: MIT +# + +# This class provides a common workflow to use asymmetric (i.e. RSA) keys to +# sign artifacts. Usually, the keys are either stored as simple files in the +# file system or on an HSM (Hardware Security Module). While files are easy to +# use, it's hard to verify that no copies of the private key have been made +# and only authorized persons are able to use the key. Use of an HSM addresses +# these risks by only allowing use of the key via an API (often PKCS #11). The +# standard way of referring to a specific key in an HSM are PKCS #11 URIs (RFC +# 7512). +# +# Many software projects support signing using PKCS #11 keys, but configuring +# this is very project specific. Furthermore, as physical HSMs are not very +# widespread, testing code signing in CI is not simple. To solve this at the +# build system level, this class takes the approach of always using PKCS #11 at +# the recipe level. For cases where the keys are available as files (i.e. test +# keys in CI), they are imported into SoftHSM (a HSM emulation library). +# +# Recipes access the available keys via a specific role. So, depending on +# whether we're building during development or for release, a given role can +# refer to different keys. +# Each key recipe PROVIDES a virtual package corresponding to the role, allowing +# the user to select one of multiple keys for a role when needed. +# +# For use with a real HSM, a PKCS #11 URI can be set (i.e. in local.conf) to +# override the SoftHSM key with the real one: +# +# SIGNING_PKCS11_URI[fit] = "pkcs11:serial=DENK0200554;object=ptx-dev-rauc&pin-value=123456" +# SIGNING_PKCS11_MODULE[fit] = "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so" +# +# Examples for defining roles and importing keys: +# +# meta-code-signing/recipes-security/signing-keys/dummy-rsa-key-native.bb +# meta-code-signing-demo/recipes-security/ptx-dev-keys/ptx-dev-keys-native_git.bb +# +# Examples for using keys for signing: +# +# meta-code-signing-demo/recipes-security/fit-image/linux-fit-image.bb +# meta-code-signing-demo/recipes-core/bundles/update-bundle.bb +# +# Examples for using keys for authentication: +# +# meta-code-signing-demo/recipes-security/fit-image/barebox_%.bbappend +# meta-code-signing-demo/recipes-core/rauc/rauc_%.bbappend +# +# Examples for using keys for both signing and authentication: +# +# meta-code-signing-demo/recipes-kernel/linux/linux-yocto_6.1.bbappend + +SIGNING_PKCS11_URI ?= "" +SIGNING_PKCS11_MODULE ?= "" + +DEPENDS += "softhsm-native libp11-native opensc-native openssl-native" + +def signing_class_prepare(d): + import os.path + + def export(role, k, v): + k = k % (role, ) + d.setVar(k, v) + d.setVarFlag(k, "export", "1") + + roles = set() + roles |= (d.getVarFlags("SIGNING_PKCS11_URI") or {}).keys() + roles |= (d.getVarFlags("SIGNING_PKCS11_MODULE") or {}).keys() + for role in roles: + if not set(role).issubset("abcdefghijklmnopqrstuvwxyz0123456789_"): + bb.fatal("key role name '%s' must consist of only [a-z0-9_]" % (role,)) + + pkcs11_uri = d.getVarFlag("SIGNING_PKCS11_URI", role) or d.getVar("SIGNING_PKCS11_URI") + if not pkcs11_uri.startswith("pkcs11:"): + bb.fatal("URI for key role '%s' must start with 'pkcs11:'" % (role,)) + + pkcs11_module = d.getVarFlag("SIGNING_PKCS11_MODULE", role) or d.getVar("SIGNING_PKCS11_MODULE") + if not os.path.isfile(pkcs11_module): + bb.fatal("module path for key role '%s' must be an existing file" % (role,)) + + if pkcs11_uri and not pkcs11_module: + bb.warn("SIGNING_PKCS11_URI[%s] is set without SIGNING_PKCS11_MODULE[%s]" % (role, role)) + if pkcs11_module and not pkcs11_uri: + bb.warn("SIGNING_PKCS11_MODULE[%s] is set without SIGNING_PKCS11_URI[%s]" % (role, role)) + + export(role, "SIGNING_PKCS11_URI_%s_", pkcs11_uri) + export(role, "SIGNING_PKCS11_MODULE_%s_", pkcs11_module) + +signing_pkcs11_tool() { + pkcs11-tool --module "${STAGING_LIBDIR_NATIVE}/softhsm/libsofthsm2.so" --login --pin 1111 $* +} + +signing_import_prepare() { + export _SIGNING_ENV_FILE_="${B}/meta-signing.env" + rm -f "$_SIGNING_ENV_FILE_" + + export SOFTHSM2_CONF="${B}/softhsm2.conf" + export SOFTHSM2_DIR="${B}/softhsm2.tokens" + export SOFTHSM2_MOD="${STAGING_LIBDIR_NATIVE}/softhsm/libsofthsm2.so" + + echo "directories.tokendir = $SOFTHSM2_DIR" > "$SOFTHSM2_CONF" + echo "objectstore.backend = db" >> "$SOFTHSM2_CONF" + rm -rf "$SOFTHSM2_DIR" + mkdir -p "$SOFTHSM2_DIR" + + softhsm2-util --module $SOFTHSM2_MOD --init-token --free --label ${PN} --pin 1111 --so-pin 222222 +} + +signing_import_define_role() { + local role="${1}" + case "${1}" in + (*[!a-z0-9_]*) false;; + (*) true;; + esac || bbfatal "invalid role name '${1}', must consist of [a-z0-9_]" + + echo "_SIGNING_PKCS11_URI_${role}_=\"pkcs11:token=${PN};object=$role;pin-value=1111\"" >> $_SIGNING_ENV_FILE_ + echo "_SIGNING_PKCS11_MODULE_${role}_=\"softhsm\"" >> $_SIGNING_ENV_FILE_ +} + +# signing_import_cert_from_der <role> <der> +# +# Import a certificate from DER file to a role. To be used +# with SoftHSM. +signing_import_cert_from_der() { + local role="${1}" + local der="${2}" + + signing_pkcs11_tool --type cert --write-object "${der}" --label "${role}" +} + +# signing_import_cert_from_pem <role> <pem> +# +# Import a certificate from PEM file to a role. To be used +# with SoftHSM. +signing_import_cert_from_pem() { + local role="${1}" + local pem="${2}" + + openssl x509 \ + -in "${pem}" -inform pem -outform der | + signing_pkcs11_tool --type cert --write-object /proc/self/fd/0 --label "${role}" +} + +# signing_import_pubkey_from_der <role> <der> +# +# Import a public key from DER file to a role. To be used with SoftHSM. +signing_import_pubkey_from_der() { + local role="${1}" + local der="${2}" + + signing_pkcs11_tool --type pubkey --write-object "${der}" --label "${role}" +} + +# signing_import_pubkey_from_pem <role> <pem> +# +# Import a public key from PEM file to a role. To be used with SoftHSM. +signing_import_pubkey_from_pem() { + local openssl_keyopt + local role="${1}" + local pem="${2}" + + if [ -n "${IMPORT_PASS_FILE}" ]; then + openssl pkey \ + -passin "file:${IMPORT_PASS_FILE}" \ + -in "${pem}" -inform pem -pubout -outform der + else + openssl pkey \ + -in "${pem}" -inform pem -pubout -outform der + fi | + signing_pkcs11_tool --type pubkey --write-object /proc/self/fd/0 --label "${role}" +} + +# signing_import_privkey_from_der <role> <der> +# +# Import a private key from DER file to a role. To be used with SoftHSM. +signing_import_privkey_from_der() { + local role="${1}" + local der="${2}" + signing_pkcs11_tool --type privkey --write-object "${der}" --label "${role}" +} + +# signing_import_privkey_from_pem <role> <pem> +# +# Import a private key from PEM file to a role. To be used with SoftHSM. +signing_import_privkey_from_pem() { + local openssl_keyopt + local role="${1}" + local pem="${2}" + + if [ -n "${IMPORT_PASS_FILE}" ]; then + openssl pkey \ + -passin "file:${IMPORT_PASS_FILE}" \ + -in "${pem}" -inform pem -outform der + else + openssl pkey \ + -in "${pem}" -inform pem -outform der + fi | + signing_pkcs11_tool --type privkey --write-object /proc/self/fd/0 --label "${role}" +} + +# signing_import_key_from_pem <role> <pem> +# +# Import a private and public key from PEM file to a role. To be used +# with SoftHSM. +signing_import_key_from_pem() { + local role="${1}" + local pem="${2}" + + signing_import_pubkey_from_pem "${role}" "${pem}" + signing_import_privkey_from_pem "${role}" "${pem}" +} + +signing_import_finish() { + echo "loaded objects:" + signing_pkcs11_tool --list-objects +} + +signing_import_install() { + install -d ${D}${localstatedir}/lib/softhsm/tokens/${PN} + install -m 600 -t ${D}${localstatedir}/lib/softhsm/tokens/${PN} ${B}/softhsm2.tokens/*/* + install -d ${D}${localstatedir}/lib/meta-signing.env.d + install -m 644 "${B}/meta-signing.env" ${D}${localstatedir}/lib/meta-signing.env.d/${PN} +} + +signing_prepare() { + export OPENSSL_MODULES="${STAGING_LIBDIR_NATIVE}/ossl-modules" + export OPENSSL_ENGINES="${STAGING_LIBDIR_NATIVE}/engines-3" + export OPENSSL_CONF="${STAGING_LIBDIR_NATIVE}/ssl-3/openssl.cnf" + export SSL_CERT_DIR="${STAGING_LIBDIR_NATIVE}/ssl-3/certs" + export SSL_CERT_FILE="${STAGING_LIBDIR_NATIVE}/ssl-3/cert.pem" + + if [ -f ${OPENSSL_CONF} ]; then + echo "Using '${OPENSSL_CONF}' for OpenSSL configuration" + else + echo "Missing 'openssl.cnf' at '${STAGING_ETCDIR_NATIVE}/ssl'" + return 1 + fi + if [ -d ${OPENSSL_MODULES} ]; then + echo "Using '${OPENSSL_MODULES}' for OpenSSL run-time modules" + else + echo "Missing OpenSSL module directory at '${OPENSSL_MODULES}'" + return 1 + fi + if [ -d ${OPENSSL_ENGINES} ]; then + echo "Using '${OPENSSL_ENGINES}' for OpenSSL run-time PKCS#11 modules" + else + echo "Missing OpenSSL PKCS11 engine directory at '${OPENSSL_ENGINES}'" + return 1 + fi + + export SOFTHSM2_CONF="${WORKDIR}/softhsm2.conf" + export SOFTHSM2_DIR="${STAGING_DIR_NATIVE}/var/lib/softhsm/tokens" + + echo "directories.tokendir = $SOFTHSM2_DIR" > "$SOFTHSM2_CONF" + echo "objectstore.backend = db" >> "$SOFTHSM2_CONF" + + for env in $(ls "${STAGING_DIR_NATIVE}/var/lib/meta-signing.env.d"); do + . "${STAGING_DIR_NATIVE}/var/lib/meta-signing.env.d/$env" + done +} +# make sure these functions are exported +signing_prepare[vardeps] += "signing_get_uri signing_get_module" + +signing_use_role() { + local role="${1}" + + export PKCS11_MODULE_PATH="$(signing_get_module $role)" + export PKCS11_URI="$(signing_get_uri $role)" + + if [ -z "$PKCS11_MODULE_PATH" ]; then + echo "No PKCS11_MODULE_PATH found for role '${role}'" + exit 1 + fi + if [ -z "$PKCS11_URI" ]; then + echo "No PKCS11_URI found for role '${role}'" + exit 1 + fi +} + +signing_get_uri() { + local role="${1}" + + # prefer local configuration + eval local uri="\$SIGNING_PKCS11_URI_${role}_" + if [ -n "$uri" ]; then + echo "$uri" + return + fi + + # fall back to softhsm + eval echo "\$_SIGNING_PKCS11_URI_${role}_" +} + +signing_get_module() { + local role="${1}" + + # prefer local configuration + eval local module="\$SIGNING_PKCS11_MODULE_${role}_" + if [ -n "$module" ]; then + echo "$module" + return + fi + + # fall back to softhsm + eval local module="\$_SIGNING_PKCS11_MODULE_${role}_" + if [ "$module" = "softhsm" ]; then + echo "${STAGING_LIBDIR_NATIVE}/softhsm/libsofthsm2.so" + else + echo "$module" + fi +} + +python () { + signing_class_prepare(d) +} diff --git a/meta-oe/classes/socorro-syms.bbclass b/meta-oe/classes/socorro-syms.bbclass index cc435aba1e..b9a5ffc881 100644 --- a/meta-oe/classes/socorro-syms.bbclass +++ b/meta-oe/classes/socorro-syms.bbclass @@ -16,7 +16,7 @@ inherit breakpad PACKAGE_PREPROCESS_FUNCS += "symbol_file_preprocess" PACKAGES =+ "${PN}-socorro-syms" -FILES_${PN}-socorro-syms = "/usr/share/socorro-syms" +FILES:${PN}-socorro-syms = "/usr/share/socorro-syms" python symbol_file_preprocess() { |