aboutsummaryrefslogtreecommitdiffstats
path: root/g10/parse-packet.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2014-06-02 16:38:04 +0000
committerWerner Koch <[email protected]>2014-06-02 16:42:45 +0000
commitd9cde7ba7d4556b216f062d0cf92d60cbb204b00 (patch)
tree8ac9ec1529c0e672bd92691c4bbb8c310a79f5ba /g10/parse-packet.c
parentgpgsm: Handle re-issued CA certificates in a better way. (diff)
downloadgnupg-d9cde7ba7d4556b216f062d0cf92d60cbb204b00.tar.gz
gnupg-d9cde7ba7d4556b216f062d0cf92d60cbb204b00.zip
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.
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r--g10/parse-packet.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 424b052b9..26ca0381f 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -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;
}