bug: gpg --edit [0-9].*

Michael Roth mroth at nessie.de
Tue Jul 20 23:39:25 CEST 1999


On Tue, 20 Jul 1999, Chip Christian wrote:

> I'm running gpg 0.98, and trying to sign someone else's key.  He happened 
> to have started his userid with the number 1.  gpg won't recognize it:

> pub  1024D/F5EA36A3 1999-07-16 1st Tech <webmaster at 1sttech.com>
> sub  3072g/48512CD9 1999-07-16

> Now I could sign is by dropping the leading digit, but as you can see that 
> would match the other key listed above.  I can ask him to change his key, 
> but it would be nice to see this work.

The solution to distinguish between ambiguous userids is to use the keyid.
In this example use 0xF5EA36A3 to choose the key you wish.

For the case where you don't would like to use the userid I wrote a small
patch which could resolve this issue. With this patch gpg is a little bit
more relaxed on interpreting a keyid or userid. Please write me if this
patch works for you.

To apply the patch change to the root of the GnuPG source directory (for
example "gnupg-0.9.8") and then type "patch -p1 <gnupg-new_key_select.diff" 
to apply the patch. After this, you must recompile GnuPG.


cu
		Michael


-------------- next part --------------
--- gnupg-cvs/gnupg/g10/getkey.c	Tue Jul 20 19:18:04 1999
+++ gnupg-new_key_select/g10/getkey.c	Tue Jul 20 21:52:21 1999
@@ -539,104 +539,131 @@
 classify_user_id( const char *name, u32 *keyid, byte *fprint,
 		  const char **retstr, size_t *retlen )
 {
-    const char *s;
-    int mode = 0;
-
-    /* check what kind of name it is */
+    const char *	s;
+    int 		mode = 0;
+    int			hexprefix = 0;
+    int			hexlength;
+    
+    /* skip leading spaces.   FIXME: what is with leading spaces? */
     for(s = name; *s && isspace(*s); s++ )
 	;
-    if( isdigit( *s ) ) { /* a keyid or a fingerprint */
-	int i, j;
-	char buf[9];
-
-	if( *s == '0' && s[1] == 'x' && isxdigit(s[2]) )
-	    s += 2; /*kludge to allow 0x034343434 */
-	for(i=0; isxdigit(s[i]); i++ )
-	    ;
-	if( s[i] && !isspace(s[i]) ) /* not terminated by EOS or blank*/
-	    return 0;
-	else if( i == 8 || (i == 9 && *s == '0') ) { /* short keyid */
-	    if( i==9 )
-		s++;
-	    if( keyid ) {
-		keyid[0] = 0;
-		keyid[1] = strtoul( s, NULL, 16 );
-	    }
-	    mode = 10;
-	}
-	else if( i == 16 || (i == 17 && *s == '0') ) { /* complete keyid */
-	    if( i==17 )
-		s++;
-	    mem2str(buf, s, 9 );
-	    keyid[0] = strtoul( buf, NULL, 16 );
-	    keyid[1] = strtoul( s+8, NULL, 16 );
-	    mode = 11;
-	}
-	else if( i == 32 || ( i == 33 && *s == '0' ) ) { /* md5 fingerprint */
-	    if( i==33 )
-		s++;
-	    if( fprint ) {
-		memset(fprint+16, 4, 0);
-		for(j=0; j < 16; j++, s+=2 ) {
-		    int c = hextobyte( s );
-		    if( c == -1 )
-			return 0;
-		    fprint[j] = c;
-		}
-	    }
-	    mode = 16;
-	}
-	else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/
-	    if( i==33 )
-		s++;
-	    if( fprint ) {
-		for(j=0; j < 20; j++, s+=2 ) {
-		    int c = hextobyte( s );
-		    if( c == -1 )
-			return 0;
-		    fprint[j] = c;
-		}
-	    }
-	    mode = 20;
-	}
-	else
-	    return 0;
+    
+    switch (*s) {
+        case 0:    /* empty string is an error */
+            return 0;
+        
+        case '.':  /* an email address, compare from end */
+            mode = 5;
+            s++;
+            break;
+        
+        case '<':  /* an email address */
+            mode = 3;
+            break;
+        
+        case '@':  /* part of an email address */
+            mode = 4;
+            s++;
+            break;
+        
+        case '=':  /* exact compare */
+            mode = 1;
+            s++;
+            break;
+        
+        case '*':  /* case insensitive substring search */
+            mode = 2;
+            s++;
+            break;
+        
+        case '+':  /* compare individual words */
+            mode = 6;
+            s++;
+            break;
+        
+        case '#':  /* local user id */
+            mode = 12;
+            s++;
+            if (keyid) {
+                if (keyid_from_lid(strtoul(s, NULL, 10), keyid))
+                    keyid[0] = keyid[1] = 0;
+            }
+            break;
+        
+        default:
+            if (s[0] == '0' && s[1] == 'x') {
+                hexprefix = 1;
+                s += 2;
+            }
+            
+            hexlength = strspn(s, "0123456789abcdefABCDEF");
+            
+            /* check if a hexadecimal number is terminated by EOS or blank */
+            if (hexlength && s[hexlength] && !isspace(s[hexlength])) {
+                if (hexprefix)
+                    return 0;		/* a "0x" prefix without correct termination is an error */
+                else
+                    hexlength = 0;	/* The first chars looked like a hex number, but really were not. */
+            }
+            
+            if (hexlength == 8 || (!hexprefix && hexlength == 9 && *s == '0')) {
+                /* short keyid */
+                if (hexlength == 9)
+                    s++;
+                if (keyid) {
+                    keyid[0] = 0;
+                    keyid[1] = strtoul( s, NULL, 16 );
+                }
+                mode = 10;
+            }
+            else if (hexlength == 16 || (!hexprefix && hexlength == 17 && *s == '0')) {
+                /* complete keyid */
+                char buf[9];
+                if (hexlength == 17)
+                    s++;
+                mem2str(buf, s, 9 );
+                keyid[0] = strtoul( buf, NULL, 16 );
+                keyid[1] = strtoul( s+8, NULL, 16 );
+                mode = 11;
+            }
+            else if (hexlength == 32 || (!hexprefix && hexlength == 33 && *s == '0')) {
+                /* md5 fingerprint */
+                int i;
+                if (hexlength == 33)
+                    s++;
+                if (fprint) {
+                    memset(fprint+16, 4, 0);
+                    for (i=0; i < 16; i++, s+=2) {
+                        int c = hextobyte(s);
+                        if (c == -1)
+                            return 0;
+                        fprint[i] = c;
+                    }
+                }
+                mode = 16;
+            }
+            else if (hexlength == 40 || (!hexprefix && hexlength == 41 && *s == '0')) {
+                /* sha1/rmd160 fingerprint */
+                int i;
+                if (hexlength == 41)
+                    s++;
+                if (fprint) {
+                    for (i=0; i < 20; i++, s+=2) {
+                        int c = hextobyte(s);
+                        if (c == -1)
+                            return 0;
+                        fprint[i] = c;
+                    }
+                }
+                mode = 20;
+            }
+            else {
+                if (hexprefix)
+                    return 0;		/* This was a hex number with a prefix and a wrong length */
+                
+                mode = 2;		/* Default is case insensitive substring search */
+            }
     }
-    else if( *s == '=' ) { /* exact search */
-	mode = 1;
-	s++;
-    }
-    else if( *s == '*' ) { /* substring search */
-	mode = 2;
-	s++;
-    }
-    else if( *s == '<' ) { /* an email address */
-	mode = 3;
-    }
-    else if( *s == '@' ) { /* a part of an email address */
-	mode = 4;
-	s++;
-    }
-    else if( *s == '.' ) { /* an email address, compare from end */
-	mode = 5;
-	s++;
-    }
-    else if( *s == '+' ) { /* word match mode */
-	mode = 6;
-	s++;
-    }
-    else if( *s == '#' ) { /* use local id */
-	mode = 12;
-	s++;
-	if( keyid ) {
-	    if( keyid_from_lid( strtoul( s, NULL, 10), keyid ) )
-		keyid[0] = keyid[1] = 0;
-	}
-    }
-    else if( !*s )  /* empty string */
-	return 0;
-    else
-	mode = 2;
 
     if( retstr )
 	*retstr = s;


More information about the Gnupg-devel mailing list