diff mbox series

[meta-swupdate] Upgrade swupdate.bbclass in morty from master.

Message ID 1518064020-56906-1-git-send-email-dmitri.toubelis@litmusautomation.com
State Accepted
Headers show
Series [meta-swupdate] Upgrade swupdate.bbclass in morty from master. | expand

Commit Message

Dmitri Toubelis Feb. 8, 2018, 4:27 a.m. UTC
This commit brings the latest version of swupdate.bbclass from `master`
into `morty`. README file is also copied over. This adds support for
CMS signing and few other conveniences to `morty`.

Signed-off-by: Dmitri Toubelis <dmitri.toubelis@litmusautomation.com>
---
 README                   | 36 +++++++++++++++-------
 classes/swupdate.bbclass | 78 ++++++++++++++++++++++++++++++++++--------------
 2 files changed, 82 insertions(+), 32 deletions(-)

Comments

Stefano Babic Feb. 8, 2018, 6:39 p.m. UTC | #1
Hi Dmitri,

On 08/02/2018 05:27, Dmitri Toubelis wrote:
> This commit brings the latest version of swupdate.bbclass from `master`
> into `morty`. README file is also copied over. This adds support for
> CMS signing and few other conveniences to `morty`.
> 
> Signed-off-by: Dmitri Toubelis <dmitri.toubelis@litmusautomation.com>
> ---
>  README                   | 36 +++++++++++++++-------
>  classes/swupdate.bbclass | 78 ++++++++++++++++++++++++++++++++++--------------
>  2 files changed, 82 insertions(+), 32 deletions(-)
> 
> diff --git a/README b/README
> index 2e50a72..df669f4 100644
> --- a/README
> +++ b/README
> @@ -21,18 +21,34 @@ image filename) are replaced with the sha256 hash of the image.
>  SWU image signing
>  ------------
>  
> -To enable signing:
> -    Set SWUPDATE_SIGNING = "1"
> -    Set SWUPDATE_PRIVATE_KEY to the full path of private key file
> +There are 3 signing mechanisms supported by meta-swupdate at the moment:
>  
> -sw-description is signed with the private key and the signature is writen to
> -sw-description.sig which is included in the SWU file.
> +1. RSA signing:
>  
> -Encrypted private keys are not currently supported since a secure 
> -mechanism must exist to provide the passphrase.
> +  * Set variable: `SWUPDATE_SIGNING = "RSA"`
> +
> +  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private key file
> +
> +2. CMS signing:
> +
> +  * Set variable: `SWUPDATE_SIGNING = "CMS"`
> +
> +  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file
> +
> +  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
>  
> -If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored and the string
> -contained in SWUPDATE_SIGN_TOOL is executed to perform the signing.
> +3. Custom signing tool:
> +
> +  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
> +
> +  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that needs to be
> +    executed in order to perform the signing
> +
> +sw-description is signed and the signature is written to sw-description.sig
> +which is included in the SWU file.
> +
> +Encrypted private keys are not currently supported since a secure
> +mechanism must exist to provide the passphrase.
>  
>  Maintainer
>  ----------
> @@ -51,5 +67,5 @@ When creating patches, please use something like:
>  
>      git format-patch -s --subject-prefix='meta-swupdate][PATCH' <revision range>
>  
> -Please use 'git send- email' to send the generated patches to the ML
> +Please use 'git send-email' to send the generated patches to the ML
>  to bypass changes from your mailer.
> diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
> index 44e4546..02db631 100644
> --- a/classes/swupdate.bbclass
> +++ b/classes/swupdate.bbclass
> @@ -1,5 +1,5 @@
>  # Copyright (C) 2015 Stefano Babic <sbabic@denx.de>
> -# 
> +#
>  # Some parts from the patch class
>  #
>  # swupdate allows to generate a compound image for the
> @@ -14,7 +14,7 @@
>  
>  S = "${WORKDIR}/${PN}"
>  
> -DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) == '1' else ''}"
> +DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
>  IMAGE_DEPENDS ?= ""
>  
>  def swupdate_is_hash_needed(s, filename):
> @@ -64,15 +64,23 @@ def swupdate_getdepends(d):
>          depstr += " " + dep + ":do_build"
>      return depstr
>  
> +IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
> +
>  do_swuimage[dirs] = "${TOPDIR}"
> -do_swuimage[cleandirs] += "${S}"
> +do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
>  do_swuimage[umask] = "022"
> +SSTATETASKS += "do_swuimage"
> +SSTATE_SKIP_CREATION_task-swuimage = '1'
> +do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
> +do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
> +do_swuimage[stamp-extra-info] = "${MACHINE}"
>  
>  do_configure[noexec] = "1"
>  do_compile[noexec] = "1"
>  do_install[noexec] = "1"
> +deltask do_populate_sysroot
>  do_package[noexec] = "1"
> -do_package_qa[noexec] = "1"
> +deltask do_package_qa
>  do_packagedata[noexec] = "1"
>  do_package_write_ipk[noexec] = "1"
>  do_package_write_deb[noexec] = "1"
> @@ -83,14 +91,6 @@ python () {
>      d.appendVarFlag('do_swuimage', 'depends', deps)
>  }
>  
> -do_install () {
> -}
> -
> -do_createlink () {
> -    cd ${DEPLOY_DIR_IMAGE}
> -    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu
> -}
> -
>  python do_swuimage () {
>      import shutil
>  
> @@ -101,7 +101,7 @@ python do_swuimage () {
>      fetch = bb.fetch2.Fetch([], d)
>      list_for_cpio = ["sw-description"]
>  
> -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
> +    if d.getVar('SWUPDATE_SIGNING', True):
>          list_for_cpio.append('sw-description.sig')
>  
>      for url in fetch.urls:
> @@ -115,6 +115,7 @@ python do_swuimage () {
>  # If they are not there, additional file can be added
>  # by fetching from URLs
>      deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
> +    imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
>  
>      for image in images:
>          fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
> @@ -140,12 +141,20 @@ python do_swuimage () {
>              hash = swupdate_get_sha256(s, file)
>              swupdate_write_sha256(s, file, hash)
>  
> -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
> -        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
> -        if sign_tool:
> -            if os.system(sign_tool) != 0:
> -                bb.fatal("Failed to sign with %s" % (sign_tool))
> -        else:
> +    signing = d.getVar('SWUPDATE_SIGNING', True)
> +    if signing == "1":
> +        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling back to "RSA". It is advised to set it to "RSA" if using RSA signing.')
> +        signing = "RSA"
> +    if signing:
> +        if signing == "CUSTOM":
> +            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
> +            if sign_tool:
> +                ret = os.system(sign_tool)
> +                if ret != 0:
> +                    bb.fatal("Failed to sign with %s" % (sign_tool))
> +            else:
> +                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not given")
> +        elif signing == "RSA":
>              privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
>              if not privkey:
>                  bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
> @@ -163,13 +172,38 @@ python do_swuimage () {
>                  os.path.join(s, 'sw-description'))
>              if os.system(signcmd) != 0:
>                  bb.fatal("Failed to sign sw-description with %s" % (privkey))
> +        elif signing == "CMS":
> +            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
> +            if not cms_cert:
> +                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', True)
> +            if not cms_key:
> +                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))
> +            signcmd = "openssl cms -sign -in '%s' -out '%s' -signer '%s' -inkey '%s' -outform DER -nosmimecap -binary" % (
> +                os.path.join(s, 'sw-description'),
> +                os.path.join(s, 'sw-description.sig'),
> +                cms_cert,
> +                cms_key)
> +            if os.system(signcmd) != 0:
> +                bb.fatal("Failed to sign sw-description with %s" % (privkey))
> +        else:
> +            bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");
>  
> -    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + '.swu')
> +    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>      os.system("cd " + s + ";" + line)
> +
> +    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
> +    os.system("cd " + imgdeploydir + "; " + line)
>  }
>  
>  COMPRESSIONTYPES = ""
>  PACKAGE_ARCH = "${MACHINE_ARCH}"
>  
> -addtask do_swuimage after do_unpack before do_install
> -addtask do_createlink after do_swuimage before do_install
> +INHIBIT_DEFAULT_DEPS = "1"
> +EXCLUDE_FROM_WORLD = "1"
> +
> +addtask do_swuimage after do_unpack after do_prepare_recipe_sysroot before do_build
> 

