]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
pkcs11: support Ed448 keys
authorDaiki Ueno <ueno@gnu.org>
Thu, 28 Sep 2023 02:38:36 +0000 (11:38 +0900)
committerDaiki Ueno <ueno@gnu.org>
Tue, 3 Oct 2023 04:53:16 +0000 (13:53 +0900)
This adds support for Ed448 keys backed by PKCS#11.  To differentiate
Ed448 keys from Ed25519 keys, this requires an extra logic to check
CKA_EC_PARAMS when reading public keys.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/pkcs11.c
lib/pkcs11_int.h
lib/pkcs11_privkey.c
lib/pkcs11_write.c
lib/pubkey.c
tests/cert-common.h
tests/pkcs11/pkcs11-eddsa-privkey-test.c
tests/pkcs11/pkcs11-privkey-generate.c
tests/tls13/ocsp-client.c

index 1066794ce58528301c15c726658dab753483dd45..4fb3ee722f6eb66a4e2482cb31686f817452f410 100644 (file)
@@ -1796,6 +1796,7 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
                        pobj->pubkey[1].size = a[1].value_len;
 
                        pobj->pubkey_size = 2;
+                       pobj->pk_algorithm = GNUTLS_PK_RSA;
                } else {
                        gnutls_assert();
                        ret = GNUTLS_E_PKCS11_ERROR;
@@ -1851,6 +1852,7 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
                        pobj->pubkey[3].size = a[1].value_len;
 
                        pobj->pubkey_size = 4;
+                       pobj->pk_algorithm = GNUTLS_PK_DSA;
                } else {
                        gnutls_assert();
                        ret = pkcs11_rv_to_err(rv);
@@ -1875,6 +1877,7 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
                        pobj->pubkey[1].size = a[1].value_len;
 
                        pobj->pubkey_size = 2;
+                       pobj->pk_algorithm = GNUTLS_PK_EC;
                } else {
                        gnutls_assert();
 
@@ -1895,6 +1898,9 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
 
                if ((rv = pkcs11_get_attribute_value(module, pks, ctx, a, 2)) ==
                    CKR_OK) {
+                       gnutls_ecc_curve_t curve;
+                       const gnutls_ecc_curve_entry_st *ce;
+
                        pobj->pubkey[0].data = a[0].value;
                        pobj->pubkey[0].size = a[0].value_len;
 
@@ -1902,13 +1908,26 @@ int pkcs11_read_pubkey(struct ck_function_list *module, ck_session_handle_t pks,
                        pobj->pubkey[1].size = a[1].value_len;
 
                        pobj->pubkey_size = 2;
+
+                       ret = _gnutls_x509_read_ecc_params(pobj->pubkey[0].data,
+                                                          pobj->pubkey[0].size,
+                                                          &curve);
+                       if (ret < 0) {
+                               ret = GNUTLS_E_INVALID_REQUEST;
+                               goto cleanup;
+                       }
+                       ce = _gnutls_ecc_curve_get_params(curve);
+                       if (unlikely(ce == NULL)) {
+                               ret = GNUTLS_E_INVALID_REQUEST;
+                               goto cleanup;
+                       }
+                       pobj->pk_algorithm = ce->pk;
                } else {
                        gnutls_assert();
 
                        ret = pkcs11_rv_to_err(rv);
                        goto cleanup;
                }
-
                break;
 #endif
        default:
@@ -1945,8 +1964,6 @@ pkcs11_obj_import_pubkey(struct ck_function_list *module,
        a[0].value_len = sizeof(key_type);
 
        if (pkcs11_get_attribute_value(module, pks, ctx, a, 1) == CKR_OK) {
-               pobj->pk_algorithm = key_type_to_pk(key_type);
-
                ret = pkcs11_read_pubkey(module, pks, ctx, key_type, pobj);
                if (ret < 0)
                        return gnutls_assert_val(ret);
index d27016ae2a521605d389fcc4f1777216e0e193da..c2476aa478d50def3966303ef24fa6c750febc37 100644 (file)
@@ -247,7 +247,7 @@ static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
        else if (pk == GNUTLS_PK_RSA_PSS)
                return CKM_RSA_PKCS_PSS;
 #ifdef HAVE_PKCS11_EDDSA
-       else if (pk == GNUTLS_PK_EDDSA_ED25519)
+       else if (pk == GNUTLS_PK_EDDSA_ED25519 || pk == GNUTLS_PK_EDDSA_ED448)
                return CKM_EDDSA;
 #endif
        else
@@ -263,29 +263,13 @@ static inline int pk_to_key_type(gnutls_pk_algorithm_t pk)
        else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA)
                return CKK_RSA;
 #ifdef HAVE_PKCS11_EDDSA
-       else if (pk == GNUTLS_PK_EDDSA_ED25519)
+       else if (pk == GNUTLS_PK_EDDSA_ED25519 || pk == GNUTLS_PK_EDDSA_ED448)
                return CKK_EC_EDWARDS;
 #endif
        else
                return -1;
 }
 
-static inline gnutls_pk_algorithm_t key_type_to_pk(ck_key_type_t m)
-{
-       if (m == CKK_RSA)
-               return GNUTLS_PK_RSA;
-       else if (m == CKK_DSA)
-               return GNUTLS_PK_DSA;
-       else if (m == CKK_ECDSA)
-               return GNUTLS_PK_EC;
-#ifdef HAVE_PKCS11_EDDSA
-       else if (m == CKK_EC_EDWARDS)
-               return GNUTLS_PK_EDDSA_ED25519;
-#endif
-       else
-               return GNUTLS_PK_UNKNOWN;
-}
-
 static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
 {
        if (pk == GNUTLS_PK_DSA) {
@@ -298,7 +282,8 @@ static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
                *type = CKK_RSA;
                return CKM_RSA_PKCS_KEY_PAIR_GEN;
 #ifdef HAVE_PKCS11_EDDSA
-       } else if (pk == GNUTLS_PK_EDDSA_ED25519) {
+       } else if (pk == GNUTLS_PK_EDDSA_ED25519 ||
+                  pk == GNUTLS_PK_EDDSA_ED448) {
                *type = CKK_EC_EDWARDS;
                return CKM_EC_EDWARDS_KEY_PAIR_GEN;
 #endif
index 163ca1f8a6337ece4b0ba1cd83f4f5977e2605dd..bbc45343511fcc3f742265b76e0a3fab79d4b320 100644 (file)
@@ -486,6 +486,61 @@ cleanup:
        return ret;
 }
 
+static inline gnutls_pk_algorithm_t
+key_type_to_pk(struct ck_function_list *module, ck_session_handle_t pks,
+              ck_object_handle_t ctx, ck_key_type_t m)
+{
+       switch (m) {
+       case CKK_RSA:
+               return GNUTLS_PK_RSA;
+       case CKK_DSA:
+               return GNUTLS_PK_DSA;
+       case CKK_ECDSA:
+               return GNUTLS_PK_EC;
+#ifdef HAVE_PKCS11_EDDSA
+       case CKK_EC_EDWARDS: {
+               struct ck_attribute a[1];
+               uint8_t *tmp1;
+               size_t tmp1_size;
+               gnutls_pk_algorithm_t pk = GNUTLS_PK_UNKNOWN;
+
+               tmp1_size = MAX_PK_PARAM_SIZE;
+               tmp1 = gnutls_calloc(1, tmp1_size);
+               if (tmp1 == NULL)
+                       return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+               a[0].type = CKA_EC_PARAMS;
+               a[0].value = tmp1;
+               a[0].value_len = tmp1_size;
+
+               if (pkcs11_get_attribute_value(module, pks, ctx, a, 1) ==
+                   CKR_OK) {
+                       gnutls_ecc_curve_t curve;
+                       const gnutls_ecc_curve_entry_st *ce;
+                       int ret;
+
+                       ret = _gnutls_x509_read_ecc_params(
+                               a[0].value, a[0].value_len, &curve);
+                       if (ret < 0) {
+                               goto edwards_cleanup;
+                       }
+                       ce = _gnutls_ecc_curve_get_params(curve);
+                       if (unlikely(ce == NULL)) {
+                               goto edwards_cleanup;
+                       }
+                       pk = ce->pk;
+               }
+
+       edwards_cleanup:
+               gnutls_free(tmp1);
+               return pk;
+       }
+#endif
+       default:
+               return GNUTLS_PK_UNKNOWN;
+       }
+}
+
 /**
  * gnutls_pkcs11_privkey_import_url:
  * @pkey: The private key
@@ -561,7 +616,9 @@ int gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
        a[0].value_len = sizeof(key_type);
        if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks,
                                       pkey->ref, a, 1) == CKR_OK) {
-               pkey->pk_algorithm = key_type_to_pk(key_type);
+               pkey->pk_algorithm = key_type_to_pk(pkey->sinfo.module,
+                                                   pkey->sinfo.pks, pkey->ref,
+                                                   key_type);
        }
 
        if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) {
@@ -1188,6 +1245,7 @@ int gnutls_pkcs11_privkey_generate3(const char *url, gnutls_pk_algorithm_t pk,
 
                break;
        case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448:
                p[p_val].type = CKA_SIGN;
                p[p_val].value = (void *)&tval;
                p[p_val].value_len = sizeof(tval);
@@ -1198,8 +1256,11 @@ int gnutls_pkcs11_privkey_generate3(const char *url, gnutls_pk_algorithm_t pk,
                a[a_val].value_len = sizeof(tval);
                a_val++;
 
-               ret = _gnutls_x509_write_ecc_params(GNUTLS_ECC_CURVE_ED25519,
-                                                   &der);
+               ret = _gnutls_x509_write_ecc_params(
+                       pk == GNUTLS_PK_EDDSA_ED25519 ?
+                               GNUTLS_ECC_CURVE_ED25519 :
+                               GNUTLS_ECC_CURVE_ED448,
+                       &der);
                if (ret < 0) {
                        gnutls_assert();
                        goto cleanup;
index 875d32bfb5092bc95084485f882aea53c350c473..3187a0ca329525b3129fba4439ec54960c8c2e31 100644 (file)
@@ -355,7 +355,8 @@ static int add_pubkey(gnutls_pubkey_t pubkey, struct ck_attribute *a,
                (*a_val)++;
                break;
        }
-       case GNUTLS_PK_EDDSA_ED25519: {
+       case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448: {
                gnutls_datum_t params, ecpoint;
 
                ret = _gnutls_x509_write_ecc_params(pubkey->params.curve,
@@ -935,7 +936,8 @@ int gnutls_pkcs11_copy_x509_privkey2(const char *token_url,
                break;
        }
 #ifdef HAVE_PKCS11_EDDSA
-       case GNUTLS_PK_EDDSA_ED25519: {
+       case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448: {
                ret = _gnutls_x509_write_ecc_params(key->params.curve, &p);
                if (ret < 0) {
                        gnutls_assert();
@@ -1001,7 +1003,8 @@ cleanup:
                break;
        }
        case GNUTLS_PK_EC:
-       case GNUTLS_PK_EDDSA_ED25519: {
+       case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448: {
                gnutls_free(p.data);
                gnutls_free(x.data);
                break;
index 8ed79d3577517c34dbe990fc2468ca7d9207787c..912b6e10c7765c1ea30b41ba6e58479ae4518276 100644 (file)
@@ -700,6 +700,7 @@ int gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key, gnutls_pkcs11_obj_t obj,
                                                    &obj->pubkey[1]);
                break;
        case GNUTLS_PK_EDDSA_ED25519:
+       case GNUTLS_PK_EDDSA_ED448:
                ret = gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
                                                     &obj->pubkey[1]);
                break;
index 33b3ee3b68077103f79a6c83716f82c8cb8c649b..57cf6c0c4f7ffe5cdfbc981ef66e3cac78026b5b 100644 (file)
@@ -36,7 +36,8 @@
  * IPv4 server (SAN: IPAddr: 127.0.0.1): server_ca3_ipaddr_cert, server_ca3_key
  * IPv4 server (RSA-PSS, SAN: localhost IPAddr: 127.0.0.1): server_ca3_rsa_pss_cert, server_ca3_rsa_pss_key
  * IPv4 server (RSA-PSS key, SAN: localhost IPAddr: 127.0.0.1): server_ca3_rsa_pss2_cert, server_ca3_rsa_pss2_key
- * IPv4 server (EdDSA, SAN: localhost IPAddr: 127.0.0.1): server_ca3_eddsa_cert, server_ca3_eddsa_key
+ * IPv4 server (Ed25519, SAN: localhost IPAddr: 127.0.0.1): server_ca3_eddsa_cert, server_ca3_eddsa_key
+ * IPv4 server (Ed448, SAN: localhost IPAddr: 127.0.0.1): server_ca3_ed448_cert, server_ca3_ed448_key
  * IPv4 server (GOST R 34.10-2001, SAN: localhost): server_ca3_gost01_cert, server_ca3_gost01_key
  * IPv4 server (GOST R 34.10-2012-256, SAN: localhost): server_ca3_gost12-256_cert, server_ca3_gost12-256_key
  * IPv4 server (GOST R 34.10-2012-512, SAN: localhost): server_ca3_gost12-512_cert, server_ca3_gost12-512_key
@@ -349,7 +350,7 @@ static unsigned char ca2_cert_pem[] =
 
 const gnutls_datum_t ca2_cert = { ca2_cert_pem, sizeof(ca2_cert_pem) - 1 };
 
-static unsigned char cert_pem[] =
+static unsigned char cli_cert_pem[] =
        "-----BEGIN CERTIFICATE-----\n"
        "MIICHjCCAYmgAwIBAgIERiYdNzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
        "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTI3WhcNMDgwNDE3MTMyOTI3WjAdMRsw\n"
@@ -364,9 +365,9 @@ static unsigned char cert_pem[] =
        "U7jyOsBJ44SEQITbin2yUeJMIm1tievvdNXBDfW95AM507ShzP12sfiJkJfjjdhy\n"
        "dc8Siq5JojruiMizAf0pA7in\n"
        "-----END CERTIFICATE-----\n";
-const gnutls_datum_t cli_cert = { cert_pem, sizeof(cert_pem) - 1 };
+const gnutls_datum_t cli_cert = { cli_cert_pem, sizeof(cli_cert_pem) - 1 };
 
-static unsigned char key_pem[] =
+static unsigned char cli_key_pem[] =
        "-----BEGIN RSA PRIVATE KEY-----\n"
        "MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
        "9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
@@ -382,7 +383,7 @@ static unsigned char key_pem[] =
        "/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
        "sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
        "-----END RSA PRIVATE KEY-----\n";
-const gnutls_datum_t cli_key = { key_pem, sizeof(key_pem) - 1 };
+const gnutls_datum_t cli_key = { cli_key_pem, sizeof(cli_key_pem) - 1 };
 
 static char dsa_key_pem[] =
        "-----BEGIN DSA PRIVATE KEY-----\n"
@@ -1081,6 +1082,42 @@ const gnutls_datum_t server_ca3_eddsa_cert = {
        sizeof(server_ca3_eddsa_cert_pem) - 1
 };
 
+/* server Ed448 key */
+static char server_ca3_ed448_key_pem[] =
+       "-----BEGIN PRIVATE KEY-----\n"
+       "MEcCAQAwBQYDK2VxBDsEOXPoCtsxxy7itrHfeuQ2bG7oh3uerkBwhabkeSsNFYoS\n"
+       "QYy6KKYld8lnhlYQQmMo6lx28x9GmpTiag==\n"
+       "-----END PRIVATE KEY-----\n";
+
+const gnutls_datum_t server_ca3_ed448_key = {
+       (unsigned char *)server_ca3_ed448_key_pem,
+       sizeof(server_ca3_ed448_key_pem) - 1
+};
+
+static char server_ca3_ed448_cert_pem[] =
+       "-----BEGIN CERTIFICATE-----\n"
+       "MIICqzCCAROgAwIBAgIUAvQ9bcei1eNZ9viV1kP7MKODp9YwDQYJKoZIhvcNAQEL\n"
+       "BQAwDzENMAsGA1UEAxMEQ0EtMzAgFw0yMzA5MjgwNjU1NThaGA85OTk5MTIzMTIz\n"
+       "NTk1OVowDTELMAkGA1UEBhMCR1IwQzAFBgMrZXEDOgAYxZxGeKtoWUL20zvrFClm\n"
+       "irhECIIdccq6x0uZccYHfmRVkFoUI7iOFj6Mlsp5vg24XZ2tGF5MBACjYDBeMAwG\n"
+       "A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBTYq6RhA2qMWmYM\n"
+       "UAEx3AlNSnhWHDAfBgNVHSMEGDAWgBT5qIYZY7akFBNgdg8BmjU27/G0rzANBgkq\n"
+       "hkiG9w0BAQsFAAOCAYEAhEd0coRahGvMx8gLS8biuaqh50+9RJIjMpf+/0IQJ4DV\n"
+       "FHT5E70YyaQ0YOsvyxGa04d+KyhdVLppD1pDztLGXYZWxzmowopwpgnpPNT25M+0\n"
+       "aQOvCZZvRlqmwgUiRXdhSxqPsUj/73uUBPIjFknrxajoox7sOLris9ujmidqgBGa\n"
+       "H1FVbQQQgDOBCKcKXTAllVKzS/ZLwlRHibbm+4UDxGk1tJv1dbnQhJk0FYSQZn3h\n"
+       "ZVmSSfP4ZB+U+lsCshypBJ9qVZEqMM2b4m1wv/VAOuw0lGA2SiPub5q91hFYRdeL\n"
+       "9FB78/WlrSCTbGeMzzDPXBf/Y2KvFAv3o7K0tsMg1vBsDJBARHEzo4GMRsYDZzvI\n"
+       "JXb5tSmJOi/PBfup8GPiG0WbZV9nuvW8V/zmfaP3s9YBfYOtL/+nZch9VdSee2xp\n"
+       "T8arukB/s2jLaXQUduD3hoFvFNgCvWJwAWQWNNyHN3ivArqNQpfl2Gtftmb6xCdW\n"
+       "Xwt1/q2XKqqLpnF1N2wU\n"
+       "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t server_ca3_ed448_cert = {
+       (unsigned char *)server_ca3_ed448_cert_pem,
+       sizeof(server_ca3_ed448_cert_pem) - 1
+};
+
 static char server_ca3_gost01_key_pem[] =
        "-----BEGIN PRIVATE KEY-----\n"
        "MEUCAQAwHAYGKoUDAgITMBIGByqFAwICJAAGByqFAwICHgEEIgQgR1lBLIr4WBpn\n"
index c1bc81e5e9601dd6d7e5951b9e32ed011a83b808..9175727dc1faefcd6294ece69a2b146124ae6849 100644 (file)
@@ -64,8 +64,8 @@ static int pin_func(void *userdata, int attempt, const char *url,
        return -1;
 }
 
-#define myfail(fmt, ...)                                             \
-       fail("%s (iter %d): " fmt, gnutls_sign_get_name(sigalgo), i, \
+#define myfail(fmt, ...)                                              \
+       fail("%s (iter %zu): " fmt, gnutls_sign_get_name(sigalgo), i, \
             ##__VA_ARGS__)
 
 static unsigned verify_eddsa_presence(void)
@@ -85,11 +85,10 @@ static unsigned verify_eddsa_presence(void)
        return 0;
 }
 
-void doit(void)
+static void test(const char *name, const gnutls_datum_t *cert_pem,
+                const gnutls_datum_t *key_pem, gnutls_sign_algorithm_t sigalgo)
 {
-       char buf[128];
        int ret;
-       const char *lib, *bin;
        gnutls_x509_crt_t crt;
        gnutls_x509_privkey_t key;
        gnutls_datum_t tmp, sig;
@@ -98,51 +97,16 @@ void doit(void)
        gnutls_pubkey_t pubkey2;
        gnutls_pubkey_t pubkey3;
        gnutls_pubkey_t pubkey4;
-       unsigned i, sigalgo;
-
-       bin = softhsm_bin();
-
-       lib = softhsm_lib();
-
-       ret = global_init();
-       if (ret != 0) {
-               fail("%d: %s\n", ret, gnutls_strerror(ret));
-       }
-
-       if (gnutls_fips140_mode_enabled()) {
-               gnutls_global_deinit();
-               return;
-       }
-
-       gnutls_pkcs11_set_pin_function(pin_func, NULL);
-       gnutls_global_set_log_function(tls_log_func);
-       if (debug)
-               gnutls_global_set_log_level(4711);
-
-       set_softhsm_conf(CONFIG);
-       snprintf(buf, sizeof(buf),
-                "%s --init-token --slot 0 --label test --so-pin " PIN
-                " --pin " PIN,
-                bin);
-       system(buf);
-
-       ret = gnutls_pkcs11_add_provider(lib, NULL);
-       if (ret < 0) {
-               fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));
-       }
+       char buf[256];
+       size_t i;
 
-       if (verify_eddsa_presence() == 0) {
-               fprintf(stderr,
-                       "Skipping test as no EDDSA mech is supported\n");
-               exit(77);
-       }
+       success("%s\n", name);
 
        ret = gnutls_x509_crt_init(&crt);
        if (ret < 0)
                fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));
 
