Package: dumpasn1
Version: 20030222-3
Severity: normal
Tags: patch

OID numbers above LONG_MAX (or so) come out as the wrong number.  For
example, dumpasn1 displays an OID '2 25
339980965254958353768657297992075035931' as '2 25 -1512717029'.  

$ /usr/bin/dumpasn1 testie.der |grep '2 25'

0 warnings, 0 errors.
  39   20:           OBJECT IDENTIFIER '2 25 -1512717029'
 107   20:           OBJECT IDENTIFIER '2 25 -1512717029'

$ openssl x509 -in testie.der -inform der -noout -text |fgrep 2.25
        Issuer: 2.25.339980965254958353768657297992075035931=testie
        Subject: 2.25.339980965254958353768657297992075035931=testie

Example and patch attached.

-- System Information:
Debian Release: 5.0.4
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-2-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages dumpasn1 depends on:
ii  libc6                       2.7-18lenny2 GNU C Library: Shared libraries

dumpasn1 recommends no packages.

dumpasn1 suggests no packages.

-- no debconf information

Attachment: testie.der
Description: Binary data

--- dumpasn1.c	2010-03-11 00:39:31.462069896 -0500
+++ dumpasn1-jtobey.c	2010-03-11 22:55:01.926066435 -0500
@@ -1221,11 +1221,11 @@
 						const unsigned char *oid, const int oidLength )
 	{
 	long value;
-	int i, length, validEncoding = TRUE;
+	int i, length = 0, validEncoding = TRUE;
 
 	for( i = 0, value = 0; i < oidLength; i++ )
 		{
-		const unsigned char data = oid[ i ];
+		unsigned char data = oid[ i ];
 		const long valTmp = value << 7;
 
 		/* Pick apart the encoding.  We keep going after hitting an encoding
@@ -1238,9 +1238,47 @@
 			}
 		if( value >= ( LONG_MAX >> 7 ) || \
 			valTmp >= LONG_MAX - ( data & 0x7F ) )
-			validEncoding = FALSE;
+			{
+			/* Big integer */
+			char bigValue[ 128 ];
+			int end = 0;
+
+			/* Encode the current value in reverse decimal. */
+			while( value != 0 )
+				{
+				bigValue[ end++ ] = value % 10;
+				value /= 10;
+				}
+			while( 1 )
+				{
+				int carry = ( data & 0x7F );
+				int j;
+
+				/* Multiply by 128 and add base-128 digit. */
+				for( j = 0; j < end; j++ )
+					{
+					int product = ( bigValue[ j ] * 128 ) + carry;
+					bigValue[ j ] = product % 10;
+					carry = product / 10;
+					}
+				while( carry != 0 )
+					{
+					bigValue[ end++ ] = carry % 10;
+					carry /= 10;
+					}
+				if( !( data & 0x80 ) )
+					break;
+				data = oid[ ++i ];
+				}
+			/* Reverse, copy to output, and convert to characters. */
+			textOID[ length++ ] = ' ';
+			while( end > 0 )
+				textOID[ length++ ] = bigValue[ --end ] + '0';
+			continue;
+			}
+
 		value = valTmp | ( data & 0x7F );
-		if( value < 0 || value > LONG_MAX / 2 )
+		if( value < 0 )
 			validEncoding = FALSE;
 		if( !( data & 0x80 ) )
 			{

Reply via email to