fixing a corrup keyring

Werner Koch wk at gnupg.org
Thu Apr 21 15:12:44 CEST 2005


On Tue, 19 Apr 2005 10:55:07 +0200, folkert  said:

> Hi,
> I have a keyring with quiet a few keys (thousands) and now something
> is wrong with it:
> gpg --list-keys gives
> gpg: Ohhhh jeeee: mpi crosses packet border

It is unfurtune that gpg bails out immediately in this caase.  In fact
it is not a bug (this is what the "Ohhh jeeee" shall indicate) but
currupt input data.  I have not created a test case yet but changed
the code to fail mopre gracefully.  This won't help too much I fear
but it is a first step to a recovery mode.

Please apply the attached patch against 1.4.1 or CVS.


Salam-Shalom,

   Werner

-------------- next part --------------
2005-04-21  Werner Koch  <wk at g10code.com>

	* mpicoder.c (mpi_read): Changed error detection to always return
	an error while maintaining the actual number of bytes read.


--- mpi/mpicoder.c	20 Dec 2004 10:05:20 -0000	1.33
+++ mpi/mpicoder.c	21 Apr 2005 13:21:15 -0000
@@ -1,5 +1,5 @@
 /* mpicoder.c  -  Coder for the external representation of MPIs
- * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -74,20 +74,23 @@ mpi_read(IOBUF inp, unsigned *ret_nread,
 #endif
 {
     int c, i, j;
+    unsigned int nmax = *ret_nread;
     unsigned nbits, nbytes, nlimbs, nread=0;
     mpi_limb_t a;
     MPI val = MPI_NULL;
 
     if( (c = iobuf_get(inp)) == -1 )
 	goto leave;
-    nread++;
+    if (++nread >= nmax)
+        goto overflow;
     nbits = c << 8;
     if( (c = iobuf_get(inp)) == -1 )
 	goto leave;
-    nread++;
+    if (++nread >= nmax)
+        goto overflow;
     nbits |= c;
     if( nbits > MAX_EXTERN_MPI_BITS ) {
-	log_error("mpi too large (%u bits)\n", nbits);
+	log_error("mpi too large for this implementation (%u bits)\n", nbits);
 	goto leave;
     }
 
@@ -108,6 +111,15 @@ mpi_read(IOBUF inp, unsigned *ret_nread,
     for( ; j > 0; j-- ) {
 	a = 0;
 	for(; i < BYTES_PER_MPI_LIMB; i++ ) {
+            if (nread >= nmax) {
+#ifdef M_DEBUG
+                mpi_debug_free (val);
+#else
+                mpi_free (val);
+#endif
+                val = NULL;
+                goto overflow;
+            }
 	    a <<= 8;
 	    a |= iobuf_get(inp) & 0xff; nread++;
 	}
@@ -116,10 +128,11 @@ mpi_read(IOBUF inp, unsigned *ret_nread,
     }
 
   leave:
-    if( nread > *ret_nread )
-	log_bug("mpi crosses packet border\n");
-    else
-	*ret_nread = nread;
+    *ret_nread = nread;
+    return val;
+  overflow:
+    log_error ("mpi larger than indicated length (%u bytes)\n", nmax);
+    *ret_nread = nread;
     return val;
 }
 


More information about the Gnupg-users mailing list