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

Reply via email to