|
|
//==============================================================================
//
// MODULE: ASN1Parser.hxx
//
// Description:
//
// Basic building blocks for ASN.1 parsing
//
// Modification History
//
// Mark Pustilnik Date: 06/08/02 - created
//
//==============================================================================
#ifndef __ASN1PARSER_HXX
#define __ASN1PARSER_HXX
#include <windows.h>
#include <netmon.h>
#include <kerbcon.h>
#include <ntsecapi.h>
#include "..\inc\kerberr.h"
//
// Utility macros
//
#define ARRAY_COUNT( a ) ( sizeof( a ) / sizeof ( a[ 0 ] ) )
#define SET_OF( s ) { ARRAY_COUNT( s ), s }
//
// Shortcut for property access
//
#define PROP( a ) g_KerberosDatabase[a].hProperty
//
// Kerberos packet types
//
enum { ASN1_KRB_AS_REQ = 0x0A, ASN1_KRB_AS_REP = 0x0B, ASN1_KRB_TGS_REQ = 0x0C, ASN1_KRB_TGS_REP = 0x0D, ASN1_KRB_AP_REQ = 0x0E, ASN1_KRB_AP_REP = 0x0F, ASN1_KRB_SAFE = 0x14, ASN1_KRB_PRIV = 0x15, ASN1_KRB_CRED = 0x16, ASN1_KRB_ERROR = 0x1E, };
//
// Kerberos address types
//
enum { KERB_ADDRTYPE_UNSPEC = 0x0, KERB_ADDRTYPE_LOCAL = 0x1, KERB_ADDRTYPE_INET = 0x2, KERB_ADDRTYPE_IMPLINK = 0x3, KERB_ADDRTYPE_PUP = 0x4, KERB_ADDRTYPE_CHAOS = 0x5, KERB_ADDRTYPE_NS = 0x6, KERB_ADDRTYPE_NBS = 0x7, KERB_ADDRTYPE_ECMA = 0x8, KERB_ADDRTYPE_DATAKIT = 0x9, KERB_ADDRTYPE_CCITT = 0xA, KERB_ADDRTYPE_SNA = 0xB, KERB_ADDRTYPE_DECnet = 0xC, KERB_ADDRTYPE_DLI = 0xD, KERB_ADDRTYPE_LAT = 0xE, KERB_ADDRTYPE_HYLINK = 0xF, KERB_ADDRTYPE_APPLETALK = 0x10, KERB_ADDRTYPE_BSC = 0x11, KERB_ADDRTYPE_DSS = 0x12, KERB_ADDRTYPE_OSI = 0x13, KERB_ADDRTYPE_NETBIOS = 0x14, KERB_ADDRTYPE_X25 = 0x15, KERB_ADDRTYPE_IPv6 = 0x18, };
//
// PAC Sections
//
enum { PAC_LOGON_INFO = 1, PAC_CREDENTIAL_TYPE = 2, PAC_SERVER_CHECKSUM = 6, PAC_PRIVSVR_CHECKSUM = 7, PAC_CLIENT_INFO_TYPE = 10, PAC_DELEGATION_INFO = 11, PAC_CLIENT_IDENTITY = 13, PAC_COMPOUND_IDENTITY = 14, };
//
// Netmon property IDs
//
enum { KRB_AS_REQ, KRB_AS_REP, KRB_TGS_REQ, KRB_TGS_REP, KRB_AP_REQ, KRB_AP_REP, KRB_SAFE, KRB_PRIV, KRB_CRED, KRB_ERROR, HostAddresses_HostAddress, EncryptedData_etype, EncryptedData_kvno, EncryptedData_cipher, PA_DATA_type, PA_DATA_value, PrincipalName_type, PrincipalName_string, Ticket_tkt_vno, Ticket_realm, Ticket_sname, Ticket_enc_part, AP_REQ_pvno, AP_REQ_msg_type, AP_REQ_ap_options_summary, AP_REQ_ap_options_value, AP_REQ_ticket, AP_REQ_authenticator, KDC_REQ_BODY_kdc_options_summary, KDC_REQ_BODY_kdc_options_value, KDC_REQ_BODY_cname, KDC_REQ_BODY_realm, KDC_REQ_BODY_sname, KDC_REQ_BODY_from, KDC_REQ_BODY_till, KDC_REQ_BODY_rtime, KDC_REQ_BODY_nonce, KDC_REQ_BODY_etype, KDC_REQ_BODY_addresses, KDC_REQ_BODY_enc_authorization_data, KDC_REQ_BODY_additional_tickets, KDC_REQ, KDC_REQ_pvno, KDC_REQ_msg_type, KDC_REQ_padata, KDC_REQ_req_body, KDC_REP_pvno, KDC_REP_msg_type, KDC_REP_padata, KDC_REP_crealm, KDC_REP_cname, KDC_REP_ticket, KDC_REP_enc_part, KRB_ERR_pvno, KRB_ERR_msg_type, KRB_ERR_ctime, KRB_ERR_cusec, KRB_ERR_stime, KRB_ERR_susec, KRB_ERR_error_code, KRB_ERR_crealm, KRB_ERR_cname, KRB_ERR_realm, KRB_ERR_sname, KRB_ERR_e_text, KRB_ERR_e_data, KERB_PA_PAC_REQUEST_include_pac, KERB_PA_PAC_REQUEST_EX_include_pac, KERB_PA_PAC_REQUEST_EX_pac_sections, KERB_PA_PAC_REQUEST_EX_pac_sections_desc, KERB_ETYPE_INFO_ENTRY_encryption_type, KERB_ETYPE_INFO_ENTRY_salt, KERB_PREAUTH_DATA_LIST, TYPED_DATA_type, TYPED_DATA_value, PA_PW_SALT_salt, PA_FOR_USER_userName, PA_FOR_USER_userRealm, PA_FOR_USER_cksum, PA_FOR_USER_authentication_package, PA_FOR_USER_authorization_data, KERB_CHECKSUM_type, KERB_CHECKSUM_checksum, AdditionalTicket, EncryptionType, ContinuationPacket, INTEGER_NOT_IN_ASN, CompoundIdentity, CompoundIdentityTicket, MAX_PROP_VALUE, // dummy value to ensure consistency
};
//
// externs
//
extern PROPERTYINFO g_KerberosDatabase[MAX_PROP_VALUE];
//==============================================================================
//
// ASN.1 constructs
//
//==============================================================================
//
// Class tags
//
typedef enum ClassTag { ctUniversal = 0x00, // 00000000
ctApplication = 0x40, // 01000000
ctContextSpecific = 0x80, // 10000000
ctPrivate = 0xC0, // 11000000
};
inline ClassTag ClassTagFromByte( IN BYTE b ) { return (ClassTag)( b & 0xC0 ); }
//
// Primitive-Constructed
//
typedef enum PC { pcPrimitive = 0x00, // 00000000
pcConstructed = 0x20, // 00100000
};
inline PC PCFromByte( IN BYTE b ) { return (PC)( b & 0x20 ); }
//
// Tags
//
const BYTE MaxTag = 0x1F; // Max value of a tag
inline BYTE TagFromByte( IN BYTE b ) { return ( b & 0x1F ); // Tags are 5 bits long
}
//
// Universal tags
//
typedef enum UniversalTag { utBoolean = 0x01, // 00001
utInteger = 0x02, // 00010
utBitString = 0x03, // 00011
utOctetString = 0x04, // 00100
utNULL = 0x05, // 00101
utObjectIdentifer = 0x06, // 00110
utObjectDescriptor = 0x07, // 00111
utExternal = 0x08, // 01000
utReal = 0x09, // 01001
utEnumerated = 0x0A, // 01010
utSequence = 0x10, // 10000
utSet = 0x11, // 10001
utNumericString = 0x12, // 10010
utPrintableString = 0x13, // 10011
utT61String = 0x14, // 10100
utVideotexString = 0x15, // 10101
utIA5String = 0x16, // 10110
utUTCTime = 0x17, // 10111
utGeneralizedTime = 0x18, // 11000
utGraphicString = 0x19, // 11001
utVisibleString = 0x1A, // 11010
utGeneralString = 0x1B, // 11011
};
inline BYTE BuildDescriptor( IN ClassTag ct, IN PC pc, IN ULONG tag ) { //
// TODO: add an assert that tag fits in one byte (or rather 0x1F bits)
//
return (BYTE)ct | (BYTE)pc | ((BYTE)tag & 0x1F ); }
//==============================================================================
//
// Class declarations
//
//==============================================================================
struct ASN1FRAME { //
// Starting address of the frame
//
ULPBYTE Address;
//
// Netmon frame handle
//
HFRAME hFrame;
//
// Netmon indentation offset
//
DWORD Level; };
// Necessary forward declaration for the subparser member
class ASN1ParserBase;
struct ASN1VALUE { //
// Constructor and destructor
//
ASN1VALUE( ) : Address( NULL ), Length( 0 ), ut( utNULL ), Allocated( FALSE ), SubParser( NULL ) {}
~ASN1VALUE();
void Purge() { if ( Allocated && ( ut == utOctetString || ut == utGeneralString )) { delete [] string.s; string.s = NULL; string.l = 0; } }
//
// Creates dynamically allocated copy of ASN1VALUE passed in
//
ASN1VALUE * Clone();
//
// Address of the actual unadulterated value
//
ULPBYTE Address;
//
// Length of the actual unadulterated value
//
DWORD Length;
//
// Type of value that follows
//
UniversalTag ut;
//
// Dynamically allocated? ('s' only)
//
BOOL Allocated;
union { BOOL b; // utBoolean
DWORD dw; // utInteger, utBitString
struct { ULONG l; ULPBYTE s; } string; // utOctetString, utGeneralString
SYSTEMTIME st; // utGeneralizedTime
};
//
// Subparser (for binary blob types only)
//
ASN1ParserBase * SubParser; // TODO: refcount this type if deep copy becomes necessary
};
typedef ASN1VALUE * PASN1VALUE;
// -----------------------------------------------------------------------------
//
// +----------------+
// | ASN1ParserBase |<------------------------+
// +----------------+ |
// ^ |
// | |
// +----------------+------------------+ |
// | | |
// +----------------+ +--------------------+ |
// | ASN1ParserUnit | | ASN1ParserSequence |<>--+
// +----------------+ +--------------------+
//
// -----------------------------------------------------------------------------
class ASN1ParserSequence; // necessary forward declaration for value collectors
class ASN1ParserBase { public:
//
// Constructor and destructor
//
ASN1ParserBase( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySummary, IN HPROPERTY hPropertyValue ) : m_IsOptional( IsOptional ), m_Descriptor( Descriptor ), m_AppDescriptor( 0 ), m_hPropertySummary( hPropertySummary ), m_hPropertyValue( hPropertyValue ), m_Modifier( NULL ), m_Modifyee( NULL ), m_ValueCollector( NULL ) {}
virtual ~ASN1ParserBase() { delete m_Modifier; }
//
// Parses the data in the block pointed to by the Frame,
// and displays the resulting data in the appropriate format
// Upon exit, Frame points to the next block to be parsed
//
virtual DWORD Parse( IN OUT ASN1FRAME * Frame ) = 0;
DWORD Display( IN ASN1FRAME * Frame, IN ASN1VALUE * Value, IN HPROPERTY hProperty, IN DWORD IFlags );
//
// Computes length of the block pointed to by Frame
//
DWORD DataLength( IN ASN1FRAME * Frame );
//
// Queries "optionality" of this parser block
//
BOOL IsOptional() { return m_IsOptional; }
//
// "Modifiers" are values which affect subsequent parsing
// in a context-specific fashion
//
DWORD SetModifier( IN ASN1VALUE * NewModifier ) { ASN1VALUE * Modifier = NewModifier->Clone();
if ( Modifier == NULL ) { return ERROR_NOT_ENOUGH_MEMORY; }
delete m_Modifier; m_Modifier = Modifier;
return ERROR_SUCCESS; }
ASN1VALUE * QueryModifier() { return m_Modifier; }
//
// "Modifyees" are objects being modified during parsing
//
void SetModifyee( IN ASN1ParserBase * Modifyee ) { m_Modifyee = Modifyee; }
ASN1ParserBase * QueryModifyee() { return m_Modifyee; }
//
// A parser can have a 'value collector' - a sequence object
// which collects the values parsed out by this parser for subsequent
// processing and display
//
void SetValueCollector( IN ASN1ParserSequence * ValueCollector ) { m_ValueCollector = ValueCollector; }
ASN1ParserSequence * QueryValueCollector() { return m_ValueCollector; }
protected:
//
// Verifies the item header and skips past the item length block
// that follows it
//
DWORD VerifyAndSkipHeader( IN OUT ASN1FRAME * Frame );
//
// Computes the length of the length header
//
ULONG HeaderLength( IN ULPBYTE Address );
//
// Netmon property handles
// Either is optional, if both are present, they are displayed
// in a hierarchical fashion
//
HPROPERTY m_hPropertySummary; HPROPERTY m_hPropertyValue;
//
// Set the application descriptor (rare so better not done during construction time)
//
void SetAppDescriptor( IN BYTE AppDescriptor ) { m_AppDescriptor = AppDescriptor; }
private:
//
// If TRUE, the item is optional and may not be present
//
BOOL m_IsOptional;
//
// One-BYTE Descriptor of the expected data that follows,
// for example 10 1 00001 (Context-Specific[10] Constructed[1] pvno[1])
// m_AppDescriptor exists for [APPLICATION 1] types of situations
//
BYTE m_Descriptor; BYTE m_AppDescriptor;
//
// Modifier value
//
ASN1VALUE * m_Modifier;
//
// Modifyee value
//
ASN1ParserBase * m_Modifyee;
//
// Value collector
//
ASN1ParserSequence * m_ValueCollector; };
// -----------------------------------------------------------------------------
//
// Derived classes of ASN1ParserBase follow
//
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
// +----------------+
// | ASN1ParserUnit |
// +----------------+
// ^
// |
// +--------------+--------+--------- ... ... ...
// ^ ^
// +-------------------+ +-------------------+
// | ASN1ParserInteger | | ASN1ParserBoolean |
// +-------------------+ +-------------------+
//
// -----------------------------------------------------------------------------
//
// A 'unit' is essentially anything that is a leaf in the parse tree
// Most units have values, some don't
//
class ASN1ParserUnit : public ASN1ParserBase { public:
//
// Constructor
//
ASN1ParserUnit( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySummary, IN HPROPERTY hPropertyValue, IN DWORD IFlags ) : ASN1ParserBase( IsOptional, Descriptor, hPropertySummary, hPropertyValue ), m_IFlags( IFlags ) {}
//
// Parses the unit and calls into the derived class (through Display)
// to display it in Netmon
//
DWORD Parse( IN OUT ASN1FRAME * Frame );
//
// A Unit-descendant that does not have a value should set the value type
// to 'void' and still delineate the value and length of the octet string
// properly so that it can be displayed correctly
//
virtual DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value ) = 0;
protected:
//
// Netmon display flags
//
DWORD m_IFlags; };
// -----------------------------------------------------------------------------
//
// Derived classes of ASN1ParserUnit follow
//
// -----------------------------------------------------------------------------
class ASN1ParserBitString : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserBitString( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySummary, IN HPROPERTY hPropertyValue, IN DWORD IFlags, IN DWORD BitMask = 0xFFFFFFFF ) : ASN1ParserUnit( IsOptional, Descriptor, hPropertySummary, hPropertyValue, IFlags ), m_BitMask( BitMask ) {}
//
// Parses the bit string
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value );
protected:
DWORD m_BitMask; };
class ASN1ParserBoolean : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserBoolean( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertyValue, IN DWORD IFlags ) : ASN1ParserUnit( IsOptional, Descriptor, NULL, // Boolean is directly displayable, no need for summary
hPropertyValue, IFlags ) {}
//
// Parses the boolean
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value ); };
class ASN1ParserInteger : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserInteger( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertyValue, IN DWORD IFlags, IN DWORD BitMask = 0xFFFFFFFF ) : ASN1ParserUnit( IsOptional, Descriptor, NULL, // Integer is directly displayable, no need for summary
hPropertyValue, IFlags ), m_BitMask( BitMask ) {}
//
// Parses the integer
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value );
protected:
DWORD m_BitMask; };
class ASN1ParserGeneralizedTime : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserGeneralizedTime( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertyValue ) : ASN1ParserUnit( IsOptional, Descriptor, NULL, // Time is directly displayable, no need for summary
hPropertyValue, 0 ) {}
//
// Parses the octet string
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value ); };
class ASN1ParserGeneralString : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserGeneralString( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertyValue, IN DWORD IFlags ) : ASN1ParserUnit( IsOptional, Descriptor, NULL, // String is directly displayable, no need for summary
hPropertyValue, IFlags ) {}
//
// Parses the octet string
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value ); };
//
// An octet string is just a binary blob that needs special decoding
// in most cases. In those cases, the class needs to be subclassed to parse
// out the actual value
//
class ASN1ParserOctetString : public ASN1ParserUnit { public:
//
// Constructor
//
ASN1ParserOctetString( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertyValue, IN DWORD IFlags ) : ASN1ParserUnit( IsOptional, Descriptor, NULL, // String is directly displayable, no need for summary
hPropertyValue, IFlags ) {}
//
// Parses the octet string
//
DWORD GetValue( IN OUT ASN1FRAME * Frame, OUT ASN1VALUE * Value );
protected:
virtual DWORD ParseBlob( IN OUT ASN1VALUE * Value ) { return ERROR_SUCCESS; } };
class ASN1ParserAddressBuffer : public ASN1ParserOctetString { public:
//
// Constructor
//
ASN1ParserAddressBuffer( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserOctetString( IsOptional, Descriptor, hProperty, 0 ) {}
protected:
DWORD ParseBlob( IN OUT ASN1VALUE * Value ); };
class ASN1ParserErrorData : public ASN1ParserOctetString { public:
//
// Constructor
//
ASN1ParserErrorData( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserOctetString( IsOptional, Descriptor, hProperty, 0 ) {}
protected:
DWORD ParseBlob( IN OUT ASN1VALUE * Value ); };
// -----------------------------------------------------------------------------
//
// +--------------------+
// | ASN1ParserSequence |
// +--------------------+
// ^
// |
// +---------------+---------+--------- ... ... ...
// ^ ^
// +------------------+ +-------------------------+
// | ASN1ParserPaData | | ASN1ParserPrincipalName |
// +------------------+ +-------------------------+
//
// -----------------------------------------------------------------------------
//
// A sequence is a collection of units or sequences, much like a directory
// contains files or other directories
//
class ASN1ParserSequence : public ASN1ParserBase { public:
//
// Constructor
//
ASN1ParserSequence( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySummary, IN ULONG Count, IN ASN1ParserBase * * Parsers, IN OPTIONAL BOOL Extensible = FALSE ) : ASN1ParserBase( IsOptional, Descriptor, hPropertySummary, NULL ), // no value property on sequences (yet?)
m_Count( Count ), m_Parsers( Parsers ), m_ValueCount( 0 ), m_ValuesCollected( NULL ), m_Extensible( Extensible ) {}
~ASN1ParserSequence() { PurgeCollectedValues(); }
//
// Parses the sequence by invoking successive sub-parsers as necessary
//
DWORD Parse( IN OUT ASN1FRAME * Frame );
//
// This method is called if this object is acting as a value collector for
// another object. A value collected is appended to the end of the array
// of like values
//
DWORD CollectValue( IN ASN1VALUE * Value );
ULONG QueryCollectedCount() { return m_ValueCount; }
ASN1VALUE * QueryCollectedValue( IN ULONG Index ) { return m_ValuesCollected[Index]; } // TODO: add range-check assert
void PurgeCollectedValues() { for ( ULONG i = 0; i < m_ValueCount; i++) { delete m_ValuesCollected[i]; } delete [] m_ValuesCollected; m_ValuesCollected = NULL; m_ValueCount = 0; }
protected:
virtual DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address ) { //
// TODO: add an assert in addition to this error check
//
return QueryCollectedCount() > 0 ? ERROR_NOT_SUPPORTED : ERROR_SUCCESS; }
private:
//
// Number of items in the sequence
//
ULONG m_Count;
//
// Array of parser objects - one for every sequence item
//
ASN1ParserBase * * m_Parsers;
//
// Values collected
//
ULONG m_ValueCount; PASN1VALUE * m_ValuesCollected;
//
// Are extensibility markers employed in the ASN.1 syntax?
//
BOOL m_Extensible; };
// -----------------------------------------------------------------------------
//
// Derived classes of ASN1ParserSequence follow
//
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// HostAddress ::= SEQUENCE {
// addr-type[0] INTEGER,
// address[1] OCTET STRING
// }
// -----------------------------------------------------------------------------
class ASN1ParserHostAddress : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserHostAddress( IN BOOL IsOptional, IN BYTE Descriptor ) : ASN1ParserSequence( IsOptional, Descriptor, NULL, ARRAY_COUNT( m_p ), m_p ), m_addr_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_addr_type ), NULL, 0 ), m_address( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_address ), NULL ) { m_p[0] = &m_addr_type; m_p[1] = &m_address;
//
// Address type affects the parsing of the address portion
//
m_addr_type.SetModifyee( &m_address );
//
// We would like to handle the display of address type and address
// value ourselves (allows for user-friendly display on the same line)
//
m_addr_type.SetValueCollector( this ); m_address.SetValueCollector( this ); }
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address );
private:
enum { e_addr_type = 0, e_address = 1, };
ASN1ParserBase * m_p[2];
ASN1ParserInteger m_addr_type; ASN1ParserAddressBuffer m_address; };
// -----------------------------------------------------------------------------
// HostAddresses ::= SEQUENCE OF HostAddress
// -----------------------------------------------------------------------------
class ASN1ParserHostAddresses : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserHostAddresses( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_HostAddress( FALSE, 0 ) // no descriptor on individual addresses sequences
{ m_p[0] = &m_HostAddress; }
private:
ASN1ParserBase * m_p[1];
ASN1ParserHostAddress m_HostAddress; };
// -----------------------------------------------------------------------------
// EncryptedData ::= SEQUENCE {
// etype[0] INTEGER, -- EncryptionType
// kvno[1] INTEGER OPTIONAL,
// cipher[2] OCTET STRING -- ciphertext
// }
// -----------------------------------------------------------------------------
class ASN1ParserEncryptedData : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserEncryptedData( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_etype( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_etype ), PROP( EncryptedData_etype ), 0 ), m_kvno( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_kvno ), PROP( EncryptedData_kvno ), 0 ), m_cipher( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cipher ), PROP( EncryptedData_cipher ), 0 ) { m_p[0] = &m_etype; m_p[1] = &m_kvno; m_p[2] = &m_cipher;
//
// m_etype type is not modifying either m_kvno or m_cipher,
// but it conceivably could
//
}
private:
enum { e_etype = 0, e_kvno = 1, e_cipher = 2, };
ASN1ParserBase * m_p[3];
ASN1ParserInteger m_etype; ASN1ParserInteger m_kvno; ASN1ParserOctetString m_cipher; };
class ASN1ParserGStringSequence : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserGStringSequence( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_string( FALSE, 0, // No descriptor on individual general string entries
NULL, // No property since we're acting as the value collector
0 ) { m_p[0] = &m_string;
//
// Act as the value collector for the string sequence
//
m_string.SetValueCollector( this ); }
private:
ASN1ParserBase * m_p[1];
ASN1ParserGeneralString m_string; };
class ASN1ParserPrincipalNameSequence : public ASN1ParserGStringSequence { public:
//
// Constructor
//
ASN1ParserPrincipalNameSequence( IN BOOL IsOptional, IN BYTE Descriptor ) : ASN1ParserGStringSequence( IsOptional, Descriptor, NULL ) {} // let the value collector display the value
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address ); };
class ASN1ParserIntegerSequence : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserIntegerSequence( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySeq, IN HPROPERTY hPropertyInteger ) : ASN1ParserSequence( IsOptional, Descriptor, hPropertySeq, ARRAY_COUNT( m_p ), m_p ), m_integer( FALSE, 0, // No descriptor on individual integer entries
NULL, // No property since we're acting as the value collector
0 ), m_hPropertyInteger( hPropertyInteger ) { m_p[0] = &m_integer;
//
// Act as the value collector for the integer sequence
//
m_integer.SetValueCollector( this ); }
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address );
private:
ASN1ParserBase * m_p[1];
ASN1ParserInteger m_integer;
HPROPERTY m_hPropertyInteger; };
// -----------------------------------------------------------------------------
// KERB-PA-PAC-REQUEST ::= SEQUENCE {
// include-pac[0] BOOLEAN
// -- if TRUE, and no pac present,
// -- include PAC. If FALSE, and pac
// -- PAC present, remove PAC
// } --#public--
// -----------------------------------------------------------------------------
class ASN1ParserKerbPaPacRequest : public ASN1ParserSequence { public:
ASN1ParserKerbPaPacRequest( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_include_pac( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_include_pac ), PROP( KERB_PA_PAC_REQUEST_include_pac ), 0 ) { m_p[0] = &m_include_pac; }
private:
enum { e_include_pac = 0, };
ASN1ParserBase * m_p[1];
ASN1ParserBoolean m_include_pac; };
// -----------------------------------------------------------------------------
// KERB-PA-PAC-REQUEST-EX ::= SEQUENCE {
// include-pac[0] BOOLEAN,
// -- if TRUE, and no pac present,
// -- include PAC. If FALSE, and pac
// -- PAC present, remove PAC
// pac-sections[1] SEQUENCE OF INTEGER OPTIONAL
// } --#public--
// -----------------------------------------------------------------------------
class ASN1ParserPaPacRequestEx : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserPaPacRequestEx( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_include_pac( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_include_pac ), PROP( KERB_PA_PAC_REQUEST_EX_include_pac ), 0 ), m_pac_sections( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_pac_sections ), PROP( KERB_PA_PAC_REQUEST_EX_pac_sections ), PROP( KERB_PA_PAC_REQUEST_EX_pac_sections_desc )) { m_p[0] = &m_include_pac; m_p[1] = &m_pac_sections; }
private:
enum { e_include_pac = 0, e_pac_sections = 1, };
ASN1ParserBase * m_p[2];
ASN1ParserBoolean m_include_pac; ASN1ParserIntegerSequence m_pac_sections; };
// -----------------------------------------------------------------------------
// PA-DATA ::= SEQUENCE {
// padata-type[1] INTEGER,
// padata-value[2] OCTET STRING, -- might be encoded AP-REQ
// }
// -----------------------------------------------------------------------------
//
// PA-DATA types
//
enum { PA_NONE = 0x00, PA_APTGS_REQ = 0x01, PA_ENC_TIMESTAMP = 0x02, PA_PW_SALT = 0x03, PA_RESERVED = 0x04, PA_ENC_UNIX_TIME = 0x05, PA_SANDIA_SECUREID = 0x06, PA_SESAME = 0x07, PA_OSF_DCE = 0x08, PA_CYBERSAFE_SECUREID = 0x09, PA_AFS3_SALT = 0x0A, PA_ETYPE_INFO = 0x0B, SAM_CHALLENGE = 0x0C, SAM_RESPONSE = 0x0D, PA_PK_AS_REQ = 0x0E, PA_PK_AS_REP = 0x0F, PA_PK_AS_SIGN = 0x10, PA_PK_KEY_REQ = 0x11, PA_PK_KEY_REP = 0x12, PA_USE_SPECIFIED_KVNO = 0x14, SAM_REDIRECT = 0x15, PA_GET_FROM_TYPED_DATA = 0x16, PA_SAM_ETYPE_INFO = 0x17, PA_ALT_PRINC = 0x18, PA_REFERRAL_INFO = 0x20, TD_PKINIT_CMS_CERTIFICATES = 0x65, TD_KRB_PRINCIPAL = 0x66, TD_KRB_REALM = 0x67, TD_TRUSTED_CERTIFIERS = 0x68, TD_CERTIFICATE_INDEX = 0x69, TD_APP_DEFINED_ERROR = 0x6A, TD_REQ_NONCE = 0x6B, TD_REQ_SEQ = 0x6C, PA_PAC_REQUEST = 0x80, PA_FOR_USER = 0x81, PA_COMPOUND_IDENTITY = 0x82, PA_PAC_REQUEST_EX = 0x83, PA_CLIENT_VERSION = 0x84, PA_XBOX_SERVICE_REQUEST = 0xC9, PA_XBOX_SERVICE_ADDRESS = 0xCA, PA_XBOX_ACCOUNT_CREATION = 0xCB, PA_XBOX_PPA = 0xCC, PA_XBOX_ECHO = 0xCD, };
class ASN1ParserPaData : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserPaData( IN BOOL IsOptional, IN BYTE Descriptor ) : ASN1ParserSequence( IsOptional, Descriptor, NULL, ARRAY_COUNT( m_p ), m_p ), m_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_type ), NULL, 0 ), m_value( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_value ), NULL, 0 ) { m_p[0] = &m_type; m_p[1] = &m_value;
//
// Name type affects the parsing of the value portion
//
m_type.SetModifyee( &m_value );
//
// Collect the values for both type and value for later processing
//
m_type.SetValueCollector( this ); m_value.SetValueCollector( this ); }
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address );
private:
enum { e_type = 1, e_value = 2, };
ASN1ParserBase * m_p[2];
ASN1ParserInteger m_type; ASN1ParserOctetString m_value; // TODO: subclass for pa-data-type modifications
};
class ASN1ParserPaDataSequence : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserPaDataSequence( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_padata( FALSE, 0 ) // No descriptor on individual pa-data entries
{ m_p[0] = &m_padata; }
private:
ASN1ParserBase * m_p[1];
ASN1ParserPaData m_padata; };
// -----------------------------------------------------------------------------
// KERB-TYPED-DATA ::= SEQUENCE {
// data-type [0] INTEGER,
// data-value [1] OCTET STRING
// }
// -----------------------------------------------------------------------------
class ASN1ParserTypedData : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserTypedData( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_data_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_data_type ), PROP( TYPED_DATA_type ), 0 ), m_data_value( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_data_value ), PROP( TYPED_DATA_value ), 0 ) { m_p[0] = &m_data_type; m_p[1] = &m_data_value;
//
// Data type affects how data value is parsed
//
m_data_type.SetModifyee( &m_data_value ); }
private:
enum { e_data_type = 0, e_data_value = 1, };
ASN1ParserBase * m_p[2];
ASN1ParserInteger m_data_type; ASN1ParserOctetString m_data_value; // TODO: change type to allow subparsers
};
// -----------------------------------------------------------------------------
//
// PrincipalName ::= SEQUENCE {
// name-type[0] INTEGER,
// name-string[1] SEQUENCE OF GeneralString
// }
// -----------------------------------------------------------------------------
class ASN1ParserPrincipalName : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserPrincipalName( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, NULL, ARRAY_COUNT( m_p ), m_p ), m_hPropertyTopLevel( hProperty ), m_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_type ), NULL, 0 ), m_string_seq( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_string )) { m_p[0] = &m_type; m_p[1] = &m_string_seq;
//
// Act as the value collector for the data inside the sequence
//
m_type.SetValueCollector( this ); m_string_seq.SetValueCollector( this ); }
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address );
HPROPERTY m_hPropertyTopLevel;
private:
enum { e_type = 0, e_string = 1, };
ASN1ParserBase * m_p[2];
ASN1ParserInteger m_type; ASN1ParserPrincipalNameSequence m_string_seq; };
// -----------------------------------------------------------------------------
// KERB-CHECKSUM ::= SEQUENCE {
// checksum-type[0] INTEGER,
// checksum[1] OCTET STRING
// } --#public--
// -----------------------------------------------------------------------------
class ASN1ParserKerbChecksum : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKerbChecksum( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_checksum_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_checksum_type ), PROP( KERB_CHECKSUM_type ), 0 ), m_checksum( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_checksum ), PROP( KERB_CHECKSUM_checksum ), 0 ) { m_p[0] = &m_checksum_type; m_p[1] = &m_checksum; }
private:
enum { e_checksum_type = 0, e_checksum = 1, };
ASN1ParserBase * m_p[2];
ASN1ParserInteger m_checksum_type; ASN1ParserOctetString m_checksum; };
// -----------------------------------------------------------------------------
// Ticket ::= [APPLICATION 1] SEQUENCE {
// tkt-vno[0] INTEGER,
// realm[1] Realm,
// sname[2] PrincipalName,
// enc-part[3] EncryptedData
// }
// -----------------------------------------------------------------------------
class ASN1ParserTicket : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserTicket( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_tkt_vno( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_tkt_vno ), PROP( Ticket_tkt_vno ), 0 ), m_realm( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_realm ), PROP( Ticket_realm ), 0 ), m_sname( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_sname ), PROP( Ticket_sname )), m_enc_part( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_enc_part ), PROP( Ticket_enc_part )) { SetAppDescriptor( BuildDescriptor( ctApplication, pcConstructed, 1 ) );
m_p[0] = &m_tkt_vno; m_p[1] = &m_realm; m_p[2] = &m_sname; m_p[3] = &m_enc_part; }
private:
enum { e_tkt_vno = 0, e_realm = 1, e_sname = 2, e_enc_part = 3 };
ASN1ParserBase * m_p[4];
ASN1ParserInteger m_tkt_vno; ASN1ParserGeneralString m_realm; ASN1ParserPrincipalName m_sname; ASN1ParserEncryptedData m_enc_part; };
class ASN1ParserTicketSequence : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserTicketSequence( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hPropertySeq, IN HPROPERTY hPropertyTicket ) : ASN1ParserSequence( IsOptional, Descriptor, hPropertySeq, ARRAY_COUNT( m_p ), m_p ), m_ticket( FALSE, 0, // No descriptor on sequences of tickets
hPropertyTicket ) { m_p[0] = &m_ticket; }
private:
ASN1ParserBase * m_p[1];
ASN1ParserTicket m_ticket; };
// -----------------------------------------------------------------------------
// KDC-REQ-BODY ::= SEQUENCE {
// kdc-options[0] KDCOptions,
// cname[1] PrincipalName OPTIONAL,
// -- Used only in AS-REQ
// realm[2] Realm, -- Server's realm
// -- Also client's in AS-REQ
// sname[3] PrincipalName OPTIONAL,
// from[4] KerberosTime OPTIONAL,
// till[5] KerberosTime,
// rtime[6] KerberosTime OPTIONAL,
// nonce[7] INTEGER,
// etype[8] SEQUENCE OF INTEGER,
// -- EncryptionType,
// -- in preference order
// addresses[9] HostAddresses OPTIONAL,
// enc-authorization-data[10] EncryptedData OPTIONAL,
// -- Encrypted AuthorizationData encoding
// additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
// }
// -----------------------------------------------------------------------------
class ASN1ParserKdcReqBody : public ASN1ParserSequence { public:
ASN1ParserKdcReqBody( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_kdc_options( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_kdc_options ), PROP( KDC_REQ_BODY_kdc_options_summary ), PROP( KDC_REQ_BODY_kdc_options_value ), 0 ), m_cname( // TODO: enforce the fact that TGS KDC-REQ-BODY does not have this
TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cname ), PROP( KDC_REQ_BODY_cname )), m_realm( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_realm ), PROP( KDC_REQ_BODY_realm ), 0 ), m_sname( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_sname ), PROP( KDC_REQ_BODY_sname )), m_from( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_from ), PROP( KDC_REQ_BODY_from)), m_till( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_till ), PROP( KDC_REQ_BODY_till )), m_rtime( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_rtime ), PROP( KDC_REQ_BODY_rtime )), m_nonce( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_nonce ), PROP( KDC_REQ_BODY_nonce ), 0 ), m_etype( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_etype ), PROP( KDC_REQ_BODY_etype ), PROP( EncryptionType )), m_addresses( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_addresses ), PROP( KDC_REQ_BODY_addresses )), m_enc_authorization_data( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_enc_authorization_data ), PROP( KDC_REQ_BODY_enc_authorization_data)), m_additional_tickets( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_additional_tickets ), PROP( KDC_REQ_BODY_additional_tickets ), PROP( AdditionalTicket )) { m_p[0] = &m_kdc_options; m_p[1] = &m_cname; m_p[2] = &m_realm; m_p[3] = &m_sname; m_p[4] = &m_from; m_p[5] = &m_till; m_p[6] = &m_rtime; m_p[7] = &m_nonce; m_p[8] = &m_etype; m_p[9] = &m_addresses; m_p[10] = &m_enc_authorization_data; m_p[11] = &m_additional_tickets; }
private:
enum { e_kdc_options = 0, e_cname = 1, e_realm = 2, e_sname = 3, e_from = 4, e_till = 5, e_rtime = 6, e_nonce = 7, e_etype = 8, e_addresses = 9, e_enc_authorization_data = 10, e_additional_tickets = 11, };
ASN1ParserBase * m_p[12];
ASN1ParserBitString m_kdc_options; ASN1ParserPrincipalName m_cname; ASN1ParserGeneralString m_realm; ASN1ParserPrincipalName m_sname; ASN1ParserGeneralizedTime m_from; ASN1ParserGeneralizedTime m_till; ASN1ParserGeneralizedTime m_rtime; ASN1ParserInteger m_nonce; ASN1ParserIntegerSequence m_etype; ASN1ParserHostAddresses m_addresses; ASN1ParserEncryptedData m_enc_authorization_data; ASN1ParserTicketSequence m_additional_tickets; };
// -----------------------------------------------------------------------------
// KDC-REQ ::= SEQUENCE {
// pvno[1] INTEGER,
// msg-type[2] INTEGER,
// padata[3] SEQUENCE OF PA-DATA OPTIONAL,
// req-body[4] KDC-REQ-BODY
// }
// -----------------------------------------------------------------------------
class ASN1ParserKdcReq : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKdcReq( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_pvno( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_pvno ), PROP( KDC_REQ_pvno ), 0 ), m_msg_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_msg_type ), PROP( KDC_REQ_msg_type ), 0, 0x1F ), // only care about the bottom five bits of the value
m_padata( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_padata ), PROP( KDC_REQ_padata )), m_kdc_req_body( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_req_body ), PROP( KDC_REQ_req_body )) { m_p[0] = &m_pvno; m_p[1] = &m_msg_type; m_p[2] = &m_padata; m_p[3] = &m_kdc_req_body; }
private:
enum { e_pvno = 1, e_msg_type = 2, e_padata = 3, e_req_body = 4, };
ASN1ParserBase * m_p[4];
ASN1ParserInteger m_pvno; ASN1ParserInteger m_msg_type; ASN1ParserPaDataSequence m_padata; ASN1ParserKdcReqBody m_kdc_req_body; };
// -----------------------------------------------------------------------------
// KDC-REP ::= SEQUENCE {
// pvno[0] INTEGER,
// msg-type[1] INTEGER,
// padata[2] SEQUENCE OF PA-DATA OPTIONAL,
// crealm[3] Realm,
// cname[4] PrincipalName,
// ticket[5] Ticket,
// enc-part[6] EncryptedData
// }
// -----------------------------------------------------------------------------
class ASN1ParserKdcRep : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKdcRep( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_pvno( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_pvno ), PROP( KDC_REP_pvno ), 0 ), m_msg_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_msg_type ), PROP( KDC_REP_msg_type ), 0 ), m_padata( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_padata ), PROP( KDC_REP_padata )), m_crealm( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_crealm ), PROP( KDC_REP_crealm ), 0 ), m_cname( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cname ), PROP( KDC_REP_cname )), m_ticket( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_ticket ), PROP( KDC_REP_ticket )), m_enc_part( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_enc_part ), PROP( KDC_REP_enc_part )) { m_p[0] = &m_pvno; m_p[1] = &m_msg_type; m_p[2] = &m_padata; m_p[3] = &m_crealm; m_p[4] = &m_cname; m_p[5] = &m_ticket; m_p[6] = &m_enc_part; }
private:
enum { e_pvno = 0, e_msg_type = 1, e_padata = 2, e_crealm = 3, e_cname = 4, e_ticket = 5, e_enc_part = 6, };
ASN1ParserBase * m_p[7];
ASN1ParserInteger m_pvno; ASN1ParserInteger m_msg_type; ASN1ParserPaDataSequence m_padata; ASN1ParserGeneralString m_crealm; ASN1ParserPrincipalName m_cname; ASN1ParserTicket m_ticket; ASN1ParserEncryptedData m_enc_part; };
// -----------------------------------------------------------------------------
// KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
// pvno[0] INTEGER,
// msg-type[1] INTEGER,
// ctime[2] KerberosTime OPTIONAL,
// cusec[3] INTEGER OPTIONAL,
// stime[4] KerberosTime,
// susec[5] INTEGER,
// error-code[6] INTEGER,
// crealm[7] Realm OPTIONAL,
// cname[8] PrincipalName OPTIONAL,
// realm[9] Realm, -- Correct realm
// sname[10] PrincipalName, -- Correct name
// e-text[11] GeneralString OPTIONAL,
// e-data[12] OCTET STRING OPTIONAL
// }
// -----------------------------------------------------------------------------
class ASN1ParserKrbError : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKrbError( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_pvno( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_pvno ), PROP( KRB_ERR_pvno ), 0 ), m_msg_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_msg_type ), PROP( KRB_ERR_msg_type ), 0 ), m_ctime( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_ctime ), PROP( KRB_ERR_ctime )), m_cusec( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cusec ), PROP( KRB_ERR_cusec ), 0 ), m_stime( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_stime ), PROP( KRB_ERR_stime )), m_susec( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_susec ), PROP( KRB_ERR_susec ), 0 ), m_error_code( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_error_code ), PROP( KRB_ERR_error_code ), 0 ), m_crealm( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_crealm ), PROP( KRB_ERR_crealm ), 0 ), m_cname( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cname ), PROP( KRB_ERR_cname )), m_realm( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_realm ), PROP( KRB_ERR_realm ), 0 ), m_sname( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_sname ), PROP( KRB_ERR_sname )), m_e_text( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_e_text ), PROP( KRB_ERR_e_text ), 0 ), m_e_data( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_e_data ), PROP( KRB_ERR_e_data )) { m_p[0] = &m_pvno; m_p[1] = &m_msg_type; m_p[2] = &m_ctime; m_p[3] = &m_cusec; m_p[4] = &m_stime; m_p[5] = &m_susec; m_p[6] = &m_error_code; m_p[7] = &m_crealm; m_p[8] = &m_cname; m_p[9] = &m_realm; m_p[10] = &m_sname; m_p[11] = &m_e_text; m_p[12] = &m_e_data;
//
// Address type affects the parsing of the error data portion
//
m_error_code.SetModifyee( &m_e_data ); }
private:
enum { e_pvno = 0, e_msg_type = 1, e_ctime = 2, e_cusec = 3, e_stime = 4, e_susec = 5, e_error_code = 6, e_crealm = 7, e_cname = 8, e_realm = 9, e_sname = 10, e_e_text = 11, e_e_data = 12, };
ASN1ParserBase * m_p[13];
ASN1ParserInteger m_pvno; ASN1ParserInteger m_msg_type; ASN1ParserGeneralizedTime m_ctime; ASN1ParserInteger m_cusec; ASN1ParserGeneralizedTime m_stime; ASN1ParserInteger m_susec; ASN1ParserInteger m_error_code; ASN1ParserGeneralString m_crealm; ASN1ParserPrincipalName m_cname; ASN1ParserGeneralString m_realm; ASN1ParserPrincipalName m_sname; ASN1ParserGeneralString m_e_text; ASN1ParserErrorData m_e_data; };
// -----------------------------------------------------------------------------
// KERB-ETYPE-INFO-ENTRY ::= SEQUENCE {
// encryption-type[0] INTEGER,
// salt[1] OCTET STRING OPTIONAL
// }
// -----------------------------------------------------------------------------
class ASN1ParserKerbEtypeInfoEntry : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKerbEtypeInfoEntry( IN BOOL IsOptional, IN BYTE Descriptor ) : ASN1ParserSequence( IsOptional, Descriptor, NULL, ARRAY_COUNT( m_p ), m_p ), m_encryption_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_encryption_type ), NULL, 0 ), m_salt( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_salt ), NULL, 0 ), m_what_is_this_integer( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_what_is_this_integer ), NULL, 0 ) { m_p[0] = &m_encryption_type; m_p[1] = &m_salt; m_p[2] = &m_what_is_this_integer;
//
// Handle the display of this one for ease of readability
//
m_encryption_type.SetValueCollector( this ); m_salt.SetValueCollector( this ); m_what_is_this_integer.SetValueCollector( this ); }
protected:
DWORD DisplayCollectedValues( IN ASN1FRAME * Frame, IN ULONG Length, IN ULPBYTE Address );
private:
enum { e_encryption_type = 0, e_salt = 1, e_what_is_this_integer = 2, };
ASN1ParserBase * m_p[3];
ASN1ParserInteger m_encryption_type; ASN1ParserOctetString m_salt; ASN1ParserInteger m_what_is_this_integer; };
// -----------------------------------------------------------------------------
// PKERB-ETYPE-INFO ::= SEQUENCE OF KERB-ETYPE-INFO-ENTRY
// -----------------------------------------------------------------------------
class ASN1ParserKerbEtypeInfo : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKerbEtypeInfo( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_kerb_etype_info_entry( FALSE, 0 ) // no descriptor on individual addresses sequences
{ m_p[0] = &m_kerb_etype_info_entry; }
private:
ASN1ParserBase * m_p[1];
ASN1ParserKerbEtypeInfoEntry m_kerb_etype_info_entry; };
// -----------------------------------------------------------------------------
// KERB-PA-FOR-USER ::= SEQUENCE {
// -- PA TYPE 129
// userName [0] KERB-PRINCIPAL-NAME,
// userRealm [1] KERB-REALM,
// cksum [2] KERB-CHECKSUM,
// authentication-package [3] GeneralString,
// authorization-data [4] OCTET STRING OPTIONAL,
// ...
// }--#public--
// -----------------------------------------------------------------------------
class ASN1ParserKerbPaForUser : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserKerbPaForUser( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p, TRUE ), m_userName( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_userName ), PROP( PA_FOR_USER_userName )), m_userRealm( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_userRealm ), PROP( PA_FOR_USER_userRealm ), 0 ), m_cksum( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_cksum ), PROP( PA_FOR_USER_cksum )), m_authentication_package( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_authentication_package ), PROP( PA_FOR_USER_authentication_package ), 0 ), m_authorization_data( TRUE, BuildDescriptor( ctContextSpecific, pcConstructed, e_authorization_data ), PROP( PA_FOR_USER_authorization_data ), 0 ) { m_p[0] = &m_userName; m_p[1] = &m_userRealm; m_p[2] = &m_cksum; m_p[3] = &m_authentication_package; m_p[4] = &m_authorization_data; }
private:
enum { e_userName = 0, e_userRealm = 1, e_cksum = 2, e_authentication_package = 3, e_authorization_data = 4, };
ASN1ParserBase * m_p[5];
ASN1ParserPrincipalName m_userName; ASN1ParserGeneralString m_userRealm; ASN1ParserKerbChecksum m_cksum; ASN1ParserGeneralString m_authentication_package; ASN1ParserOctetString m_authorization_data; };
// -----------------------------------------------------------------------------
// AP-REQ ::= [APPLICATION 14] SEQUENCE {
// pvno[0] INTEGER,
// msg-type[1] INTEGER,
// ap-options[2] APOptions,
// ticket[3] Ticket,
// authenticator[4] EncryptedData
// }
// -----------------------------------------------------------------------------
class ASN1ParserApReq : public ASN1ParserSequence { public:
//
// Constructor
//
ASN1ParserApReq( IN BOOL IsOptional, IN BYTE Descriptor, IN HPROPERTY hProperty ) : ASN1ParserSequence( IsOptional, Descriptor, hProperty, ARRAY_COUNT( m_p ), m_p ), m_pvno( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_pvno ), PROP( AP_REQ_pvno ), 0 ), m_msg_type( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_msg_type ), PROP( AP_REQ_msg_type ), 0 ), m_ap_options( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_ap_options ), PROP( AP_REQ_ap_options_summary ), PROP( AP_REQ_ap_options_value ), 0 ), m_ticket( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_ticket ), PROP( AP_REQ_ticket )), m_authenticator( FALSE, BuildDescriptor( ctContextSpecific, pcConstructed, e_authenticator ), PROP( AP_REQ_authenticator )) { SetAppDescriptor( BuildDescriptor( ctApplication, pcConstructed, ASN1_KRB_AP_REQ ) );
m_p[0] = &m_pvno; m_p[1] = &m_msg_type; m_p[2] = &m_ap_options; m_p[3] = &m_ticket; m_p[4] = &m_authenticator; }
private:
enum { e_pvno = 0, e_msg_type = 1, e_ap_options = 2, e_ticket = 3, e_authenticator = 4, };
ASN1ParserBase * m_p[5];
ASN1ParserInteger m_pvno; ASN1ParserInteger m_msg_type; ASN1ParserBitString m_ap_options; ASN1ParserTicket m_ticket; ASN1ParserEncryptedData m_authenticator; };
#endif // __ASN1PARSER_HXX
|