Tested-by : Stefano Babic <sbabic@denx.de>
Acked-by : Stefano Babic <sbabic@denx.de>

This flows soon in -morty, thanks !

Best regards,
Stefano Babic
Dmitri Toubelis Feb. 11, 2018, 1:17 a.m. UTC | #2
It just occurred to me that CMS validation is not available in `morty` so 
it looks like it would require upgrading 
`meta-swupdate/recipes-support/swupdate` recipe.

Do you have an easy way of doing this? Or would you prefer a patch?

-Dmitri

On Thursday, February 8, 2018 at 1:39:37 PM UTC-5, Stefano Babic wrote:
>
> Hi Dmitri, 
>
> On 08/02/2018 05:27, Dmitri Toubelis wrote: 
> > This commit brings the latest version of swupdate.bbclass from `master` 
> > into `morty`. README file is also copied over. This adds support for 
> > CMS signing and few other conveniences to `morty`. 
> > 
> > Signed-off-by: Dmitri Toubelis <dmitri....@litmusautomation.com 
> <javascript:>> 
> > --- 
> >  README                   | 36 +++++++++++++++------- 
> >  classes/swupdate.bbclass | 78 
> ++++++++++++++++++++++++++++++++++-------------- 
> >  2 files changed, 82 insertions(+), 32 deletions(-) 
> > 
> > diff --git a/README b/README 
> > index 2e50a72..df669f4 100644 
> > --- a/README 
> > +++ b/README 
> > @@ -21,18 +21,34 @@ image filename) are replaced with the sha256 hash of 
> the image. 
> >  SWU image signing 
> >  ------------ 
> >   
> > -To enable signing: 
> > -    Set SWUPDATE_SIGNING = "1" 
> > -    Set SWUPDATE_PRIVATE_KEY to the full path of private key file 
> > +There are 3 signing mechanisms supported by meta-swupdate at the 
> moment: 
> >   
> > -sw-description is signed with the private key and the signature is 
> writen to 
> > -sw-description.sig which is included in the SWU file. 
> > +1. RSA signing: 
> >   
> > -Encrypted private keys are not currently supported since a secure 
> > -mechanism must exist to provide the passphrase. 
> > +  * Set variable: `SWUPDATE_SIGNING = "RSA"` 
> > + 
> > +  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private key file 
> > + 
> > +2. CMS signing: 
> > + 
> > +  * Set variable: `SWUPDATE_SIGNING = "CMS"` 
> > + 
> > +  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file 
> > + 
> > +  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file 
> >   
> > -If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored and the 
> string 
> > -contained in SWUPDATE_SIGN_TOOL is executed to perform the signing. 
> > +3. Custom signing tool: 
> > + 
> > +  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"` 
> > + 
> > +  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that needs to be 
> > +    executed in order to perform the signing 
> > + 
> > +sw-description is signed and the signature is written to 
> sw-description.sig 
> > +which is included in the SWU file. 
> > + 
> > +Encrypted private keys are not currently supported since a secure 
> > +mechanism must exist to provide the passphrase. 
> >   
> >  Maintainer 
> >  ---------- 
> > @@ -51,5 +67,5 @@ When creating patches, please use something like: 
> >   
> >      git format-patch -s --subject-prefix='meta-swupdate][PATCH' 
> <revision range> 
> >   
> > -Please use 'git send- email' to send the generated patches to the ML 
> > +Please use 'git send-email' to send the generated patches to the ML 
> >  to bypass changes from your mailer. 
> > diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass 
> > index 44e4546..02db631 100644 
> > --- a/classes/swupdate.bbclass 
> > +++ b/classes/swupdate.bbclass 
> > @@ -1,5 +1,5 @@ 
> >  # Copyright (C) 2015 Stefano Babic <sba...@denx.de <javascript:>> 
> > -# 
> > +# 
> >  # Some parts from the patch class 
> >  # 
> >  # swupdate allows to generate a compound image for the 
> > @@ -14,7 +14,7 @@ 
> >   
> >  S = "${WORKDIR}/${PN}" 
> >   
> > -DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) 
> == '1' else ''}" 
> > +DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) 
> else ''}" 
> >  IMAGE_DEPENDS ?= "" 
> >   
> >  def swupdate_is_hash_needed(s, filename): 
> > @@ -64,15 +64,23 @@ def swupdate_getdepends(d): 
> >          depstr += " " + dep + ":do_build" 
> >      return depstr 
> >   
> > +IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage" 
> > + 
> >  do_swuimage[dirs] = "${TOPDIR}" 
> > -do_swuimage[cleandirs] += "${S}" 
> > +do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}" 
> >  do_swuimage[umask] = "022" 
> > +SSTATETASKS += "do_swuimage" 
> > +SSTATE_SKIP_CREATION_task-swuimage = '1' 
> > +do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}" 
> > +do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" 
> > +do_swuimage[stamp-extra-info] = "${MACHINE}" 
> >   
> >  do_configure[noexec] = "1" 
> >  do_compile[noexec] = "1" 
> >  do_install[noexec] = "1" 
> > +deltask do_populate_sysroot 
> >  do_package[noexec] = "1" 
> > -do_package_qa[noexec] = "1" 
> > +deltask do_package_qa 
> >  do_packagedata[noexec] = "1" 
> >  do_package_write_ipk[noexec] = "1" 
> >  do_package_write_deb[noexec] = "1" 
> > @@ -83,14 +91,6 @@ python () { 
> >      d.appendVarFlag('do_swuimage', 'depends', deps) 
> >  } 
> >   
> > -do_install () { 
> > -} 
> > - 
> > -do_createlink () { 
> > -    cd ${DEPLOY_DIR_IMAGE} 
> > -    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu 
> > -} 
> > - 
> >  python do_swuimage () { 
> >      import shutil 
> >   
> > @@ -101,7 +101,7 @@ python do_swuimage () { 
> >      fetch = bb.fetch2.Fetch([], d) 
> >      list_for_cpio = ["sw-description"] 
> >   
> > -    if d.getVar('SWUPDATE_SIGNING', True) == '1': 
> > +    if d.getVar('SWUPDATE_SIGNING', True): 
> >          list_for_cpio.append('sw-description.sig') 
> >   
> >      for url in fetch.urls: 
> > @@ -115,6 +115,7 @@ python do_swuimage () { 
> >  # If they are not there, additional file can be added 
> >  # by fetching from URLs 
> >      deploydir = d.getVar('DEPLOY_DIR_IMAGE', True) 
> > +    imgdeploydir = d.getVar('IMGDEPLOYDIR', True) 
> >   
> >      for image in images: 
> >          fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) 
> or "").split() 
> > @@ -140,12 +141,20 @@ python do_swuimage () { 
> >              hash = swupdate_get_sha256(s, file) 
> >              swupdate_write_sha256(s, file, hash) 
> >   
> > -    if d.getVar('SWUPDATE_SIGNING', True) == '1': 
> > -        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True) 
> > -        if sign_tool: 
> > -            if os.system(sign_tool) != 0: 
> > -                bb.fatal("Failed to sign with %s" % (sign_tool)) 
> > -        else: 
> > +    signing = d.getVar('SWUPDATE_SIGNING', True) 
> > +    if signing == "1": 
> > +        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling back to 
> "RSA". It is advised to set it to "RSA" if using RSA signing.') 
> > +        signing = "RSA" 
> > +    if signing: 
> > +        if signing == "CUSTOM": 
> > +            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True) 
> > +            if sign_tool: 
> > +                ret = os.system(sign_tool) 
> > +                if ret != 0: 
> > +                    bb.fatal("Failed to sign with %s" % (sign_tool)) 
> > +            else: 
> > +                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not given") 
> > +        elif signing == "RSA": 
> >              privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True) 
> >              if not privkey: 
> >                  bb.fatal("SWUPDATE_PRIVATE_KEY isn't set") 
> > @@ -163,13 +172,38 @@ python do_swuimage () { 
> >                  os.path.join(s, 'sw-description')) 
> >              if os.system(signcmd) != 0: 
> >                  bb.fatal("Failed to sign sw-description with %s" % 
> (privkey)) 
> > +        elif signing == "CMS": 
> > +            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True) 
> > +            if not cms_cert: 
> > +                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', True) 
> > +            if not cms_key: 
> > +                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)) 
> > +            signcmd = "openssl cms -sign -in '%s' -out '%s' -signer 
> '%s' -inkey '%s' -outform DER -nosmimecap -binary" % ( 
> > +                os.path.join(s, 'sw-description'), 
> > +                os.path.join(s, 'sw-description.sig'), 
> > +                cms_cert, 
> > +                cms_key) 
> > +            if os.system(signcmd) != 0: 
> > +                bb.fatal("Failed to sign sw-description with %s" % 
> (privkey)) 
> > +        else: 
> > +            bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism."); 
> >   
> > -    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | 
> cpio -ov -H crc >' + os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + 
> '.swu') 
> > +    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | 
> cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) 
> + '.swu') 
> >      os.system("cd " + s + ";" + line) 
> > + 
> > +    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + 
> d.getVar('IMAGE_LINK_NAME', True) + '.swu' 
> > +    os.system("cd " + imgdeploydir + "; " + line) 
> >  } 
> >   
> >  COMPRESSIONTYPES = "" 
> >  PACKAGE_ARCH = "${MACHINE_ARCH}" 
> >   
> > -addtask do_swuimage after do_unpack before do_install 
> > -addtask do_createlink after do_swuimage before do_install 
> > +INHIBIT_DEFAULT_DEPS = "1" 
> > +EXCLUDE_FROM_WORLD = "1" 
> > + 
> > +addtask do_swuimage after do_unpack after do_prepare_recipe_sysroot 
> before do_build 
> > 
>
> Tested-by : Stefano Babic <sba...@denx.de <javascript:>> 
> Acked-by : Stefano Babic <sba...@denx.de <javascript:>> 
>
> This flows soon in -morty, thanks ! 
>
> Best regards, 
> Stefano Babic 
>
> -- 
> ===================================================================== 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk 
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany 
> Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de 
> <javascript:> 
> ===================================================================== 
>
Stefano Babic Feb. 11, 2018, 9:18 a.m. UTC | #3
Hi Dmitri,

