Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libjcat for openSUSE:Factory checked 
in at 2022-04-22 21:52:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libjcat (Old)
 and      /work/SRC/openSUSE:Factory/.libjcat.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libjcat"

Fri Apr 22 21:52:44 2022 rev:7 rq:970783 version:0.1.10

Changes:
--------
--- /work/SRC/openSUSE:Factory/libjcat/libjcat.changes  2022-01-05 
13:39:28.829512741 +0100
+++ /work/SRC/openSUSE:Factory/.libjcat.new.1538/libjcat.changes        
2022-04-22 21:53:08.206729596 +0200
@@ -1,0 +2,10 @@
+Sun Apr 10 13:27:31 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 0.1.10:
+  - Add ED25519 support (Richard Hughes)
+  - Define three more types used for the firmware transparency log (Richard 
Hughes)
+  - Include the pkgconfig variables in the subproject dependency (Richard 
Hughes)
+  - Drop the use of setuptools in the test script for regenerating ld version 
file (Eli Schwartz)
+  - Use the correct lookup method for the python3 script interpreter (Eli 
Schwartz)
+
+-------------------------------------------------------------------

Old:
----
  libjcat-0.1.9.tar.gz

New:
----
  libjcat-0.1.10.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libjcat.spec ++++++
--- /var/tmp/diff_new_pack.wpUQxk/_old  2022-04-22 21:53:08.714730175 +0200
+++ /var/tmp/diff_new_pack.wpUQxk/_new  2022-04-22 21:53:08.718730179 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libjcat
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %define sover 1
 
 Name:           libjcat
-Version:        0.1.9
+Version:        0.1.10
 Release:        0
 Summary:        Library for reading and writing gzip-compressed JSON catalog 
files
 License:        LGPL-2.1-or-later

++++++ libjcat-0.1.9.tar.gz -> libjcat-0.1.10.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/NEWS new/libjcat-0.1.10/NEWS
--- old/libjcat-0.1.9/NEWS      2021-11-28 16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/NEWS     2022-02-16 16:55:31.000000000 +0100
@@ -1,3 +1,16 @@
+Version 0.1.10
+~~~~~~~~~~~~~~
+Released: 2022-02-16
+
+New Features:
+ - Add ED25519 support (Richard Hughes)
+ - Define three more types used for the firmware transparency log (Richard 
Hughes)
+
+Bugfixes:
+ - Include the pkgconfig variables in the subproject dependency (Richard 
Hughes)
+ - Drop the use of setuptools in the test script for regenerating ld version 
file (Eli Schwartz)
+ - Use the correct lookup method for the python3 script interpreter (Eli 
Schwartz)
+
 Version 0.1.9
 ~~~~~~~~~~~~~
 Released: 2021-11-28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/RELEASE new/libjcat-0.1.10/RELEASE
--- old/libjcat-0.1.9/RELEASE   2021-11-28 16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/RELEASE  2022-02-16 16:55:31.000000000 +0100
@@ -2,11 +2,11 @@
 
 1. Write NEWS entries for libjcat in the same format as usual.
 
-git shortlog 0.1.8.. | grep -i -v trivial | grep -v Merge > NEWS.new
+git shortlog 0.1.9.. | grep -i -v trivial | grep -v Merge > NEWS.new
 
-Version 0.1.9
-~~~~~~~~~~~~~
-Released: 2021-xx-xx
+Version 0.1.10
+~~~~~~~~~~~~~~
+Released: 202-xx-xx
 
 New Features:
 Bugfixes:
@@ -15,17 +15,14 @@
 Commit changes to git:
 
 # MAKE SURE THESE ARE CORRECT
-export release_ver="0.1.9"
+export release_ver="0.1.10"
 
 git commit -a -m "Release libjcat ${release_ver}"
 git tag -s -f -m "Release libjcat ${release_ver}" "${release_ver}"
+ninja dist
 git push --tags
 git push
 
-Generate the tarball:
-
-ninja dist
-
 Generate the additional verification metadata
 
 gpg -b -a meson-dist/libjcat-${release_ver}.tar.xz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/contrib/generate-version-script.py 
new/libjcat-0.1.10/contrib/generate-version-script.py
--- old/libjcat-0.1.9/contrib/generate-version-script.py        2021-11-28 
16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/contrib/generate-version-script.py       2022-02-16 
16:55:31.000000000 +0100
@@ -6,15 +6,19 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 import sys
+import argparse
 import xml.etree.ElementTree as ET
 
-from pkg_resources import parse_version
+XMLNS = "{http://www.gtk.org/introspection/core/1.0}";
+XMLNS_C = "{http://www.gtk.org/introspection/c/1.0}";
+
+
+def parse_version(ver):
+    return tuple(map(int, ver.split(".")))
 
-XMLNS = '{http://www.gtk.org/introspection/core/1.0}'
-XMLNS_C = '{http://www.gtk.org/introspection/c/1.0}'
 
 def usage(return_code):
-    """ print usage and exit with the supplied return code """
+    """print usage and exit with the supplied return code"""
     if return_code == 0:
         out = sys.stdout
     else:
@@ -22,19 +26,25 @@
     out.write("usage: %s <NAME> <INPUT> <OUTPUT>\n" % sys.argv[0])
     sys.exit(return_code)
 
+
 class LdVersionScript:
-    """ Rasterize some text """
+    """Rasterize some text"""
 
     def __init__(self, library_name):
         self.library_name = library_name
         self.releases = {}
+        self.overrides = {}
 
     def _add_node(self, node):
-        identifier = node.attrib[XMLNS_C + 'identifier']
-        if 'version' not in node.attrib:
-            print('No version for', identifier)
+        identifier = node.attrib[XMLNS_C + "identifier"]
+        introspectable = int(node.get("introspectable", 1))
+        version = node.get("version", None)
+        if introspectable and not version:
+            print("No version for", identifier)
             sys.exit(1)
-        version = node.attrib['version']
+        if not version:
+            return None
+        version = node.attrib["version"]
         if version not in self.releases:
             self.releases[version] = []
         release = self.releases[version]
@@ -45,42 +55,48 @@
     def _add_cls(self, cls):
 
         # add all class functions
-        for node in cls.findall(XMLNS + 'function'):
+        for node in cls.findall(XMLNS + "function"):
             self._add_node(node)
 
         # choose the lowest version method for the _get_type symbol
         version_lowest = None
