3 Commits 30b8bb07bd ... 075be4c9aa

Auteur SHA1 Message Date
  Oliver Kaestner 075be4c9aa swupdate: don't set default mongoose port in args il y a 1 mois
  Hamish Guthrie 1177d733b5 swupdate.inc: add OFL-1.1 to LICENSE:${PN}-www il y a 1 semaine
  Ayoub Zaki 41b37d191c swupdate-common: add support for multiple CMS signers il y a 2 semaines

+ 11 - 3
README

@@ -60,9 +60,15 @@ There are 3 signing mechanisms supported by meta-swupdate at the moment:
 
   * Set variable: `SWUPDATE_SIGNING = "CMS"`
 
-  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file
+  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file. A space
+    delimited list of certificates may be given to produce a CMS with multiple
+    signers (e.g. hybrid classic + post-quantum signing). SWUpdate verifies the
+    signers as an AND, so every certificate must be present in the target trust
+    store.
 
-  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
+  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file. When several
+    certificates are listed in `SWUPDATE_CMS_CERT`, list the matching private
+    keys here in the same order; the two lists must have the same length.
 
   * (Optional) Set `SWUPDATE_CMS_EXTRA_CERTS` to a space delimited list of intermediate certificate files
 
@@ -70,7 +76,9 @@ There are 3 signing mechanisms supported by meta-swupdate at the moment:
     `openssl cms -sign` via `-md` (e.g. `sha256`, `sha512`). When unset, openssl
     picks the signing key's default digest. This is required for signing keys
     that have no default digest such as ML-DSA where openssl otherwise fails
-    with "no default digest".
+    with "no default digest". `openssl cms` uses a single digest for all
+    signers, so with multiple certificates choose one strong enough for the
+    strongest key (e.g. `sha512` when any of ML-DSA-65/87 is used).
 
 3. Custom signing tool:
 

+ 14 - 9
classes-recipe/swupdate-common.bbclass

@@ -218,19 +218,24 @@ def prepare_sw_description(d):
             signcmd = ["openssl", "dgst", "-sha256", "-sign", privkey] + get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + \
                       ["-sigopt", "rsa_padding_mode:pss", "-sigopt", "rsa_pss_saltlen:-2", "-out", sw_desc_sig, sw_desc]
         elif signing == "CMS":
-            cms_cert = d.getVar('SWUPDATE_CMS_CERT')
-            if not cms_cert:
+            cms_certs = (d.getVar('SWUPDATE_CMS_CERT') or "").split()
+            if not cms_certs:
                 bb.fatal("SWUPDATE_CMS_CERT is not set")
-            if not os.path.exists(cms_cert):
-                bb.fatal("SWUPDATE_CMS_CERT %s doesn't exist" % (cms_cert))
-            cms_key = d.getVar('SWUPDATE_CMS_KEY')
-            if not cms_key:
+            cms_keys = (d.getVar('SWUPDATE_CMS_KEY') or "").split()
+            if not cms_keys:
                 bb.fatal("SWUPDATE_CMS_KEY isn't set")
-            if not os.path.exists(cms_key):
-                bb.fatal("SWUPDATE_CMS_KEY %s doesn't exist" % (cms_key))
+            if len(cms_certs) != len(cms_keys):
+                bb.fatal("SWUPDATE_CMS_CERT and SWUPDATE_CMS_KEY must list the same number of entries (got %d certs, %d keys)" % (len(cms_certs), len(cms_keys)))
+            signer_args = []
+            for cms_cert, cms_key in zip(cms_certs, cms_keys):
+                if not os.path.exists(cms_cert):
+                    bb.fatal("SWUPDATE_CMS_CERT %s doesn't exist" % (cms_cert))
+                if not os.path.exists(cms_key):
+                    bb.fatal("SWUPDATE_CMS_KEY %s doesn't exist" % (cms_key))
+                signer_args += ["-signer", cms_cert, "-inkey", cms_key]
             cms_md = d.getVar('SWUPDATE_CMS_MD')
             md_args = ["-md", cms_md] if cms_md else []
-            signcmd = ["openssl", "cms", "-sign", "-in", sw_desc, "-out", sw_desc_sig, "-signer", cms_cert, "-inkey", cms_key] + \
+            signcmd = ["openssl", "cms", "-sign", "-in", sw_desc, "-out", sw_desc_sig] + signer_args + \
                         ["-outform", "DER", "-nosmimecap", "-binary"] + md_args + \
                         get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + \
                         get_certfile_args(d)

+ 1 - 1
recipes-support/swupdate/swupdate.inc

@@ -10,7 +10,7 @@ DEPENDS += "libconfig zlib libubootenv json-c"
 LICENSE = "GPL-2.0-only & GPL-2.0-or-later & LGPL-2.1-or-later & LGPL-2.1-only & MIT & ISC & BSD-1-Clause & BSD-3-Clause"
 LICENSE:${PN}-ipc = "LGPL-2.1-or-later"
 LICENSE:${PN}-lua = "LGPL-2.1-only & MIT"
-LICENSE:${PN}-www = "MIT"
+LICENSE:${PN}-www = "MIT & OFL-1.1"
 
 LIC_FILES_CHKSUM = " \
     file://LICENSES/BSD-1-Clause.txt;md5=4c75b3902cf6a01969906bcae9cf8cd6 \

+ 1 - 1
recipes-support/swupdate/swupdate/10-mongoose-args.in

@@ -1 +1 @@
-SWUPDATE_WEBSERVER_ARGS="-r @@wwwdir@@ ${SWUPDATE_MONGOOSE_EXTRA_ARGS:--p 8080}"
+SWUPDATE_WEBSERVER_ARGS="-r @@wwwdir@@ ${SWUPDATE_MONGOOSE_EXTRA_ARGS}"