diff options
Diffstat (limited to 'lib/pubkey.c')
| -rw-r--r-- | lib/pubkey.c | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/lib/pubkey.c b/lib/pubkey.c index 8ff248e2cd..4d14c73547 100644 --- a/lib/pubkey.c +++ b/lib/pubkey.c @@ -50,7 +50,8 @@ int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params) return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]); case GNUTLS_PK_DSA: return _gnutls_mpi_get_nbits(params->params[DSA_P]); - case GNUTLS_PK_EC: + case GNUTLS_PK_ECDSA: + case GNUTLS_PK_EDDSA: return gnutls_ecc_curve_get_size(params->flags) * 8; default: return 0; @@ -289,7 +290,7 @@ gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key, if (mand) *mand = 1; /* fallthrough */ - case GNUTLS_PK_EC: + case GNUTLS_PK_ECDSA: me = _gnutls_dsa_q_to_hash(key->pk_algorithm, &key->params, NULL); if (hash) @@ -297,6 +298,12 @@ gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key, ret = 0; break; + case GNUTLS_PK_EDDSA: + if (hash) + *hash = GNUTLS_DIG_SHA512; + + ret = 0; + break; case GNUTLS_PK_RSA: if (hash) *hash = GNUTLS_DIG_SHA256; @@ -954,6 +961,7 @@ gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key, * This function will export the ECC public key's parameters found in * the given key. The new parameters will be allocated using * gnutls_malloc() and will be stored in the appropriate datum. + * For EdDSA public keys, @y will be set to %NULL. * * This function allows for %NULL parameters since 3.4.1. * @@ -973,7 +981,7 @@ gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, return GNUTLS_E_INVALID_REQUEST; } - if (key->pk_algorithm != GNUTLS_PK_EC) { + if (!IS_EC(key->pk_algorithm)) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } @@ -981,6 +989,17 @@ gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key, if (curve) *curve = key->params.flags; + if (key->pk_algorithm == GNUTLS_PK_EDDSA) { + if (x) { + ret = _gnutls_set_datum(x, key->params.raw_pub.data, key->params.raw_pub.size); + if (ret < 0) + return gnutls_assert_val(ret); + } + return 0; + } + + /* ECDSA */ + /* X */ if (x) { ret = _gnutls_mpi_dprint_lz(key->params.params[ECC_X], x); @@ -1395,7 +1414,8 @@ gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, * @y: holds the y * * This function will convert the given elliptic curve parameters to a - * #gnutls_pubkey_t. The output will be stored in @key. + * #gnutls_pubkey_t. The output will be stored in @key. For EdDSA + * keys the @y parameter should be %NULL. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. @@ -1420,6 +1440,19 @@ gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, key->params.flags = curve; + if (curve_is_eddsa(curve)) { + key->pk_algorithm = GNUTLS_PK_EDDSA; + + ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size); + if (ret < 0) + return gnutls_assert_val(ret); + + return 0; + } + + /* ECDSA */ + key->pk_algorithm = GNUTLS_PK_ECDSA; + if (_gnutls_mpi_init_scan_nz (&key->params.params[ECC_X], x->data, x->size)) { gnutls_assert(); @@ -1435,7 +1468,6 @@ gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key, goto cleanup; } key->params.params_nr++; - key->pk_algorithm = GNUTLS_PK_EC; return 0; @@ -1870,6 +1902,30 @@ dsa_verify_hashed_data(gnutls_pk_algorithm_t pk, } static int +eddsa_verify_data(gnutls_pk_algorithm_t pk, + const mac_entry_st * algo, + const gnutls_datum_t * data, + const gnutls_datum_t * signature, + gnutls_pk_params_st * params) +{ + int ret; + uint8_t _digest[MAX_HASH_SIZE]; + gnutls_datum_t digest; + + if (algo == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + ret = _gnutls_hash_fast(algo->id, data->data, data->size, _digest); + if (ret < 0) + return gnutls_assert_val(ret); + + digest.data = _digest; + digest.size = _gnutls_hash_get_algo_len(algo); + + return _gnutls_pk_verify(pk, &digest, signature, params); +} + +static int dsa_verify_data(gnutls_pk_algorithm_t pk, const mac_entry_st * algo, const gnutls_datum_t * data, @@ -1957,7 +2013,15 @@ pubkey_verify_data(gnutls_pk_algorithm_t pk, return 1; break; - case GNUTLS_PK_EC: + case GNUTLS_PK_EDDSA: + if (eddsa_verify_data(pk, me, data, signature, issuer_params) != 0) { + gnutls_assert(); + return GNUTLS_E_PK_SIG_VERIFY_FAILED; + } + + return 1; + break; + case GNUTLS_PK_ECDSA: case GNUTLS_PK_DSA: if (dsa_verify_data(pk, me, data, signature, issuer_params) != 0) { |