-        if '{http://www.gtk.org/introspection/glib/1.0}get-type' not in 
cls.attrib:
-            return
-        type_name = 
cls.attrib['{http://www.gtk.org/introspection/glib/1.0}get-type']
 
         # add all class methods
-        for node in cls.findall(XMLNS + 'method'):
+        for node in cls.findall(XMLNS + "method"):
             version_tmp = self._add_node(node)
             if version_tmp:
-                if not version_lowest or parse_version(version_tmp) < 
parse_version(version_lowest):
+                if not version_lowest or parse_version(version_tmp) < 
parse_version(
+                    version_lowest
+                ):
                     version_lowest = version_tmp
 
         # add the constructor
-        for node in cls.findall(XMLNS + 'constructor'):
+        for node in cls.findall(XMLNS + "constructor"):
             version_tmp = self._add_node(node)
             if version_tmp:
-                if not version_lowest or parse_version(version_tmp) < 
parse_version(version_lowest):
+                if not version_lowest or parse_version(version_tmp) < 
parse_version(
+                    version_lowest
+                ):
                     version_lowest = version_tmp
 
+        if "{http://www.gtk.org/introspection/glib/1.0}get-type"; not in 
cls.attrib:
+            return
+        type_name = 
cls.attrib["{http://www.gtk.org/introspection/glib/1.0}get-type";]
+
         # finally add the get_type symbol
-        if version_lowest:
-            self.releases[version_lowest].append(type_name)
+        version = self.overrides.get(type_name, version_lowest)
+        if version:
+            self.releases[version].append(type_name)
 
     def import_gir(self, filename):
         tree = ET.parse(filename)
         root = tree.getroot()
-        for ns in root.findall(XMLNS + 'namespace'):
-            for node in ns.findall(XMLNS + 'function'):
+        for ns in root.findall(XMLNS + "namespace"):
+            for node in ns.findall(XMLNS + "function"):
                 self._add_node(node)
-            for cls in ns.findall(XMLNS + 'record'):
+            for cls in ns.findall(XMLNS + "record"):
                 self._add_cls(cls)
-            for cls in ns.findall(XMLNS + 'class'):
+            for cls in ns.findall(XMLNS + "class"):
                 self._add_cls(cls)
 
     def render(self):
@@ -91,28 +107,36 @@
             versions.append(version)
 
         # output the version data to a file
-        verout = '# generated automatically, do not edit!\n'
+        verout = "# generated automatically, do not edit!\n"
         oldversion = None
         for version in sorted(versions, key=parse_version):
             symbols = sorted(self.releases[version])
-            verout += '\n%s_%s {\n' % (self.library_name, version)
-            verout += '  global:\n'
+            verout += "\n%s_%s {\n" % (self.library_name, version)
+            verout += "  global:\n"
             for symbol in symbols:
-                verout += '    %s;\n' % symbol
-            verout += '  local: *;\n'
+                verout += "    %s;\n" % symbol
+            verout += "  local: *;\n"
             if oldversion:
-                verout += '} %s_%s;\n' % (self.library_name, oldversion)
+                verout += "} %s_%s;\n" % (self.library_name, oldversion)
             else:
-                verout += '};\n'
+                verout += "};\n"
             oldversion = version
         return verout
 
-if __name__ == '__main__':
-    if {'-?', '--help', '--usage'}.intersection(set(sys.argv)):
-        usage(0)
-    if len(sys.argv) != 4:
+
+if __name__ == "__main__":
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "-r", "--override", action="append", nargs=2, metavar=("symbol", 
"version")
+    )
+    args, argv = parser.parse_known_args()
+    if len(argv) != 3:
         usage(1)
 
-    ld = LdVersionScript(library_name=sys.argv[1])
-    ld.import_gir(sys.argv[2])
-    open(sys.argv[3], 'w').write(ld.render())
+    ld = LdVersionScript(library_name=argv[0])
+    if args.override:
+        for override_symbol, override_version in args.override:
+            ld.overrides[override_symbol] = override_version
+    ld.import_gir(argv[1])
+    open(argv[2], "w").write(ld.render())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libjcat-0.1.9/data/tests/colorhug/firmware.bin.ed25519 
new/libjcat-0.1.10/data/tests/colorhug/firmware.bin.ed25519
--- old/libjcat-0.1.9/data/tests/colorhug/firmware.bin.ed25519  1970-01-01 
01:00:00.000000000 +0100
+++ new/libjcat-0.1.10/data/tests/colorhug/firmware.bin.ed25519 2022-02-16 
16:55:31.000000000 +0100
@@ -0,0 +1,2 @@
+?.?]?)???g?j??? ?^?Q??qR?
+o?A???*??Ik?????????%??yQZ??
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/data/tests/pki/test.ed25519 
new/libjcat-0.1.10/data/tests/pki/test.ed25519
--- old/libjcat-0.1.9/data/tests/pki/test.ed25519       1970-01-01 
01:00:00.000000000 +0100
+++ new/libjcat-0.1.10/data/tests/pki/test.ed25519      2022-02-16 
16:55:31.000000000 +0100
@@ -0,0 +1 @@
+?V?6??????T?3????g,?????pF??
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/data/tests/secret.ed25519 
new/libjcat-0.1.10/data/tests/secret.ed25519
--- old/libjcat-0.1.9/data/tests/secret.ed25519 1970-01-01 01:00:00.000000000 
+0100
+++ new/libjcat-0.1.10/data/tests/secret.ed25519        2022-02-16 
16:55:31.000000000 +0100
@@ -0,0 +1 @@
+M??O?8?+?5???|?t?\B?\j???7?????????l
?S?N?v?????-a?'c~????
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-blob.c 
new/libjcat-0.1.10/libjcat/jcat-blob.c
--- old/libjcat-0.1.9/libjcat/jcat-blob.c       2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-blob.c      2022-02-16 16:55:31.000000000 
+0100
@@ -67,6 +67,16 @@
                return JCAT_BLOB_KIND_SHA256;
        if (g_strcmp0(kind, "sha1") == 0)
                return JCAT_BLOB_KIND_SHA1;
