diff options
author | Werner Koch <[email protected]> | 2014-06-02 16:38:04 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2014-06-02 16:42:45 +0000 |
commit | d9cde7ba7d4556b216f062d0cf92d60cbb204b00 (patch) | |
tree | 8ac9ec1529c0e672bd92691c4bbb8c310a79f5ba /g10/parse-packet.c | |
parent | gpgsm: Handle re-issued CA certificates in a better way. (diff) | |
download | gnupg-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.c | 26 |
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; } |