pem-dev
[Top] [All Lists]

Re: Kerberos v5's experience with ASN.1

1995-09-21 10:01:00
Carl,

From: Carl Ellison <cme(_at_)TIS(_dot_)COM>

From: Benjamin Pivnic <pivnic(_at_)norden1(_dot_)com>

[...] job of the encoding rules, such as BER, DER, PER, etc.  For example,
though the following is specified in ASN.1

       MyInt ::= INTEGER (123456789 .. 123456792)
       ix MyInt ::= 123456789

the value ix is encoded using DER in 6 bytes, while in PER it is
encoded in 2 bits (yes, bits).  The point is that ASN.1 has nothing to
do with how data is encoded or space usage, it is strictly used to
describe the fields in messages in a way that allows interoperability
regardless of the machine, OS or programming language in use.

And this was from a defender of ASN.1 !!  This construct is a wonderful
sample of the perversion which ASN.1 encourages.  Thank you for the
addition to my list.

I suspect that your (incorrect) conclusion that the above is a perversion
of ASN.1 is founded in the misconception of what ASN.1 is.  ASN.1 is
meant to describe data types, period.  Not how they are encoded.

Can you spell out in greater detail what you propose as an alternate to
ASN.1 and its encoding rules, other than that standards should say "put
this byte here and that one there"?

There are several alternatives but I'm still building my list and inviting
more.

The leading contender to me, so far, is a cleaned-up version of the
intersection between C and PASCAL structure declarations (cleaned up by
removal of the union construct, among a few other things).

The question is why one would use ASN.1 in the first place.

Among the reasons for using ASN.1 are:

1. It cleanly divorces the description of data types from any particular
language, so you can readily use such types in C, C++, Pascal, etc.,
all from a single data type description.

2. It gives the implementor the freedom to choose the C (or whatever
language) representation that is most suitable for their
implementation.  For example, one implementor may find it most
effective to represent a "SEQUENCE OF Names" as a doubly linked list
because they need to rapidly make insertions and deletions to the list
with a minimum of overhead, while another may find it most effective
to represent the same type as an array because they need rapid random
access to arbitrary elements in the array with minimum overhead.

3. It allows you to define "extensible" types, so that new fields can
later be added to the type in a wholly non-disruptive manner.  For
example, it allows you to define:

        Record ::= SEQUENCE {
                name    IA5String,
                age     INTEGER,
                ...
        }

Note the "...".  This is a very powerful feature of ASN.1:1994, for it
allows you to express in ASN.1 the fact that "Record" is extensible,
which means two different versions of software can continue to
interoperate even though one has more fields defined for it than the
other.  For example, in version 2 the above may be changed to:

        Record ::= SEQUENCE {
                name    IA5String,
                age     INTEGER,
                ...,
                address IA5String OPTIONAL
        }

Version 2 implementations thus know that they should expect version 1
records that are missing "address", and version 1 implementations know
that they should expect and ignore fields that they don't understand.
All this translates to there being no disruptions in services due to
having to shut down a part of a network to bring up a new software
version; different versions can continue talking with no difficulty.

4. It allows you to use the subtype notation to place constraints on the
set of values that a type can have.  For example:

        Record ::= SEQUENCE {
                name    IA5String (SIZE(1..100)),
                age     INTEGER (65..140),
                ...
        }

Since such constraints can be formally expressed in ASN.1 it allows ASN.1
compilers to generate code to perform such checks on your behalf.  This
results in your having to write fewer lines of code and thus there is less
likelihood for error, which translates into greater productivity on your part.

5. It allows for the definition of OPTIONAL fields.  Since it is often
the case that in a given message not all fields are required (e.g., a
person's name and address may be required, but their car's make and
model may be optional), ASN.1 allows you to define optional fields.
This not only allows you to define messages that reflect real life,
but reduces bandwidth by not encoding fillers for fields that are absent.

6. It frees application and protocol designers to focus on describing
the messages that they wish to exchange between application programs
without having to worry about the bits and bytes details of how such
messages are laid out while in transit between machines.  Yet, since
there are encoding rules designed expressly to work with types defined
in ASN.1, interoperability is guaranteed because they (encoding rules)
describe precisely how the data should look while on the wire.

7. It gives different sectors of industry the freedom to choose from
any of several encoding rules that are designed for use with ASN.1.
For example, those who have the need to work with older protocols or who
desire the highest degree of flexibility in how types are extended will
typically use BER, while those newer protocols that are more concerned
with the speed of encoding and in significant compaction of the encoded
data can use PER.

I do not want to be seduced into writing well-nested definitions (ala 
BNF), the way ASN.1 does, because that structure nesting is not what a
C or PASCAL programmer would do (because it leads to variable names with
too many fields). 

If you don't wish to write in this manner, don't.  C does not force you
to write using typedefs, nor does ASN.1 force you to write using type
references.

I do not want a
language which won't let me specify "unsigned char" without adding some
wart that requires runtime checking to an INTEGER specification. 

I have no idea what you are talking about.  In what way do you think
that ASN.1 requires runtime checking of an INTEGER specification, and
what wart having to do with "unsigned char" are you referring to?  None
of this is true.  ASN.1 does have syntax for constraining values, but
this does not require you to check such constraints (though it would
be wise for you to do so), nor does it require encoding rules to take
such constraints into consideration.

I do not want unlimited size INTEGERs as my only choice. 

Unlimited size INTEGERs are not your only choice.  You can, and
generally should, constrain them to describe the set of values that
you expect them to carry.

ASN.1 might be an interesting exercise for people who believe LISP is the
only real language or who really like to play with abstract syntax or who
like to write specs while ignoring implementations (ie., write standards).
It's *really* easy to write structure declarations in ASN.1 -- as long as
you don't try to implement from them.

I have implemented many a structure defined using ASN.1, and with
ease.  I find it even easier using an ASN.1 compiler, for it not only
generates the data structures for me, but generates the encoders/decoders 
and also ensures that my values are valid.

Bancroft Scott


<Prev in Thread] Current Thread [Next in Thread>