]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Add tests for different EDDSA ecpoint encodings
authorZoltan Fridrich <zfridric@redhat.com>
Tue, 17 Feb 2026 13:07:39 +0000 (14:07 +0100)
committerZoltan Fridrich <zfridric@redhat.com>
Mon, 23 Feb 2026 09:24:43 +0000 (10:24 +0100)
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
.gitignore
lib/libgnutls.map
lib/pkcs11_int.h
lib/pubkey.c
tests/Makefile.am
tests/pkcs11/eddsa-ecpoint-encodings.c [new file with mode: 0644]

index 8f00901e649cb161db3538680fcf51414ba03e66..88583f593f2cf74dd6a69ed14b5e01cb6e4ed192 100644 (file)
@@ -578,6 +578,7 @@ tests/pkcs11-privkey-raw
 tests/pkcs11-privkey-safenet-always-auth
 tests/pkcs11-token-raw
 tests/pkcs11/distrust-after
+tests/pkcs11/eddsa-ecpoint-encodings
 tests/pkcs11/gnutls_pcert_list_import_x509_file
 tests/pkcs11/gnutls_x509_crt_list_import_url
 tests/pkcs11/list-objects
index 955704e3fe7ed6a02e9238f79f2f901d2ce7ea54..f31c429978bce07e9d63055ebd6642736b19e928 100644 (file)
@@ -1574,4 +1574,6 @@ GNUTLS_PRIVATE_3_4 {
        _gnutls_pathbuf_append;
        _gnutls_pathbuf_truncate;
        _gnutls_pathbuf_deinit;
+       # needed by tests/pkcs11/eddsa-ecpoint-encodings
+       _gnutls_pubkey_import_ecc_eddsa;
 } GNUTLS_3_4;
index b3a046c30be5e839aad5ee49e4218d828e4d0d7a..046c3353ccb30d8f7e8480e767e660f6e8633a6f 100644 (file)
@@ -239,6 +239,10 @@ int _pkcs11_privkey_get_pubkey(gnutls_pkcs11_privkey_t pkey,
 int _gnutls_pubkey_parse_ecc_eddsa_params(const gnutls_datum_t *parameters,
                                          gnutls_ecc_curve_t *outcurve);
 
+int _gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
+                                   const gnutls_datum_t *parameters,
+                                   const gnutls_datum_t *ecpoint);
+
 static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
 {
        if (pk == GNUTLS_PK_DSA)
index 23da05534721b29e2917510346b7c678e6d3ff94..d96dbef0ebf58eab184c3067a1eefc5899c87c96 100644 (file)
@@ -478,9 +478,9 @@ cleanup:
        return ret;
 }
 
