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
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 ) ) {