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

📄 asn1fix_constr.c

📁 ASN.1解析解码工具,可以解析各种ASN.1格式的文件,并对相应的BER文件解码
💻 C
字号:
#include "asn1fix/asn1fix_internal.h"static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);static int _asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr);intasn1f_pull_components_of(arg_t *arg) {	TQ_HEAD(asn1p_expr_t) list;	asn1p_expr_t *expr = arg->expr;	asn1p_expr_t *memb;	int r_value = 0;	switch(expr->expr_type) {	case ASN_CONSTR_SEQUENCE:	case ASN_CONSTR_SET:		break;	default:		return 0;	}	TQ_INIT(&list);	/*	 * Look into	 */	while((memb = TQ_REMOVE_TYPE(asn1p_expr_t,&(expr->members), next))) {		asn1p_expr_t *coft;	/* COMPONENTS OF thing itself */		asn1p_expr_t *terminal;	/* Terminal of the referenced type */		if(memb->expr_type != A1TC_COMPONENTS_OF) {			TQ_ADD_TYPE(asn1p_expr_t,&list, memb, next);			continue;		}		coft = TQ_FIRST(&memb->members);		assert(coft);		assert(!TQ_NEXT(coft, next));		/*		 * Find the referenced type.		 */		terminal = asn1f_find_terminal_type(arg, coft);		if(!terminal || (terminal->expr_type != expr->expr_type)) {			FATAL("COMPONENTS OF at line %d "				"must reference a %s type",				coft->_lineno,				expr->expr_type==ASN_CONSTR_SET					? "SET" : "SEQUENCE"			);			TQ_ADD_TYPE(asn1p_expr_t,&list, memb, next);			r_value = -1;			continue;		}		/*		 * Clone the final structure.		 */		coft = asn1p_expr_clone(terminal, 1 /* Skip extensions */);		if(!coft) return -1;	/* ENOMEM */		if(0) {			asn1p_expr_free(memb);	/* Don't need it anymore*/		} else {			/* Actual removal clashes with constraints... skip. */		}		/*		 * Move all components of the cloned structure		 * into the current one.		 */		while((memb = TQ_REMOVE_TYPE(asn1p_expr_t,&(coft->members), next))) {			TQ_ADD_TYPE(asn1p_expr_t,&list, memb, next);			memb->parent_expr = expr;		}		asn1p_expr_free(coft);	/* Remove wrapper */	}	/* Move the stuff back */	TQ_MOVE(&(expr->members), &list);	return r_value;}/* * Fix extensibility parts inside constructed types (SEQUENCE, SET, CHOICE). */intasn1f_fix_constr_ext(arg_t *arg) {	asn1p_expr_t *expr = arg->expr;	asn1p_expr_t *v;	TQ_HEAD(asn1p_expr_t) root_list;	TQ_HEAD(asn1p_expr_t) ext_list;	TQ_HEAD(asn1p_expr_t) *cur_list;	int r_value = 0;	int ext_count = 0;	switch(expr->expr_type) {	case ASN_CONSTR_SEQUENCE:	case ASN_CONSTR_SET:	case ASN_CONSTR_CHOICE:		break;	default:		return 0;	}	DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);	TQ_INIT(&root_list);	TQ_INIT(&ext_list);	cur_list = (void *)&root_list;	/*	 * Split the set of fields into two lists, the root list	 * and the extensions list.	 */	while((v = TQ_REMOVE_TYPE(asn1p_expr_t,&(expr->members), next))) {		if(v->expr_type == A1TC_EXTENSIBLE) {			ext_count++;			switch(ext_count) {			case 1: cur_list = (void *)&ext_list; break;			case 2:				cur_list = (void *)&root_list;				if(v->value) {					FATAL("Optional extension marker "						"must not contain "						"an exception mark "						"at line %d", v->_lineno);					r_value = -1;				}				asn1p_expr_free(v);				continue;			case 3:				FATAL("Third extension marker "				"is not allowed at line %d", v->_lineno);			default:				r_value = -1;			}		}		TQ_ADD_TYPE(asn1p_expr_t,cur_list, v, next);	}	/*	 * Copy the root list and extension list back into the main list.	 */	TQ_MOVE(&(expr->members), &root_list);	while((v = TQ_REMOVE_TYPE(asn1p_expr_t,&ext_list, next)))		TQ_ADD_TYPE(asn1p_expr_t,&(expr->members), v, next);	if(arg->mod->module_flags & MSF_EXTENSIBILITY_IMPLIED	&& ext_count == 0) {		v = asn1p_expr_new(0, arg->mod);		if(v) {			v->Identifier = strdup("...");			v->expr_type = A1TC_EXTENSIBLE;			v->meta_type = AMT_TYPE;			v->_lineno = expr->_lineno;	/* The best we can do */			if(v->Identifier == NULL) {				asn1p_expr_free(v);				r_value = -1;			} else {				asn1p_expr_add(expr, v);			}		} else {			r_value = -1;		}	}	return r_value;}intasn1f_fix_constr_tag(arg_t *arg, int fix_top_level) {	asn1p_expr_t *expr = arg->expr;	asn1p_expr_t *v;	int root_tagged = 0;	/* The root component is manually tagged */	int ext_tagged = 0;	/* The extensions are manually tagged */	int imp_tagged = 0; /*implicit tag*/	int component_number = 0;	int r_value = 0;	DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);	/*	 * Fix the top-level type itself first.	 */	if(fix_top_level) {		if(expr->tag.tag_class == TC_NOCLASS)			return r_value;		if(_asn1f_fix_type_tag(arg, expr))			r_value = -1;		return r_value;	}	switch(expr->expr_type) {	case ASN_CONSTR_SEQUENCE:	case ASN_CONSTR_SET:	case ASN_CONSTR_CHOICE:		break;	default:		return 0;	}	TQ_FOR(v, &(expr->members), next) {		if(v->expr_type == A1TC_EXTENSIBLE) {			component_number++;			continue;		}		if(v->tag.tag_class == TC_NOCLASS) {			imp_tagged = 1;			continue;		}		switch(component_number) {		case 0: case 2:			root_tagged = 1; break;		default:			ext_tagged = 1; break;		}		if(_asn1f_fix_type_tag(arg, v))			r_value = -1;	}		if((arg->mod->module_flags & (MSF_AUTOMATIC_TAGS|MSF_IMPLICIT_TAGS) )/* 王斌修改此段			*//*	&& !root_tagged) { */	&& imp_tagged) {/* 		printf("aaaaaaaaaaaaaaa[%s]aaaaaaaaaaaaa[%d]aaaaaaaa[%d]aaaaaaaaa\n",
// 			expr->Identifier,root_tagged,ext_tagged);
// 		if(ext_tagged) {
// 			FATAL("In %s at line %d: "
// 				"extensions are tagged "
// 				"but root components are not",
// 				expr->Identifier, expr->_lineno);
// 			r_value = -1;
// 		} else {
*/		/* Make a decision on automatic tagging */			expr->auto_tags_OK = 1;/*		} */	}	return r_value;}static int_asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr) {	int must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, expr);	int module_impl_tags = (arg->mod->module_flags				& (MSF_IMPLICIT_TAGS | MSF_AUTOMATIC_TAGS));	int r_value = 0;	if(expr->tag.tag_mode == TM_DEFAULT) {		if(must_explicit || module_impl_tags == 0)			expr->tag.tag_mode = TM_EXPLICIT;		else			expr->tag.tag_mode = TM_IMPLICIT;	}	/*	 * Perform a final sanity check.	 */	if(must_explicit) {		if(expr->tag.tag_mode == TM_IMPLICIT) {			FATAL("%s tagged in IMPLICIT mode "				"but must be EXPLICIT at line %d",				expr->Identifier, expr->_lineno);			r_value = -1;		} else {			expr->tag.tag_mode = TM_EXPLICIT;		}	}	return r_value;}intasn1f_fix_constr_autotag(arg_t *arg) {	asn1p_expr_t *expr = arg->expr;	asn1p_expr_t *v,*real_type;	asn1c_integer_t tag_value = 0;	int r_value = 0;	switch(expr->expr_type) {	case ASN_CONSTR_SEQUENCE:	case ASN_CONSTR_SET:	case ASN_CONSTR_CHOICE:		if(expr->auto_tags_OK)		{			break;		}		/* Automatic tagging is not applicable */		/* Fall through */	default:		return 0;	}	DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);	TQ_FOR(v, &(expr->members), next) {		int must_explicit;		if(v->expr_type == A1TC_EXTENSIBLE) {			/* 28.5, d) */			continue;		}		if(0) {			/* This may be not true in case COMPONENTS OF */			assert(v->tag.tag_class == TC_NOCLASS);		}		/* add by wangbin 2007-06-25,自动生成 tag */		if (v->tag.tag_class != TC_NOCLASS)
		{
			if (v->tag.tag_class == TC_CONTEXT_SPECIFIC)
			{
				tag_value = v->tag.tag_value + 1;
			}
			continue;
		}
				must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);		real_type = asn1f_find_terminal_type(arg,v);		if (real_type->expr_type == ASN_CONSTR_CHOICE ||real_type->expr_type == ASN_TYPE_ANY)
		{
			/*
			struct asn1p_type_tag_s tag;
			int nRet;
			memset(&tag,0,sizeof(tag) );
			nRet = asn1f_fetch_outmost_tag(arg->asn, arg->mod, v, &tag, 0);
			printf("[%s.%s]---[%d]----[%lld]----[%lld][%lld]-[%d]----\n",				expr->Identifier,v->Identifier,must_explicit,tag_value,v->tag.tag_value,				tag.tag_value,nRet);			*/			v->tag.tag_class = TC_CONTEXT_SPECIFIC;			v->tag.tag_mode = must_explicit ? TM_EXPLICIT : TM_IMPLICIT;			v->tag.tag_value = tag_value++;					}	}	return r_value;}/* * Check that tags are distinct. */intasn1f_check_constr_tags_distinct(arg_t *arg) {	asn1p_expr_t *expr = arg->expr;	asn1p_expr_t *v;	int r_value = 0;	switch(expr->expr_type) {	case ASN_CONSTR_SEQUENCE:	case ASN_CONSTR_SET:	case ASN_CONSTR_CHOICE:		break;	default:		return 0;	}	TQ_FOR(v, &(expr->members), next) {		/*		 * In every series of non-mandatory components,		 * the tags must be distinct from each other AND the		 * tag of the following mandatory component.		 * For SET and CHOICE treat everything as a big set of		 * non-mandatory components.		 */		if(expr->expr_type != ASN_CONSTR_SEQUENCE || v->marker.flags) {			asn1p_expr_t *nv;			for(nv = v; (nv = TQ_NEXT(nv, next));) {				DEBUG("S/C comparing tags %s s. %s",					v->Identifier, nv->Identifier);				if(_asn1f_compare_tags(arg, v, nv))					r_value = -1;				if(expr->expr_type == ASN_CONSTR_SEQUENCE				&& !nv->marker.flags) break;			}		}	}	return r_value;}static int_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {	struct asn1p_type_tag_s tag;	struct asn1p_type_tag_s save_tag;	asn1p_expr_t *reft;	int ret;	/*	 * Fetch the _next_ tag for this type.	 */	save_tag = v->tag;			/* Save existing tag */	memset(&v->tag, 0, sizeof(v->tag));	/* Remove it temporarily */	ret = asn1f_fetch_outmost_tag(arg->asn, arg->mod, v, &tag, 0);	v->tag = save_tag;			/* Restore the tag back */	if(ret == 0) return 0;	/* If found tag, it's okay */	reft = asn1f_find_terminal_type(arg, v);	if(reft) {		switch(reft->expr_type) {		case ASN_TYPE_ANY:		case ASN_CONSTR_CHOICE:			return 1;		default:			return 0;		}	}	return 0;}/* * Check that the tags are distinct. */static int_asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {	struct asn1p_type_tag_s ta, tb;	int ra, rb;	int ret;	ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a,			&ta, AFT_IMAGINARY_ANY);	rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b,			&tb, AFT_IMAGINARY_ANY);	/*	 * If both tags are explicitly or implicitly given, use them.	 */	DEBUG("Fetching outmost tags: %d, %d", ra, rb);	if(ra == 0 && rb == 0) {		/*		 * Simple case: fetched both tags.		 */		if((ta.tag_value == tb.tag_value			&& ta.tag_class == tb.tag_class)		|| ta.tag_value == -1	/* Spread IMAGINARY ANY tag... */		|| tb.tag_value == -1	/* ...it is an evil virus, fear it! */		) {			char tagbuf[2][TAG2STRING_BUFFER_SIZE];			char *p = (a->expr_type == A1TC_EXTENSIBLE)				?"potentially ":"";			FATAL("Processing %s at line %d: component \"%s\" at line %d %shas the same tag "				"with component \"%s\" at line %d,tagA[%lld],tagB[%lld]",				arg->expr->Identifier,				arg->expr->_lineno,				a->Identifier,				a->_lineno,				p,				b->Identifier,				b->_lineno,				ta.tag_value,				tb.tag_value			);			DEBUG("Tags: %s %s  vs.  %s %s",				asn1p_tag2string(&ta, tagbuf[0]),				a->Identifier,				asn1p_tag2string(&tb, tagbuf[1]),				b->Identifier			);			if((arg->mod->module_flags & MSF_EXTENSIBILITY_IMPLIED)			&& (a->expr_type == A1TC_EXTENSIBLE)			&& (b->expr_type == A1TC_EXTENSIBLE)) {				FATAL("The previous error is due to "					"improper use of "					"EXTENSIBILITY IMPLIED flag "					"of module %s",					arg->mod->ModuleName);			}			return -1;		} else {			/* Tags are distinct */			return 0;		}	}	/**********************************************************	 * Now we must perform some very funny recursion to check	 * multiple components of CHOICE type, etc.	 */	DEBUG("Comparing tags %s:%x <-> %s:%x",		a->Identifier, a->expr_type,		b->Identifier, b->expr_type);	if(ra && a->meta_type == AMT_TYPEREF) {		DEBUG(" %s is a type reference", a->Identifier);		a = asn1f_lookup_symbol(arg,			a->module, a->rhs_pspecs, a->reference);		if(!a) return 0;	/* Already FATAL()'ed somewhere else */		WITH_MODULE(a->module, ret = _asn1f_compare_tags(arg, a, b));		return ret;	}	if(ra && a->expr_type == ASN_CONSTR_CHOICE) {		asn1p_expr_t *v;		DEBUG(" %s is a choice type (%d)", a->Identifier, a->_mark);		/*		 * Iterate over members of CHOICE.		 */		/* if(a->_mark & TM_RECURSION) return 0; */		TQ_FOR(v, &(a->members), next) {			/* a->_mark |= TM_RECURSION; */			ret = _asn1f_compare_tags(arg, v, b);			/* a->_mark &= ~TM_RECURSION; */			if(ret) return ret;		}		return 0;	}	if(rb && b->expr_type == ASN_CONSTR_CHOICE) {		return _asn1f_compare_tags(arg, b, a);	}	if(a->_mark & TM_RECURSION) return 0;	if(b->_mark & TM_RECURSION) return 0;	a->_mark |= TM_RECURSION;	b->_mark |= TM_RECURSION;	ret = _asn1f_compare_tags(arg, b, a);	a->_mark &= ~TM_RECURSION;	b->_mark &= ~TM_RECURSION;	return ret;}

⌨️ 快捷键说明

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