On 11/02/2018 02:17, Dmitri Toubelis wrote:
> It just occurred to me that CMS validation is not available in `morty`
> so it looks like it would require upgrading
> `meta-swupdate/recipes-support/swupdate` recipe.
> 
> Do you have an easy way of doing this? Or would you prefer a patch?
> 

I do not understand what you mind - I have already applied your patch
into -morty.

Best regards,
Stefano Babic


> -Dmitri
> 
> On Thursday, February 8, 2018 at 1:39:37 PM UTC-5, Stefano Babic wrote:
> 
>     Hi Dmitri,
> 
>     On 08/02/2018 05:27, Dmitri Toubelis wrote:
>     > This commit brings the latest version of swupdate.bbclass from
>     `master`
>     > into `morty`. README file is also copied over. This adds support for
>     > CMS signing and few other conveniences to `morty`.
>     >
>     > Signed-off-by: Dmitri Toubelis <dmitri....@litmusautomation.com
>     <javascript:>>
>     > ---
>     >  README                   | 36 +++++++++++++++-------
>     >  classes/swupdate.bbclass | 78
>     ++++++++++++++++++++++++++++++++++--------------
>     >  2 files changed, 82 insertions(+), 32 deletions(-)
>     >
>     > diff --git a/README b/README
>     > index 2e50a72..df669f4 100644
>     > --- a/README
>     > +++ b/README
>     > @@ -21,18 +21,34 @@ image filename) are replaced with the sha256
>     hash of the image.
>     >  SWU image signing
>     >  ------------
>     >  
>     > -To enable signing:
>     > -    Set SWUPDATE_SIGNING = "1"
>     > -    Set SWUPDATE_PRIVATE_KEY to the full path of private key file
>     > +There are 3 signing mechanisms supported by meta-swupdate at the
>     moment:
>     >  
>     > -sw-description is signed with the private key and the signature
>     is writen to
>     > -sw-description.sig which is included in the SWU file.
>     > +1. RSA signing:
>     >  
>     > -Encrypted private keys are not currently supported since a secure
>     > -mechanism must exist to provide the passphrase.
>     > +  * Set variable: `SWUPDATE_SIGNING = "RSA"`
>     > +
>     > +  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private key file
>     > +
>     > +2. CMS signing:
>     > +
>     > +  * Set variable: `SWUPDATE_SIGNING = "CMS"`
>     > +
>     > +  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file
>     > +
>     > +  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
>     >  
>     > -If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored and
>     the string
>     > -contained in SWUPDATE_SIGN_TOOL is executed to perform the signing.
>     > +3. Custom signing tool:
>     > +
>     > +  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
>     > +
>     > +  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that needs
>     to be
>     > +    executed in order to perform the signing
>     > +
>     > +sw-description is signed and the signature is written to
>     sw-description.sig
>     > +which is included in the SWU file.
>     > +
>     > +Encrypted private keys are not currently supported since a secure
>     > +mechanism must exist to provide the passphrase.
>     >  
>     >  Maintainer
>     >  ----------
>     > @@ -51,5 +67,5 @@ When creating patches, please use something like:
>     >  
>     >      git format-patch -s --subject-prefix='meta-swupdate][PATCH'
>     <revision range>
>     >  
>     > -Please use 'git send- email' to send the generated patches to the ML
>     > +Please use 'git send-email' to send the generated patches to the ML
>     >  to bypass changes from your mailer.
>     > diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
>     > index 44e4546..02db631 100644
>     > --- a/classes/swupdate.bbclass
>     > +++ b/classes/swupdate.bbclass
>     > @@ -1,5 +1,5 @@
>     >  # Copyright (C) 2015 Stefano Babic <sba...@denx.de <javascript:>>
>     > -#
>     > +#
>     >  # Some parts from the patch class
>     >  #
>     >  # swupdate allows to generate a compound image for the
>     > @@ -14,7 +14,7 @@
>     >  
>     >  S = "${WORKDIR}/${PN}"
>     >  
>     > -DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING',
>     True) == '1' else ''}"
>     > +DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING',
>     True) else ''}"
>     >  IMAGE_DEPENDS ?= ""
>     >  
>     >  def swupdate_is_hash_needed(s, filename):
>     > @@ -64,15 +64,23 @@ def swupdate_getdepends(d):
>     >          depstr += " " + dep + ":do_build"
>     >      return depstr
>     >  
>     > +IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
>     > +
>     >  do_swuimage[dirs] = "${TOPDIR}"
>     > -do_swuimage[cleandirs] += "${S}"
>     > +do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
>     >  do_swuimage[umask] = "022"
>     > +SSTATETASKS += "do_swuimage"
>     > +SSTATE_SKIP_CREATION_task-swuimage = '1'
>     > +do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
>     > +do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
>     > +do_swuimage[stamp-extra-info] = "${MACHINE}"
>     >  
>     >  do_configure[noexec] = "1"
>     >  do_compile[noexec] = "1"
>     >  do_install[noexec] = "1"
>     > +deltask do_populate_sysroot
>     >  do_package[noexec] = "1"
>     > -do_package_qa[noexec] = "1"
>     > +deltask do_package_qa
>     >  do_packagedata[noexec] = "1"
>     >  do_package_write_ipk[noexec] = "1"
>     >  do_package_write_deb[noexec] = "1"
>     > @@ -83,14 +91,6 @@ python () {
>     >      d.appendVarFlag('do_swuimage', 'depends', deps)
>     >  }
>     >  
>     > -do_install () {
>     > -}
>     > -
>     > -do_createlink () {
>     > -    cd ${DEPLOY_DIR_IMAGE}
>     > -    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu
>     > -}
>     > -
>     >  python do_swuimage () {
>     >      import shutil
>     >  
>     > @@ -101,7 +101,7 @@ python do_swuimage () {
>     >      fetch = bb.fetch2.Fetch([], d)
>     >      list_for_cpio = ["sw-description"]
>     >  
>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>     > +    if d.getVar('SWUPDATE_SIGNING', True):
>     >          list_for_cpio.append('sw-description.sig')
>     >  
>     >      for url in fetch.urls:
>     > @@ -115,6 +115,7 @@ python do_swuimage () {
>     >  # If they are not there, additional file can be added
>     >  # by fetching from URLs
>     >      deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
>     > +    imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
>     >  
>     >      for image in images:
>     >          fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image,
>     True) or "").split()
>     > @@ -140,12 +141,20 @@ python do_swuimage () {
>     >              hash = swupdate_get_sha256(s, file)
>     >              swupdate_write_sha256(s, file, hash)
>     >  
>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>     > -        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>     > -        if sign_tool:
>     > -            if os.system(sign_tool) != 0:
>     > -                bb.fatal("Failed to sign with %s" % (sign_tool))
>     > -        else:
>     > +    signing = d.getVar('SWUPDATE_SIGNING', True)
>     > +    if signing == "1":
>     > +        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling
>     back to "RSA". It is advised to set it to "RSA" if using RSA signing.')
>     > +        signing = "RSA"
>     > +    if signing:
>     > +        if signing == "CUSTOM":
>     > +            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>     > +            if sign_tool:
>     > +                ret = os.system(sign_tool)
>     > +                if ret != 0:
>     > +                    bb.fatal("Failed to sign with %s" % (sign_tool))
>     > +            else:
>     > +                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not given")
>     > +        elif signing == "RSA":
>     >              privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
>     >              if not privkey:
>     >                  bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
>     > @@ -163,13 +172,38 @@ python do_swuimage () {
>     >                  os.path.join(s, 'sw-description'))
>     >              if os.system(signcmd) != 0:
>     >                  bb.fatal("Failed to sign sw-description with %s"
>     % (privkey))
>     > +        elif signing == "CMS":
>     > +            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
>     > +            if not cms_cert:
>     > +                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', True)
>     > +            if not cms_key:
>     > +                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))
>     > +            signcmd = "openssl cms -sign -in '%s' -out '%s'
>     -signer '%s' -inkey '%s' -outform DER -nosmimecap -binary" % (
>     > +                os.path.join(s, 'sw-description'),
>     > +                os.path.join(s, 'sw-description.sig'),
>     > +                cms_cert,
>     > +                cms_key)
>     > +            if os.system(signcmd) != 0:
>     > +                bb.fatal("Failed to sign sw-description with %s"
>     % (privkey))
>     > +        else:
>     > +            bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");
>     >  
>     > -    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>     $i;done | cpio -ov -H crc >' +
>     os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>     > +    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>     $i;done | cpio -ov -H crc >' +
>     os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>     >      os.system("cd " + s + ";" + line)
>     > +
>     > +    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' +
>     d.getVar('IMAGE_LINK_NAME', True) + '.swu'
>     > +    os.system("cd " + imgdeploydir + "; " + line)
>     >  }
>     >  
>     >  COMPRESSIONTYPES = ""
>     >  PACKAGE_ARCH = "${MACHINE_ARCH}"
>     >  
>     > -addtask do_swuimage after do_unpack before do_install
>     > -addtask do_createlink after do_swuimage before do_install
>     > +INHIBIT_DEFAULT_DEPS = "1"
>     > +EXCLUDE_FROM_WORLD = "1"
>     > +
>     > +addtask do_swuimage after do_unpack after
>     do_prepare_recipe_sysroot before do_build
>     >
> 
>     Tested-by : Stefano Babic <sba...@denx.de <javascript:>>
>     Acked-by : Stefano Babic <sba...@denx.de <javascript:>>
> 
>     This flows soon in -morty, thanks !
> 
>     Best regards,
>     Stefano Babic
> 
>     -- 
>     =====================================================================
>     DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>     HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>     Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email:
>     sba...@denx.de <javascript:>
>     =====================================================================
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "swupdate" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swupdate+unsubscribe@googlegroups.com
> <mailto:swupdate+unsubscribe@googlegroups.com>.
> To post to this group, send email to swupdate@googlegroups.com
> <mailto:swupdate@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.
Stefano Babic Feb. 11, 2018, 6:09 p.m. UTC | #4
Hi Dmitri,

