mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-17 14:07:03 +01:00
gpg: Emit compatible Ed25519 signature.
* g10/pkglue.c (sexp_extract_param_sos_nlz): New. * g10/pkglue.h: Add the declaration. * g10/sign.c (do_sign): Use sexp_extract_param_sos_nlz for Ed25519. -- Ed25519 signature in GnuPG 2.2 has no leading zeros. GnuPG-bug-id: 5331 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
426d82fcf1
commit
61ac580a20
79
g10/pkglue.c
79
g10/pkglue.c
@ -47,8 +47,20 @@ get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SOS (Simply, Octet String) is an attempt to handle opaque octet
|
||||||
|
* string in OpenPGP, where well-formed MPI cannot represent octet
|
||||||
|
* string with leading zero octets.
|
||||||
|
*
|
||||||
|
* To retain maximum compatibility to existing MPI handling, SOS
|
||||||
|
* has same structure, but allows leading zero octets. When there
|
||||||
|
* is no leading zero octets, SOS representation is as same as MPI one.
|
||||||
|
* With leading zero octets, NBITS is 8*(length of octets), regardless
|
||||||
|
* of leading zero bits.
|
||||||
|
*/
|
||||||
/* Extract SOS representation from SEXP for PARAM, return the result
|
/* Extract SOS representation from SEXP for PARAM, return the result
|
||||||
in R_SOS. */
|
* in R_SOS. It is represented by opaque MPI with GCRYMPI_FLAG_USER2
|
||||||
|
* flag. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
sexp_extract_param_sos (gcry_sexp_t sexp, const char *param, gcry_mpi_t *r_sos)
|
sexp_extract_param_sos (gcry_sexp_t sexp, const char *param, gcry_mpi_t *r_sos)
|
||||||
{
|
{
|
||||||
@ -98,6 +110,71 @@ sexp_extract_param_sos (gcry_sexp_t sexp, const char *param, gcry_mpi_t *r_sos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* "No leading zero octets" (nlz) version of the function above.
|
||||||
|
*
|
||||||
|
* This routine is used for backward compatibility to existing
|
||||||
|
* implementation with the weird handling of little endian integer
|
||||||
|
* representation with leading zero octets. For the sake of
|
||||||
|
* "well-fomed" MPI, which is designed for big endian integer, leading
|
||||||
|
* zero octets are removed when output, and they are recovered at
|
||||||
|
* input.
|
||||||
|
*
|
||||||
|
* Extract SOS representation from SEXP for PARAM, removing leading
|
||||||
|
* zeros, return the result in R_SOS. */
|
||||||
|
gpg_error_t
|
||||||
|
sexp_extract_param_sos_nlz (gcry_sexp_t sexp, const char *param,
|
||||||
|
gcry_mpi_t *r_sos)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
gcry_sexp_t l2 = gcry_sexp_find_token (sexp, param, 0);
|
||||||
|
|
||||||
|
*r_sos = NULL;
|
||||||
|
if (!l2)
|
||||||
|
err = gpg_error (GPG_ERR_NO_OBJ);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t buflen;
|
||||||
|
const void *p0 = gcry_sexp_nth_data (l2, 1, &buflen);
|
||||||
|
|
||||||
|
if (!p0)
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gcry_mpi_t sos;
|
||||||
|
unsigned int nbits = buflen*8;
|
||||||
|
const unsigned char *p = p0;
|
||||||
|
|
||||||
|
/* Strip leading zero bits. */
|
||||||
|
for (; nbits >= 8 && !*p; p++, nbits -= 8)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (nbits >= 8 && !(*p & 0x80))
|
||||||
|
if (--nbits >= 7 && !(*p & 0x40))
|
||||||
|
if (--nbits >= 6 && !(*p & 0x20))
|
||||||
|
if (--nbits >= 5 && !(*p & 0x10))
|
||||||
|
if (--nbits >= 4 && !(*p & 0x08))
|
||||||
|
if (--nbits >= 3 && !(*p & 0x04))
|
||||||
|
if (--nbits >= 2 && !(*p & 0x02))
|
||||||
|
if (--nbits >= 1 && !(*p & 0x01))
|
||||||
|
--nbits;
|
||||||
|
|
||||||
|
sos = gcry_mpi_set_opaque_copy (NULL, p, nbits);
|
||||||
|
if (sos)
|
||||||
|
{
|
||||||
|
gcry_mpi_set_flag (sos, GCRYMPI_FLAG_USER2);
|
||||||
|
*r_sos = sos;
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
gcry_sexp_release (l2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static byte *
|
static byte *
|
||||||
get_data_from_sexp (gcry_sexp_t sexp, const char *item, size_t *r_size)
|
get_data_from_sexp (gcry_sexp_t sexp, const char *item, size_t *r_size)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt);
|
gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt);
|
||||||
gpg_error_t sexp_extract_param_sos (gcry_sexp_t sexp, const char *param,
|
gpg_error_t sexp_extract_param_sos (gcry_sexp_t sexp, const char *param,
|
||||||
gcry_mpi_t *r_sos);
|
gcry_mpi_t *r_sos);
|
||||||
|
gpg_error_t sexp_extract_param_sos_nlz (gcry_sexp_t sexp, const char *param,
|
||||||
|
gcry_mpi_t *r_sos);
|
||||||
|
|
||||||
int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data,
|
int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data,
|
||||||
gcry_mpi_t *pkey);
|
gcry_mpi_t *pkey);
|
||||||
|
@ -506,6 +506,13 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
|
|||||||
else if (pksk->pubkey_algo == GCRY_PK_RSA
|
else if (pksk->pubkey_algo == GCRY_PK_RSA
|
||||||
|| pksk->pubkey_algo == GCRY_PK_RSA_S)
|
|| pksk->pubkey_algo == GCRY_PK_RSA_S)
|
||||||
sig->data[0] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG);
|
sig->data[0] = get_mpi_from_sexp (s_sigval, "s", GCRYMPI_FMT_USG);
|
||||||
|
else if (pksk->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||||
|
&& openpgp_oid_is_ed25519 (pksk->pkey[0]))
|
||||||
|
{
|
||||||
|
err = sexp_extract_param_sos_nlz (s_sigval, "r", &sig->data[0]);
|
||||||
|
if (!err)
|
||||||
|
err = sexp_extract_param_sos_nlz (s_sigval, "s", &sig->data[1]);
|
||||||
|
}
|
||||||
else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||||
|| pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
|
|| pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user