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

📄 asn_codecs_prim.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
字号:
/*- * 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 <asn_codecs_prim.h>#include <assert.h>#include <errno.h>/* * Decode an always-primitive type. */asn_dec_rval_tber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,	asn_TYPE_descriptor_t *td,	void **sptr, void *buf_ptr, size_t size, int tag_mode) {	ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;	asn_dec_rval_t rval;	ber_tlv_len_t length;	/*	 * If the structure is not there, allocate it.	 */	if(st == NULL) {		st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));		if(st == NULL) {			rval.code = RC_FAIL;			rval.consumed = 0;			return rval;		}		*sptr = (void *)st;	}	ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",		td->name, tag_mode);	/*	 * Check tags and extract value length.	 */	rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,			tag_mode, 0, &length, 0);	if(rval.code != RC_OK)		return rval;	ASN_DEBUG("%s length is %d bytes", td->name, (int)length);	/*	 * Make sure we have this length.	 */	buf_ptr = ((char *)buf_ptr) + rval.consumed;	size -= rval.consumed;	if(length > (ber_tlv_len_t)size) {		rval.code = RC_WMORE;		rval.consumed = 0;		return rval;	}	st->size = (int)length;	/* The following better be optimized away. */	if(sizeof(st->size) != sizeof(length)			&& (ber_tlv_len_t)st->size != length) {		st->size = 0;		rval.code = RC_FAIL;		rval.consumed = 0;		return rval;	}	st->buf = (uint8_t *)MALLOC(length + 1);	if(!st->buf) {		st->size = 0;		rval.code = RC_FAIL;		rval.consumed = 0;		return rval;	}	memcpy(st->buf, buf_ptr, length);	st->buf[length] = '\0';		/* Just in case */	rval.code = RC_OK;	rval.consumed += length;	ASN_DEBUG("Took %ld/%ld bytes to encode %s",		(long)rval.consumed,		(long)length, td->name);	return rval;}/* * Encode an always-primitive type using DER. */asn_enc_rval_tder_encode_primitive(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 erval;	ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;	ASN_DEBUG("%s %s as a primitive type (tm=%d)",		cb?"Encoding":"Estimating", td->name, tag_mode);	erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,		cb, app_key);	ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);	if(erval.encoded == -1) {		erval.failed_type = td;		erval.structure_ptr = sptr;		return erval;	}	if(cb && st->buf) {		if(cb(st->buf, st->size, app_key) < 0) {			erval.encoded = -1;			erval.failed_type = td;			erval.structure_ptr = sptr;			return erval;		}	} else {		assert(st->buf || st->size == 0);	}	erval.encoded += st->size;	return erval;}voidASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,		int contents_only) {	ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;	if(!td || !sptr)		return;	ASN_DEBUG("Freeing %s as a primitive type", td->name);	if(st->buf)		FREEMEM(st->buf);	if(!contents_only)		FREEMEM(st);}/* * Local internal type passed around as an argument. */struct xdp_arg_s {	asn_TYPE_descriptor_t *type_descriptor;	void *struct_key;	xer_primitive_body_decoder_f *prim_body_decoder;	int decoded_something;	int want_more;};static intxer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {	struct xdp_arg_s *arg = (struct xdp_arg_s *)key;	enum xer_pbd_rval bret;	if(arg->decoded_something) {		if(xer_is_whitespace(chunk_buf, chunk_size))			return 0;	/* Skip it. */		/*		 * Decoding was done once already. Prohibit doing it again.		 */		return -1;	}	bret = arg->prim_body_decoder(arg->type_descriptor,		arg->struct_key, chunk_buf, chunk_size);	switch(bret) {	case XPBD_SYSTEM_FAILURE:	case XPBD_DECODER_LIMIT:	case XPBD_BROKEN_ENCODING:		break;	case XPBD_BODY_CONSUMED:		/* Tag decoded successfully */		arg->decoded_something = 1;		/* Fall through */	case XPBD_NOT_BODY_IGNORE:	/* Safe to proceed further */		return 0;	}	return -1;}static ssize_txer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {	struct xdp_arg_s *arg = (struct xdp_arg_s *)key;	enum xer_pbd_rval bret;	if(arg->decoded_something) {		if(xer_is_whitespace(chunk_buf, chunk_size))			return chunk_size;		/*		 * Decoding was done once already. Prohibit doing it again.		 */		return -1;	}	if(!have_more) {		/*		 * If we've received something like "1", we can't really		 * tell whether it is really `1` or `123`, until we know		 * that there is no more data coming.		 * The have_more argument will be set to 1 once something		 * like this is available to the caller of this callback:		 * "1<tag_start..."		 */		arg->want_more = 1;		return -1;	}	bret = arg->prim_body_decoder(arg->type_descriptor,		arg->struct_key, chunk_buf, chunk_size);	switch(bret) {	case XPBD_SYSTEM_FAILURE:	case XPBD_DECODER_LIMIT:	case XPBD_BROKEN_ENCODING:		break;	case XPBD_BODY_CONSUMED:		/* Tag decoded successfully */		arg->decoded_something = 1;		/* Fall through */	case XPBD_NOT_BODY_IGNORE:	/* Safe to proceed further */		return chunk_size;	}	return -1;}asn_dec_rval_txer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,	asn_TYPE_descriptor_t *td,	void **sptr,	size_t struct_size,	const char *opt_mname,	void *buf_ptr, size_t size,	xer_primitive_body_decoder_f *prim_body_decoder) {	const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;	asn_struct_ctx_t s_ctx;	struct xdp_arg_s s_arg;	asn_dec_rval_t rc;	/*	 * Create the structure if does not exist.	 */	if(!*sptr) {		*sptr = CALLOC(1, struct_size);		if(!*sptr) {			asn_dec_rval_t rval;			rval.code = RC_FAIL;			rval.consumed = 0;			return rval;		}	}	memset(&s_ctx, 0, sizeof(s_ctx));	s_arg.type_descriptor = td;	s_arg.struct_key = *sptr;	s_arg.prim_body_decoder = prim_body_decoder;	s_arg.decoded_something = 0;	s_arg.want_more = 0;	rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,		xml_tag, buf_ptr, size,		xer_decode__unexpected_tag, xer_decode__body);	switch(rc.code) {	case RC_OK:		if(!s_arg.decoded_something) {			char ch;			ASN_DEBUG("Primitive body is not recognized, "				"supplying empty one");			/*			 * Decoding opportunity has come and gone.			 * Where's the result?			 * Try to feed with empty body, see if it eats it.			 */			if(prim_body_decoder(s_arg.type_descriptor,				s_arg.struct_key, &ch, 0)					!= XPBD_BODY_CONSUMED) {				/*				 * This decoder does not like empty stuff.				 */				rc.code = RC_FAIL;				rc.consumed = 0;			}		}		break;	case RC_WMORE:		/*		 * Redo the whole thing later.		 * We don't have a context to save intermediate parsing state.		 */		rc.consumed = 0;		break;	case RC_FAIL:		rc.consumed = 0;		if(s_arg.want_more)			rc.code = RC_WMORE;		break;	}	return rc;}

⌨️ 快捷键说明

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