-       ret = gnutls_x509_crt_import(crt, &server_ca3_eddsa_cert,
-                                    GNUTLS_X509_FMT_PEM);
+       ret = gnutls_x509_crt_import(crt, cert_pem, GNUTLS_X509_FMT_PEM);
        if (ret < 0)
                fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
 
@@ -158,25 +122,12 @@ void doit(void)
                fail("gnutls_x509_privkey_init: %s\n", gnutls_strerror(ret));
        }
 
-       ret = gnutls_x509_privkey_import(key, &server_ca3_eddsa_key,
-                                        GNUTLS_X509_FMT_PEM);
+       ret = gnutls_x509_privkey_import(key, key_pem, GNUTLS_X509_FMT_PEM);
        if (ret < 0) {
                fail("gnutls_x509_privkey_import: %s\n", gnutls_strerror(ret));
        }
 
-       /* initialize softhsm token */
-       ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test");
-       if (ret < 0) {
-               fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
-       }
-
-       ret = gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN,
-                                         GNUTLS_PIN_USER);
-       if (ret < 0) {
-               fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret));
-       }
-
-       ret = gnutls_pkcs11_copy_x509_crt(SOFTHSM_URL, crt, "cert",
+       ret = gnutls_pkcs11_copy_x509_crt(SOFTHSM_URL, crt, name,
                                          GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE |
                                                  GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
        if (ret < 0) {
@@ -184,7 +135,7 @@ void doit(void)
        }
 
        ret = gnutls_pkcs11_copy_x509_privkey(
-               SOFTHSM_URL, key, "cert",
+               SOFTHSM_URL, key, name,
                GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
                GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE |
                        GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE |
@@ -199,7 +150,7 @@ void doit(void)
        assert(gnutls_pubkey_import_x509(pubkey, crt, 0) == 0);
 
        ret = gnutls_pkcs11_copy_pubkey(
-               SOFTHSM_URL, pubkey, "cert", NULL,
+               SOFTHSM_URL, pubkey, name, NULL,
                GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 0);
        if (ret < 0) {
                fail("gnutls_pkcs11_copy_pubkey: %s\n", gnutls_strerror(ret));
@@ -210,11 +161,13 @@ void doit(void)
        gnutls_pubkey_deinit(pubkey);
        gnutls_pkcs11_set_pin_function(NULL, NULL);
 
+       assert(snprintf(buf, sizeof(buf),
+                       "%s;object=%s;object-type=private?pin-value=" PIN,
+                       SOFTHSM_URL, name) < (int)sizeof(buf));
+
        assert(gnutls_privkey_init(&pkey) == 0);
 
-       ret = gnutls_privkey_import_pkcs11_url(
-               pkey,
-               SOFTHSM_URL ";object=cert;object-type=private;pin-value=" PIN);
+       ret = gnutls_privkey_import_pkcs11_url(pkey, buf);
        if (ret < 0) {
                fail("error in gnutls_privkey_import_pkcs11_url: %s\n",
                     gnutls_strerror(ret));
@@ -223,10 +176,7 @@ void doit(void)
        /* Try to read the public key with public key URI */
        assert(gnutls_pubkey_init(&pubkey3) == 0);
 
-       ret = gnutls_pubkey_import_pkcs11_url(
-               pubkey3,
-               SOFTHSM_URL ";object=cert;object-type=public;pin-value=" PIN,
-               0);
+       ret = gnutls_pubkey_import_pkcs11_url(pubkey3, buf, 0);
        if (ret < 0) {
                fail("error in gnutls_pubkey_import_pkcs11_url: %s\n",
                     gnutls_strerror(ret));
@@ -235,9 +185,7 @@ void doit(void)
        /* Try to read the public key with certificate URI */
        assert(gnutls_pubkey_init(&pubkey4) == 0);
 
-       ret = gnutls_pubkey_import_pkcs11_url(
-               pubkey4,
-               SOFTHSM_URL ";object=cert;object-type=cert;pin-value=" PIN, 0);
+       ret = gnutls_pubkey_import_pkcs11_url(pubkey4, buf, 0);
        if (ret < 0) {
                fail("error in gnutls_pubkey_import_pkcs11_url: %s\n",
                     gnutls_strerror(ret));
@@ -247,12 +195,9 @@ void doit(void)
        assert(gnutls_pubkey_import_privkey(pubkey, pkey, 0, 0) == 0);
 
        assert(gnutls_pubkey_init(&pubkey2) == 0);
-       assert(gnutls_pubkey_import_x509_raw(pubkey2, &server_ca3_eddsa_cert,
+       assert(gnutls_pubkey_import_x509_raw(pubkey2, cert_pem,
                                             GNUTLS_X509_FMT_PEM, 0) == 0);
 
-       /* this is the algorithm supported by the certificate */
-       sigalgo = GNUTLS_SIGN_EDDSA_ED25519;
-
        for (i = 0; i < 20; i++) {
                /* check whether privkey and pubkey are operational
                 * by signing and verifying */
@@ -284,6 +229,71 @@ void doit(void)
        gnutls_pubkey_deinit(pubkey2);
        gnutls_pubkey_deinit(pubkey);
        gnutls_privkey_deinit(pkey);
+}
+
+void doit(void)
+{
+       char buf[256];
+       int ret;
+       const char *lib, *bin;
+
+       bin = softhsm_bin();
+
+       lib = softhsm_lib();
+
+       ret = global_init();
+       if (ret != 0) {
+               fail("%d: %s\n", ret, gnutls_strerror(ret));
+       }
+
+       if (gnutls_fips140_mode_enabled()) {
+               gnutls_global_deinit();
+               return;
+       }
+
+       gnutls_pkcs11_set_pin_function(pin_func, NULL);
+       gnutls_global_set_log_function(tls_log_func);
+       if (debug)
+               gnutls_global_set_log_level(4711);
+
+       set_softhsm_conf(CONFIG);
+       assert(snprintf(buf, sizeof(buf),
+                       "%s --init-token --slot 0 --label test --so-pin " PIN
+                       " --pin " PIN,
+                       bin) < (int)sizeof(buf));
+       system(buf);
+
+       ret = gnutls_pkcs11_add_provider(lib, NULL);
+       if (ret < 0) {
+               fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));
+       }
+
+       if (verify_eddsa_presence() == 0) {
+               fprintf(stderr,
+                       "Skipping test as no EDDSA mech is supported\n");
+               exit(77);
+       }
+
+       /* initialize softhsm token */
+       ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test");
+       if (ret < 0) {
+               fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
+       }
+
+       ret = gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN,
+                                         GNUTLS_PIN_USER);
+       if (ret < 0) {
+               fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret));
+       }
+
+       test("ed25519", &server_ca3_eddsa_cert, &server_ca3_eddsa_key,
+            GNUTLS_SIGN_EDDSA_ED25519);
+
+       /* test clears PIN function to check "?pin-value" works */
+       gnutls_pkcs11_set_pin_function(pin_func, NULL);
+
+       test("ed448", &server_ca3_ed448_cert, &server_ca3_ed448_key,
+            GNUTLS_SIGN_EDDSA_ED448);
 
        gnutls_global_deinit();
 
index e9e8fcbf88a57be671cd51b8c4c799e7a98b9ccc..be765010944062b2c21929a8dbd5b148cbb2038b 100644 (file)
@@ -98,8 +98,7 @@ static void generate_keypair(gnutls_pk_algorithm_t algo, size_t bits,
                fail("%d: %s\n", ret, gnutls_strerror(ret));
        }
 
-       success("generated %s key (%s)\n",
-               gnutls_pk_get_name(algo),
+       success("generated %s key (%s)\n", gnutls_pk_get_name(algo),
                sensitive ? "sensitive" : "non sensitive");
 
        assert(gnutls_pkcs11_obj_init(&obj) >= 0);
@@ -131,6 +130,9 @@ void doit(void)
        char buf[128];
        int ret;
        const char *lib, *bin;
+#ifdef CKM_EC_EDWARDS_KEY_PAIR_GEN
+       CK_MECHANISM_INFO minfo;
+#endif
 
        if (gnutls_fips140_mode_enabled())
                exit(77);
@@ -174,13 +176,20 @@ void doit(void)
        generate_keypair(GNUTLS_PK_RSA, 2048, "rsa-non-sensitive", false);
 
 #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);
+       ret = gnutls_pkcs11_token_check_mechanism("pkcs11:token=test",
+                                                 CKM_EC_EDWARDS_KEY_PAIR_GEN,
+                                                 &minfo, sizeof(minfo), 0);
        if (ret != 0) {
                generate_keypair(GNUTLS_PK_EDDSA_ED25519, 256,
                                 "ed25519-sensitive", true);
                generate_keypair(GNUTLS_PK_EDDSA_ED25519, 256,
                                 "ed25519-non-sensitive", false);
+               if (minfo.ulMaxKeySize >= 456) {
+                       generate_keypair(GNUTLS_PK_EDDSA_ED448, 456,
+                                        "ed448-sensitive", true);
+                       generate_keypair(GNUTLS_PK_EDDSA_ED448, 456,
+                                        "ed448-non-sensitive", false);
+               }
        }
 #endif
 
index 023393c4c98e676dbe920bcadab385e47368ccb9..936a40f41960e045c541db8678d0c030ab25f333 100644 (file)
@@ -169,8 +169,8 @@ void doit(void)
        fp = fopen(certfile3, "wb");
        if (fp == NULL)
                fail("error in fopen\n");
-       assert(fwrite(cert_pem, 1, strlen((char *)cert_pem), fp) > 0);
-       assert(fwrite(key_pem, 1, strlen((char *)key_pem), fp) > 0);
+       assert(fwrite(cli_cert_pem, 1, strlen((char *)cli_cert_pem), fp) > 0);
+       assert(fwrite(cli_key_pem, 1, strlen((char *)cli_key_pem), fp) > 0);
        fclose(fp);
 
        ret = gnutls_certificate_set_x509_key_file2(