]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
pkcs11: fix key pair generation for EdDSA
authorDaiki Ueno <ueno@gnu.org>
Sat, 23 Sep 2023 06:37:03 +0000 (15:37 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sat, 23 Sep 2023 06:55:49 +0000 (15:55 +0900)
Previouly we used the CKM_EDDSA mechanism to generate key pair, though
the mechanism can only be used for signing and verification as
specified in PKCS#11 3.1 section 6.3.  For key generation, the
CKM_EC_EDWARDS_KEY_PAIR_GEN mechanism (or
CKM_EC_MONTGOMERY_KEY_PAIR_GEN, if the point is represented in the
Montgomery form) needs to be used.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/pkcs11.c
lib/pkcs11_int.h
lib/pkcs11_write.c
tests/pkcs11/pkcs11-privkey-generate.c

index 8b8b62b8642a13feef6524b56ab975bfac8870d0..1066794ce58528301c15c726658dab753483dd45 100644 (file)
@@ -1883,7 +1883,7 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
                }
 
                break;
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        case CKK_EC_EDWARDS:
                a[0].type = CKA_EC_PARAMS;
                a[0].value = tmp1;
index d29617ab110af2992a2823a852bb673a6857a084..d27016ae2a521605d389fcc4f1777216e0e193da 100644 (file)
@@ -29,8 +29,8 @@
 #include <x509/x509_int.h>
 
 /* Part of PKCS#11 3.0 interface, which was added in p11-kit 0.23.14 */
-#ifdef CKM_EDDSA
-#define HAVE_CKM_EDDSA
+#if defined(CKM_EDDSA) && defined(CKM_EC_EDWARDS_KEY_PAIR_GEN)
+#define HAVE_PKCS11_EDDSA
 #endif
 
 #define PKCS11_ID_SIZE 128
@@ -246,7 +246,7 @@ static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
                return CKM_RSA_PKCS;
        else if (pk == GNUTLS_PK_RSA_PSS)
                return CKM_RSA_PKCS_PSS;
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        else if (pk == GNUTLS_PK_EDDSA_ED25519)
                return CKM_EDDSA;
 #endif
@@ -262,7 +262,7 @@ static inline int pk_to_key_type(gnutls_pk_algorithm_t pk)
                return CKK_ECDSA;
        else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA)
                return CKK_RSA;
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        else if (pk == GNUTLS_PK_EDDSA_ED25519)
                return CKK_EC_EDWARDS;
 #endif
@@ -278,7 +278,7 @@ static inline gnutls_pk_algorithm_t key_type_to_pk(ck_key_type_t m)
                return GNUTLS_PK_DSA;
        else if (m == CKK_ECDSA)
                return GNUTLS_PK_EC;
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        else if (m == CKK_EC_EDWARDS)
                return GNUTLS_PK_EDDSA_ED25519;
 #endif
@@ -297,10 +297,10 @@ static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
        } else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA) {
                *type = CKK_RSA;
                return CKM_RSA_PKCS_KEY_PAIR_GEN;
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        } else if (pk == GNUTLS_PK_EDDSA_ED25519) {
                *type = CKK_EC_EDWARDS;
-               return CKM_EDDSA;
+               return CKM_EC_EDWARDS_KEY_PAIR_GEN;
 #endif
        } else {
                *type = -1;
index f37b2400ea316b375402926b3135ed494b8df730..875d32bfb5092bc95084485f882aea53c350c473 100644 (file)
@@ -934,7 +934,7 @@ int gnutls_pkcs11_copy_x509_privkey2(const char *token_url,
 
                break;
        }
-#ifdef HAVE_CKM_EDDSA
+#ifdef HAVE_PKCS11_EDDSA
        case GNUTLS_PK_EDDSA_ED25519: {
                ret = _gnutls_x509_write_ecc_params(key->params.curve, &p);
                if (ret < 0) {
index 2a58bc9df9895d435c0c2bd4390ca01550f04a1f..0409ad3a523d6e3e421b265c98c5714ba86f74d2 100644 (file)
@@ -35,6 +35,7 @@
 #include <gnutls/x509.h>
 #include <gnutls/abstract.h>
 #include <gnutls/pkcs11.h>
+#include <p11-kit/pkcs11.h>
 
 #ifdef _WIN32
 
@@ -133,6 +134,8 @@ void doit(void)
                exit(1);
        }
 
+       success("generated RSA key\n");
+
        assert(gnutls_pkcs11_obj_init(&obj) >= 0);
        assert(out.size > 0);
 
@@ -160,6 +163,8 @@ void doit(void)
                exit(1);
        }
 
+       success("generated RSA key (non-sensitive)\n");
+
        assert(gnutls_pkcs11_obj_init(&obj) >= 0);
        assert(out.size > 0);
 
@@ -176,6 +181,40 @@ void doit(void)
        gnutls_free(out.data);
        gnutls_pkcs11_obj_deinit(obj);
 
+#ifdef CKM_EC_EDWARDS_KEY_PAIR_GEN
+       ret = gnutls_pkcs11_token_check_mechanism(
+               "pkcs11:token=test", CKM_EC_EDWARDS_KEY_PAIR_GEN, NULL, 0, 0);
+       if (ret != 0) {
+               ret = gnutls_pkcs11_privkey_generate3(
+                       "pkcs11:token=test", GNUTLS_PK_EDDSA_ED25519, 256,
+                       "testkey-ed25519", NULL, GNUTLS_X509_FMT_DER, &out, 0,
+                       GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+               if (ret < 0) {
+                       fail("%d: %s\n", ret, gnutls_strerror(ret));
+                       exit(1);
+               }
+
+               success("generated Ed25519 key\n");
+
+               assert(gnutls_pkcs11_obj_init(&obj) >= 0);
+               assert(out.size > 0);
+
+               gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL);
+               assert(gnutls_pkcs11_obj_import_url(
+                              obj,
+                              "pkcs11:token=test;object=testkey-ed25519;type=private",
+                              GNUTLS_PKCS11_OBJ_FLAG_LOGIN) >= 0);
+
+               assert(gnutls_pkcs11_obj_get_flags(obj, &flags) >= 0);
+
+               assert(!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE));
+               assert(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
+
+               gnutls_free(out.data);
+               gnutls_pkcs11_obj_deinit(obj);
+       }
+#endif
+
        gnutls_pkcs11_deinit();
        gnutls_global_deinit();
        remove(CONFIG);