+       if (g_strcmp0(kind, "bt-manifest") == 0)
+               return JCAT_BLOB_KIND_BT_MANIFEST;
+       if (g_strcmp0(kind, "bt-checkpoint") == 0)
+               return JCAT_BLOB_KIND_BT_CHECKPOINT;
+       if (g_strcmp0(kind, "bt-inclusion-proof") == 0)
+               return JCAT_BLOB_KIND_BT_INCLUSION_PROOF;
+       if (g_strcmp0(kind, "bt-verifier") == 0)
+               return JCAT_BLOB_KIND_BT_VERIFIER;
+       if (g_strcmp0(kind, "ed25519") == 0)
+               return JCAT_BLOB_KIND_ED25519;
        return JCAT_BLOB_KIND_UNKNOWN;
 }
 
@@ -91,6 +101,16 @@
                return "sha256";
        if (kind == JCAT_BLOB_KIND_SHA1)
                return "sha1";
+       if (kind == JCAT_BLOB_KIND_BT_MANIFEST)
+               return "bt-manifest";
+       if (kind == JCAT_BLOB_KIND_BT_CHECKPOINT)
+               return "bt-checkpoint";
+       if (kind == JCAT_BLOB_KIND_BT_INCLUSION_PROOF)
+               return "bt-inclusion-proof";
+       if (kind == JCAT_BLOB_KIND_BT_VERIFIER)
+               return "bt-verifier";
+       if (kind == JCAT_BLOB_KIND_ED25519)
+               return "ed25519";
        return NULL;
 }
 
@@ -115,6 +135,16 @@
                return "sha256";
        if (kind == JCAT_BLOB_KIND_SHA1)
                return "sha1";
+       if (kind == JCAT_BLOB_KIND_BT_MANIFEST)
+               return "btmanifest";
+       if (kind == JCAT_BLOB_KIND_BT_CHECKPOINT)
+               return "btcheckpoint";
+       if (kind == JCAT_BLOB_KIND_BT_INCLUSION_PROOF)
+               return "btinclusionproof";
+       if (kind == JCAT_BLOB_KIND_BT_VERIFIER)
+               return "btverifier";
+       if (kind == JCAT_BLOB_KIND_ED25519)
+               return "ed25519";
        return NULL;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-blob.h 
new/libjcat-0.1.10/libjcat/jcat-blob.h
--- old/libjcat-0.1.9/libjcat/jcat-blob.h       2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-blob.h      2022-02-16 16:55:31.000000000 
+0100
@@ -19,6 +19,11 @@
  * @JCAT_BLOB_KIND_GPG:                        GPG detached signature
  * @JCAT_BLOB_KIND_PKCS7:              PKCS-7 detached signature
  * @JCAT_BLOB_KIND_SHA1:               SHA-1 checksum
+ * @JCAT_BLOB_KIND_BT_MANIFEST:                Binary transparency manifest
+ * @JCAT_BLOB_KIND_BT_CHECKPOINT:      Binary transparency checkpoint
+ * @JCAT_BLOB_KIND_BT_INCLUSION_PROOF: Binary transparency inclusion proof
+ * @JCAT_BLOB_KIND_BT_VERIFIER:                Binary transparency verifier
+ * @JCAT_BLOB_KIND_ED25519:            ED25519 signature
  *
  * The kind of blob stored as a signature on the item.
  **/
@@ -28,6 +33,11 @@
        JCAT_BLOB_KIND_GPG,
        JCAT_BLOB_KIND_PKCS7,
        JCAT_BLOB_KIND_SHA1,
+       JCAT_BLOB_KIND_BT_MANIFEST,        /* Since: 0.1.9 */
+       JCAT_BLOB_KIND_BT_CHECKPOINT,      /* Since: 0.1.9 */
+       JCAT_BLOB_KIND_BT_INCLUSION_PROOF, /* Since: 0.1.9 */
+       JCAT_BLOB_KIND_BT_VERIFIER,        /* Since: 0.1.9 */
+       JCAT_BLOB_KIND_ED25519,            /* Since: 0.1.9 */
        /*< private >*/
        JCAT_BLOB_KIND_LAST
 } JcatBlobKind;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-context.c 
new/libjcat-0.1.10/libjcat/jcat-context.c
--- old/libjcat-0.1.9/libjcat/jcat-context.c    2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-context.c   2022-02-16 16:55:31.000000000 
+0100
@@ -19,6 +19,9 @@
 #ifdef ENABLE_PKCS7
 #include "jcat-pkcs7-engine.h"
 #endif
