Aller au contenu
ecdsa.com
C · Ligne de commande

GnuTLS

GnuTLS, la bibliothèque TLS et X.509 du projet GNU : ECDSA en DER sur les courbes NIST, RFC 6979 via un indicateur, Ed25519 et Ed448, et, dans le build de distribution testé, ni secp256k1 ni algorithmes post-quantiques fonctionnels.
Licence
LGPL-2.1-or-later
Version vérifiée
3.8.13 ·
Code source
gitlab.com/gnutls/gnutls
Documentation
www.gnutls.org/manual/

Compatibilité en un coup d’œil

ECDSAEdDSA

Courbes ECDSA
P-224P-256P-384P-521
EdDSA
Ed25519Ed448

GnuTLS assure la gestion de TLS, de X.509 et de PKCS pour de nombreux composants GNU et Linux, et fournit certtool et gnutls-cli. Ses interfaces abstraites gnutls_privkey_* et gnutls_pubkey_* fonctionnent de la même façon pour les clés logicielles, les jetons PKCS#11 et les TPM. Les faits présentés ici ont été vérifiés sur le paquet Alpine 3.24.2, GnuTLS 3.8.13, qui utilise Nettle pour l’arithmétique. Depuis GnuTLS 3.8.10, les algorithmes post-quantiques proviennent uniquement de la bibliothèque optionnelle leancrypto, avec laquelle ce paquet n’est pas lié.

gnutls_privkey_sign_data renvoie des signatures ECDSA en DER avec un nonce aléatoire ; l’indicateur GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE fait passer à la RFC 6979, et avec lui le vecteur de test P-256 de la RFC a été reproduit exactement. s n’est pas normalisé et les signatures high-S passent la vérification. gnutls_privkey_sign_hash2 signe un condensat que vous avez calculé.

En cas d’échec, la vérification renvoie un code d’erreur négatif, et tous les types d’échec se sont présentés de la même façon : une signature r‖s brute, un blob de 3 octets et une signature valide portant sur d’autres données ont tous donné GNUTLS_E_PK_SIG_VERIFY_FAILED (-89). Utilisez le convertisseur DER ⇄ brut pour écarter un problème d’encodage.

ECDSA est limité aux courbes NIST de P-224 à P-521 (gnutls_ecc_curve_get_id("SECP256K1") a renvoyé 0, c’est-à-dire courbe inconnue), alors qu’Ed25519 et Ed448 ont tous deux réussi la signature et la vérification. Les en-têtes déclarent GNUTLS_PK_MLKEM768 et GNUTLS_PK_MLDSA65, mais ce build n’implémente ni l’un ni l’autre : ils sont absents de gnutls_pk_list(), la génération de clés ML-DSA-65 échoue avec GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM, et les groupes TLS listés par gnutls-cli --list comprennent X25519 et X448, mais aucun hybride ML-KEM. Un code qui compile avec ces constantes peut donc quand même échouer à l’exécution : vérifiez la liste fournie par l’environnement d’exécution. Examinez les certificats produits par certtool avec le décodeur de certificats.

Les faits et les vérifications qui les fondent