please do not drop the ML in your replies - thanks !

On 11/02/2018 18:31, Dmitri Toubelis wrote:
> What I mean is that the latest version of swupdate from morty does not 
> support CMS signatures yet, so the 
> `meta-swupdate/recipes-support/swupdate` recipe need to be upgraded as 
> well. The latest version in morty is 2017.01 and doesn't support CMS.
> 

ok, got it. This happens with all packages. From a Yocto release to next
release, packages are updated to newer releases, fixing bugs and adding
features. It is part of the game.

However, adding a recipe in morty for latest release (2017.11) cannot be
accepted. This breaks all products using morty, or at least, a new build
will contain a different SWUpdate release. The policy in Yocto is to fix
bugs or security leak, but new features are available in new releases
and are not backported.

However, I have foreseen the case in SWUpdate using the _git version.
swupdate_git is not chosen as default (see previous discussions in this
ML), but it can be used to switch to last SWUpdate version. People
requiring a new SWupdate version as the one in their release should set
PREFERRED_VERSION_swupdate = "git", and set a SRCREV into an own
.bbappend to set a specific version (if desired).

Best regards,
Stefano Babic

> ------ Original Message ------
> From: "Stefano Babic" <sbabic@denx.de>
> To: "Dmitri Toubelis" <dmitri.toubelis@litmusautomation.com>; "swupdate" 
> <swupdate@googlegroups.com>
> Sent: 2018-02-11 4:18:18 AM
> Subject: Re: [swupdate] [meta-swupdate][PATCH] Upgrade swupdate.bbclass 
> in morty from master.
> 
>> Hi Dmitri,
>>
>> On 11/02/2018 02:17, Dmitri Toubelis wrote:
>>> It just occurred to me that CMS validation is not available in `morty`
>>> so it looks like it would require upgrading
>>> `meta-swupdate/recipes-support/swupdate` recipe.
>>>
>>> Do you have an easy way of doing this? Or would you prefer a patch?
>>>
>>
>> I do not understand what you mind - I have already applied your patch
>> into -morty.
>>
>> Best regards,
>> Stefano Babic
>>
>>
>>> -Dmitri
>>>
>>> On Thursday, February 8, 2018 at 1:39:37 PM UTC-5, Stefano Babic 
>>> wrote:
>>>
>>>     Hi Dmitri,
>>>
>>>     On 08/02/2018 05:27, Dmitri Toubelis wrote:
>>>     > This commit brings the latest version of swupdate.bbclass from
>>>     `master`
>>>     > into `morty`. README file is also copied over. This adds support 
>>> for
>>>     > CMS signing and few other conveniences to `morty`.
>>>     >
>>>     > Signed-off-by: Dmitri Toubelis <dmitri....@litmusautomation.com
>>>     <javascript:>>
>>>     > ---
>>>     >  README                   | 36 +++++++++++++++-------
>>>     >  classes/swupdate.bbclass | 78
>>>     ++++++++++++++++++++++++++++++++++--------------
>>>     >  2 files changed, 82 insertions(+), 32 deletions(-)
>>>     >
>>>     > diff --git a/README b/README
>>>     > index 2e50a72..df669f4 100644
>>>     > --- a/README
>>>     > +++ b/README
>>>     > @@ -21,18 +21,34 @@ image filename) are replaced with the sha256
>>>     hash of the image.
>>>     >  SWU image signing
>>>     >  ------------
>>>     >
>>>     > -To enable signing:
>>>     > -    Set SWUPDATE_SIGNING = "1"
>>>     > -    Set SWUPDATE_PRIVATE_KEY to the full path of private key 
>>> file
>>>     > +There are 3 signing mechanisms supported by meta-swupdate at 
>>> the
>>>     moment:
>>>     >
>>>     > -sw-description is signed with the private key and the signature
>>>     is writen to
>>>     > -sw-description.sig which is included in the SWU file.
>>>     > +1. RSA signing:
>>>     >
>>>     > -Encrypted private keys are not currently supported since a 
>>> secure
>>>     > -mechanism must exist to provide the passphrase.
>>>     > +  * Set variable: `SWUPDATE_SIGNING = "RSA"`
>>>     > +
>>>     > +  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private key 
>>> file
>>>     > +
>>>     > +2. CMS signing:
>>>     > +
>>>     > +  * Set variable: `SWUPDATE_SIGNING = "CMS"`
>>>     > +
>>>     > +  * Set `SWUPDATE_CMS_CERT` to the full path of certificate 
>>> file
>>>     > +
>>>     > +  * Set `SWUPDATE_CMS_KEY ` to the full path of private key 
>>> file
>>>     >
>>>     > -If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored 
>>> and
>>>     the string
>>>     > -contained in SWUPDATE_SIGN_TOOL is executed to perform the 
>>> signing.
>>>     > +3. Custom signing tool:
>>>     > +
>>>     > +  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
>>>     > +
>>>     > +  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that 
>>> needs
>>>     to be
>>>     > +    executed in order to perform the signing
>>>     > +
>>>     > +sw-description is signed and the signature is written to
>>>     sw-description.sig
>>>     > +which is included in the SWU file.
>>>     > +
>>>     > +Encrypted private keys are not currently supported since a 
>>> secure
>>>     > +mechanism must exist to provide the passphrase.
>>>     >
>>>     >  Maintainer
>>>     >  ----------
>>>     > @@ -51,5 +67,5 @@ When creating patches, please use something 
>>> like:
>>>     >
>>>     >      git format-patch -s --subject-prefix='meta-swupdate][PATCH'
>>>     <revision range>
>>>     >
>>>     > -Please use 'git send- email' to send the generated patches to 
>>> the ML
>>>     > +Please use 'git send-email' to send the generated patches to 
>>> the ML
>>>     >  to bypass changes from your mailer.
>>>     > diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
>>>     > index 44e4546..02db631 100644
>>>     > --- a/classes/swupdate.bbclass
>>>     > +++ b/classes/swupdate.bbclass
>>>     > @@ -1,5 +1,5 @@
>>>     >  # Copyright (C) 2015 Stefano Babic <sba...@denx.de 
>>> <javascript:>>
>>>     > -#
>>>     > +#
>>>     >  # Some parts from the patch class
>>>     >  #
>>>     >  # swupdate allows to generate a compound image for the
>>>     > @@ -14,7 +14,7 @@
>>>     >
>>>     >  S = "${WORKDIR}/${PN}"
>>>     >
>>>     > -DEPENDS += "${@ 'openssl-native' if 
>>> d.getVar('SWUPDATE_SIGNING',
>>>     True) == '1' else ''}"
>>>     > +DEPENDS += "${@ 'openssl-native' if 
>>> d.getVar('SWUPDATE_SIGNING',
>>>     True) else ''}"
>>>     >  IMAGE_DEPENDS ?= ""
>>>     >
>>>     >  def swupdate_is_hash_needed(s, filename):
>>>     > @@ -64,15 +64,23 @@ def swupdate_getdepends(d):
>>>     >          depstr += " " + dep + ":do_build"
>>>     >      return depstr
>>>     >
>>>     > +IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
>>>     > +
>>>     >  do_swuimage[dirs] = "${TOPDIR}"
>>>     > -do_swuimage[cleandirs] += "${S}"
>>>     > +do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
>>>     >  do_swuimage[umask] = "022"
>>>     > +SSTATETASKS += "do_swuimage"
>>>     > +SSTATE_SKIP_CREATION_task-swuimage = '1'
>>>     > +do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
>>>     > +do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
>>>     > +do_swuimage[stamp-extra-info] = "${MACHINE}"
>>>     >
>>>     >  do_configure[noexec] = "1"
>>>     >  do_compile[noexec] = "1"
>>>     >  do_install[noexec] = "1"
>>>     > +deltask do_populate_sysroot
>>>     >  do_package[noexec] = "1"
>>>     > -do_package_qa[noexec] = "1"
>>>     > +deltask do_package_qa
>>>     >  do_packagedata[noexec] = "1"
>>>     >  do_package_write_ipk[noexec] = "1"
>>>     >  do_package_write_deb[noexec] = "1"
>>>     > @@ -83,14 +91,6 @@ python () {
>>>     >      d.appendVarFlag('do_swuimage', 'depends', deps)
>>>     >  }
>>>     >
>>>     > -do_install () {
>>>     > -}
>>>     > -
>>>     > -do_createlink () {
>>>     > -    cd ${DEPLOY_DIR_IMAGE}
>>>     > -    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu
>>>     > -}
>>>     > -
>>>     >  python do_swuimage () {
>>>     >      import shutil
>>>     >
>>>     > @@ -101,7 +101,7 @@ python do_swuimage () {
>>>     >      fetch = bb.fetch2.Fetch([], d)
>>>     >      list_for_cpio = ["sw-description"]
>>>     >
>>>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>>>     > +    if d.getVar('SWUPDATE_SIGNING', True):
>>>     >          list_for_cpio.append('sw-description.sig')
>>>     >
>>>     >      for url in fetch.urls:
>>>     > @@ -115,6 +115,7 @@ python do_swuimage () {
>>>     >  # If they are not there, additional file can be added
>>>     >  # by fetching from URLs
>>>     >      deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
>>>     > +    imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
>>>     >
>>>     >      for image in images:
>>>     >          fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", 
>>> image,
>>>     True) or "").split()
>>>     > @@ -140,12 +141,20 @@ python do_swuimage () {
>>>     >              hash = swupdate_get_sha256(s, file)
>>>     >              swupdate_write_sha256(s, file, hash)
>>>     >
>>>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>>>     > -        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>>>     > -        if sign_tool:
>>>     > -            if os.system(sign_tool) != 0:
>>>     > -                bb.fatal("Failed to sign with %s" % 
>>> (sign_tool))
>>>     > -        else:
>>>     > +    signing = d.getVar('SWUPDATE_SIGNING', True)
>>>     > +    if signing == "1":
>>>     > +        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling
>>>     back to "RSA". It is advised to set it to "RSA" if using RSA 
>>> signing.')
>>>     > +        signing = "RSA"
>>>     > +    if signing:
>>>     > +        if signing == "CUSTOM":
>>>     > +            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>>>     > +            if sign_tool:
>>>     > +                ret = os.system(sign_tool)
>>>     > +                if ret != 0:
>>>     > +                    bb.fatal("Failed to sign with %s" % 
>>> (sign_tool))
>>>     > +            else:
>>>     > +                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not 
>>> given")
>>>     > +        elif signing == "RSA":
>>>     >              privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
>>>     >              if not privkey:
>>>     >                  bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
>>>     > @@ -163,13 +172,38 @@ python do_swuimage () {
>>>     >                  os.path.join(s, 'sw-description'))
>>>     >              if os.system(signcmd) != 0:
>>>     >                  bb.fatal("Failed to sign sw-description with 
>>> %s"
>>>     % (privkey))
>>>     > +        elif signing == "CMS":
>>>     > +            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
>>>     > +            if not cms_cert:
>>>     > +                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', True)
>>>     > +            if not cms_key:
>>>     > +                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))
>>>     > +            signcmd = "openssl cms -sign -in '%s' -out '%s'
>>>     -signer '%s' -inkey '%s' -outform DER -nosmimecap -binary" % (
>>>     > +                os.path.join(s, 'sw-description'),
>>>     > +                os.path.join(s, 'sw-description.sig'),
>>>     > +                cms_cert,
>>>     > +                cms_key)
>>>     > +            if os.system(signcmd) != 0:
>>>     > +                bb.fatal("Failed to sign sw-description with 
>>> %s"
>>>     % (privkey))
>>>     > +        else:
>>>     > +            bb.fatal("Unrecognized SWUPDATE_SIGNING 
>>> mechanism.");
>>>     >
>>>     > -    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>>>     $i;done | cpio -ov -H crc >' +
>>>     os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>>>     > +    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>>>     $i;done | cpio -ov -H crc >' +
>>>     os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>>>     >      os.system("cd " + s + ";" + line)
>>>     > +
>>>     > +    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' +
>>>     d.getVar('IMAGE_LINK_NAME', True) + '.swu'
>>>     > +    os.system("cd " + imgdeploydir + "; " + line)
>>>     >  }
>>>     >
>>>     >  COMPRESSIONTYPES = ""
>>>     >  PACKAGE_ARCH = "${MACHINE_ARCH}"
>>>     >
>>>     > -addtask do_swuimage after do_unpack before do_install
>>>     > -addtask do_createlink after do_swuimage before do_install
>>>     > +INHIBIT_DEFAULT_DEPS = "1"
>>>     > +EXCLUDE_FROM_WORLD = "1"
>>>     > +
>>>     > +addtask do_swuimage after do_unpack after
>>>     do_prepare_recipe_sysroot before do_build
>>>     >
>>>
>>>     Tested-by : Stefano Babic <sba...@denx.de <javascript:>>
>>>     Acked-by : Stefano Babic <sba...@denx.de <javascript:>>
>>>
>>>     This flows soon in -morty, thanks !
>>>
>>>     Best regards,
>>>     Stefano Babic
>>>
>>>     --
>>>     
>>> =====================================================================
>>>     DENX Software Engineering GmbH,      Managing Director: Wolfgang 
>>> Denk
>>>     HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, 
>>> Germany
>>>     Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email:
>>>     sba...@denx.de <javascript:>
>>>     
>>> =====================================================================
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "swupdate" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to swupdate+unsubscribe@googlegroups.com
>>> <mailto:swupdate+unsubscribe@googlegroups.com>.
>>> To post to this group, send email to swupdate@googlegroups.com
>>> <mailto:swupdate@googlegroups.com>.
>>> For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> =====================================================================
>> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>> Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
>> =====================================================================
Dmitri Toubelis Feb. 11, 2018, 7:11 p.m. UTC | #5
Got it, not a problem. The git version fails to compile in `morty` 
because of some dependencies that were introduced in later revisions but 
I can see how it may break the backward compatibility if swupdate.inc 
file is changed (one of the reasons I avoid includes myself). But it is 
not a biggie, I'm going to create a separate recipe for myself and I 
will send a patch to you later if you decide to include it anyway.

