6 Appendix A: Full NEGOEX

For ease of implementation, the following is the full NEGOEX version 4 syntax for this protocol, as defined in [IETFDRAFT-NEGOEX-04].

 #define MESSAGE_SIGNATURE   0x535458454f47454ei64  // "NEGOEXTS"
  
 struct
 {
    ULONG ByteArrayOffset; // each element contains a byte
    ULONG ByteArrayLength;
 } BYTE_VECTOR;
  
 struct
 {
   ULONG AuthSchemeArrayOffset;  // each element contains an AUTH_SCHEME
   USHORT AuthSchemeCount;
 } AUTH_SCHEME_VECTOR;
  
 struct
 {
   ULONG ExtensionArrayOffset;  // each element contains an EXTENSION
   USHORT ExtensionCount;
 } EXTENSION_VECTOR;
  
 struct
 {
   ULONG ExtensionType; // negative extensions are critical
   BYTE_VECTOR ExtensionValue;
 } EXTENSION;
  
 //
 // schemes defined for the checksum in the VERIFY message
 //
  
 #define CHECKSUM_SCHEME_RFC3961  1
 struct
 {
   ULONG cbHeaderLength;
   ULONG ChecksumScheme;
   ULONG ChecksumType; // in the case of RFC3961 scheme, this is the RFC3961 checksum type
   BYTE_VECTOR ChecksumValue;
} CHECKSUM;
 
 typedef GUID AUTH_SCHEME;
typedef GUID CONVERSATION_ID;
 
 enum
 {
   MESSAGE_TYPE_INITIATOR_NEGO = 0,
   MESSAGE_TYPE_ACCEPTOR_NEGO,
   MESSAGE_TYPE_INITIATOR_META_DATA,
   MESSAGE_TYPE_ACCEPTOR_META_DATA,
   MESSAGE_TYPE_CHALLENGE,   // an exchange message from the acceptor
   MESSAGE_TYPE_AP_REQUEST,  // an exchange message from the initiator
   MESSAGE_TYPE_VERIFY,
   MESSAGE_TYPE_ALERT,
} MESSAGE_TYPE;
  
 struct
 {
   ULONG64 Signature; // contains MESSAGE_SIGNATURE
   MESSAGE_TYPE MessageType;
   ULONG SequenceNum; 
     // the message sequence number of this, conversation,
     // starting with 0 and sequentially incremented
   ULONG cbHeaderLength; 
     // the header length of this message, including
     // the message specific header, excluding the payload
   ULONG cbMessageLength; // the length of this message
   CONVERSATION_ID ConversationId;
} MESSAGE_HEADER;
  
 struct
 {
   MESSAGE_HEADER Header;  
     // MESSAGE_TYPE_INITIATOR_NEGO for the initiator,
     // MESSAGE_TYPE_ACCEPTOR_NEGO for the acceptor
   UCHAR Random[32];
   ULONG64 ProtocolVersion;  // version of the protocol, this contains 0
   AUTH_SCHEME_VECTOR AuthSchemes;
   EXTENSION_VECTOR Extensions;
} NEGO_MESSAGE;
 
 struct
 {
   MESSAGE_HEADER Header;
     // MESSAGE_TYPE_CHALLENGE for the acceptor, or
     // MESSAGE_TYPE_AP_REQUEST for the initiator
     // MESSAGE_TYPE_INITIATOR_META_DATA for the initiator metadata
     // MESSAGE_TYPE_ACCEPTOR_META_DATA for the acceptor metadata
   AUTH_SCHEME AuthScheme;
   BYTE_VECTOR Exchange; 
     // contains the opaque handshake message for the authentication scheme
} EXCHANGE_MESSAGE;
 
 struct
 {
   MESSAGE_HEADER Header; // MESSAGE_TYPE_VERIFY
   AUTH_SCHEME AuthScheme;
   CHECKSUM Checksum;
     // contains the checksum of all the previously
     // exchanged messages in the order they were sent.
} VERIFY_MESSAGE;
 
 struct
 {
   ULONG AlertType;
   BYTE_VECTOR AlertValue;
 } ALERT;
  
 //
 // alert types
 //
  
 #define ALERT_TYPE_PULSE  1
  
 //
 // reason codes for the heartbeat message
 //
  
 #define ALERT_VERIFY_NO_KEY  1
  
 struct
 {
   ULONG cbHeaderLength;
   ULONG Reason;
} ALERT_PULSE;
 
 struct
 {
   ULONG AlertArrayOffset; // the element is an ALERT
   USHORT AlertCount; // contains the number of alerts
} ALERT_VECTOR;
 
 struct
 {
   MESSAGE_HEADER Header;
   AUTH_SCHEME AuthScheme;
   ULONG ErrorCode; // an NTSTATUS code
   ALERT_VECTOR Alerts;
} ALERT_MESSAGE;