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

📄 asn1fix_bitstring.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
字号:
#include "asn1fix_internal.h"int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);intasn1f_fix_bit_string(arg_t *arg) {	asn1p_expr_t *expr = arg->expr;	int r_value = 0;	int ret;	if(expr->meta_type == AMT_VALUE) {		asn1p_expr_t *ttype;		DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);		ttype = asn1f_find_terminal_type(arg, expr);		if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {			ret = asn1f_fix_bit_string_value(arg, ttype);			RET2RVAL(ret, r_value);		}	}	return r_value;}intasn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {	asn1p_expr_t *expr = arg->expr;	int r_value = 0;	DEBUG("(%s) for line %d",		expr->Identifier, expr->_lineno);	switch(expr->value->type) {	case ATV_UNPARSED:		/*		 * Most definitely we have something like		 * 	value BitStringType1 ::= { a, b, c }		 * which could not be parsed by the LALR parser, mostly		 * because it requires knowledge about BitStringType1		 * during the parsing. So, here's a little hack: we create		 * a buffer containing the full specification of a module,		 * which contains some pre-defined INTEGER type with the		 * opaque definition "{ a, b, c }" from the bit string.		 */		if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {			r_value = -1;			break;		}		/* Fall through: remove trailing zero bits */	case ATV_BITVECTOR:		asn1f_BS_remove_trailing_zero_bits(expr->value);		break;	default:		break;	}	return r_value;}static voidasn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {	int lmfb = -1;	/* Last meaningful byte position */	int bits;	/* Number of bits in the BIT STRING value */	int b;	assert(value->type == ATV_BITVECTOR);	bits = value->value.binary_vector.size_in_bits;	/*	 * Figure out the rightmost meaningful byte.	 */	for(b = 0; b < ((bits + 7) >> 3); b++) {		uint8_t uc = value->value.binary_vector.bits[b];		if(uc && b > lmfb)			lmfb = b;	}	if(lmfb == -1) {		bits = 0;	} else {		uint8_t uc;		uc = value->value.binary_vector.bits[lmfb];		bits = (lmfb+1) * 8;		/*		 * Squeeze the bit string width until the rightmost		 * bit is set.		 */		for(; uc && (uc & 1) == 0; uc >>= 1)			bits--;		if(uc == 0) {			bits = lmfb * 8;		}	}	value->value.binary_vector.size_in_bits = bits;}static intasn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {	asn1p_t *asn;	asn1p_module_t *mod;	asn1p_expr_t *V;	asn1p_expr_t *bit;	asn1c_integer_t aI;	uint8_t *bitbuf;	int bits;	int psize;	char *p;	int ret;	int r_value = 0;	assert(value->type == ATV_UNPARSED);	psize = value->value.string.size + 64;	p = malloc(psize);	if(p == NULL)		return -1;	ret = snprintf(p, psize,		"M DEFINITIONS ::=\nBEGIN\n"		"V ::= INTEGER %s\n"		"END\n",		value->value.string.buf	);	assert(ret < psize);	psize = ret;	asn = asn1p_parse_buffer(p, psize, A1P_NOFLAGS);	free(p);	if(asn == NULL) {		FATAL("Cannot parse BIT STRING value %s "			"defined as %s at line %d",			arg->expr->Identifier,			value->value.string.buf,			arg->expr->_lineno		);		return -1;	}	mod = TQ_FIRST(&(asn->modules));	assert(mod);	V = TQ_FIRST(&(mod->members));	assert(V);	assert(strcmp(V->Identifier, "V") == 0);	assert(TQ_FIRST(&(V->members)));	/*	 * Simple loop just to fetch the maximal bit position	 * out of the BIT STRING value defined as NamedBitList.	 */	aI = -1;	TQ_FOR(bit, &(V->members), next) {		asn1p_expr_t *bitdef;		bitdef = asn1f_lookup_child(ttype, bit->Identifier);		if(bitdef && bitdef->value		&& bitdef->value->type == ATV_INTEGER) {			if(bitdef->value->value.v_integer > aI)				aI = bitdef->value->value.v_integer;		}	}	if(aI > 1024 * 1024 * 8) {	/* One megabyte */		FATAL("Unsupportedly large BIT STRING value \"%s\" "			"defined at line %d "			"(larger than 1MByte)",			arg->expr->Identifier,			arg->expr->_lineno		);		asn1p_free(asn);		return -1;	}	bits = aI + 1;	/* Number of bits is more than a last bit position */	bitbuf = calloc(1, 1 + ((bits + 7) / 8));	if(bitbuf == NULL) {		asn1p_free(asn);		return -1;	}	TQ_FOR(bit, &(V->members), next) {		asn1p_expr_t *bitdef;		int set_bit_pos;		if(bit->value) {			WARNING("Identifier \"%s\" at line %d "				"must not have a value",				bit->Identifier, bit->_lineno);			RET2RVAL(1, r_value);		}		bitdef = asn1f_lookup_child(ttype, bit->Identifier);		if(bitdef == NULL) {			FATAL("Identifier \"%s\" at line %d is not defined "				"in the \"%s\" type definition at line %d",				bit->Identifier,				bit->_lineno,				ttype->Identifier,				ttype->_lineno			);			RET2RVAL(-1, r_value);			continue;		}		if(bitdef->value == NULL		|| bitdef->value->type != ATV_INTEGER) {			FATAL("Broken identifier "				"\"%s\" at line %d "				"referenced by \"%s\" at line %d",				bitdef->Identifier,				bitdef->_lineno,				arg->expr->Identifier,				arg->expr->_lineno			);			RET2RVAL(-1, r_value);			continue;		}		assert(bitdef->value->value.v_integer < bits);		set_bit_pos = bitdef->value->value.v_integer;		bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));	}	asn1p_free(asn);	free(value->value.string.buf);	value->type = ATV_BITVECTOR;	value->value.binary_vector.bits = bitbuf;	value->value.binary_vector.size_in_bits = bits;	return r_value;}

⌨️ 快捷键说明

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