On Feb 11, 2008 2:54 PM, Ludovic Rousseau <[EMAIL PROTECTED]> wrote: > Hello, > > It looks like the functions asn1_encode_integer() and > sc_asn1_decode_integer() from src/libopensc/asn1.c are not correct. > > For example the integer 128 is encoded 0x80 but should be encoded 0x00 > 0x80. 0x80 is the encoding of -128 > -128 is encoded FF FF FF 80 but I don't know if that is a valid coding. > > I am not expert in ASN.1 so am not sure it is a bug. > I found ASN.1 encoding examples in [1]: > ## > ## INTEGER (tests 13 - 21) > ## > > my %INTEGER = ( > pack("C*", 0x02, 0x02, 0x00, 0x80), 128, > pack("C*", 0x02, 0x01, 0x80), -128, > pack("C*", 0x02, 0x02, 0xff, 0x01), -255, > pack("C*", 0x02, 0x01, 0x00), 0, > pack("C*", 0x02, 0x03, 0x66, 0x77, 0x99), 0x667799, > pack("C*", 0x02, 0x02, 0xFE, 0x37), -457, > pack("C*", 0x02, 0x04, 0x40, 0x00, 0x00, 0x00), 2**30, > pack("C*", 0x02, 0x04, 0xC0, 0x00, 0x00, 0x00), -2**30, > ); > > > I propose the attached patch for asn1_encode_integer(). > sc_asn1_decode_integer() should also be patched.
The patch was not complete. The encoding of negative values was also wrong. A complete patch is attached. sc_asn1_decode_integer() should still decode INTEGERs encoded with the old/bogus encoding function. If nobody complains I will commit the patch. Bye, [1] http://search.cpan.org/src/GBARR/Convert-ASN1-0.21/t/00prim.t -- Dr. Ludovic Rousseau
Index: src/libopensc/asn1.c =================================================================== --- src/libopensc/asn1.c (révision 3386) +++ src/libopensc/asn1.c (copie de travail) @@ -533,6 +533,8 @@ int sc_asn1_decode_integer(const u8 * in if (inlen > sizeof(int)) return SC_ERROR_INVALID_ASN1_OBJECT; + if (inbuf[0] & 0x80) + a = -1; for (i = 0; i < inlen; i++) { a <<= 8; a |= *inbuf++; @@ -543,20 +545,53 @@ int sc_asn1_decode_integer(const u8 * in static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize) { - int i = sizeof(in) * 8, skip = 1; + int i = sizeof(in) * 8, skip_zero, skip_sign; u8 *p, b; - *obj = p = (u8 *) malloc(sizeof(in)); + if (in < 0) + { + skip_sign = 1; + skip_zero= 0; + } + else + { + skip_sign = 0; + skip_zero= 1; + } + *obj = p = (u8 *) malloc(sizeof(in)+1); if (*obj == NULL) return SC_ERROR_OUT_OF_MEMORY; do { i -= 8; b = in >> i; - if (b == 0 && skip) + if (skip_sign) + { + if (b != 0xff) + skip_sign = 0; + if (b & 0x80) + { + *p = b; + if (0xff == b) + continue; + } + else + { + p++; + skip_sign = 0; + } + } + if (b == 0 && skip_zero) continue; - skip = 0; + if (skip_zero) { + skip_zero = 0; + /* prepend 0x00 if MSb is 1 and integer positive */ + if ((b & 0x80) != 0 && in > 0) + *p++ = 0; + } *p++ = b; } while (i > 0); + if (skip_sign) + p++; *objsize = p - *obj; if (*objsize == 0) { *objsize = 1;
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel