SPNEGO ASN.1 codec
Spnego ASN.1 State Automaton
The SPNEGO ASN.1 grammar seems very simple, but as there are a lot of optional elements, it is not that simple to implement...
It is fully described in RFC 2478.
Spnego Grammar
Here is the SPNEGO grammar :
NegotiationToken ::= CHOICE { negTokenInit [0] NegTokenInit, negTokenTarg [1] NegTokenTarg } NegTokenInit ::= SEQUENCE { mechTypes [0] MechTypeList OPTIONAL, reqFlags [1] ContextFlags OPTIONAL, mechToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL } NegTokenTarg ::= SEQUENCE { negResult [0] ENUMERATED { accept_completed (0), accept_incomplete (1), reject (2) } OPTIONAL, supportedMech [1] MechType OPTIONAL, responseToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL } MechTypeList ::= SEQUENCE OF MechType MechType::= OBJECT IDENTIFIER ContextFlags ::= BIT STRING { delegFlag (0), mutualFlag (1), replayFlag (2), sequenceFlag (3), anonFlag (4), confFlag (5), integFlag (6) }
Spnego state automaton
Here is the state automaton of this grammar :
We can see that the automaton is quite intricated. The following picture is a typical PDU of the first part of this grammar: the NegTokenInit element :
Of course, as some elements are optional, this PDU could be very different. Here is another PDU, where the reqFlags and the mechListMIC are missing :
Spnego used POJO's
We will store the result of a decoding in POJO's, where each constructed element is implemented as a POJO.
Spnego Neg Token INIT POJO
Here is the class diagram that could be used to store a SPNEGO negTokenInit:
This is a little bit complicated, and some classes could be implemented as members. We just have to aggregate the Length part of each POJO as members in the main POJO, to be able to check the length while processing the decoding.
Here is the definitive class diagram:
Spnego Neg Token Targ POJO
This POJO is a little simpler, as there is no recursive element.
The following schema shows a PDU where we can see the Length dependencies.
As we can see, we will have to keep a track of the expected length of following parts :
- The negTokenArg length must be equal to the length of the negTokenTargSequence TLV
- The negTokenTargSequence length must be equal to the sum of each included TLV
- and so on...