Leaked source code of windows server 2003
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.
|
|
//=============================================================================
//
// MODULE: ASN1Base.cxx
//
// Description:
//
// Implementation of the ASN1ParserBase class
//
// Modification History
//
// Mark Pustilnik Date: 06/09/02 - created
//
//=============================================================================
#include "ASN1Parser.hxx"
//
// For a frame which starts with 6a 82 01 30 ... (long form)
//
// 82 (*(Frame+1)) indicates "long form" where Size is 2 (0x82 & 0x7F)
// and the return value is ( 0x01 << 8 ) | 0x30 = 0x130
//
// For a frame which starts with 6a 30 ... (short form)
//
// the return value is simply 0x30
//
DWORD ASN1ParserBase::DataLength( IN ASN1FRAME * Frame ) { LPBYTE LengthPortion = Frame->Address + 1;
if ( *LengthPortion & 0x80 ) // long form
{ USHORT i; DWORD Sum = 0; BYTE Size = *LengthPortion & 0x7F;
for ( i = 1; i <= Size; i++ ) { Sum <<= 8; Sum |= *(LengthPortion + i); }
return Sum; } else // short form
{ return *LengthPortion; } }
//
// Calculates the length of the length header in either short or long form
// Returns '3' for "82 01 30"
// Returns '1' for "30"
//
ULONG ASN1ParserBase::HeaderLength( IN ULPBYTE Address ) { if ( *Address & 0x80 ) { //
// If long form, assign size to value of bits 7-1
//
return ( 1 + *Address & 0x7F); } else { //
// Short form only takes one octet
//
return 1; } }
//
// Verifies that the frame is pointing at the type of item we expect by
// performing a descriptor comparison, then moves past the descriptor and
// the length header. The caller uses this to point the frame at the next
// item to be parsed.
//
DWORD ASN1ParserBase::VerifyAndSkipHeader( IN OUT ASN1FRAME * Frame ) { DWORD dw;
//
// Check both optional descriptors associated with this frame
//
BYTE Descriptors[2] = { m_Descriptor, m_AppDescriptor };
for ( ULONG i = 0; i < ARRAY_COUNT( Descriptors ); i++ ) { if ( Descriptors[i] != 0 ) { //
// Verify the descriptor and bail on mismatch
//
if ( *Frame->Address != Descriptors[i] ) { dw = ERROR_INVALID_USER_BUFFER; goto Cleanup; }
//
// Skip over the descriptor
//
Frame->Address++;
//
// Skip over the length header
//
Frame->Address += HeaderLength( Frame->Address ); } }
dw = ERROR_SUCCESS;
Cleanup:
return dw; }
//
// Displays the value of the unit, mapping between the ASN.1 encoding and the
// actual parsed-out value as necessary
//
DWORD ASN1ParserBase::Display( IN ASN1FRAME * Frame, IN ASN1VALUE * Value, IN HPROPERTY hProperty, IN DWORD IFlags ) { DWORD dw = ERROR_SUCCESS; DWORD Length; ULPVOID Address;
switch( Value->ut ) { case utGeneralizedTime:
Length = sizeof( Value->st ); Address = &Value->st; break;
case utBoolean:
Length = sizeof( Value->b ); Address = &Value->b; break;
case utInteger: case utBitString:
//
// ASN.1 integers are optimally encoded using the fewest number of bytes
// This does not bode well with Netmon which insists on knowing how long
// a value is before displaying it. The mapping below will show both
// the raw buffer and the corresponding value properly
//
Length = sizeof( Value->dw ); Address = &Value->dw; break;
case utGeneralString: case utOctetString:
if ( Value->string.l == 0 ) { Address = "<empty string>"; Length = strlen(( const char * )Address ); } else { Address = Value->string.s; Length = Value->string.l; } break;
default:
//
// By default, display unadulterated raw data pointed to by 'Value'
//
Length = Value->Length; Address = Value->Address; }
if ( FALSE == AttachPropertyInstanceEx( Frame->hFrame, hProperty, Value->Length, Value->Address, Length, Address, 0, Frame->Level, IFlags )) { dw = ERROR_CAN_NOT_COMPLETE; }
return dw; }
|