+#ifdef ENABLE_ED25519
+#include "jcat-ed25519-engine.h"
+#endif
 
 typedef struct {
        GPtrArray *engines;
@@ -63,6 +66,9 @@
 #ifdef ENABLE_PKCS7
        g_ptr_array_add(priv->engines, jcat_pkcs7_engine_new(self));
 #endif
+#ifdef ENABLE_ED25519
+       g_ptr_array_add(priv->engines, jcat_ed25519_engine_new(self));
+#endif
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-ed25519-engine.c 
new/libjcat-0.1.10/libjcat/jcat-ed25519-engine.c
--- old/libjcat-0.1.9/libjcat/jcat-ed25519-engine.c     1970-01-01 
01:00:00.000000000 +0100
+++ new/libjcat-0.1.10/libjcat/jcat-ed25519-engine.c    2022-02-16 
16:55:31.000000000 +0100
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2021 Richard Hughes <[email protected]>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "config.h"
+
+#include <nettle/eddsa.h>
+#include <gnutls/crypto.h>
+
+#include "jcat-common-private.h"
+#include "jcat-ed25519-engine.h"
+#include "jcat-engine-private.h"
+
+struct _JcatEd25519Engine {
+       JcatEngine parent_instance;
+       GPtrArray *pubkeys; /* of Ed25519Key */
+};
+
+typedef unsigned char Ed25519Key[ED25519_KEY_SIZE];
+typedef unsigned char Ed25519Sig[ED25519_SIGNATURE_SIZE];
+
+G_DEFINE_TYPE(JcatEd25519Engine, jcat_ed25519_engine, JCAT_TYPE_ENGINE)
+
+static GBytes *
+jcat_ed25519_sig_to_bytes(const Ed25519Sig privkey)
+{
+       return g_bytes_new(privkey, sizeof(Ed25519Sig));
+}
+
+static gboolean
+jcat_ed25519_sig_from_bytes(GBytes *blob, Ed25519Sig privkey, GError **error)
+{
+       if (g_bytes_get_size(blob) != sizeof(Ed25519Sig)) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_DATA,
+                                   "invalid privkey size");
+               return FALSE;
+       }
+       memcpy(privkey, g_bytes_get_data(blob, NULL), sizeof(Ed25519Sig));
+       return TRUE;
+}
+
+static GBytes *
+jcat_ed25519_key_to_bytes(const Ed25519Key pubkey)
+{
+       return g_bytes_new(pubkey, sizeof(Ed25519Key));
+}
+
+static gboolean
+jcat_ed25519_key_from_bytes(GBytes *blob, Ed25519Key pubkey, GError **error)
+{
+       if (g_bytes_get_size(blob) != sizeof(Ed25519Key)) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_DATA,
+                                   "invalid pubkey size");
+               return FALSE;
+       }
+       memcpy(pubkey, g_bytes_get_data(blob, NULL), sizeof(Ed25519Key));
+       return TRUE;
+}
+
+static gboolean
+jcat_ed25519_engine_add_public_key_raw(JcatEngine *engine, GBytes *blob, 
GError **error)
+{
+       JcatEd25519Engine *self = JCAT_ED25519_ENGINE(engine);
+       g_autofree Ed25519Key *pubkey = g_new0(Ed25519Key, 1);
+       if (!jcat_ed25519_key_from_bytes(blob, *pubkey, error))
+               return FALSE;
+       g_ptr_array_add(self->pubkeys, g_steal_pointer(&pubkey));
+       return TRUE;
+}
+
+static gboolean
+jcat_ed25519_engine_add_public_key(JcatEngine *engine, const gchar *filename, 
GError **error)
+{
+       g_autoptr(GBytes) blob = NULL;
+
+       /* ignore */
+       if (!g_str_has_suffix(filename, ".ed25519"))
+               return TRUE;
+
+       blob = jcat_get_contents_bytes(filename, error);
+       if (blob == NULL)
+               return FALSE;
+       return jcat_ed25519_engine_add_public_key_raw(engine, blob, error);
+}
+
+static JcatResult *
+jcat_ed25519_engine_pubkey_verify(JcatEngine *engine,
+                                 GBytes *blob,
+                                 GBytes *blob_signature,
+                                 JcatVerifyFlags flags,
+                                 GError **error)
+{
+       JcatEd25519Engine *self = JCAT_ED25519_ENGINE(engine);
+       Ed25519Sig sig = {0};
+
+       /* sanity check */
+       if (self->pubkeys->len == 0) {
+               g_set_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "no 
keys in keyring");
+               return NULL;
+       }
+       if (!jcat_ed25519_sig_from_bytes(blob_signature, sig, error))
+               return NULL;
+
+       /* verifies against any of the public keys */
+       for (guint i = 0; i < self->pubkeys->len; i++) {
+               Ed25519Key *pubkey = g_ptr_array_index(self->pubkeys, i);
+               if (ed25519_sha512_verify(*pubkey,
+                                         g_bytes_get_size(blob),
+                                         g_bytes_get_data(blob, NULL),
+                                         sig) != 0) {
+                       return JCAT_RESULT(g_object_new(JCAT_TYPE_RESULT, 
"engine", engine, NULL));
+               }
+       }
+
+       /* nothing found */
+       g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed 
to verify data");
+       return NULL;
+}
+
+static JcatBlob *
+jcat_ed25519_engine_pubkey_sign(JcatEngine *engine,
+                               GBytes *blob,
+                               GBytes *blob_cert,
+                               GBytes *blob_privkey,
+                               JcatSignFlags flags,
+                               GError **error)
+{
+       Ed25519Key pubkey = {0};
+       Ed25519Sig privkey = {0};
+       Ed25519Sig sig = {0};
+       g_autoptr(GBytes) blob_sig = NULL;
+
+       /* nothing to do */
+       if (g_bytes_get_size(blob) == 0) {
+               g_set_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, 
"nothing to do");
+               return NULL;
+       }
+
+       /* load */
+       if (!jcat_ed25519_sig_from_bytes(blob_privkey, privkey, error))
+               return NULL;
+       if (!jcat_ed25519_key_from_bytes(blob_cert, pubkey, error))
+               return NULL;
+
+       /* simple */
+       ed25519_sha512_sign(pubkey,
+                           privkey,
+                           g_bytes_get_size(blob),
+                           g_bytes_get_data(blob, NULL),
+                           sig);
+       blob_sig = jcat_ed25519_sig_to_bytes(sig);
+       return jcat_blob_new(JCAT_BLOB_KIND_ED25519, blob_sig);
+}
+
+static JcatResult *
+jcat_ed25519_engine_self_verify(JcatEngine *engine,
+                               GBytes *blob,
+                               GBytes *blob_signature,
+                               JcatVerifyFlags flags,
+                               GError **error)
+{
+       Ed25519Key pubkey = {0};
+       Ed25519Sig sig = {0};
+       const gchar *keyring_path = jcat_engine_get_keyring_path(engine);
+       g_autofree gchar *fn_pubkey = NULL;
+       g_autoptr(GBytes) blob_pubkey = NULL;
+
+       fn_pubkey = g_build_filename(keyring_path, "pki", "public.ed25519", 
NULL);
+       blob_pubkey = jcat_get_contents_bytes(fn_pubkey, error);
+       if (blob_pubkey == NULL)
+               return NULL;
+       if (!jcat_ed25519_key_from_bytes(blob_pubkey, pubkey, error))
+               return NULL;
+       if (!jcat_ed25519_sig_from_bytes(blob_signature, sig, error))
+               return NULL;
+       if (ed25519_sha512_verify(pubkey,
+                                 g_bytes_get_size(blob),
+                                 g_bytes_get_data(blob, NULL),
+                                 sig) == 0) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_DATA,
+                                   "failed to verify data");
+               return NULL;
+       }
+
+       /* success */
+       return JCAT_RESULT(g_object_new(JCAT_TYPE_RESULT, "engine", engine, 
NULL));
+}
+
+static JcatBlob *
+jcat_ed25519_engine_self_sign(JcatEngine *engine, GBytes *blob, JcatSignFlags 
flags, GError **error)
+{
+       Ed25519Key pubkey = {0};
+       Ed25519Sig privkey = {0};
+       Ed25519Sig sig = {0};
+       const gchar *keyring_path = jcat_engine_get_keyring_path(engine);
+       g_autofree gchar *fn_privkey = NULL;
+       g_autofree gchar *fn_pubkey = NULL;
+       g_autoptr(GBytes) blob_privkey = NULL;
+       g_autoptr(GBytes) blob_pubkey = NULL;
+       g_autoptr(GBytes) blob_sig = NULL;
+
+       /* check keypair exists, otherwise generate and save */
+       fn_privkey = g_build_filename(keyring_path, "pki", "secret.ed25519", 
NULL);
+       fn_pubkey = g_build_filename(keyring_path, "pki", "public.ed25519", 
NULL);
+       if (!g_file_test(fn_privkey, G_FILE_TEST_EXISTS)) {
+               gint rc;
+
+               /* randomize contents */
+               rc = gnutls_rnd(GNUTLS_RND_KEY, privkey, sizeof(Ed25519Sig));
+               if (rc < 0) {
+                       g_set_error(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_INVALID_DATA,
+                                   "failed to generate private key: %s [%i]",
+                                   gnutls_strerror(rc),
+                                   rc);
+                       return NULL;
+               }
+               ed25519_sha512_public_key(pubkey, privkey);
+               if (!jcat_mkdir_parent(fn_privkey, error))
+                       return NULL;
+               blob_privkey = jcat_ed25519_sig_to_bytes(privkey);
+               if (!jcat_set_contents_bytes(fn_privkey, blob_privkey, error))
+                       return NULL;
+               blob_pubkey = jcat_ed25519_key_to_bytes(pubkey);
+               if (!jcat_set_contents_bytes(fn_pubkey, blob_pubkey, error))
+                       return NULL;
+       } else {
+               blob_privkey = jcat_get_contents_bytes(fn_privkey, error);
+               if (blob_privkey == NULL)
+                       return NULL;
+               if (!jcat_ed25519_sig_from_bytes(blob_privkey, privkey, error))
+                       return NULL;
+               blob_pubkey = jcat_get_contents_bytes(fn_pubkey, error);
+               if (blob_pubkey == NULL)
+                       return NULL;
+               if (!jcat_ed25519_key_from_bytes(blob_pubkey, pubkey, error))
+                       return NULL;
+       }
+
+       /* simple */
+       ed25519_sha512_sign(pubkey,
+                           privkey,
+                           g_bytes_get_size(blob),
+                           g_bytes_get_data(blob, NULL),
+                           sig);
+       blob_sig = jcat_ed25519_sig_to_bytes(sig);
+       return jcat_blob_new(JCAT_BLOB_KIND_ED25519, blob_sig);
+}
+
+static void
+jcat_ed25519_engine_finalize(GObject *object)
+{
+       JcatEd25519Engine *self = JCAT_ED25519_ENGINE(object);
+       g_ptr_array_unref(self->pubkeys);
+       G_OBJECT_CLASS(jcat_ed25519_engine_parent_class)->finalize(object);
+}
+
+static void
+jcat_ed25519_engine_class_init(JcatEd25519EngineClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS(klass);
+       JcatEngineClass *klass_app = JCAT_ENGINE_CLASS(klass);
+       klass_app->add_public_key = jcat_ed25519_engine_add_public_key;
+       klass_app->add_public_key_raw = jcat_ed25519_engine_add_public_key_raw;
+       klass_app->pubkey_verify = jcat_ed25519_engine_pubkey_verify;
+       klass_app->pubkey_sign = jcat_ed25519_engine_pubkey_sign;
+       klass_app->self_verify = jcat_ed25519_engine_self_verify;
+       klass_app->self_sign = jcat_ed25519_engine_self_sign;
+       object_class->finalize = jcat_ed25519_engine_finalize;
+}
+
+static void
+jcat_ed25519_engine_init(JcatEd25519Engine *self)
+{
+       self->pubkeys = g_ptr_array_new_with_free_func(g_free);
+}
+
+JcatEngine *
+jcat_ed25519_engine_new(JcatContext *context)
+{
+       g_return_val_if_fail(JCAT_IS_CONTEXT(context), NULL);
+       return JCAT_ENGINE(g_object_new(JCAT_TYPE_ED25519_ENGINE,
+                                       "context",
+                                       context,
+                                       "kind",
+                                       JCAT_BLOB_KIND_ED25519,
+                                       "method",
+                                       JCAT_BLOB_METHOD_SIGNATURE,
+                                       NULL));
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-ed25519-engine.h 
new/libjcat-0.1.10/libjcat/jcat-ed25519-engine.h
--- old/libjcat-0.1.9/libjcat/jcat-ed25519-engine.h     1970-01-01 
01:00:00.000000000 +0100
+++ new/libjcat-0.1.10/libjcat/jcat-ed25519-engine.h    2022-02-16 
16:55:31.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2021 Richard Hughes <[email protected]>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#pragma once
+
+#include "jcat-context.h"
+#include "jcat-engine.h"
+
+#define JCAT_TYPE_ED25519_ENGINE (jcat_ed25519_engine_get_type())
+
+G_DECLARE_FINAL_TYPE(JcatEd25519Engine, jcat_ed25519_engine, JCAT, 
ED25519_ENGINE, JcatEngine)
+
+JcatEngine *
+jcat_ed25519_engine_new(JcatContext *context);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-engine.c 
new/libjcat-0.1.10/libjcat/jcat-engine.c
--- old/libjcat-0.1.9/libjcat/jcat-engine.c     2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-engine.c    2022-02-16 16:55:31.000000000 
+0100
@@ -231,6 +231,36 @@
 }
 
 /**
+ * jcat_engine_add_public_key_raw:
+ * @self: #JcatEngine
+ * @blob: #GBytes
+ * @error: #GError, or %NULL
+ *
+ * Adds a public key manually.
+ *
+ * Returns: %
+ *
+ * Since: 0.1.9
+ **/
+gboolean
+jcat_engine_add_public_key_raw(JcatEngine *self, GBytes *blob, GError **error)
+{
+       JcatEngineClass *klass = JCAT_ENGINE_GET_CLASS(self);
+       g_return_val_if_fail(JCAT_IS_ENGINE(self), FALSE);
+       g_return_val_if_fail(blob != NULL, FALSE);
+       if (klass->add_public_key_raw == NULL) {
+               g_set_error_literal(error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_NOT_SUPPORTED,
+                                   "adding public keys manually is not 
supported");
+               return FALSE;
+       }
+       if (!jcat_engine_setup(self, error))
+               return FALSE;
+       return klass->add_public_key_raw(self, blob, error);
+}
+
+/**
  * jcat_engine_get_kind:
  * @self: #JcatEngine
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-engine.h 
new/libjcat-0.1.10/libjcat/jcat-engine.h
--- old/libjcat-0.1.9/libjcat/jcat-engine.h     2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-engine.h    2022-02-16 16:55:31.000000000 
+0100
@@ -37,7 +37,8 @@
                                   JcatVerifyFlags flags,
                                   GError **error);
        JcatBlob *(*self_sign)(JcatEngine *self, GBytes *blob, JcatSignFlags 
flags, GError **error);
-       gpointer padding[9];
+       gboolean (*add_public_key_raw)(JcatEngine *self, GBytes *blob, GError 
**error);
+       gpointer padding[8];
 };
 
 JcatBlobKind
@@ -65,3 +66,5 @@
                        GError **error);
 JcatBlob *
 jcat_engine_self_sign(JcatEngine *self, GBytes *blob, JcatSignFlags flags, 
GError **error);
+gboolean
+jcat_engine_add_public_key_raw(JcatEngine *self, GBytes *blob, GError **error);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-pkcs7-engine.c 
new/libjcat-0.1.10/libjcat/jcat-pkcs7-engine.c
--- old/libjcat-0.1.9/libjcat/jcat-pkcs7-engine.c       2021-11-28 
16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/libjcat/jcat-pkcs7-engine.c      2022-02-16 
16:55:31.000000000 +0100
@@ -19,21 +19,16 @@
 G_DEFINE_TYPE(JcatPkcs7Engine, jcat_pkcs7_engine, JCAT_TYPE_ENGINE)
 
 static gboolean
-jcat_pkcs7_engine_add_pubkey(JcatPkcs7Engine *self,
-                            const gchar *filename,
-                            gnutls_x509_crt_fmt_t format,
-                            GError **error)
+jcat_pkcs7_engine_add_pubkey_blob_fmt(JcatPkcs7Engine *self,
+                                     GBytes *blob,
+                                     gnutls_x509_crt_fmt_t format,
+                                     GError **error)
 {
        guint key_usage = 0;
        int rc;
        g_auto(gnutls_x509_crt_t) crt = NULL;
-       g_autoptr(GBytes) blob = NULL;
 
        /* load file and add to the trust list */
-       g_debug("trying to load certificate from %s", filename);
-       blob = jcat_get_contents_bytes(filename, error);
-       if (blob == NULL)
-               return FALSE;
        crt = jcat_pkcs7_load_crt_from_blob(blob, format, error);
        if (crt == NULL)
                return FALSE;
@@ -52,8 +47,7 @@
                g_set_error(error,
                            G_IO_ERROR,
                            G_IO_ERROR_INVALID_DATA,
-                           "certificate %s not suitable for use [0x%x]",
-                           filename,
+                           "certificate not suitable for use [0x%x]",
                            key_usage);
                return FALSE;
        }