Regards,
-Dmitri

------ Original Message ------
From: "Stefano Babic" <sbabic@denx.de>
To: "Dmitri Toubelis" <dmitri.toubelis@litmusautomation.com>; "Stefano 
Babic" <sbabic@denx.de>; "swupdate@googlegroups.com" 
<swupdate@googlegroups.com>
Sent: 2018-02-11 1:09:12 PM
Subject: Re: [swupdate] [meta-swupdate][PATCH] Upgrade swupdate.bbclass 
in morty from master.

>Hi Dmitri,
>
>please do not drop the ML in your replies - thanks !
>
>On 11/02/2018 18:31, Dmitri Toubelis wrote:
>>What I mean is that the latest version of swupdate from morty does not
>>support CMS signatures yet, so the
>>`meta-swupdate/recipes-support/swupdate` recipe need to be upgraded as
>>well. The latest version in morty is 2017.01 and doesn't support CMS.
>>
>
>ok, got it. This happens with all packages. From a Yocto release to 
>next
>release, packages are updated to newer releases, fixing bugs and adding
>features. It is part of the game.
>
>However, adding a recipe in morty for latest release (2017.11) cannot 
>be
>accepted. This breaks all products using morty, or at least, a new 
>build
>will contain a different SWUpdate release. The policy in Yocto is to 
>fix
>bugs or security leak, but new features are available in new releases
>and are not backported.
>
>However, I have foreseen the case in SWUpdate using the _git version.
>swupdate_git is not chosen as default (see previous discussions in this
>ML), but it can be used to switch to last SWUpdate version. People
>requiring a new SWupdate version as the one in their release should set
>PREFERRED_VERSION_swupdate = "git", and set a SRCREV into an own
>.bbappend to set a specific version (if desired).
>
>Best regards,
>Stefano Babic
>
>>------ Original Message ------
>>From: "Stefano Babic" <sbabic@denx.de>
>>To: "Dmitri Toubelis" <dmitri.toubelis@litmusautomation.com>; 
>>"swupdate"
>><swupdate@googlegroups.com>
>>Sent: 2018-02-11 4:18:18 AM
>>Subject: Re: [swupdate] [meta-swupdate][PATCH] Upgrade 
>>swupdate.bbclass
>>in morty from master.
>>
>>>Hi Dmitri,
>>>
>>>On 11/02/2018 02:17, Dmitri Toubelis wrote:
>>>>It just occurred to me that CMS validation is not available in 
>>>>`morty`
>>>>so it looks like it would require upgrading
>>>>`meta-swupdate/recipes-support/swupdate` recipe.
>>>>
>>>>Do you have an easy way of doing this? Or would you prefer a patch?
>>>>
>>>
>>>I do not understand what you mind - I have already applied your patch
>>>into -morty.
>>>
>>>Best regards,
>>>Stefano Babic
>>>
>>>
>>>>-Dmitri
>>>>
>>>>On Thursday, February 8, 2018 at 1:39:37 PM UTC-5, Stefano Babic
>>>>wrote:
>>>>
>>>>     Hi Dmitri,
>>>>
>>>>     On 08/02/2018 05:27, Dmitri Toubelis wrote:
>>>>     > This commit brings the latest version of swupdate.bbclass from
>>>>     `master`
>>>>     > into `morty`. README file is also copied over. This adds 
>>>>support
>>>>for
>>>>     > CMS signing and few other conveniences to `morty`.
>>>>     >
>>>>     > Signed-off-by: Dmitri Toubelis 
>>>><dmitri....@litmusautomation.com
>>>>     <javascript:>>
>>>>     > ---
>>>>     >  README                   | 36 +++++++++++++++-------
>>>>     >  classes/swupdate.bbclass | 78
>>>>     ++++++++++++++++++++++++++++++++++--------------
>>>>     >  2 files changed, 82 insertions(+), 32 deletions(-)
>>>>     >
>>>>     > diff --git a/README b/README
>>>>     > index 2e50a72..df669f4 100644
>>>>     > --- a/README
>>>>     > +++ b/README
>>>>     > @@ -21,18 +21,34 @@ image filename) are replaced with the 
>>>>sha256
>>>>     hash of the image.
>>>>     >  SWU image signing
>>>>     >  ------------
>>>>     >
>>>>     > -To enable signing:
>>>>     > -    Set SWUPDATE_SIGNING = "1"
>>>>     > -    Set SWUPDATE_PRIVATE_KEY to the full path of private key
>>>>file
>>>>     > +There are 3 signing mechanisms supported by meta-swupdate at
>>>>the
>>>>     moment:
>>>>     >
>>>>     > -sw-description is signed with the private key and the 
>>>>signature
>>>>     is writen to
>>>>     > -sw-description.sig which is included in the SWU file.
>>>>     > +1. RSA signing:
>>>>     >
>>>>     > -Encrypted private keys are not currently supported since a
>>>>secure
>>>>     > -mechanism must exist to provide the passphrase.
>>>>     > +  * Set variable: `SWUPDATE_SIGNING = "RSA"`
>>>>     > +
>>>>     > +  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private 
>>>>key
>>>>file
>>>>     > +
>>>>     > +2. CMS signing:
>>>>     > +
>>>>     > +  * Set variable: `SWUPDATE_SIGNING = "CMS"`
>>>>     > +
>>>>     > +  * Set `SWUPDATE_CMS_CERT` to the full path of certificate
>>>>file
>>>>     > +
>>>>     > +  * Set `SWUPDATE_CMS_KEY ` to the full path of private key
>>>>file
>>>>     >
>>>>     > -If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored
>>>>and
>>>>     the string
>>>>     > -contained in SWUPDATE_SIGN_TOOL is executed to perform the
>>>>signing.
>>>>     > +3. Custom signing tool:
>>>>     > +
>>>>     > +  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
>>>>     > +
>>>>     > +  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that
>>>>needs
>>>>     to be
>>>>     > +    executed in order to perform the signing
>>>>     > +
>>>>     > +sw-description is signed and the signature is written to
>>>>     sw-description.sig
>>>>     > +which is included in the SWU file.
>>>>     > +
>>>>     > +Encrypted private keys are not currently supported since a
>>>>secure
>>>>     > +mechanism must exist to provide the passphrase.
>>>>     >
>>>>     >  Maintainer
>>>>     >  ----------
>>>>     > @@ -51,5 +67,5 @@ When creating patches, please use something
>>>>like:
>>>>     >
>>>>     >      git format-patch -s 
>>>>--subject-prefix='meta-swupdate][PATCH'
>>>>     <revision range>
>>>>     >
>>>>     > -Please use 'git send- email' to send the generated patches to
>>>>the ML
>>>>     > +Please use 'git send-email' to send the generated patches to
>>>>the ML
>>>>     >  to bypass changes from your mailer.
>>>>     > diff --git a/classes/swupdate.bbclass 
>>>>b/classes/swupdate.bbclass
>>>>     > index 44e4546..02db631 100644
>>>>     > --- a/classes/swupdate.bbclass
>>>>     > +++ b/classes/swupdate.bbclass
>>>>     > @@ -1,5 +1,5 @@
>>>>     >  # Copyright (C) 2015 Stefano Babic <sba...@denx.de
>>>><javascript:>>
>>>>     > -#
>>>>     > +#
>>>>     >  # Some parts from the patch class
>>>>     >  #
>>>>     >  # swupdate allows to generate a compound image for the
>>>>     > @@ -14,7 +14,7 @@
>>>>     >
>>>>     >  S = "${WORKDIR}/${PN}"
>>>>     >
>>>>     > -DEPENDS += "${@ 'openssl-native' if
>>>>d.getVar('SWUPDATE_SIGNING',
>>>>     True) == '1' else ''}"
>>>>     > +DEPENDS += "${@ 'openssl-native' if
>>>>d.getVar('SWUPDATE_SIGNING',
>>>>     True) else ''}"
>>>>     >  IMAGE_DEPENDS ?= ""
>>>>     >
>>>>     >  def swupdate_is_hash_needed(s, filename):
>>>>     > @@ -64,15 +64,23 @@ def swupdate_getdepends(d):
>>>>     >          depstr += " " + dep + ":do_build"
>>>>     >      return depstr
>>>>     >
>>>>     > +IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
>>>>     > +
>>>>     >  do_swuimage[dirs] = "${TOPDIR}"
>>>>     > -do_swuimage[cleandirs] += "${S}"
>>>>     > +do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
>>>>     >  do_swuimage[umask] = "022"
>>>>     > +SSTATETASKS += "do_swuimage"
>>>>     > +SSTATE_SKIP_CREATION_task-swuimage = '1'
>>>>     > +do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
>>>>     > +do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
>>>>     > +do_swuimage[stamp-extra-info] = "${MACHINE}"
>>>>     >
>>>>     >  do_configure[noexec] = "1"
>>>>     >  do_compile[noexec] = "1"
>>>>     >  do_install[noexec] = "1"
>>>>     > +deltask do_populate_sysroot
>>>>     >  do_package[noexec] = "1"
>>>>     > -do_package_qa[noexec] = "1"
>>>>     > +deltask do_package_qa
>>>>     >  do_packagedata[noexec] = "1"
>>>>     >  do_package_write_ipk[noexec] = "1"
>>>>     >  do_package_write_deb[noexec] = "1"
>>>>     > @@ -83,14 +91,6 @@ python () {
>>>>     >      d.appendVarFlag('do_swuimage', 'depends', deps)
>>>>     >  }
>>>>     >
>>>>     > -do_install () {
>>>>     > -}
>>>>     > -
>>>>     > -do_createlink () {
>>>>     > -    cd ${DEPLOY_DIR_IMAGE}
>>>>     > -    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu
>>>>     > -}
>>>>     > -
>>>>     >  python do_swuimage () {
>>>>     >      import shutil
>>>>     >
>>>>     > @@ -101,7 +101,7 @@ python do_swuimage () {
>>>>     >      fetch = bb.fetch2.Fetch([], d)
>>>>     >      list_for_cpio = ["sw-description"]
>>>>     >
>>>>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>>>>     > +    if d.getVar('SWUPDATE_SIGNING', True):
>>>>     >          list_for_cpio.append('sw-description.sig')
>>>>     >
>>>>     >      for url in fetch.urls:
>>>>     > @@ -115,6 +115,7 @@ python do_swuimage () {
>>>>     >  # If they are not there, additional file can be added
>>>>     >  # by fetching from URLs
>>>>     >      deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
>>>>     > +    imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
>>>>     >
>>>>     >      for image in images:
>>>>     >          fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES",
>>>>image,
>>>>     True) or "").split()
>>>>     > @@ -140,12 +141,20 @@ python do_swuimage () {
>>>>     >              hash = swupdate_get_sha256(s, file)
>>>>     >              swupdate_write_sha256(s, file, hash)
>>>>     >
>>>>     > -    if d.getVar('SWUPDATE_SIGNING', True) == '1':
>>>>     > -        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>>>>     > -        if sign_tool:
>>>>     > -            if os.system(sign_tool) != 0:
>>>>     > -                bb.fatal("Failed to sign with %s" %
>>>>(sign_tool))
>>>>     > -        else:
>>>>     > +    signing = d.getVar('SWUPDATE_SIGNING', True)
>>>>     > +    if signing == "1":
>>>>     > +        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, 
>>>>falling
>>>>     back to "RSA". It is advised to set it to "RSA" if using RSA
>>>>signing.')
>>>>     > +        signing = "RSA"
>>>>     > +    if signing:
>>>>     > +        if signing == "CUSTOM":
>>>>     > +            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
>>>>     > +            if sign_tool:
>>>>     > +                ret = os.system(sign_tool)
>>>>     > +                if ret != 0:
>>>>     > +                    bb.fatal("Failed to sign with %s" %
>>>>(sign_tool))
>>>>     > +            else:
>>>>     > +                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not
>>>>given")
>>>>     > +        elif signing == "RSA":
>>>>     >              privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
>>>>     >              if not privkey:
>>>>     >                  bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
>>>>     > @@ -163,13 +172,38 @@ python do_swuimage () {
>>>>     >                  os.path.join(s, 'sw-description'))
>>>>     >              if os.system(signcmd) != 0:
>>>>     >                  bb.fatal("Failed to sign sw-description with
>>>>%s"
>>>>     % (privkey))
>>>>     > +        elif signing == "CMS":
>>>>     > +            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
>>>>     > +            if not cms_cert:
>>>>     > +                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', True)
>>>>     > +            if not cms_key:
>>>>     > +                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))
>>>>     > +            signcmd = "openssl cms -sign -in '%s' -out '%s'
>>>>     -signer '%s' -inkey '%s' -outform DER -nosmimecap -binary" % (
>>>>     > +                os.path.join(s, 'sw-description'),
>>>>     > +                os.path.join(s, 'sw-description.sig'),
>>>>     > +                cms_cert,
>>>>     > +                cms_key)
>>>>     > +            if os.system(signcmd) != 0:
>>>>     > +                bb.fatal("Failed to sign sw-description with
>>>>%s"
>>>>     % (privkey))
>>>>     > +        else:
>>>>     > +            bb.fatal("Unrecognized SWUPDATE_SIGNING
>>>>mechanism.");
>>>>     >
>>>>     > -    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>>>>     $i;done | cpio -ov -H crc >' +
>>>>     os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>>>>     > +    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo
>>>>     $i;done | cpio -ov -H crc >' +
>>>>     os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
>>>>     >      os.system("cd " + s + ";" + line)
>>>>     > +
>>>>     > +    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' 
>>>>+
>>>>     d.getVar('IMAGE_LINK_NAME', True) + '.swu'
>>>>     > +    os.system("cd " + imgdeploydir + "; " + line)
>>>>     >  }
>>>>     >
>>>>     >  COMPRESSIONTYPES = ""
>>>>     >  PACKAGE_ARCH = "${MACHINE_ARCH}"
>>>>     >
>>>>     > -addtask do_swuimage after do_unpack before do_install
>>>>     > -addtask do_createlink after do_swuimage before do_install
>>>>     > +INHIBIT_DEFAULT_DEPS = "1"
>>>>     > +EXCLUDE_FROM_WORLD = "1"
>>>>     > +
>>>>     > +addtask do_swuimage after do_unpack after
>>>>     do_prepare_recipe_sysroot before do_build
>>>>     >
>>>>
>>>>     Tested-by : Stefano Babic <sba...@denx.de <javascript:>>
>>>>     Acked-by : Stefano Babic <sba...@denx.de <javascript:>>
>>>>
>>>>     This flows soon in -morty, thanks !
>>>>
>>>>     Best regards,
>>>>     Stefano Babic
>>>>
>>>>     --
>>>>
>>>>=====================================================================
>>>>     DENX Software Engineering GmbH,      Managing Director: Wolfgang
>>>>Denk
>>>>     HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
>>>>Germany
>>>>     Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email:
>>>>     sba...@denx.de <javascript:>
>>>>
>>>>=====================================================================
>>>>
>>>>--
>>>>You received this message because you are subscribed to the Google
>>>>Groups "swupdate" group.
>>>>To unsubscribe from this group and stop receiving emails from it, 
>>>>send
>>>>an email to swupdate+unsubscribe@googlegroups.com
>>>><mailto:swupdate+unsubscribe@googlegroups.com>.
>>>>To post to this group, send email to swupdate@googlegroups.com
>>>><mailto:swupdate@googlegroups.com>.
>>>>For more options, visit https://groups.google.com/d/optout.
>>>
>>>--
>>>=====================================================================
>>>DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>>>HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>>>Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
>>>=====================================================================
>
>--
>=====================================================================
>DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
>=====================================================================
diff mbox series