Rien de ce qui suit n’est copié d’une documentation. La vérification content/libraries/verify/gnutls/run.sh a exécuté GnuTLS 3.8.13 dans l’image de conteneur alpine:3.24.2 le 20 octobre 2026 ; la page doit correspondre à ce que la vérification a affiché, et chaque fait cite les lignes en question.

  • Encodage des signatures ECDSA

    der

    gnutls_privkey_sign_data renvoie du DER ASN.1.

    Relevé par la vérification
    fact ecdsa-signature-encoding = der
  • Nonce ECDSA

    rfc6979-opt-in

    Nonce aléatoire par défaut ; GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE a donné des signatures identiques et reproduit l’annexe A.2.5 de la RFC 6979.

    Relevé par la vérification
    fact ecdsa-nonce = rfc6979-opt-in
    evidence ecdsa-nonce: default repeats: no; GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE repeats: yes and reproduces the RFC 6979 A.2.5 r: yes
  • Low-S à la signature

    either

    s n’est pas normalisé : des valeurs high-S sont apparues parmi 64 signatures.

    Relevé par la vérification
    fact ecdsa-low-s-sign = either
  • High-S à la vérification

    accepts-high-s

    Une signature DER dont s a été remplacé par n − s a été vérifiée.

    Relevé par la vérification
    fact ecdsa-low-s-verify = accepts-high-s
  • Ce que l’appel de signature hache

    hashes-message-or-digest

    gnutls_privkey_sign_data hache les données ; gnutls_privkey_sign_hash2 signe un condensat, et cette signature a été vérifiée sur le message.

    Relevé par la vérification
    fact ecdsa-prehash = hashes-message-or-digest
  • Signature ECDSA mal formée

    returns-false

    Une signature r‖s brute, un blob de 3 octets et une signature valide portant sur d’autres données ont tous renvoyé GNUTLS_E_PK_SIG_VERIFY_FAILED (-89).

    Relevé par la vérification
    fact ecdsa-malformed-signature = returns-false
    evidence ecdsa-malformed-signature: gnutls_pubkey_verify_data2: raw r||s -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED), 3 bytes -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED), wrong message -89 (GNUTLS_E_PK_SIG_VERIFY_FAILED)
  • Courbes ECDSA

    P-224P-256P-384P-521

    P-224, P-256, P-384 et P-521 ; SECP256K1 n’est pas une courbe connue.

    Relevé par la vérification
    fact ecdsa-curves = P-224, P-256, P-384, P-521
    evidence ecdsa-curves: gnutls_ecc_curve_get_id("SECP256K1") = 0 (0 = unknown)
  • EdDSA

    Ed25519Ed448

    Génération de clés, signature et vérification réussies avec Ed25519 et Ed448.

    Relevé par la vérification
    fact eddsa = Ed25519, Ed448
    evidence eddsa: Ed25519: keygen GNUTLS_E_SUCCESS, sign ok, verify ok
    evidence eddsa: Ed448: keygen GNUTLS_E_SUCCESS, sign ok, verify ok
  • Algorithmes post-quantiques

    none

    ML-DSA et ML-KEM sont déclarés dans les en-têtes, mais absents de gnutls_pk_list() ; la génération de clés ML-DSA-65 a échoué, et X25519-MLKEM768 est un groupe inconnu.

    Relevé par la vérification
    fact pqc = none
    evidence pqc: the headers declare GNUTLS_PK_MLKEM768 = 14 and GNUTLS_PK_MLDSA65 = 16; gnutls_pk_list(): RSA, RSA-PSS, RSA-OAEP, RSA, DSA, GOST R 34.10-2012-512, GOST R 34.10-2012-256, GOST R 34.10-2001, EC/ECDSA, EdDSA (Ed25519), EdDSA (Ed448), DH, ECDH (X25519), ECDH (X448)
    evidence pqc: ML-DSA-65: in gnutls_pk_list: no; key generation GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM, sign and verify failed
    evidence pqc: ML-KEM-768: in gnutls_pk_list: no; gnutls_group_get_id("X25519-MLKEM768") = 0 (0 = unknown)
    evidence pqc: gnutls-cli --list Groups: GROUP-SECP192R1, GROUP-SECP224R1, GROUP-SECP256R1, GROUP-SECP384R1, GROUP-SECP521R1, GROUP-X25519, GROUP-GC256B, GROUP-GC512A, GROUP-X448, GROUP-FFDHE2048, GROUP-FFDHE3072, GROUP-FFDHE4096, GROUP-FFDHE6144, GROUP-FFDHE8192
    evidence pqc: shared libraries the gnutls package depends on: libbrotlidec.so.1 libbrotlienc.so.1 libc.musl-aarch64.so.1 libgmp.so.10 libhogweed.so.6 libidn2.so.0 libnettle.so.8 libp11-kit.so.0 libtasn1.so.6 libunistring.so.5 libz.so.1 libzstd.so.1 (GnuTLS 3.8.10 NEWS: PQC is only provided through leancrypto)

Utilisation

Générer une clé P-256, signer deux fois avec l’indicateur de reproductibilité et vérifier, en contrôlant que les signatures sont identiques.
#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    gnutls_global_init();
    gnutls_privkey_t priv;
    gnutls_pubkey_t pub;
    gnutls_privkey_init(&priv);
    gnutls_privkey_generate(priv, GNUTLS_PK_ECDSA, GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), 0);
    gnutls_pubkey_init(&pub);
    gnutls_pubkey_import_privkey(pub, priv, 0, 0);

    gnutls_datum_t msg = {(unsigned char *)"order #1042 approved", 20}, sig1, sig2;
    /* REPRODUCIBLE switches ECDSA to RFC 6979 nonces; the default is random. */
    gnutls_privkey_sign_data(priv, GNUTLS_DIG_SHA256, GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE, &msg, &sig1);
    gnutls_privkey_sign_data(priv, GNUTLS_DIG_SHA256, GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE, &msg, &sig2);

    /* Negative return codes mean failure; any malformed input is GNUTLS_E_PK_SIG_VERIFY_FAILED. */
    int rc = gnutls_pubkey_verify_data2(pub, GNUTLS_SIGN_ECDSA_SHA256, 0, &msg, &sig1);
    printf("verified: %d, deterministic: %d\n", rc >= 0, sig1.size == sig2.size && memcmp(sig1.data, sig2.data, sig1.size) == 0);
    gnutls_global_deinit();
    return 0;
}

Le banc de test des extraits de code exécute chaque exemple tel quel dans l’image de conteneur alpine:3.24.2, et l’exécution échoue si la sortie ne correspond pas.

Mise en place
apk add --no-cache -q build-base gnutls-dev=3.8.13-r0 >/dev/null
Commande
cc -o usage usage.c -lgnutls && ./usage
La sortie doit correspondre à cette expression régulière
verified: 1, deterministic: 1

Bibliothèques