1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: Fix modifying signature data by pk_verify for Ed25519.

* g10/pkglue.c (pk_verify): When fixing R and S, make sure those are
copies.

--

GnuPG-bug-id: 7426
Fixing-commit: 0a5a854510fda6e6990938a3fca424df868fe676
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>

Also avoid clearing the error by the S code of a failed mpi_print of
R.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
NIIBE Yutaka 2024-11-25 14:39:59 +09:00 committed by Werner Koch
parent 72c5f7b0f7
commit 7c378e0be7
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -323,9 +323,18 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
rc = gpg_error (GPG_ERR_BAD_MPI); rc = gpg_error (GPG_ERR_BAD_MPI);
else else
{ {
r = gcry_mpi_copy (r);
s = gcry_mpi_copy (s);
if (!r || !s)
{
rc = gpg_error_from_syserror ();
goto leave;
}
/* We need to fixup the length in case of leading zeroes. /* We need to fixup the length in case of leading zeroes.
* OpenPGP does not allow leading zeroes and the parser for * OpenPGP does not allow leading zeroes and the parser for
* the signature packet has no information on the use curve, * the signature packet has no information on the used curve,
* thus we need to do it here. We won't do it for opaque * thus we need to do it here. We won't do it for opaque
* MPIs under the assumption that they are known to be fine; * MPIs under the assumption that they are known to be fine;
* we won't see them here anyway but the check is anyway * we won't see them here anyway but the check is anyway
@ -335,12 +344,13 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
if (rlen < neededfixedlen if (rlen < neededfixedlen
&& !gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE) && !gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE)
&& !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, r))) && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG,
buf, sizeof buf, &n, r)))
{ {
log_assert (n < neededfixedlen); log_assert (n < neededfixedlen);
memmove (buf + (neededfixedlen - n), buf, n); memmove (buf + (neededfixedlen - n), buf, n);
memset (buf, 0, neededfixedlen - n); memset (buf, 0, neededfixedlen - n);
r = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); gcry_mpi_set_opaque_copy (r, buf, neededfixedlen * 8);
} }
else if (rlen < neededfixedlen else if (rlen < neededfixedlen
&& gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE)) && gcry_mpi_get_flag (r, GCRYMPI_FLAG_OPAQUE))
@ -353,14 +363,18 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
memset (buf, 0, neededfixedlen - n); memset (buf, 0, neededfixedlen - n);
gcry_mpi_set_opaque_copy (r, buf, neededfixedlen * 8); gcry_mpi_set_opaque_copy (r, buf, neededfixedlen * 8);
} }
if (slen < neededfixedlen
if (rc)
;
else if (slen < neededfixedlen
&& !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE) && !gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE)
&& !(rc=gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, s))) && !(rc=gcry_mpi_print (GCRYMPI_FMT_USG,
buf, sizeof buf, &n, s)))
{ {
log_assert (n < neededfixedlen); log_assert (n < neededfixedlen);
memmove (buf + (neededfixedlen - n), buf, n); memmove (buf + (neededfixedlen - n), buf, n);
memset (buf, 0, neededfixedlen - n); memset (buf, 0, neededfixedlen - n);
s = gcry_mpi_set_opaque_copy (NULL, buf, neededfixedlen * 8); gcry_mpi_set_opaque_copy (s, buf, neededfixedlen * 8);
} }
else if (slen < neededfixedlen else if (slen < neededfixedlen
&& gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE)) && gcry_mpi_get_flag (s, GCRYMPI_FLAG_OPAQUE))
@ -408,6 +422,7 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
if (!rc) if (!rc)
rc = gcry_pk_verify (s_sig, s_hash, s_pkey); rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
leave:
gcry_sexp_release (s_sig); gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey); gcry_sexp_release (s_pkey);