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

📄 object_identifier.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */#include <asn_internal.h>#include <OBJECT_IDENTIFIER.h>#include <limits.h>	/* for CHAR_BIT */#include <assert.h>#include <errno.h>/* * OBJECT IDENTIFIER basic type description. */static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {	(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))};asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {	"OBJECT IDENTIFIER",	"OBJECT_IDENTIFIER",	ASN__PRIMITIVE_TYPE_free,	OBJECT_IDENTIFIER_print,	OBJECT_IDENTIFIER_constraint,	ber_decode_primitive,	der_encode_primitive,	OBJECT_IDENTIFIER_decode_xer,	OBJECT_IDENTIFIER_encode_xer,	0, /* Use generic outmost tag fetcher */	asn_DEF_OBJECT_IDENTIFIER_tags,	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),	asn_DEF_OBJECT_IDENTIFIER_tags,	/* Same as above */	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),	0, 0,	/* No members */	0	/* No specifics */};intOBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,		asn_app_consume_bytes_f *app_errlog, void *app_key) {	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;	if(st && st->buf) {		if(st->size < 1) {			_ASN_ERRLOG(app_errlog, app_key,				"%s: at least one numerical value "				"expected (%s:%d)",				td->name, __FILE__, __LINE__);			return -1;		}	} else {		_ASN_ERRLOG(app_errlog, app_key,			"%s: value not given (%s:%d)",			td->name, __FILE__, __LINE__);		return -1;	}	return 0;}intOBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {	unsigned LE __attribute__ ((unused)) = 1; /* Little endian (x86) */	uint8_t *arcend = arcbuf + arclen;	/* End of arc */	unsigned int cache = 0;	/* No more than 14 significant bits */	unsigned char *rvbuf = (unsigned char *)rvbufp;	unsigned char *rvstart = rvbuf;	/* Original start of the value buffer */	int inc;	/* Return value growth direction */	rvsize *= CHAR_BIT;	/* bytes to bits */	arclen *= 7;		/* bytes to bits */	/*	 * The arc has the number of bits	 * cannot be represented using supplied return value type.	 */	if(arclen > rvsize) {		if(arclen > (rvsize + CHAR_BIT)) {			errno = ERANGE;	/* Overflow */			return -1;		} else {			/*			 * Even if the number of bits in the arc representation			 * is higher than the width of supplied * return value			 * type, there is still possible to fit it when there			 * are few unused high bits in the arc value			 * representaion.			 * 			 * Moreover, there is a possibility that the			 * number could actually fit the arc space, given			 * that add is negative, but we don't handle			 * such "temporary lack of precision" situation here.			 * May be considered as a bug.			 */			uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f;			if((*arcbuf & mask)) {				errno = ERANGE;	/* Overflow */				return -1;			}			/* Fool the routine computing unused bits */			arclen -= 7;			cache = *arcbuf & 0x7f;			arcbuf++;		}	}	/* Faster path for common size */	if(rvsize == (CHAR_BIT * sizeof(unsigned long))) {		unsigned long accum;		/* Gather all bits into the accumulator */		for(accum = cache; arcbuf < arcend; arcbuf++)			accum = (accum << 7) | (*arcbuf & ~0x80);		if(accum < (unsigned)-add) {			errno = ERANGE;	/* Overflow */			return -1;		}		*(unsigned long *)rvbuf = accum + add;	/* alignment OK! */		return 0;	}#ifndef	WORDS_BIGENDIAN	if(*(unsigned char *)&LE) {	/* Little endian (x86) */		/* "Convert" to big endian */		rvbuf += rvsize / CHAR_BIT - 1;		rvstart--;		inc = -1;	/* Descending */	} else#endif	/* !WORDS_BIGENDIAN */		inc = +1;	/* Big endian is known [at compile time] */	{		int bits;	/* typically no more than 3-4 bits */		/* Clear the high unused bits */		for(bits = rvsize - arclen;			bits > CHAR_BIT;				rvbuf += inc, bits -= CHAR_BIT)				*rvbuf = 0;		/* Fill the body of a value */		for(; arcbuf < arcend; arcbuf++) {			cache = (cache << 7) | (*arcbuf & 0x7f);			bits += 7;			if(bits >= CHAR_BIT) {				bits -= CHAR_BIT;				*rvbuf = (cache >> bits);				rvbuf += inc;			}		}		if(bits) {			*rvbuf = cache;			rvbuf += inc;		}	}	if(add) {		for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {			int v = add + *rvbuf;			if(v & (-1 << CHAR_BIT)) {				*rvbuf = (unsigned char)(v + (1 << CHAR_BIT));				add = -1;			} else {				*rvbuf = v;				break;			}		}		if(rvbuf == rvstart) {			/* No space to carry over */			errno = ERANGE;	/* Overflow */			return -1;		}	}	return 0;}ssize_tOBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,		asn_app_consume_bytes_f *cb, void *app_key) {	char scratch[64];	/* Conservative estimate */	unsigned long accum;	/* Bits accumulator */	char *p;		/* Position in the scratch buffer */	if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,			&accum, sizeof(accum)))		return -1;	if(accum) {		ssize_t len;		/* Fill the scratch buffer in reverse. */		p = scratch + sizeof(scratch);		for(; accum; accum /= 10)			*(--p) = (char)(accum % 10) + 0x30; /* Put a digit */		len = sizeof(scratch) - (p - scratch);		if(cb(p, len, app_key) < 0)			return -1;		return len;	} else {		*scratch = 0x30;		if(cb(scratch, 1, app_key) < 0)			return -1;		return 1;	}}intOBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,		asn_app_consume_bytes_f *cb, void *app_key) {	if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)		return -1;	return 0;}static ssize_tOBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {	ssize_t wrote_len = 0;	int startn;	int add = 0;	int i;	for(i = 0, startn = 0; i < st->size; i++) {		uint8_t b = st->buf[i];		if((b & 0x80))			/* Continuation expected */			continue;		if(startn == 0) {			/*			 * First two arcs are encoded through the backdoor.			 */			if(i) {				add = -80;				if(cb("2", 1, app_key) < 0) return -1;			} else if(b <= 39) {				add = 0;				if(cb("0", 1, app_key) < 0) return -1;			} else if(b < 79) {				add = -40;				if(cb("1", 1, app_key) < 0) return -1;			} else {				add = -80;				if(cb("2", 1, app_key) < 0) return -1;			}			wrote_len += 1;		}		if(cb(".", 1, app_key) < 0)	/* Separate arcs */			return -1;		add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],				i - startn + 1, add, cb, app_key);		if(add < 0) return -1;		wrote_len += 1 + add;		startn = i + 1;		add = 0;	}	return wrote_len;}static enum xer_pbd_rvalOBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {	OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;	const char *chunk_end = (const char *)chunk_buf + chunk_size;	const char *endptr;	long s_arcs[10];	long *arcs = s_arcs;	int arcs_count;	int ret;	(void)td;	arcs_count = OBJECT_IDENTIFIER_parse_arcs(		(const char *)chunk_buf, chunk_size, arcs,			sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);	if(arcs_count <= 0) {		/* Expecting more than zero arcs */		return XPBD_BROKEN_ENCODING;	}	if(endptr < chunk_end) {		/* We have a tail of unrecognized data. Check its safety. */		if(!xer_is_whitespace(endptr, chunk_end - endptr))			return XPBD_BROKEN_ENCODING;	}	if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {		arcs = (long *)MALLOC(arcs_count * sizeof(long));		if(!arcs) return XPBD_SYSTEM_FAILURE;		ret = OBJECT_IDENTIFIER_parse_arcs(			(const char *)chunk_buf, chunk_size,			arcs, arcs_count, &endptr);		if(ret != arcs_count)			return XPBD_SYSTEM_FAILURE;	/* assert?.. */	}	/*	 * Convert arcs into BER representation.	 */	ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count);	if(arcs != s_arcs) FREEMEM(arcs);	return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;}asn_dec_rval_tOBJECT_IDENTIFIER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,	asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,		void *buf_ptr, size_t size) {	return xer_decode_primitive(opt_codec_ctx, td,		sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,			buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);}asn_enc_rval_tOBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,	int ilevel, enum xer_encoder_flags_e flags,		asn_app_consume_bytes_f *cb, void *app_key) {	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;	asn_enc_rval_t er;	(void)ilevel;	(void)flags;	if(!st || !st->buf)		_ASN_ENCODE_FAILED;	er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);	if(er.encoded < 0) _ASN_ENCODE_FAILED;	return er;}intOBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,	int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;	(void)td;	/* Unused argument */	(void)ilevel;	/* Unused argument */	if(!st || !st->buf)		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;	/* Dump preamble */	if(cb("{ ", 2, app_key) < 0)		return -1;	if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)		return -1;	return (cb(" }", 2, app_key) < 0) ? -1 : 0;}intOBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *oid, void *arcs,		unsigned int arc_type_size, unsigned int arc_slots) {	void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);	int num_arcs = 0;	int startn = 0;	int add = 0;	int i;	if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) {

⌨️ 快捷键说明

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