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')