@@ -75,17 +69,30 @@
 }
 
 static gboolean
+jcat_pkcs7_engine_add_public_key_raw(JcatEngine *engine, GBytes *blob, GError 
**error)
+{
+       JcatPkcs7Engine *self = JCAT_PKCS7_ENGINE(engine);
+       return jcat_pkcs7_engine_add_pubkey_blob_fmt(self, blob, 
GNUTLS_X509_FMT_PEM, error);
+}
+
+static gboolean
 jcat_pkcs7_engine_add_public_key(JcatEngine *engine, const gchar *filename, 
GError **error)
 {
        JcatPkcs7Engine *self = JCAT_PKCS7_ENGINE(engine);
 
        /* search all the public key files */
        if (g_str_has_suffix(filename, ".pem")) {
-               if (!jcat_pkcs7_engine_add_pubkey(self, filename, 
GNUTLS_X509_FMT_PEM, error))
+               g_autoptr(GBytes) blob = jcat_get_contents_bytes(filename, 
error);
+               if (blob == NULL)
+                       return FALSE;
+               if (!jcat_pkcs7_engine_add_pubkey_blob_fmt(self, blob, 
GNUTLS_X509_FMT_PEM, error))
                        return FALSE;
        } else if (g_str_has_suffix(filename, ".cer") || 
g_str_has_suffix(filename, ".crt") ||
                   g_str_has_suffix(filename, ".der")) {
-               if (!jcat_pkcs7_engine_add_pubkey(self, filename, 
GNUTLS_X509_FMT_DER, error))
+               g_autoptr(GBytes) blob = jcat_get_contents_bytes(filename, 
error);
+               if (blob == NULL)
+                       return FALSE;
+               if (!jcat_pkcs7_engine_add_pubkey_blob_fmt(self, blob, 
GNUTLS_X509_FMT_DER, error))
                        return FALSE;
        } else {
                g_autofree gchar *basename = g_path_get_basename(filename);
@@ -454,6 +461,7 @@
        JcatEngineClass *klass_app = JCAT_ENGINE_CLASS(klass);
        klass_app->setup = jcat_pkcs7_engine_setup;
        klass_app->add_public_key = jcat_pkcs7_engine_add_public_key;
+       klass_app->add_public_key_raw = jcat_pkcs7_engine_add_public_key_raw;
        klass_app->pubkey_verify = jcat_pkcs7_engine_pubkey_verify;
        klass_app->pubkey_sign = jcat_pkcs7_engine_pubkey_sign;
        klass_app->self_verify = jcat_pkcs7_engine_self_verify;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-self-test.c 
new/libjcat-0.1.10/libjcat/jcat-self-test.c
--- old/libjcat-0.1.9/libjcat/jcat-self-test.c  2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-self-test.c 2022-02-16 16:55:31.000000000 
+0100
@@ -572,6 +572,120 @@
 }
 
 static void
+jcat_ed25519_engine_func(void)
+{
+#ifdef ENABLE_ED25519
+       g_autofree gchar *fn_fail = NULL;
+       g_autofree gchar *fn_pass = NULL;
+       g_autofree gchar *fn_sig = NULL;
+       g_autofree gchar *pki_dir = NULL;
+       g_autofree gchar *sig_fn2 = NULL;
+       g_autoptr(GBytes) blob_sig2 = NULL;
+       g_autoptr(GBytes) data_fail = NULL;
+       g_autoptr(GBytes) data_fwbin = NULL;
+       g_autoptr(GBytes) data_sig = NULL;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(JcatContext) context = jcat_context_new();
+       g_autoptr(JcatEngine) engine = NULL;
+       g_autoptr(JcatResult) result_fail = NULL;
+       g_autoptr(JcatResult) result_pass = NULL;
+
+       /* set up context */
+       jcat_context_set_keyring_path(context, "/tmp/libjcat-self-test/var");
+       pki_dir = g_test_build_filename(G_TEST_DIST, "pki", NULL);
+       jcat_context_add_public_keys(context, pki_dir);
+
+       /* get engine */
+       engine = jcat_context_get_engine(context, JCAT_BLOB_KIND_ED25519, 
&error);
+       g_assert_no_error(error);
+       g_assert_nonnull(engine);
+       g_assert_cmpint(jcat_engine_get_kind(engine), ==, 
JCAT_BLOB_KIND_ED25519);
+       g_assert_cmpint(jcat_engine_get_method(engine), ==, 
JCAT_BLOB_METHOD_SIGNATURE);
+
+       /* verify with a manually generated signature */
+       fn_pass = g_test_build_filename(G_TEST_DIST, "colorhug", 
"firmware.bin", NULL);
+       data_fwbin = jcat_get_contents_bytes(fn_pass, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(data_fwbin);
+       fn_sig = g_test_build_filename(G_TEST_DIST, "colorhug", 
"firmware.bin.ed25519", NULL);
+       data_sig = jcat_get_contents_bytes(fn_sig, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(data_sig);
+       result_pass =
+           jcat_engine_pubkey_verify(engine, data_fwbin, data_sig, 
JCAT_VERIFY_FLAG_NONE, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(result_pass);
+
+       /* verify will fail with valid signature and different data */
+       fn_fail = g_test_build_filename(G_TEST_DIST, "colorhug", 
"firmware.bin.asc", NULL);
+       data_fail = jcat_get_contents_bytes(fn_fail, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(data_fail);
+       result_fail =
+           jcat_engine_pubkey_verify(engine, data_fail, data_sig, 
JCAT_VERIFY_FLAG_NONE, &error);
+       g_assert_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
+       g_assert_null(result_fail);
+       g_clear_error(&error);
+#else
+       g_test_skip("no GnuTLS support enabled");
+#endif
+}
+
+static void
+jcat_ed25519_engine_self_signed_func(void)
+{
+#ifdef ENABLE_ED25519
+       static const char payload_str[] = "Hello, world!";
+       g_autofree gchar *str = NULL;
+       g_autoptr(JcatBlob) signature = NULL;
+       g_autoptr(JcatContext) context = jcat_context_new();
+       g_autoptr(JcatEngine) engine = NULL;
+       g_autoptr(JcatEngine) engine2 = NULL;
+       g_autoptr(JcatResult) result = NULL;
+       g_autoptr(GBytes) payload = NULL;
+       g_autoptr(GError) error = NULL;
+       const gchar *str_perfect = "JcatResult:\n"
+                                  "  Timestamp:             
1970-01-01T03:25:45Z\n"
+                                  "  JcatEd25519Engine:\n"
+                                  "    Kind:                ed25519\n"
+                                  "    VerifyKind:          signature\n";
+
+       /* set up context */
+       jcat_context_set_keyring_path(context, "/tmp");
+
+       /* get engine */
+       engine = jcat_context_get_engine(context, JCAT_BLOB_KIND_ED25519, 
&error);
+       g_assert_no_error(error);
+       g_assert_nonnull(engine);
+
+       payload = g_bytes_new_static(payload_str, sizeof(payload_str));
+       g_assert_nonnull(payload);
+       signature = jcat_engine_self_sign(engine, payload, 
JCAT_SIGN_FLAG_ADD_TIMESTAMP, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(signature);
+       result = jcat_engine_self_verify(engine,
+                                        payload,
+                                        jcat_blob_get_data(signature),
+                                        JCAT_VERIFY_FLAG_NONE,
+                                        &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(result);
+
+       /* verify engine set */
+       engine2 = jcat_result_get_engine(result);
+       g_assert(engine == engine2);
+
+       /* to string */
+       g_object_set(result, "timestamp", (gint64)12345, NULL);
+       str = jcat_result_to_string(result);
+       g_print("%s", str);
+       g_assert_cmpstr(str, ==, str_perfect);
+#else
+       g_test_skip("no GnuTLS support enabled");
+#endif
+}
+
+static void
 jcat_context_verify_blob_func(void)
 {
 #ifdef ENABLE_PKCS7
@@ -823,6 +937,8 @@
        g_test_add_func("/jcat/engine{gpg-msg}", jcat_gpg_engine_msg_func);
        g_test_add_func("/jcat/engine{pkcs7}", jcat_pkcs7_engine_func);
        g_test_add_func("/jcat/engine{pkcs7-self-signed}", 
jcat_pkcs7_engine_self_signed_func);
+       g_test_add_func("/jcat/engine{ed25519}", jcat_ed25519_engine_func);
+       g_test_add_func("/jcat/engine{ed25519-self-signed}", 
jcat_ed25519_engine_self_signed_func);
        g_test_add_func("/jcat/context{verify-blob}", 
jcat_context_verify_blob_func);
        g_test_add_func("/jcat/context{verify-item-sign}", 
jcat_context_verify_item_sign_func);
        g_test_add_func("/jcat/context{verify-item-csum}", 
jcat_context_verify_item_csum_func);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat-tool.c 
new/libjcat-0.1.10/libjcat/jcat-tool.c
--- old/libjcat-0.1.9/libjcat/jcat-tool.c       2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/jcat-tool.c      2022-02-16 16:55:31.000000000 
+0100
@@ -302,11 +302,29 @@
        /* guess format */
        if (g_str_has_suffix(values[2], ".asc")) {
                blob = jcat_blob_new_full(JCAT_BLOB_KIND_GPG, data_sig, 
JCAT_BLOB_FLAG_IS_UTF8);
+       } else if (g_str_has_suffix(values[2], ".btmanifest")) {
+               blob = jcat_blob_new_full(JCAT_BLOB_KIND_BT_MANIFEST,
+                                         data_sig,
+                                         JCAT_BLOB_FLAG_IS_UTF8);
+       } else if (g_str_has_suffix(values[2], ".btcheckpoint")) {
+               blob = jcat_blob_new_full(JCAT_BLOB_KIND_BT_CHECKPOINT,
+                                         data_sig,
+                                         JCAT_BLOB_FLAG_IS_UTF8);
+       } else if (g_str_has_suffix(values[2], ".btinclusionproof")) {
+               blob = jcat_blob_new_full(JCAT_BLOB_KIND_BT_INCLUSION_PROOF,
+                                         data_sig,
+                                         JCAT_BLOB_FLAG_IS_UTF8);
+       } else if (g_str_has_suffix(values[2], ".btverifier")) {
+               blob = jcat_blob_new_full(JCAT_BLOB_KIND_BT_VERIFIER,
+                                         data_sig,
+                                         JCAT_BLOB_FLAG_IS_UTF8);
        } else if (g_str_has_suffix(values[2], ".p7b") || 
g_str_has_suffix(values[2], ".p7c") ||
                   g_str_has_suffix(values[2], ".pem")) {
                blob = jcat_blob_new_full(JCAT_BLOB_KIND_PKCS7, data_sig, 
JCAT_BLOB_FLAG_IS_UTF8);
        } else if (g_str_has_suffix(values[2], ".der")) {
                blob = jcat_blob_new_full(JCAT_BLOB_KIND_PKCS7, data_sig, 
JCAT_BLOB_FLAG_NONE);
+       } else if (g_str_has_suffix(values[2], ".ed25519")) {
+               blob = jcat_blob_new_full(JCAT_BLOB_KIND_ED25519, data_sig, 
JCAT_BLOB_FLAG_NONE);
        } else if (g_str_has_suffix(values[2], ".sha256") ||
                   g_str_has_suffix(values[2], ".SHA256")) {
                blob = jcat_blob_new_full(JCAT_BLOB_KIND_SHA256, data_sig, 
JCAT_BLOB_FLAG_IS_UTF8);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/jcat.map 
new/libjcat-0.1.10/libjcat/jcat.map
--- old/libjcat-0.1.9/libjcat/jcat.map  2021-11-28 16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/libjcat/jcat.map 2022-02-16 16:55:31.000000000 +0100
@@ -76,3 +76,9 @@
     jcat_result_get_method;
   local: *;
 } LIBJCAT_0.1.1;
+
+LIBJCAT_0.1.9 {
+  global:
+    jcat_engine_add_public_key_raw;
+  local: *;
+} LIBJCAT_0.1.3;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/libjcat/meson.build 
new/libjcat-0.1.10/libjcat/meson.build
--- old/libjcat-0.1.9/libjcat/meson.build       2021-11-28 16:58:08.000000000 
+0100
+++ new/libjcat-0.1.10/libjcat/meson.build      2022-02-16 16:55:31.000000000 
+0100
@@ -33,6 +33,9 @@
   jcat_src += 'jcat-pkcs7-common.c'
   jcat_src += 'jcat-pkcs7-engine.c'
 endif
+if get_option('ed25519')
+  jcat_src += 'jcat-ed25519-engine.c'
+endif
 
 jcat_mapfile = 'jcat.map'
 libjcat_ldflags = cc.get_supported_link_arguments([
@@ -68,6 +71,9 @@
 if get_option('pkcs7')
   pkgg_variables += 'supported_pkcs7=1'
 endif
+if get_option('ed25519')
+  pkgg_variables += 'supported_ed25519=1'
+endif
 
 pkgg = import('pkgconfig')
 pkgg.generate(libjcat,
@@ -89,6 +95,7 @@
     include_directories('.'),
     configinc,
   ],
+  variables : pkgg_variables,
   dependencies : libjcat_deps
 )
 
@@ -146,13 +153,7 @@
     )
   endif
 
-  python = import('python')
-  python_interpreter = python.find_installation(
-    modules: [
-      'xml.etree.ElementTree',
-      'pkg_resources',
-    ],
-  )
+  python_interpreter = find_program('python3')
 
   # Verify the map file is correct -- note we can't actually use the generated
   # file for two reasons:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/meson.build 
new/libjcat-0.1.10/meson.build
--- old/libjcat-0.1.9/meson.build       2021-11-28 16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/meson.build      2022-02-16 16:55:31.000000000 +0100
@@ -1,5 +1,5 @@
 project('libjcat', 'c',
-  version : '0.1.9',
+  version : '0.1.10',
   license : 'LGPL-2.1+',
   meson_version : '>=0.49.2',
   default_options : ['warning_level=2', 'c_std=c99'],
@@ -140,6 +140,12 @@
   libjcat_deps += gnutls
 endif
 
+if get_option('ed25519')
+  conf.set('ENABLE_ED25519', '1')
+  libjcat_deps += dependency('hogweed')
+  libjcat_deps += dependency('gnutls')
+endif
+
 if get_option('gpg')
   gpgme = cc.find_library('gpgme')
   gpgerror = cc.find_library('gpg-error')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libjcat-0.1.9/meson_options.txt 
new/libjcat-0.1.10/meson_options.txt
--- old/libjcat-0.1.9/meson_options.txt 2021-11-28 16:58:08.000000000 +0100
+++ new/libjcat-0.1.10/meson_options.txt        2022-02-16 16:55:31.000000000 
+0100
@@ -4,5 +4,6 @@
 option('tests', type : 'boolean', value : true, description : 'enable tests')
 option('gpg', type : 'boolean', value : true, description : 'enable the GPG 
verification support')
 option('pkcs7', type : 'boolean', value : true, description : 'enable the 
PKCS7 verification support')
+option('ed25519', type : 'boolean', value : true, description : 'enable the 
ED25519 verification support')
 option('man', type : 'boolean', value : true, description : 'enable man pages')
 option('cli', type : 'boolean', value : true, description : 'build and install 
the jcat-tool CLI')

Reply via email to