-static int gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
-                                         const gnutls_datum_t *parameters,
-                                         const gnutls_datum_t *ecpoint)
+int _gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
+                                   const gnutls_datum_t *parameters,
+                                   const gnutls_datum_t *ecpoint)
 {
        int ret, tag_len, len_len;
        long data_len;
@@ -753,8 +753,8 @@ int gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key, gnutls_pkcs11_obj_t obj,
                break;
        case GNUTLS_PK_EDDSA_ED25519:
        case GNUTLS_PK_EDDSA_ED448:
-               ret = gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
-                                                    &obj->pubkey[1]);
+               ret = _gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
+                                                     &obj->pubkey[1]);
                break;
        case GNUTLS_PK_ECDH_X25519:
                ret = gnutls_pubkey_import_ecc_ecdh(key, &obj->pubkey[0],
index db5aa4e3a63c31b9d7ea40e45821e1d75601cd68..0acb40e18b398490dc4a277ebdf468f86fbbc6ba 100644 (file)
@@ -427,7 +427,7 @@ ctests += pkcs11-cert-import-url-exts pkcs11-get-exts pkcs11-get-raw-issuer-exts
        pkcs11-privkey-fork-reinit pkcs11-mechanisms pkcs11-privkey-safenet-always-auth \
        pkcs11/pkcs11-rsa-pss-privkey-test pkcs11/tls-neg-pkcs11-key pkcs11/pkcs11-privkey-generate \
        pkcs11/gnutls_x509_crt_list_import_url pkcs11/gnutls_pcert_list_import_x509_file \
-       pkcs11/pkcs11-eddsa-privkey-test \
+       pkcs11/pkcs11-eddsa-privkey-test pkcs11/eddsa-ecpoint-encodings \
        pkcs11-token-raw pkcs11-obj-raw
 
 if P11KIT_0_23_11_API
diff --git a/tests/pkcs11/eddsa-ecpoint-encodings.c b/tests/pkcs11/eddsa-ecpoint-encodings.c
new file mode 100644 (file)
index 0000000..ddbf4ef
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2026 Red Hat, Inc.
+ *
+ * Authors: Zoltan Fridrich, Conor Tull
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnutls/abstract.h>
+
+#include "utils.h"
+
+#define ECPOINT_RAW_DATA                                                    \
+       0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe,   \
+               0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, \
+               0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, \
+               0x1a
+
+int _gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
+                                   const gnutls_datum_t *parameters,
+                                   const gnutls_datum_t *ecpoint);
+
+static const unsigned char ecpoint_raw_data[] = { ECPOINT_RAW_DATA };
+static const unsigned char ecpoint_bitstring_data[] = { 0x03, 0x21, 0x00,
+                                                       ECPOINT_RAW_DATA };
+static const unsigned char ecpoint_octetstring_data[] = { 0x04, 0x20,
+                                                         ECPOINT_RAW_DATA };
+
+static const gnutls_datum_t ecpoint_raw = { (unsigned char *)ecpoint_raw_data,
+                                           sizeof(ecpoint_raw_data) };
+static const gnutls_datum_t ecpoint_bitstring = {
+       (unsigned char *)ecpoint_bitstring_data, sizeof(ecpoint_bitstring_data)
+};
+static const gnutls_datum_t ecpoint_octetstring = {
+       (unsigned char *)ecpoint_octetstring_data,
+       sizeof(ecpoint_octetstring_data)
+};
+
+static const unsigned char ed25519_params_der[] = { 0x06, 0x03, 0x2B, 0x65,
+                                                   0x70 };
+static const gnutls_datum_t params = { (unsigned char *)ed25519_params_der,
+                                      sizeof(ed25519_params_der) };
+
+static void test_eddsa_encoding(const char *name, const gnutls_datum_t *ecpoint,
+                               const gnutls_datum_t *expected)
+{
+       int ret;
+       gnutls_pubkey_t pubkey;
+       gnutls_pk_algorithm_t pk_alg;
+       gnutls_datum_t exported = { 0 };
+
+       success("Testing: EdDSA %s encoding\n", name);
+
+       assert(gnutls_pubkey_init(&pubkey) >= 0);
+       ret = _gnutls_pubkey_import_ecc_eddsa(pubkey, &params, ecpoint);
+       if (ret < 0)
+               fail("failed to import public key: %s\n", gnutls_strerror(ret));
+
+       pk_alg = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
+       if (pk_alg != GNUTLS_PK_EDDSA_ED25519)
+               fail("imported key has the wrong id: %s != EdDSA (Ed25519)\n",
+                    gnutls_pk_get_name(pk_alg));
+
+       ret = gnutls_pubkey_export_ecc_raw(pubkey, NULL, &exported, NULL);
+       if (ret < 0)
+               fail("failed to export public key: %s\n", gnutls_strerror(ret));
+
+       if (exported.size != expected->size ||
+           memcmp(exported.data, expected->data, expected->size) != 0) {
+               success("exported data:\n");
+               hexprint(exported.data, exported.size);
+               success("expected data:\n");
+               hexprint(expected->data, expected->size);
+               fail("exported key does not match the expected result\n");
+       }
+
+       success("success\n");
+
+       gnutls_free(exported.data);
+       gnutls_pubkey_deinit(pubkey);
+}
+
+void doit(void)
+{
+       test_eddsa_encoding("raw", &ecpoint_raw, &ecpoint_raw);
+       test_eddsa_encoding("bit string", &ecpoint_bitstring, &ecpoint_raw);
+       test_eddsa_encoding("octet string", &ecpoint_octetstring, &ecpoint_raw);
+}