Add feature of autosigning widgets 37/24137/1
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 27 Feb 2020 16:12:55 +0000 (17:12 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 28 Feb 2020 11:39:07 +0000 (12:39 +0100)
This adds the ability to automatically sign the
widgets that are packaged.

This is done by defining in the environment of
the packaging process the variables

  WGTPKG_AUTOSIGN_X=key-filepath[:cert-filepath]...

Where X is a number.

If such variable exist, signatures are generated
in the directory of the packaged or signed widget,
one for each variable, replacing any existing one.

Obviously, nothing is done if no such variable exist.

The generated signature file depends on X.

 - 0 is for file author-signature.xml
 - X is for file signature-X.xml

The program wgtpkg-pack automatically include that
behaviour by default. An option allows to remove it.

Bug-AGL: SPEC-2840

Change-Id: I00bc4a4d094f71b307e467f984f20d3d4cc3c7bd
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/main-wgtpkg-pack.c
src/wgtpkg-digsig.c
src/wgtpkg-digsig.h

index e448497..5e9a18f 100644 (file)
@@ -31,6 +31,7 @@
 #include "wgtpkg-files.h"
 #include "wgtpkg-workdir.h"
 #include "wgtpkg-zip.h"
 #include "wgtpkg-files.h"
 #include "wgtpkg-workdir.h"
 #include "wgtpkg-zip.h"
+#include "wgtpkg-digsig.h"
 
 const char appname[] = "wgtpkg-pack";
 
 
 const char appname[] = "wgtpkg-pack";
 
@@ -55,7 +56,9 @@ static void usage()
                "\n"
                "   -o wgtfile       the output widget file\n"
                "   -f               force overwriting\n"
                "\n"
                "   -o wgtfile       the output widget file\n"
                "   -f               force overwriting\n"
+               "   -N               no auto-sign"
                "   -q               quiet\n"
                "   -q               quiet\n"
+               "   -S               auto-sign"
                "   -v               verbose\n"
                "   -V               version\n"
                "\n",
                "   -v               verbose\n"
                "   -V               version\n"
                "\n",
@@ -67,7 +70,9 @@ static struct option options[] = {
        { "output",      required_argument, NULL, 'o' },
        { "force",       no_argument,       NULL, 'f' },
        { "help",        no_argument,       NULL, 'h' },
        { "output",      required_argument, NULL, 'o' },
        { "force",       no_argument,       NULL, 'f' },
        { "help",        no_argument,       NULL, 'h' },
+       { "no-auto-sign",no_argument,       NULL, 'N' },
        { "quiet",       no_argument,       NULL, 'q' },
        { "quiet",       no_argument,       NULL, 'q' },
+       { "auto-sign",   no_argument,       NULL, 'S' },
        { "verbose",     no_argument,       NULL, 'v' },
        { "version",     no_argument,       NULL, 'V' },
        { NULL, 0, NULL, 0 }
        { "verbose",     no_argument,       NULL, 'v' },
        { "version",     no_argument,       NULL, 'V' },
        { NULL, 0, NULL, 0 }
@@ -76,12 +81,13 @@ static struct option options[] = {
 /* install the widgets of the list */
 int main(int ac, char **av)
 {
 /* install the widgets of the list */
 int main(int ac, char **av)
 {
-       int i, force;
+       int i, force, autosign;
        char *wgtfile, *directory, *x;
        struct stat s;
 
        LOGUSER(appname);
 
        char *wgtfile, *directory, *x;
        struct stat s;
 
        LOGUSER(appname);
 
+       autosign = 1;
        force = 0;
        wgtfile = directory = NULL;
        for (;;) {
        force = 0;
        wgtfile = directory = NULL;
        for (;;) {
@@ -105,9 +111,15 @@ int main(int ac, char **av)
                case 'h':
                        usage();
                        return 0;
                case 'h':
                        usage();
                        return 0;
+               case 'N':
+                       autosign = 0;
+                       break;
                case 'V':
                        version();
                        return 0;
                case 'V':
                        version();
                        return 0;
+               case 'S':
+                       autosign = 1;
+                       break;
                case ':':
                        ERROR("missing argument");
                        return 1;
                case ':':
                        ERROR("missing argument");
                        return 1;
@@ -174,10 +186,12 @@ int main(int ac, char **av)
        if (set_workdir(".", 0))
                return 1;
 
        if (set_workdir(".", 0))
                return 1;
 
-
        if (fill_files())
                return 1;
 
        if (fill_files())
                return 1;
 
+       if (autosign && create_auto_digsig() < 0)
+               return 1;
+
        return !!zwrite(wgtfile);
 }
 
        return !!zwrite(wgtfile);
 }
 
index d190d23..94f1d28 100644 (file)
@@ -419,4 +419,92 @@ error:
        return rc;
 }
 
        return rc;
 }
 
+/* create a digital signature(s) from environment data */
+int create_auto_digsig()
+{
+       static const char envvar_prefix[] = "WGTPKG_AUTOSIGN_";
+       extern char **environ;
+
+       char **enviter;
+       char *var;
+       char *iter;
+       char *equal;
+       unsigned int num;
+       char *keyfile;
+       const char *certfiles[10];
+       int ncert;
+       int rc;
+       int i;
+
+       rc = 0;
+       /* enumerate environment variables */
+       enviter = environ;
+       while  (rc == 0 && (var = *enviter++) != NULL) {
+               /* check the prefix */
+               if (0 != strncmp(var, envvar_prefix, sizeof(envvar_prefix) - 1))
+                       continue; /* not an auto sign variable */
+               DEBUG("autosign found %s", var);
+
+               /* check the num */
+               iter = &var[sizeof(envvar_prefix) - 1];
+               if (*iter < '0' || *iter > '9') {
+                       ERROR("bad autosign key found: %s", var);
+                       rc = -1;
+                       continue;
+               }
+
+               /* compute the number */
+               num = (unsigned int)(*iter++ - '0');
+               while (*iter >= '0' && *iter <= '9')
+                       num = 10 * num + (unsigned int)(*iter++ - '0');
+
+               /* next char must be = */
+               if (*iter != '=' || !iter[1]) {
+                       /* it is not an error to have an empty autosign */
+                       WARNING("ignoring autosign key %.*s", (int)(iter - var), var);
+                       continue;
+               }
+
+               /* auto signing with num */
+               INFO("autosign key %u found", num);
+
+               /* compute key and certificates */
+               equal = iter++;
+               keyfile = iter;
+               *equal = 0;
+               ncert = 0;
+               while (ncert < (int)((sizeof certfiles / sizeof *certfiles) - 1)
+                               && (iter = strchr(iter, ':')) != NULL) {
+                       *iter++ = 0;
+                       certfiles[ncert++] = iter;
+               }
+               certfiles[ncert] = NULL;
+
+               /* check the parameters */
+               if (access(keyfile, R_OK) != 0) {
+                       ERROR("autosign %u can't access private key %s", num, keyfile);
+                       rc = -1;
+               }
+               for(i = 0 ; i < ncert ; i++) {
+                       if (access(certfiles[i], R_OK) != 0) {
+                               ERROR("autosign %u can't access certificate %s", num, certfiles[i]);
+                               rc = -1;
+                       }
+               }
+
+               /* sign now */
+               if (rc == 0) {
+                       rc = xmlsec_init();
+                       if (rc == 0) {
+                               rc = create_digsig(num, keyfile, certfiles);
+                       }
+               }
+
+               /* restore stolen chars */
+               while(ncert)
+                       *(char*)(certfiles[--ncert] - 1) = ':';
+               *equal = '=';
+       }
+       return rc;
+}
 
 
index defcfa1..a1cc32d 100644 (file)
@@ -26,3 +26,6 @@ extern int create_digsig(unsigned int index, const char *key, const char **certs
 /* check the signatures of the current directory */
 extern int check_all_signatures(int allow_none);
 
 /* check the signatures of the current directory */
 extern int check_all_signatures(int allow_none);
 
+/* create a digital signature(s) from environment data */
+extern int create_auto_digsig();
+