You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2719 lines
71 KiB
2719 lines
71 KiB
//==============================================================================
|
|
//
|
|
// 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
|