[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: going back to stone axes



> From: cme@cybercash.com (Carl Ellison)
> 
> I'm not sure which way you're advocating, but the limitless length
> strings of ASN.1 is one of its biggest mistakes.  This is not a case of
> breaking away from 8+3 character file names.  A 16-bit string length is
> not infinite, but infinite enough for our purposes.  With radix64 encodings
> often presented as lines of less than 80 characters, far smaller strings
> are probably adequate.  However, a 16-bit byte count field greatly simplifies
> the life of an implementor over the baroque machinations which ASN.1
> encodings are forced to go through in order to accomodate infinite length
> strings.

I agree that the infinite-length capability of BER/DER (this isn't an
ASN.1 issue, it's an encoding rules issue) is kind of ugly, but
"greatly simplifies" and "baroque machinations" is a slight exaggeration.

Back when I got involved with certificate handling, I wrote an ASN.1/BER
dumper to display certificates (or any other BER transfer string) in raw
form.  The routine to retrieve an item (a Tag, Length, Value structure)
from the transfer string was 25 lines of C.

To suggest that infinite-length strings contribute significantly to
either code bloat or machine-cycle inefficiency over using a fixed
length field is not a convincing argument.  If this is your primary
objection to using X.509 certificates, forming an entirely new IETF
working group to address the problem seems like overkill :-).

I don't claim that the following code has any particular merit, but it
does work, and doesn't seem excessively baroque.  It does impose an
arbitrary string length limit of 2^32 bytes, but if that's too small,
the length field could easily be changed to a long long, which should
be sufficient for most purposes.


/*************************************************************************
 * Get an ASN.1 item, which includes: 1) Tag, 2) Length, and 3) Contents.
 ************************************************************************/
struct Item *
get_item(u_char *b)
{
        int  i, n;
        static struct Item a;

        if ((a.id = *b++) == 0)
            return ((struct Item *)0);
        if ((n = *b++) & LEN_XTND) {
            n &= LEN_MASK;
            if (n > 4) {
                printf("get_item: length too big! n=%d bytes\n", n);
                exit(1);
            }
            a.len = 0;
            for (i=0; i<n; i++)
                a.len = a.len << 8 | *b++;
        } else {
            a.len = n;
        }
        a.next = a.data = b;
        if ((a.id & CONSTRUCTED) == 0)
            a.next += a.len;
        return(&a);
}



Sorry for posting code; I know this isn't comp.sources, but sometimes
a concrete example is useful for it's expository value.