gpg: Graceful skip reading of corrupt MPIs.

* g10/parse-packet.c (mpi_read): Change error message on overflow.
--

This gets gpg 2.x in sync to what gpg 1.4 does.  No need to die for a
broken MPI.

GnuPG-bug-id: 1593

Resolved conflicts:
	g10/parse-packet.c - whitespaces fixes.
This commit is contained in:
Werner Koch 2014-06-02 18:38:04 +02:00
parent 715285bcbc
commit d9cde7ba7d
1 changed files with 18 additions and 8 deletions

View File

@ -107,27 +107,32 @@ read_32 (IOBUF inp)
static gcry_mpi_t
mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
{
/*FIXME: Needs to be synced with gnupg14/mpi/mpicoder.c */
int c, c1, c2, i;
unsigned int nmax = *ret_nread;
unsigned int nbits, nbytes;
size_t nread = 0;
gcry_mpi_t a = NULL;
byte *buf = NULL;
byte *p;
if (!nmax)
goto overflow;
if ((c = c1 = iobuf_get (inp)) == -1)
goto leave;
if (++nread == nmax)
goto overflow;
nbits = c << 8;
if ((c = c2 = iobuf_get (inp)) == -1)
goto leave;
++nread;
nbits |= c;
if (nbits > MAX_EXTERN_MPI_BITS)
{
log_error ("mpi too large (%u bits)\n", nbits);
goto leave;
}
nread = 2;
nbytes = (nbits + 7) / 8;
buf = secure ? gcry_xmalloc_secure (nbytes + 2) : gcry_xmalloc (nbytes + 2);
p = buf;
@ -136,18 +141,23 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure)
for (i = 0; i < nbytes; i++)
{
p[i + 2] = iobuf_get (inp) & 0xff;
if (nread == nmax)
goto overflow;
nread++;
}
if (gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buf, nread, &nread))
a = NULL;
*ret_nread = nread;
gcry_free(buf);
return a;
overflow:
log_error ("mpi larger than indicated length (%u bits)\n", 8*nmax);
leave:
gcry_free (buf);
if (nread > *ret_nread)
log_bug ("mpi larger than packet (%zu/%u)", nread, *ret_nread);
else
*ret_nread = nread;
*ret_nread = nread;
gcry_free(buf);
return a;
}