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

📄 octet_string.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
📖 第 1 页 / 共 3 页
字号:
	    }		break;	case 3:	phase3:		/*		 * Primitive form, no stack required.		 */		assert(ctx->left >= 0);		if(size < (size_t)ctx->left) {			if(!size) RETURN(RC_WMORE);			if(type_variant == _TT_BIT_STRING && ctx->step == 0) {				st->bits_unused = *(uint8_t *)buf_ptr;				ctx->left--;				ADVANCE(1);			}			APPEND(buf_ptr, size);			assert(ctx->step);			ctx->left -= size;			ADVANCE(size);			RETURN(RC_WMORE);		} else {			if(type_variant == _TT_BIT_STRING			&& ctx->step == 0 && ctx->left) {				st->bits_unused = *(uint8_t *)buf_ptr;				ctx->left--;				ADVANCE(1);			}			APPEND(buf_ptr, ctx->left);			ADVANCE(ctx->left);			ctx->left = 0;			NEXT_PHASE(ctx);		}		break;	}	if(sel) {		ASN_DEBUG("3sel p=%p, wn=%d, l=%ld, g=%ld, size=%ld",			sel->prev, sel->want_nulls,			(long)sel->left, (long)sel->got, (long)size);		if(sel->prev || sel->want_nulls > 1 || sel->left > 0) {			RETURN(RC_WMORE);		}	}	/*	 * BIT STRING-specific processing.	 */	if(type_variant == _TT_BIT_STRING && st->size) {		/* Finalize BIT STRING: zero out unused bits. */		st->buf[st->size-1] &= 0xff << st->bits_unused;	}	ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",		(long)consumed_myself, td->name,		(type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",		(long)st->size);	RETURN(RC_OK);}/* * Encode OCTET STRING type using DER. */asn_enc_rval_tOCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,	int tag_mode, ber_tlv_tag_t tag,	asn_app_consume_bytes_f *cb, void *app_key) {	asn_enc_rval_t er;	asn_OCTET_STRING_specifics_t *specs = td->specifics				? (asn_OCTET_STRING_specifics_t *)td->specifics				: &asn_DEF_OCTET_STRING_specs;	BIT_STRING_t *st = (BIT_STRING_t *)sptr;	OS_type_e type_variant = (OS_type_e)specs->subvariant;	int fix_last_byte = 0;	ASN_DEBUG("%s %s as OCTET STRING",		cb?"Estimating":"Encoding", td->name);	/*	 * Write tags.	 */	if(type_variant != _TT_ANY || tag_mode == 1) {		er.encoded = der_write_tags(td,				(type_variant == _TT_BIT_STRING) + st->size,			tag_mode, type_variant == _TT_ANY, tag, cb, app_key);		if(er.encoded == -1) {			er.failed_type = td;			er.structure_ptr = sptr;			return er;		}	} else {		/* Disallow: [<tag>] IMPLICIT ANY */		assert(type_variant != _TT_ANY || tag_mode != -1);		er.encoded = 0;	}	if(!cb) {		er.encoded += (type_variant == _TT_BIT_STRING) + st->size;		return er;	}	/*	 * Prepare to deal with the last octet of BIT STRING.	 */	if(type_variant == _TT_BIT_STRING) {		uint8_t b = st->bits_unused & 0x07;		if(b && st->size) fix_last_byte = 1;		_ASN_CALLBACK(&b, 1);		er.encoded++;	}	/* Invoke callback for the main part of the buffer */	_ASN_CALLBACK(st->buf, st->size - fix_last_byte);	/* The last octet should be stripped off the unused bits */	if(fix_last_byte) {		uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);		_ASN_CALLBACK(&b, 1);	}	er.encoded += st->size;	return er;cb_failed:	_ASN_ENCODE_FAILED;}asn_enc_rval_tOCTET_STRING_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) {	static const char *h2c = "0123456789ABCDEF";	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;	asn_enc_rval_t er;	char scratch[16 * 3 + 4];	char *p = scratch;	uint8_t *buf;	uint8_t *end;	size_t i;	if(!st || !st->buf)		_ASN_ENCODE_FAILED;	er.encoded = 0;	/*	 * Dump the contents of the buffer in hexadecimal.	 */	buf = st->buf;	end = buf + st->size;	if(flags & XER_F_CANONICAL) {		char *scend = scratch + (sizeof(scratch) - 2);		for(; buf < end; buf++) {			if(p >= scend) {				_ASN_CALLBACK(scratch, p - scratch);				er.encoded += p - scratch;				p = scratch;			}			*p++ = h2c[(*buf >> 4) & 0x0F];			*p++ = h2c[*buf & 0x0F];		}		_ASN_CALLBACK(scratch, p-scratch);	/* Dump the rest */		er.encoded += p - scratch;	} else {		for(i = 0; buf < end; buf++, i++) {			if(!(i % 16) && (i || st->size > 16)) {				_ASN_CALLBACK(scratch, p-scratch);				er.encoded += (p-scratch);				p = scratch;				_i_ASN_TEXT_INDENT(1, ilevel);			}			*p++ = h2c[(*buf >> 4) & 0x0F];			*p++ = h2c[*buf & 0x0F];			*p++ = 0x20;		}		if(p - scratch) {			p--;	/* Remove the tail space */			_ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */			er.encoded += p - scratch;			if(st->size > 16)				_i_ASN_TEXT_INDENT(1, ilevel-1);		}	}	return er;cb_failed:	_ASN_ENCODE_FAILED;}static struct OCTET_STRING__xer_escape_table_s {	char *string;	int size;} OCTET_STRING__xer_escape_table[] = {#define	OSXET(s)	{ s, sizeof(s) - 1 }	OSXET("\074\156\165\154\057\076"),	/* <nul/> */	OSXET("\074\163\157\150\057\076"),	/* <soh/> */	OSXET("\074\163\164\170\057\076"),	/* <stx/> */	OSXET("\074\145\164\170\057\076"),	/* <etx/> */	OSXET("\074\145\157\164\057\076"),	/* <eot/> */	OSXET("\074\145\156\161\057\076"),	/* <enq/> */	OSXET("\074\141\143\153\057\076"),	/* <ack/> */	OSXET("\074\142\145\154\057\076"),	/* <bel/> */	OSXET("\074\142\163\057\076"),		/* <bs/> */	OSXET("\011"),				/* \t */	OSXET("\012"),				/* \n */	OSXET("\074\166\164\057\076"),		/* <vt/> */	OSXET("\074\146\146\057\076"),		/* <ff/> */	OSXET("\015"),				/* \r */	OSXET("\074\163\157\057\076"),		/* <so/> */	OSXET("\074\163\151\057\076"),		/* <si/> */	OSXET("\074\144\154\145\057\076"),	/* <dle/> */	OSXET("\074\144\143\061\057\076"),	/* <de1/> */	OSXET("\074\144\143\062\057\076"),	/* <de2/> */	OSXET("\074\144\143\063\057\076"),	/* <de3/> */	OSXET("\074\144\143\064\057\076"),	/* <de4/> */	OSXET("\074\156\141\153\057\076"),	/* <nak/> */	OSXET("\074\163\171\156\057\076"),	/* <syn/> */	OSXET("\074\145\164\142\057\076"),	/* <etb/> */	OSXET("\074\143\141\156\057\076"),	/* <can/> */	OSXET("\074\145\155\057\076"),		/* <em/> */	OSXET("\074\163\165\142\057\076"),	/* <sub/> */	OSXET("\074\145\163\143\057\076"),	/* <esc/> */	OSXET("\074\151\163\064\057\076"),	/* <is4/> */	OSXET("\074\151\163\063\057\076"),	/* <is3/> */	OSXET("\074\151\163\062\057\076"),	/* <is2/> */	OSXET("\074\151\163\061\057\076"),	/* <is1/> */	{ 0, 0 },	/* " " */	{ 0, 0 },	/* ! */	{ 0, 0 },	/* \" */	{ 0, 0 },	/* # */	{ 0, 0 },	/* $ */	{ 0, 0 },	/* % */	OSXET("\046\141\155\160\073"),	/* &amp; */	{ 0, 0 },	/* ' */	{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */	{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */	{0,0},{0,0},{0,0},{0,0},			 /* 89:; */	OSXET("\046\154\164\073"),	/* &lt; */	{ 0, 0 },	/* = */	OSXET("\046\147\164\073"),	/* &gt; */};static intOS__check_escaped_control_char(const void *buf, int size) {	size_t i;	/*	 * Inefficient algorithm which translates the escape sequences	 * defined above into characters. Returns -1 if not found.	 * TODO: replace by a faster algorithm (bsearch(), hash or	 * nested table lookups).	 */	for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {		struct OCTET_STRING__xer_escape_table_s *el;		el = &OCTET_STRING__xer_escape_table[i];		if(el->size == size && memcmp(buf, el->string, size) == 0)			return i;	}	return -1;}static intOCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) {	/*	 * This might be one of the escape sequences	 * for control characters. Check it out.	 * #11.15.5	 */	int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);	if(control_char >= 0) {		OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;		void *p = REALLOC(st->buf, st->size + 2);		if(p) {			st->buf = (uint8_t *)p;			st->buf[st->size++] = control_char;			st->buf[st->size] = '\0';	/* nul-termination */			return 0;		}	}		return -1;	/* No, it's not */}asn_enc_rval_tOCTET_STRING_encode_xer_utf8(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 OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;	asn_enc_rval_t er;	uint8_t *buf, *end;	uint8_t *ss;	/* Sequence start */	ssize_t encoded_len = 0;	(void)ilevel;	/* Unused argument */	(void)flags;	/* Unused argument */	if(!st || !st->buf)		_ASN_ENCODE_FAILED;	buf = st->buf;	end = buf + st->size;	for(ss = buf; buf < end; buf++) {		unsigned int ch = *buf;		int s_len;	/* Special encoding sequence length */		/*		 * Escape certain characters: X.680/11.15		 */		if(ch < sizeof(OCTET_STRING__xer_escape_table)			/sizeof(OCTET_STRING__xer_escape_table[0])		&& (s_len = OCTET_STRING__xer_escape_table[ch].size)) {			if(((buf - ss) && cb(ss, buf - ss, app_key) < 0)			|| cb(OCTET_STRING__xer_escape_table[ch].string, s_len,					app_key) < 0)				_ASN_ENCODE_FAILED;			encoded_len += (buf - ss) + s_len;			ss = buf + 1;		}	}	encoded_len += (buf - ss);	if((buf - ss) && cb(ss, buf - ss, app_key) < 0)		_ASN_ENCODE_FAILED;	er.encoded = encoded_len;	return er;}/* * Convert from hexadecimal format (cstring): "AB CD EF" */static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {	OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;	const char *chunk_stop = (const char *)chunk_buf;	const char *p = chunk_stop;	const char *pend = p + chunk_size;	unsigned int clv = 0;	int half = 0;	/* Half bit */	uint8_t *buf;	/* Reallocate buffer according to high cap estimation */	ssize_t _ns = st->size + (chunk_size + 1) / 2;	void *nptr = REALLOC(st->buf, _ns + 1);	if(!nptr) return -1;	st->buf = (uint8_t *)nptr;	buf = st->buf + st->size;	/*	 * If something like " a b c " appears here, the " a b":3 will be	 * converted, and the rest skipped. That is, unless buf_size is greater	 * than chunk_size, then it'll be equivalent to "ABC0".	 */	for(; p < pend; p++) {		int ch = *(const unsigned char *)p;		switch(ch) {		case 0x09: case 0x0a: case 0x0c: case 0x0d:		case 0x20:			/* Ignore whitespace */			continue;		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/			clv = (clv << 4) + (ch - 0x30);			break;		case 0x41: case 0x42: case 0x43:	/* ABC */		case 0x44: case 0x45: case 0x46:	/* DEF */			clv = (clv << 4) + (ch - 0x41 + 10);			break;		case 0x61: case 0x62: case 0x63:	/* abc */		case 0x64: case 0x65: case 0x66:	/* def */			clv = (clv << 4) + (ch - 0x61 + 10);			break;		default:			*buf = 0;	/* JIC */			return -1;		}		if(half++) {			half = 0;			*buf++ = clv;			chunk_stop = p + 1;		}	}	/*	 * Check partial decoding.	 */	if(half) {		if(have_more) {			/*			 * Partial specification is fine,			 * because no more more PXER_TEXT data is available.			 */			*buf++ = clv << 4;			chunk_stop = p;		}	} else {		chunk_stop = p;	}	st->size = buf - st->buf;	/* Adjust the buffer size */	assert(st->size <= _ns);	st->buf[st->size] = 0;		/* Courtesy termination */	return (chunk_stop - (const char *)chunk_buf);	/* Converted size */}/* * Convert from binary format: "00101011101" */static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {	BIT_STRING_t *st = (BIT_STRING_t *)sptr;	const char *p = (const char *)chunk_buf;	const char *pend = p + chunk_size;	int bits_unused = st->bits_unused & 0x7;	uint8_t *buf;	/* Reallocate buffer according to high cap estimation */	ssize_t _ns = st->size + (chunk_size + 7) / 8;	void *nptr = REALLOC(st->buf, _ns + 1);	if(!nptr) return -1;	st->buf = (uint8_t *)nptr;	buf = st->buf + st->size;	(void)have_more;	if(bits_unused == 0)		bits_unused = 8;	else if(st->size)		buf--;	/*	 * Convert series of 0 and 1 into the octet string.	 */	for(; p < pend; p++) {		int ch = *(const unsigned char *)p;		switch(ch) {		case 0x09: case 0x0a: case 0x0c: case 0x0d:		case 0x20:			/* Ignore whitespace */			break;		case 0x30:		case 0x31:			if(bits_unused-- <= 0) {				*++buf = 0;	/* Clean the cell */				bits_unused = 7;			}

⌨️ 快捷键说明

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