Patch

diff --git a/README b/README
index 2e50a72..df669f4 100644
--- a/README
+++ b/README
@@ -21,18 +21,34 @@  image filename) are replaced with the sha256 hash of the image.
 SWU image signing
 ------------
 
-To enable signing:
-    Set SWUPDATE_SIGNING = "1"
-    Set SWUPDATE_PRIVATE_KEY to the full path of private key file
+There are 3 signing mechanisms supported by meta-swupdate at the moment:
 
-sw-description is signed with the private key and the signature is writen to
-sw-description.sig which is included in the SWU file.
+1. RSA signing:
 
-Encrypted private keys are not currently supported since a secure 
-mechanism must exist to provide the passphrase.
+  * Set variable: `SWUPDATE_SIGNING = "RSA"`
+
+  * Set `SWUPDATE_PRIVATE_KEY` to the full path of private key file
+
+2. CMS signing:
+
+  * Set variable: `SWUPDATE_SIGNING = "CMS"`
+
+  * Set `SWUPDATE_CMS_CERT` to the full path of certificate file
+
+  * Set `SWUPDATE_CMS_KEY ` to the full path of private key file
 
-If SWUPDATE_SIGN_TOOL is set, SWUPDATE_PRIVATE_KEY is ignored and the string
-contained in SWUPDATE_SIGN_TOOL is executed to perform the signing.
+3. Custom signing tool:
+
+  * Set variable: `SWUPDATE_SIGNING = "CUSTOM"`
+
+  * Set variable `SWUPDATE_SIGN_TOOL' to custom string that needs to be
+    executed in order to perform the signing
+
+sw-description is signed and the signature is written to sw-description.sig
+which is included in the SWU file.
+
+Encrypted private keys are not currently supported since a secure
+mechanism must exist to provide the passphrase.
 
 Maintainer
 ----------
@@ -51,5 +67,5 @@  When creating patches, please use something like:
 
     git format-patch -s --subject-prefix='meta-swupdate][PATCH' <revision range>
 
-Please use 'git send- email' to send the generated patches to the ML
+Please use 'git send-email' to send the generated patches to the ML
 to bypass changes from your mailer.
diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
index 44e4546..02db631 100644
--- a/classes/swupdate.bbclass
+++ b/classes/swupdate.bbclass
@@ -1,5 +1,5 @@ 
 # Copyright (C) 2015 Stefano Babic <sbabic@denx.de>
-# 
+#
 # Some parts from the patch class
 #
 # swupdate allows to generate a compound image for the
@@ -14,7 +14,7 @@ 
 
 S = "${WORKDIR}/${PN}"
 
-DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) == '1' else ''}"
+DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
 IMAGE_DEPENDS ?= ""
 
 def swupdate_is_hash_needed(s, filename):
@@ -64,15 +64,23 @@  def swupdate_getdepends(d):
         depstr += " " + dep + ":do_build"
     return depstr
 
+IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
+
 do_swuimage[dirs] = "${TOPDIR}"
-do_swuimage[cleandirs] += "${S}"
+do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
 do_swuimage[umask] = "022"
+SSTATETASKS += "do_swuimage"
+SSTATE_SKIP_CREATION_task-swuimage = '1'
+do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
+do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
+do_swuimage[stamp-extra-info] = "${MACHINE}"
 
 do_configure[noexec] = "1"
 do_compile[noexec] = "1"
 do_install[noexec] = "1"
+deltask do_populate_sysroot
 do_package[noexec] = "1"
-do_package_qa[noexec] = "1"
+deltask do_package_qa
 do_packagedata[noexec] = "1"
 do_package_write_ipk[noexec] = "1"
 do_package_write_deb[noexec] = "1"
@@ -83,14 +91,6 @@  python () {
     d.appendVarFlag('do_swuimage', 'depends', deps)
 }
 
-do_install () {
-}
-
-do_createlink () {
-    cd ${DEPLOY_DIR_IMAGE}
-    ln -sf ${IMAGE_NAME}.swu ${IMAGE_LINK_NAME}.swu
-}
-
 python do_swuimage () {
     import shutil
 
@@ -101,7 +101,7 @@  python do_swuimage () {
     fetch = bb.fetch2.Fetch([], d)
     list_for_cpio = ["sw-description"]
 
-    if d.getVar('SWUPDATE_SIGNING', True) == '1':
+    if d.getVar('SWUPDATE_SIGNING', True):
         list_for_cpio.append('sw-description.sig')
 
     for url in fetch.urls:
@@ -115,6 +115,7 @@  python do_swuimage () {
 # If they are not there, additional file can be added
 # by fetching from URLs
     deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
+    imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
 
     for image in images:
         fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
@@ -140,12 +141,20 @@  python do_swuimage () {
             hash = swupdate_get_sha256(s, file)
             swupdate_write_sha256(s, file, hash)
 
-    if d.getVar('SWUPDATE_SIGNING', True) == '1':
-        sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
-        if sign_tool:
-            if os.system(sign_tool) != 0:
-                bb.fatal("Failed to sign with %s" % (sign_tool))
-        else:
+    signing = d.getVar('SWUPDATE_SIGNING', True)
+    if signing == "1":
+        bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling back to "RSA". It is advised to set it to "RSA" if using RSA signing.')
+        signing = "RSA"
+    if signing:
+        if signing == "CUSTOM":
+            sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
+            if sign_tool:
+                ret = os.system(sign_tool)
+                if ret != 0:
+                    bb.fatal("Failed to sign with %s" % (sign_tool))
+            else:
+                bb.fatal("Custom SWUPDATE_SIGN_TOOL is not given")
+        elif signing == "RSA":
             privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
             if not privkey:
                 bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
@@ -163,13 +172,38 @@  python do_swuimage () {
                 os.path.join(s, 'sw-description'))
             if os.system(signcmd) != 0:
                 bb.fatal("Failed to sign sw-description with %s" % (privkey))
+        elif signing == "CMS":
+            cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
+            if not cms_cert:
+                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', True)
+            if not cms_key:
+                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))
+            signcmd = "openssl cms -sign -in '%s' -out '%s' -signer '%s' -inkey '%s' -outform DER -nosmimecap -binary" % (
+                os.path.join(s, 'sw-description'),
+                os.path.join(s, 'sw-description.sig'),
+                cms_cert,
+                cms_key)
+            if os.system(signcmd) != 0:
+                bb.fatal("Failed to sign sw-description with %s" % (privkey))
+        else:
+            bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");
 
-    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(deploydir,d.getVar('IMAGE_NAME', True) + '.swu')
+    line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
     os.system("cd " + s + ";" + line)
+
+    line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
+    os.system("cd " + imgdeploydir + "; " + line)
 }
 
 COMPRESSIONTYPES = ""
 PACKAGE_ARCH = "${MACHINE_ARCH}"
 
-addtask do_swuimage after do_unpack before do_install
-addtask do_createlink after do_swuimage before do_install
+INHIBIT_DEFAULT_DEPS = "1"
+EXCLUDE_FROM_WORLD = "1"
+
+addtask do_swuimage after do_unpack after do_prepare_recipe_sysroot before do_build