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

📄 object_identifier.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
📖 第 1 页 / 共 2 页
字号:
		errno = EINVAL;		return -1;	}	for(i = 0; i < oid->size; i++) {		uint8_t b = oid->buf[i];		if((b & 0x80))			/* Continuation expected */			continue;		if(num_arcs == 0) {			/*			 * First two arcs are encoded through the backdoor.			 */			unsigned LE = 1;	/* Little endian */			int first_arc;			num_arcs++;			if(!arc_slots) { num_arcs++; continue; }			if(i) first_arc = 2;			else if(b <= 39) first_arc = 0;			else if(b < 79)	first_arc = 1;			else first_arc = 2;			add = -40 * first_arc;			memset(arcs, 0, arc_type_size);			*(unsigned char *)((char *)arcs				+ ((*(char *)&LE)?0:(arc_type_size - 1)))					= first_arc;			arcs = ((char *)arcs) + arc_type_size;		}		/* Decode, if has space */		if(arcs < arcs_end) {			if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn],				i - startn + 1, add,					arcs, arc_type_size))				return -1;			startn = i + 1;			arcs = ((char *)arcs) + arc_type_size;			add = 0;		}		num_arcs++;	}	return num_arcs;}/* * Save the single value as an object identifier arc. */intOBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, void *arcval, unsigned int arcval_size, int prepared_order) {	/*	 * The following conditions must hold:	 * assert(arcval);	 * assert(arcval_size > 0);	 * assert(arcbuf);	 */#ifdef	WORDS_BIGENDIAN	const unsigned isLittleEndian = 0;#else	unsigned LE = 1;	unsigned isLittleEndian = *(char *)&LE;#endif	uint8_t *tp, *tend;	unsigned int cache;	uint8_t *bp = arcbuf;	int bits;#ifdef	__GNUC__	uint8_t buffer[arcval_size];#else	uint8_t *buffer = alloca(arcval_size);	if(!buffer) { errno = ENOMEM; return -1; }#endif	if(isLittleEndian && !prepared_order) {		uint8_t *a = (unsigned char *)arcval + arcval_size - 1;		uint8_t *aend = (uint8_t *)arcval;		uint8_t *msb = buffer + arcval_size - 1;		for(tp = buffer; a >= aend; tp++, a--)			if((*tp = *a) && (tp < msb))				msb = tp;		tend = &buffer[arcval_size];		tp = msb;	/* Most significant non-zero byte */	} else {		/* Look for most significant non-zero byte */		tend = (unsigned char *)arcval + arcval_size;		for(tp = (uint8_t *)arcval; tp < tend - 1; tp++)			if(*tp) break;	}	/*	 * Split the value in 7-bits chunks.	 */	bits = ((tend - tp) * CHAR_BIT) % 7;	if(bits) {		cache = *tp >> (CHAR_BIT - bits);		if(cache) {			*bp++ = cache | 0x80;			cache = *tp++;			bits = CHAR_BIT - bits;		} else {			bits = -bits;		}	} else {		cache = 0;	}	for(; tp < tend; tp++) {		cache = (cache << CHAR_BIT) + *tp;		bits += CHAR_BIT;		while(bits >= 7) {			bits -= 7;			*bp++ = 0x80 | (cache >> bits);		}	}	if(bits) *bp++ = cache;	bp[-1] &= 0x7f;	/* Clear the last bit */	return bp - arcbuf;}intOBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {	uint8_t *buf;	uint8_t *bp;	unsigned LE = 1;	/* Little endian (x86) */	unsigned isLittleEndian = *((char *)&LE);	unsigned int arc0;	unsigned int arc1;	unsigned size;	unsigned i;	if(!oid || !arcs || arc_type_size < 1 || arc_slots < 2) {		errno = EINVAL;		return -1;	}	switch(arc_type_size) {	case sizeof(char):		arc0 = ((unsigned char *)arcs)[0];		arc1 = ((unsigned char *)arcs)[1];		break;	case sizeof(short):		arc0 = ((unsigned short *)arcs)[0];		arc1 = ((unsigned short *)arcs)[1];		break;	case sizeof(int):		arc0 = ((unsigned int *)arcs)[0];		arc1 = ((unsigned int *)arcs)[1];		break;	default:		arc1 = arc0 = 0;		if(isLittleEndian) {	/* Little endian (x86) */			unsigned char *ps, *pe;			/* If more significant bytes are present,			 * make them > 255 quick */			for(ps = (unsigned char *)arcs + 1, pe = ps+arc_type_size;					ps < pe; ps++)				arc0 |= *ps, arc1 |= *(ps + arc_type_size);			arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT;			arc0 = *((unsigned char *)arcs + 0);			arc1 = *((unsigned char *)arcs + arc_type_size);		} else {			unsigned char *ps, *pe;			/* If more significant bytes are present,			 * make them > 255 quick */			for(ps = (unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++)				arc0 |= *ps, arc1 |= *(ps + arc_type_size);			arc0 = *((unsigned char *)arcs + arc_type_size - 1);			arc1 = *((unsigned char *)arcs +(arc_type_size<< 1)-1);		}	}	/*	 * The previous chapter left us with the first and the second arcs.	 * The values are not precise (that is, they are valid only if	 * they're less than 255), but OK for the purposes of making	 * the sanity test below.	 */	if(arc0 <= 1) {		if(arc1 >= 39) {			/* 8.19.4: At most 39 subsequent values (including 0) */			errno = ERANGE;			return -1;		}	} else if(arc0 > 2) {		/* 8.19.4: Only three values are allocated from the root node */		errno = ERANGE;		return -1;	}	/*	 * After above tests it is known that the value of arc0 is completely	 * trustworthy (0..2). However, the arc1's value is still meaningless.	 */	/*	 * Roughly estimate the maximum size necessary to encode these arcs.	 * This estimation implicitly takes in account the following facts,	 * that cancel each other:	 * 	* the first two arcs are encoded in a single value.	 * 	* the first value may require more space (+1 byte)	 * 	* the value of the first arc which is in range (0..2)	 */	size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots;	bp = buf = (uint8_t *)MALLOC(size + 1);	if(!buf) {		/* ENOMEM */		return -1;	}	/*	 * Encode the first two arcs.	 * These require special treatment.	 */	{		uint8_t *tp;#ifdef	__GNUC__		uint8_t first_value[1 + arc_type_size];	/* of two arcs */		uint8_t *fv = first_value;#else		uint8_t *first_value = alloca(1 + arc_type_size);		uint8_t *fv = first_value;		if(!first_value) {			errno = ENOMEM;			return -1;		}#endif		/*		 * Simulate first_value = arc0 * 40 + arc1;		 */		/* Copy the second (1'st) arcs[1] into the first_value */		*fv++ = 0;		arcs = ((char *)arcs) + arc_type_size;		if(isLittleEndian) {			uint8_t *aend = (unsigned char *)arcs - 1;			uint8_t *a1 = (unsigned char *)arcs + arc_type_size - 1;			for(; a1 > aend; fv++, a1--) *fv = *a1;		} else {			uint8_t *a1 = (uint8_t *)arcs;			uint8_t *aend = a1 + arc_type_size;			for(; a1 < aend; fv++, a1++) *fv = *a1;		}		/* Increase the first_value by arc0 */		arc0 *= 40;	/* (0..80) */		for(tp = first_value + arc_type_size; tp >= first_value; tp--) {			unsigned int v = *tp;			v += arc0;			*tp = v;			if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT;			else break;		}		assert(tp >= first_value);		bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value,			fv - first_value, 1); 	}	/*	 * Save the rest of arcs.	 */	for(arcs = ((char *)arcs) + arc_type_size, i = 2;		i < arc_slots;			i++, arcs = ((char *)arcs) + arc_type_size) {		bp += OBJECT_IDENTIFIER_set_single_arc(bp,			arcs, arc_type_size, 0);	}	assert((unsigned)(bp - buf) <= size);	/*	 * Replace buffer.	 */	oid->size = bp - buf;	bp = oid->buf;	oid->buf = buf;	if(bp) FREEMEM(bp);	return 0;}intOBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,	long *arcs, unsigned int arcs_slots, const char **oid_text_end) {	unsigned int arcs_count = 0;	const char *oid_end;	long value = 0;	enum {		ST_SKIPSPACE,		ST_WAITDIGITS,	/* Next character is expected to be a digit */		ST_DIGITS,	} state = ST_SKIPSPACE;	if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {		if(oid_text_end) *oid_text_end = oid_text;		errno = EINVAL;		return -1;	}	if(oid_txt_length == -1)		oid_txt_length = strlen(oid_text);	for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {	    switch(*oid_text) {	    case 0x09: case 0x0a: case 0x0d: case 0x20:	/* whitespace */		if(state == ST_SKIPSPACE) {			continue;		} else {			break;	/* Finish */		}	    case 0x2e:	/* '.' */		if(state != ST_DIGITS		|| (oid_text + 1) == oid_end) {			state = ST_WAITDIGITS;			break;		}		if(arcs_count < arcs_slots)			arcs[arcs_count] = value;		arcs_count++;		state = ST_WAITDIGITS;		continue;	    case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:	    case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:		if(state != ST_DIGITS) {			state = ST_DIGITS;			value = 0;		}		if(1) {			long new_value = value * 10;			if(new_value / 10 != value			|| (value = new_value + (*oid_text - 0x30)) < 0) {				/* Overflow */				state = ST_WAITDIGITS;				break;			}			continue;		}	    default:		/* Unexpected symbols */		state = ST_WAITDIGITS;		break;	    } /* switch() */	    break;	} /* for() */	if(oid_text_end) *oid_text_end = oid_text;	/* Finalize last arc */	switch(state) {	case ST_WAITDIGITS:		errno = EINVAL;		return -1;	case ST_DIGITS:		if(arcs_count < arcs_slots)			arcs[arcs_count] = value;		arcs_count++;		/* Fall through */	default:		return arcs_count;	}}

⌨️ 快捷键说明

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