diff mbox series

[meta-swupdate] swupdate-common: add -certfile arg to CMS signing

Message ID 20231009074344.2890616-1-viktor.voronin@evologics.de
State Accepted
Delegated to: Stefano Babic
Headers show
Series [meta-swupdate] swupdate-common: add -certfile arg to CMS signing | expand

Commit Message

Victor Voronin Oct. 9, 2023, 7:43 a.m. UTC
Using openssl cms the recipient may not share intermediate certs in the
chain. The -certfile option includes these certificates in the message,
ensuring the recipient can establish the full chain of trust from a root
CA they already have, through the intermediate certificate(s) to the
signing certificate.

Add optional SWUPDATE_CMS_EXTRA_CERTS var to add additional certs to CMS
output using -certfile argument.

Patch based on the original work from Wes Malone, applied manually and
tested on 'dunfell', will require a rebase to apply on 'master'.

Signed-off-by: Victor Voronin <viktor.voronin@evologics.de>
---
 README                          |  2 ++
 classes/swupdate-common.bbclass | 16 +++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

Comments

Stefano Babic Oct. 18, 2023, 8:52 p.m. UTC | #1
On 09.10.23 09:43, 'Victor Voronin' via swupdate wrote:
> Using openssl cms the recipient may not share intermediate certs in the
> chain. The -certfile option includes these certificates in the message,
> ensuring the recipient can establish the full chain of trust from a root
> CA they already have, through the intermediate certificate(s) to the
> signing certificate.
> 
> Add optional SWUPDATE_CMS_EXTRA_CERTS var to add additional certs to CMS
> output using -certfile argument.
> 
> Patch based on the original work from Wes Malone, applied manually and
> tested on 'dunfell', will require a rebase to apply on 'master'.
> 
> Signed-off-by: Victor Voronin <viktor.voronin@evologics.de>
> ---
>   README                          |  2 ++
>   classes/swupdate-common.bbclass | 16 +++++++++++++++-
>   2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/README b/README
> index 52987bd..6975ae9 100644
> --- a/README
> +++ b/README
> @@ -62,6 +62,8 @@ There are 3 signing mechanisms supported by meta-swupdate at the moment:
>   
>     * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
>   
> +  * (Optional) Set `SWUPDATE_CMS_EXTRA_CERTS` to a space delimited list of intermediate certificate files
> +
>   3. Custom signing tool:
>   
>     * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
> diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
> index fbbd275..40c1afe 100644
> --- a/classes/swupdate-common.bbclass
> +++ b/classes/swupdate-common.bbclass
> @@ -34,6 +34,18 @@ def get_pwd_file_args(d, passfile):
>          pwd_args = ["-passin", "file:%s" % pwd_file]
>       return pwd_args
>   
> +def get_certfile_args(d):
> +    extra_certs = d.getVar('SWUPDATE_CMS_EXTRA_CERTS', True)
> +    if not extra_certs:
> +        return []
> +    certfile_args = []
> +    extra_paths = extra_certs.split()
> +    for crt_path in extra_paths:
> +        if not os.path.exists(crt_path):
> +            bb.fatal("SWUPDATE_CMS_EXTRA_CERTS path %s doesn't exist" % (crt_path))
> +        certfile_args.extend(["-certfile", crt_path])
> +    return certfile_args
> +
>   def swupdate_getdepends(d):
>       def adddep(depstr, deps):
>           for i in (depstr or "").split():
> @@ -205,7 +217,9 @@ def prepare_sw_description(d):
>               if not os.path.exists(cms_key):
>                   bb.fatal("SWUPDATE_CMS_KEY %s doesn't exist" % (cms_key))
>               signcmd = ["openssl", "cms", "-sign", "-in", sw_desc, "-out", sw_desc_sig, "-signer", cms_cert, "-inkey", cms_key] + \
> -                        get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + ["-outform", "DER", "-nosmimecap", "-binary"]
> +                        ["-outform", "DER", "-nosmimecap", "-binary"] + \
> +                        get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + \
> +                        get_certfile_args(d)
>           else:
>               bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.")
>           subprocess.run(' '.join(signcmd), shell=True, check=True)

Applied to -master, -mickeldore, -kirkstone, -dunfell, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/README b/README
index 52987bd..6975ae9 100644
--- a/README
+++ b/README
@@ -62,6 +62,8 @@  There are 3 signing mechanisms supported by meta-swupdate at the moment:
 
   * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
 
+  * (Optional) Set `SWUPDATE_CMS_EXTRA_CERTS` to a space delimited list of intermediate certificate files
+
 3. Custom signing tool:
 
   * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index fbbd275..40c1afe 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -34,6 +34,18 @@  def get_pwd_file_args(d, passfile):
        pwd_args = ["-passin", "file:%s" % pwd_file]
     return pwd_args
 
+def get_certfile_args(d):
+    extra_certs = d.getVar('SWUPDATE_CMS_EXTRA_CERTS', True)
+    if not extra_certs:
+        return []
+    certfile_args = []
+    extra_paths = extra_certs.split()
+    for crt_path in extra_paths:
+        if not os.path.exists(crt_path):
+            bb.fatal("SWUPDATE_CMS_EXTRA_CERTS path %s doesn't exist" % (crt_path))
+        certfile_args.extend(["-certfile", crt_path])
+    return certfile_args
+
 def swupdate_getdepends(d):
     def adddep(depstr, deps):
         for i in (depstr or "").split():
@@ -205,7 +217,9 @@  def prepare_sw_description(d):
             if not os.path.exists(cms_key):
                 bb.fatal("SWUPDATE_CMS_KEY %s doesn't exist" % (cms_key))
             signcmd = ["openssl", "cms", "-sign", "-in", sw_desc, "-out", sw_desc_sig, "-signer", cms_cert, "-inkey", cms_key] + \
-                        get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + ["-outform", "DER", "-nosmimecap", "-binary"]
+                        ["-outform", "DER", "-nosmimecap", "-binary"] + \
+                        get_pwd_file_args(d, 'SWUPDATE_PASSWORD_FILE') + \
+                        get_certfile_args(d)
         else:
             bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.")
         subprocess.run(' '.join(signcmd), shell=True, check=True)