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

📄 asn1p_expr.c

📁 ASN.1解析解码工具,可以解析各种ASN.1格式的文件,并对相应的BER文件解码
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <assert.h>#include "asn1parser/asn1parser.h"#include <stdarg.h>
static asn1p_expr_t *asn1p_expr_clone_impl(asn1p_expr_t *expr, int skip_extensions, asn1p_expr_t *(*)(asn1p_expr_t *, void *), void *);static asn1p_value_t *value_resolver(asn1p_value_t *, void *arg);/* * Construct a new empty types collection. */asn1p_expr_t *asn1p_expr_new(int _lineno, asn1p_module_t *mod) {	asn1p_expr_t *expr;	expr = calloc(1, sizeof *expr);	if(expr) {		TQ_INIT(&(expr->members));		expr->spec_index = -1;		expr->module = mod;		expr->_lineno = _lineno;	}	return expr;}asn1p_expr_t *asn1p_expr_clone(asn1p_expr_t *expr, int skip_extensions) {	return asn1p_expr_clone_impl(expr, skip_extensions, 0, 0);}asn1p_expr_t *asn1p_expr_clone_with_resolver(asn1p_expr_t *expr, asn1p_expr_t *(*r)(asn1p_expr_t *, void *), void *rarg) {	return asn1p_expr_clone_impl(expr, 0, r, rarg);}static asn1p_expr_t *asn1p_expr_clone_impl(asn1p_expr_t *expr, int skip_extensions, asn1p_expr_t *(*r)(asn1p_expr_t *, void *), void *rarg) {	asn1p_value_t *(*vr)(asn1p_value_t *, void *) = 0;	asn1p_expr_t *clone = 0;	asn1p_expr_t *tcmemb;	/* Child of tc */	int hit_ext = 0;#define	CLCOPY(field)	do { clone->field = expr->field; } while(0)#define	CLCLONE(field, func)	do { if(expr->field) {			\			clone->field = func(expr->field);		\			if(clone->field == NULL) {			\				asn1p_expr_free(clone);			\				return NULL;				\			}						\		} } while(0)#define	CLVRCLONE(field, func)	do { if(expr->field) {			\			clone->field = func(expr->field, vr, rarg);	\			if(clone->field == NULL) {			\				asn1p_expr_free(clone);			\				return NULL;				\			}						\		} } while(0)	if(r) {		vr = value_resolver;		clone = r(expr, rarg);		if(clone) {			/* Merge constraints */			if(expr->constraints) {				asn1p_constraint_t *tmpct = asn1p_constraint_clone_with_resolver(expr->constraints, vr, rarg);				if(clone->constraints) {					if(asn1p_constraint_insert(clone->constraints, tmpct)) {						asn1p_constraint_free(tmpct);						asn1p_expr_free(clone);						return NULL;					}				} else {					clone->constraints = tmpct;				}				assert(expr->combined_constraints == 0);			}			/* Merge defaults */			CLCOPY(marker.flags);			CLVRCLONE(marker.default_value,				asn1p_value_clone_with_resolver);			if(clone->tag.tag_class == TC_NOCLASS) {				CLCOPY(tag);			} else if(expr->tag.tag_class != TC_NOCLASS) {				fprintf(stderr, "asn1c does not support "					"nested tagging in parameterization, "					"necessary at line %d\n",					expr->_lineno);				asn1p_expr_free(clone);				return NULL;			}			return clone;		} else if(errno != ESRCH) {			return NULL;	/* Hard error */		}	}	if(!clone) clone = asn1p_expr_new(expr->_lineno, expr->module);	if(!clone) return NULL;	/*	 * Copy simple fields.	 */	CLCOPY(meta_type);	CLCOPY(expr_type);	CLCOPY(tag);	CLCOPY(marker.flags);		/* OPTIONAL/DEFAULT */	CLCOPY(_mark);	clone->data = 0;	/* Do not clone this */	clone->data_free = 0;	/* Do not clone this */	/*	 * Clone complex fields.	 */	CLCLONE(Identifier, strdup);	CLCLONE(reference, asn1p_ref_clone);	CLVRCLONE(constraints, asn1p_constraint_clone_with_resolver);	CLVRCLONE(combined_constraints, asn1p_constraint_clone_with_resolver);	CLCLONE(lhs_params, asn1p_paramlist_clone);	CLVRCLONE(value, asn1p_value_clone_with_resolver);	CLVRCLONE(marker.default_value, asn1p_value_clone_with_resolver);	CLCLONE(with_syntax, asn1p_wsyntx_clone);	/*	 * Copy all the children of this expr.	 */	TQ_FOR(tcmemb, &(expr->members), next) {		asn1p_expr_t *cmemb;		if(skip_extensions		&& tcmemb->expr_type == A1TC_EXTENSIBLE) {			hit_ext++; /* Even if hit_ext wraps around, we're OK. */			continue;		}		if(hit_ext == 1) continue;	/* Skip between ...'s */		cmemb = asn1p_expr_clone_impl(tcmemb, skip_extensions, r, rarg);		if(cmemb == NULL) {			asn1p_expr_free(clone);			return NULL;		}		asn1p_expr_add(clone, cmemb);	}	return clone;}static asn1p_value_t *value_resolver(asn1p_value_t *value, void *rarg) {	asn1p_value_t *cval;	asn1p_expr_t *tmpexpr;	asn1p_expr_t *target;	asn1p_ref_t *ref;	struct {		asn1p_expr_t *(*expr_resolve)(asn1p_expr_t *, void *arg);	} *varg = rarg;	if(!value || value->type != ATV_REFERENCED) {		errno = ESRCH;		return NULL;	}	ref = value->value.reference;	tmpexpr = asn1p_expr_new(ref->_lineno, 0);	tmpexpr->meta_type = AMT_TYPEREF;	tmpexpr->expr_type = A1TC_REFERENCE;	tmpexpr->reference = ref;	target = varg->expr_resolve(tmpexpr, rarg);	tmpexpr->reference = 0;	asn1p_expr_free(tmpexpr);	if(!target)		return NULL;	/* errno's are compatible */	if(target->meta_type == AMT_VALUE) {		if(!target->value) {			fprintf(stderr,			"FATAL: Parameterization did not resolve "			"value reference at line %d\n", ref->_lineno);			asn1p_expr_free(target);			errno = EPERM;			return NULL;		}		cval = asn1p_value_clone(target->value);	} else if(target->meta_type == AMT_VALUESET) {		if(!target->constraints) {			fprintf(stderr,			"FATAL: Parameterization did not resolve "			"value set reference at line %d\n", ref->_lineno);			asn1p_expr_free(target);			errno = EPERM;			return NULL;		}		cval = asn1p_value_fromconstr(target->constraints, 1);	} else {		errno = EPERM;		cval = NULL;	}	asn1p_expr_free(target);	return cval;}/* * Add expression as a member of another. */voidasn1p_expr_add(asn1p_expr_t *to, asn1p_expr_t *what) {	TQ_ADD_TYPE(asn1p_expr_t,&(to->members), what, next);	what->parent_expr = to;}/* * Destruct the types collection structure. */voidasn1p_expr_free(asn1p_expr_t *expr) {	if(expr) {		asn1p_expr_t *tm;		/* Remove all children */		while((tm = TQ_REMOVE_TYPE(asn1p_expr_t,&(expr->members), next))) {			if(tm->parent_expr != expr)				printf("<%s:%p !-> %s:%p>\n",					tm->Identifier, tm->parent_expr,					expr->Identifier, expr);			assert(tm->parent_expr == expr);			asn1p_expr_free(tm);		}		if(expr->Identifier)			free(expr->Identifier);		if(expr->reference)			asn1p_ref_free(expr->reference);		if(expr->constraints)			asn1p_constraint_free(expr->constraints);		if(expr->combined_constraints)			asn1p_constraint_free(expr->combined_constraints);		if(expr->lhs_params)			asn1p_paramlist_free(expr->lhs_params);		if(expr->value)			asn1p_value_free(expr->value);		if(expr->marker.default_value)			asn1p_value_free(expr->marker.default_value);		if(expr->with_syntax)			asn1p_wsyntx_free(expr->with_syntax);		if(expr->data && expr->data_free)			expr->data_free(expr->data);		memset(expr, 0, sizeof(*expr));		free(expr);	}}char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *buf) {	static char buf_stat[TAG2STRING_BUFFER_SIZE];	char *start;	char *end;	if(!buf) buf = buf_stat;	start = buf;	end = buf + TAG2STRING_BUFFER_SIZE;	if(tag->tag_class == TC_NOCLASS) {		*buf = 0;		return buf;	}	strcpy(buf, "[");	switch(tag->tag_class) {	case TC_NOCLASS:		assert(tag->tag_class != TC_NOCLASS);		break;	case TC_UNIVERSAL:	strcat(buf, "UNIVERSAL ");	break;	case TC_PRIVATE:	strcat(buf, "PRIVATE ");	break;	case TC_APPLICATION:	strcat(buf, "APPLICATION ");	break;	case TC_CONTEXT_SPECIFIC:		break;	}	buf += asn1p_expr_snprintf(buf + strlen(buf), end - buf,		"%" PRIdASN "]", tag->tag_value);	assert((unsigned int)(buf - end) > sizeof(" IMPLICIT "));	switch(tag->tag_mode) {	case TM_DEFAULT: break;	case TM_IMPLICIT: strcat(buf, " IMPLICIT"); break;	case TM_EXPLICIT: strcat(buf, " EXPLICIT"); break;	}	return start;}int asn1p_expr_snprintf (char *buf, size_t maxlen, const char *format, ...)
{
	int result;
	va_list ap;
	va_start (ap, format);
#  if defined (WIN32)
	result = vsnprintf (buf, maxlen, format, ap);

#  else
	result = vsnprintf (buf, maxlen, format, ap);
	if (result == (int)(maxlen))
		result = -1;

	if (result == -1)
		buf[maxlen-1] = '\0';
#  endif
	va_end (ap);
	if (result == -1)
		result = (int) (maxlen + 1);
	return result;
}

char *asn_expr_type2str(size_t type){	switch(type)
	{		case ASN_CONSTR_SEQUENCE :			return "SEQUENCE";		case ASN_CONSTR_CHOICE :			return "CHOICE";		case ASN_CONSTR_SET :			return "SET";		case ASN_CONSTR_SEQUENCE_OF :			return "SEQUENCE OF";		case ASN_CONSTR_SET_OF :			return "SET OF";		case ASN_TYPE_ANY :			return "ANY";		case ASN_BASIC_BOOLEAN :			return "BOOLEAN";		case ASN_BASIC_NULL :			return "NULL";		case ASN_BASIC_INTEGER :			return "INTEGER";		case ASN_BASIC_REAL :			return "REAL";		case ASN_BASIC_ENUMERATED :			return "ENUMERATED";		case ASN_BASIC_BIT_STRING :			return "BIT STRING";		case ASN_BASIC_OCTET_STRING :			return "OCTET STRING";		case ASN_BASIC_OBJECT_IDENTIFIER :			return "OBJECT IDENTIFIER";		case ASN_BASIC_RELATIVE_OID :			return "RELATIVE-OID";		case ASN_BASIC_EXTERNAL :			return "EXTERNAL";		case ASN_BASIC_EMBEDDED_PDV :			return "EMBEDDED PDV";		case ASN_BASIC_CHARACTER_STRING :			return "CHARACTER STRING";		case ASN_BASIC_UTCTime :			return "UTCTime";		case ASN_BASIC_GeneralizedTime :			return "GeneralizedTime";		case ASN_STRING_IA5String :			return "IA5String";		case ASN_STRING_PrintableString :			return "PrintableString";		case ASN_STRING_VisibleString :			return "VisibleString";		case ASN_STRING_ISO646String :			return "ISO646String";		case ASN_STRING_NumericString :			return "NumericString";		case ASN_STRING_UniversalString :			return "UniversalString";		case ASN_STRING_BMPString :			return "BMPString";		case ASN_STRING_UTF8String :			return "UTF8String";		case ASN_STRING_GeneralString :			return "GeneralString";		case ASN_STRING_GraphicString :			return "GraphicString";		case ASN_STRING_TeletexString :			return "TeletexString";		case ASN_STRING_T61String :			return "T61String";		case ASN_STRING_VideotexString :			return "VideotexString";		case ASN_STRING_ObjectDescriptor :			return "ObjectDescriptor";	}
	return NULL;
}int asn_expr_type2uclass(int tag){	int nret = -1;	switch(tag)
	{
	case ASN_BASIC_BOOLEAN:
		nret=1;
		break;
	case ASN_BASIC_INTEGER:
		nret=2;
		break;
	case ASN_BASIC_BIT_STRING:
		nret=3;
		break;
	case ASN_BASIC_OCTET_STRING:
		nret=4;
		break;
	case ASN_BASIC_NULL:
		nret=5;
		break;
	case ASN_BASIC_OBJECT_IDENTIFIER:
		nret=6;
		break;
	case ASN_STRING_ObjectDescriptor:
		nret=7;
		break;
	case ASN_BASIC_EXTERNAL:
		nret=8;
		break;
	case ASN_BASIC_REAL:
		nret=9;
		break;
	case ASN_BASIC_ENUMERATED:
		nret=10;
		break;
	case ASN_BASIC_EMBEDDED_PDV:
		nret=11;
		break;
	case ASN_STRING_UTF8String:
		nret=12;
		break;
	case ASN_BASIC_RELATIVE_OID:
		nret=13;
		break;
	case ASN_CONSTR_SEQUENCE:
		nret=16;
		break;
	case ASN_CONSTR_SEQUENCE_OF:
		nret=16;
		break;
	case ASN_CONSTR_SET:
		nret=17;
		break;
	case ASN_CONSTR_SET_OF:
		nret=17;
		break;
	case ASN_STRING_NumericString:
		nret=18;
		break;
	case ASN_STRING_PrintableString:
		nret=19;
		break;
	case ASN_STRING_TeletexString:
		nret=20;
		break;
	case ASN_STRING_T61String:
		nret=20;
		break;
	case ASN_STRING_VideotexString:
		nret=21;
		break;
	case ASN_STRING_IA5String:
		nret=22;
		break;
	case ASN_BASIC_UTCTime:
		nret=23;
		break;
	case ASN_BASIC_GeneralizedTime:
		nret=24;
		break;
	case ASN_STRING_GraphicString:
		nret=25;
		break;
	case ASN_STRING_VisibleString:
		nret=26;
		break;
	case ASN_STRING_ISO646String:
		nret=26;
		break;
	case ASN_STRING_GeneralString:
		nret=27;
		break;
	case ASN_STRING_UniversalString:
		nret=28;
		break;
	case ASN_BASIC_CHARACTER_STRING:
		nret=29;
		break;
	case ASN_STRING_BMPString:
		nret=30;
		break;
	}
		return nret;}

⌨️ 快捷键说明

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