⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcasnberdecoder.cpp

📁 ASN.1解析解码工具,可以解析各种ASN.1格式的文件,并对相应的BER文件解码
💻 CPP
字号:
/****************************************************************************************
* Copyrights  2006,深圳天源迪科信息技术股份有限公司
*
* All rights reserved.
*
* Filename:	DCAsnBerDecoder.cpp		
* Indentifier:		
* Description:	
* Version:		V1.0
* Author:		wangbin
* Finished:	2007年6月20日
* History:
******************************************************************************************/

#include "dicasnutil/DCAsnBerDecoder.h"

/*******************************************************************************************/
namespace dicasn1p
{
/*******************************************************************************************/

void tlv_tree_fix(arg_t *arg,DCTreeNode<DCBerTlv> *root)
{
	root->data->reference =	arg->expr;
	if (root->data->reference == NULL)
	{
		return;
	}
	arg_t child_arg;
	child_arg.asn = arg->asn;
	child_arg.mod = NULL;
	child_arg.expr = arg->expr;

	asn1p_expr_t *real_type;
	
	if(arg->expr->expr_type == A1TC_REFERENCE)
	{
		real_type = asn1f_find_terminal_type(&child_arg,arg->expr);
	}
	else
	{
		real_type = arg->expr;
	}

	if(root->data->constructed &&real_type)
	{
		asn1p_expr_t *child_type;
		DCTreeNode<DCBerTlv> *node;

		switch(real_type->expr_type)
		{
		case ASN_CONSTR_CHOICE:		/* CHOICE */
			node = root;
			if (node->depth)
			{
				node = node->head;
			}
			child_type = find_child_member_by_tag(real_type,node->data->tag);
			child_arg.expr = child_type;
			tlv_tree_fix(&child_arg,node);
			break;

		case ASN_CONSTR_SEQUENCE:	/* SEQUENCE */
		case ASN_CONSTR_SET:			/* SET */
			DCASN1P_NODE_FOR (node,root)
			{
				child_type = find_child_member_by_tag(real_type,node->data->tag);
				child_arg.expr = child_type;
				tlv_tree_fix(&child_arg,node);
			}
			break;
	
		case ASN_CONSTR_SEQUENCE_OF:		/* SEQUENCE OF */
		case ASN_CONSTR_SET_OF:		/* SET OF */
			DCASN1P_NODE_FOR (node,root)
			{
				child_arg.expr = TQ_FIRST(&(real_type->members) );
				tlv_tree_fix(&child_arg,node);
			}
			break;

		}
		
	}
}

asn1p_expr_t * find_child_member_by_tag( asn1p_expr_t* node,int tag )
{
	if(! node->expr_type&ASN_CONSTR_MASK )
		return NULL;
	asn1p_expr_t *child;
	TQ_FOR(child,&(node->members),next)
	{
		if (child->tag.tag_value == tag)
		{
			return child;
		}
	}
	return NULL;
}

DCTreeNode<DCBerTlv> * find_child_member_by_name(DCTreeNode<DCBerTlv> *node,const char *childName)
{
	if(!childName || strcmp(childName,"*") == 0)
	{
		return node->head;
	}
	DCTreeNode<DCBerTlv> * child;
	DCASN1P_NODE_FOR(child,node)
	{
		if(child->data->reference && child->data->reference->Identifier &&
			strcmp(child->data->reference->Identifier,childName)==0 )
			return child;
	}
	return NULL;
}
DCTreeNode<DCBerTlv> * find_sibling_member_by_name(DCTreeNode<DCBerTlv> *node,const char *siblingName)
{
	if(!siblingName || strcmp(siblingName,"*") == 0)
	{
		return node->next;
	}
	DCTreeNode<DCBerTlv> *sibling = node->next;
	for (;sibling;sibling = sibling->next)
	{
		if(sibling->data->reference && sibling->data->reference->Identifier &&
			strcmp(sibling->data->reference->Identifier,siblingName) )
			return sibling;
	}
	return NULL;
}

DCTreeNode<DCBerTlv> * find_child_member_by_path( DCTreeNode<DCBerTlv> *node,const char *path )
{
	char name[128];
	size_t len = strlen(path);
	if(len == 0)
		return node;
	if(!strchr(path,'.') && !strchr(path,'/') )
	{
		return match_member_name(node,path);
	}
	DCTreeNode<DCBerTlv> *child;
	DCTreeNode<DCBerTlv> *res = NULL;
	for (int i=0;i<=len;++i)
	{
		if(path[i]=='.' || path[i]=='/' )
		{
			memcpy(name,path,i);
			name[i] = 0;
			if (match_member_name(node,name))
			{
				DCASN1P_NODE_FOR(child,node)
				{
					if( res = find_child_member_by_path(child,path+i+1) )
					{
						return res;
					}
				}
			}
			break;
		}
	}
	return NULL;
}

DCTreeNode<DCBerTlv> * match_member_name( DCTreeNode<DCBerTlv> *node,const char *name )
{
	if (strcmp(name,"*")==0 )
	{
		return node;
	}
	if (node->data->reference &&node->data->reference->Identifier &&
		strcmp(node->data->reference->Identifier,name) == 0)
	{
		return node;
	}
	return NULL;
}

enum asn_tag_class asn_tag_class_to_ber( enum asn1p_tag_class_e v_asn_class )
{
	switch(v_asn_class)
	{
	case TC_NOCLASS:
	case TC_UNIVERSAL:
		return ASN_TAG_CLASS_UNIVERSAL;
	case TC_APPLICATION:
		return ASN_TAG_CLASS_APPLICATION;
	case TC_CONTEXT_SPECIFIC:
		return ASN_TAG_CLASS_CONTEXT;
	case TC_PRIVATE:
		return ASN_TAG_CLASS_PRIVATE;
	}
	return ASN_TAG_CLASS_UNIVERSAL;
}

/*******************************************************************************************/

DCAsnBerValue::DCAsnBerValue()
{
}

DCAsnBerValue::~DCAsnBerValue()
{
	clear();
}

DCAsnBerValue* DCAsnBerValue::fromExpr( arg_t *p_arg,int depth )
{
	DCAsnBerValue* newValue = NULL;
	asn1p_expr_t *expr = p_arg->expr;
	asn1p_expr_t *origin_expr = expr;
	arg_t new_arg;
	memset(&new_arg,0,sizeof(new_arg) );
	new_arg.asn = p_arg->asn;
	expr = asn1f_find_terminal_type(&new_arg,expr);
	switch(expr->expr_type)
	{
	case A1TC_INVALID:		/* Invalid type */
	case A1TC_REFERENCE:		/* Reference to the type defined elsewhere */
	case A1TC_EXPORTVAR:		/* We're exporting this definition */
		break;
	case A1TC_EXTENSIBLE:	/* An extension marker "..." */
		break;
	case A1TC_COMPONENTS_OF:	/* COMPONENTS OF clause */
	case A1TC_VALUESET:		/* Value set definition */
	case A1TC_CLASSDEF:		/* Information Object Class */
	case A1TC_INSTANCE:		/* Instance of Object Class */
	case A1TC_CLASSFIELD_TFS:	/* TypeFieldSpec */
	case A1TC_CLASSFIELD_FTVFS:		/* FixedTypeValueFieldSpec */
	case A1TC_CLASSFIELD_VTVFS:		/* VariableTypeValueFieldSpec */
	case A1TC_CLASSFIELD_FTVSFS:		/* FixedTypeValueSetFieldSpec */
	case A1TC_CLASSFIELD_VTVSFS:		/* VariableTypeValueSetFieldSpec */
	case A1TC_CLASSFIELD_OFS:		/* ObjectFieldSpec */
	case A1TC_CLASSFIELD_OSFS:		/* ObjectSetFieldSpec */
		break;
	case ASN_CONSTR_SEQUENCE:	/* SEQUENCE */
		newValue = new DCStructValue(DCStructValue::TYPE_SEQUENCE);
		break;
	case ASN_CONSTR_CHOICE:		/* CHOICE */
		newValue = new DCChoiceValue(DCStructValue::TYPE_CHOICE);
		break;
	case ASN_CONSTR_SET:			/* SET */
		newValue = new DCStructValue(DCStructValue::TYPE_SET);
		break;
	case ASN_CONSTR_SEQUENCE_OF:		/* SEQUENCE OF */
		newValue = new DCArrayValue(DCStructValue::TYPE_SEQUENCE_OF);
		break;
	case ASN_CONSTR_SET_OF:		/* SET OF */
		newValue = new DCArrayValue(DCStructValue::TYPE_SET_OF);
		break;
	case ASN_TYPE_ANY:	/* ANY (deprecated) */
		newValue = new DCBasicValue(DCBasicValue::TYPE_ANY);
		break;
	case A1TC_UNIVERVAL:		/* A value of an ENUMERATED: INTEGER or BS */
	case A1TC_BITVECTOR:		/* A plain collection of bits */
	case A1TC_OPAQUE:		/* Opaque data encoded as a bitvector */
	case ASN_BASIC_BOOLEAN:
	case ASN_BASIC_NULL:
	case ASN_BASIC_INTEGER:
	case ASN_BASIC_REAL:
	case ASN_BASIC_ENUMERATED:
	case ASN_BASIC_BIT_STRING:
	case ASN_BASIC_OCTET_STRING:
	case ASN_BASIC_OBJECT_IDENTIFIER:
	case ASN_BASIC_RELATIVE_OID:
	case ASN_BASIC_EXTERNAL:
	case ASN_BASIC_EMBEDDED_PDV:
		newValue = new DCBasicValue(DCBasicValue::TYPE_INT);
		break;
	case ASN_BASIC_UTCTime:
	case ASN_BASIC_GeneralizedTime:
		newValue = new DCBasicValue(DCBasicValue::TYPE_UTCTIME);
		break;
	case ASN_BASIC_CHARACTER_STRING:
	case ASN_STRING_IA5String:
	case ASN_STRING_PrintableString:
	case ASN_STRING_VisibleString:
	case ASN_STRING_ISO646String:	/* aka VisibleString */
	case ASN_STRING_NumericString:
	case ASN_STRING_UniversalString:
	case ASN_STRING_BMPString:
	case ASN_STRING_UTF8String:
	case ASN_STRING_GeneralString:
	case ASN_STRING_GraphicString:
	case ASN_STRING_TeletexString:
	case ASN_STRING_T61String:
	case ASN_STRING_VideotexString:
	case ASN_STRING_ObjectDescriptor:
		newValue = new DCBasicValue(DCBasicValue::TYPE_STRING);
		break;
	}
	if (newValue)
	{
		newValue->reference = origin_expr;
		newValue->depth = depth;
		newValue->asn = p_arg->asn;
		if (origin_expr->Identifier)
		{
			newValue->name = origin_expr->Identifier;
		}
		struct asn1p_type_tag_s s_tag;
		int nRet;
		
		nRet = asn1f_fetch_outmost_tag(p_arg->asn,origin_expr->module,origin_expr,&s_tag,AFT_FETCH_OUTMOST);
		if(nRet == 0)
		{
			newValue->tag = (int)s_tag.tag_value;
			newValue->tag_class = asn_tag_class_to_ber(s_tag.tag_class);
		}
		if (expr->expr_type & ASN_CONSTR_MASK)
		{
			asn1p_expr_t * child;
			DCAsnBerValue* childValue;
			switch(expr->expr_type)
			{
			case ASN_CONSTR_SEQUENCE_OF:
			case ASN_CONSTR_SET_OF:
				new_arg.expr = TQ_FIRST(&expr->members);
				childValue = fromExpr(&new_arg,depth +1 );
				if (childValue)
				{
					((DCArrayValue*)newValue)->member_type = childValue;
				}
				break;
			case ASN_CONSTR_CHOICE:
				TQ_FOR(child,&(expr->members),next)
				{
					new_arg.expr = child;
					childValue = fromExpr(&new_arg,depth +1);
					if (childValue)
					{
						((DCChoiceValue*)newValue)->member_types.push_back(childValue);
					}
				}
				break;
			default:
				TQ_FOR(child,&(expr->members),next)
				{
					new_arg.expr = child;
					childValue = fromExpr(&new_arg,depth +1);
					if (childValue)
					{
						((DCStructValue*)newValue)->members.push_back(childValue);
					}
				}
				break;
			}
		}
	}
	return newValue;
}

int DCAsnBerValue::fromRoot( DCBerTlvNode* root )
{
	root->data->reference = reference;
	switch(value_type)
	{
	case TYPE_BASIC:
		return fromNode(root);
	}
	return fromNode(root->head);
}

void DCAsnBerValue::clear() /*=0*/
{

}
/*************************************  DCBasicValue  ******************************************************/

DCBasicValue::DCBasicValue( T_basicType type )
{
	this->type = type;
	value_type = TYPE_BASIC;
	buf = NULL;
	size = 0;
}

int DCBasicValue::fromNode( DCBerTlvNode* first )
{
	if (first && first->data)
	{
		buf = first->data->value;
		size = first->data->length;
	}
	return 0;
}

void DCBasicValue::clear()
{

}
/*************************************  DCStructValue  ******************************************************/

DCStructValue::DCStructValue( T_structType type )
{
	this->type = type;
	value_type = TYPE_STRUCT;
}

int DCStructValue::fromNode( DCBerTlvNode* first )
{
	if (first && first->data)
	{
		int imember = 0;
		DCBerTlvNode* oldfirst;
		switch(type)
		{
		case TYPE_SEQUENCE:
			for (imember=0;imember<members.size() && first;++imember)
			{
				if (members[imember]->tag == first->data->tag && members[imember]->tag_class == first->data->tag_class)
				{
					members[imember]->fromRoot(first);
					first = first->next;
				}
			}
			break;
		case TYPE_SET:
			oldfirst = first;
			for (imember=0;imember<members.size();++imember)
			{
				first = oldfirst;
				while (first)
				{
					if (members[imember]->tag == first->data->tag && members[imember]->tag_class == first->data->tag_class)
					{
						members[imember]->fromRoot(first);
						break;
					}
					first = first->next;
				}
			}
			break;
		default:
			return -1;
		}
	}
	return 0;
}

void DCStructValue::clear()
{
	for (int i=0;i<members.size(); ++i)
	{
		delete members[i];
	}
	members.clear();
}
/********************************  DCArrayValue  ***********************************************************/

DCArrayValue::DCArrayValue( T_structType type ):DCStructValue(type)
{

}

int DCArrayValue::fromNode( DCBerTlvNode* first )
{
	DCStructValue::clear();
	DCAsnBerValue *value;
	arg_t arg;
	arg.asn = asn;
	arg.expr = member_type->reference;
	while (first)
	{
		first->data->reference = reference;
		value = fromExpr(&arg,member_type->depth);
		if (value)
		{
			value->fromRoot(first);
			members.push_back(value);
		}
		first = first->next;
	}
	return 0;
}

void DCArrayValue::clear()
{
	DCStructValue::clear();
	delete member_type;
}

/*******************************************************************************************/

DCChoiceValue::DCChoiceValue( T_structType type ):DCStructValue(type)
{

}

int DCChoiceValue::fromNode( DCBerTlvNode* first )
{
	members.clear();
	for (int i=0;i<member_types.size();++i)
	{
		if (member_types[i]->tag == first->data->tag && member_types[i]->tag_class == first->data->tag_class)
		{
			member_types[i]->fromRoot(first);
			members.push_back(member_types[i]);
			break;
		}
	}
	return 0;
}

void DCChoiceValue::clear()
{
	for (int i=0;i<member_types.size(); ++i)
	{
		delete member_types[i];
	}
	member_types.clear();
}
/*******************************************************************************************/
}
/*******************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -