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

📄 asn-decoder-template.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
字号:
/* * This is a generic BER decoder template for any ASN.1 type. *  * To compile with your own ASN.1 type, please redefine the asn_DEF as shown: *  * cc -Dasn_DEF=asn_DEF_MyCustomType -o myDecoder.o -c asn-decoder-template.c */#ifdef	HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <sys/types.h>#include <unistd.h>	/* for getopt */#include <string.h>	/* for strerror(3) */#include <errno.h>	/* for errno */#include <assert.h>	/* for assert(3) */#include <sysexits.h>	/* for EX_* exit codes */#include <asn_application.h>extern asn_TYPE_descriptor_t asn_DEF;	/* ASN.1 type to be decoded *//* * Open file and parse its contens. */static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,	const char *fname, ssize_t suggested_bufsize);       int opt_debug;	/* -d */static int opt_check;	/* -c */static int opt_print;	/* -p */static int opt_stack;	/* -s */static int opt_toxml;	/* -x */#define	DEBUG(fmt, args...)	do {		\	if(!opt_debug) break;			\	fprintf(stderr, fmt, ##args);		\	fprintf(stderr, "\n");			\} while(0)intmain(int ac, char **av) {	ssize_t suggested_bufsize = 8192;  /* close or equal to stdio buffer */	asn_TYPE_descriptor_t *pduType = &asn_DEF;	int number_of_iterations = 1;	int num;	int ch;	/*	 * Pocess the command-line argments.	 */	while((ch = getopt(ac, av, "b:cdn:hps:x")) != -1)	switch(ch) {	case 'b':		suggested_bufsize = atoi(optarg);		if(suggested_bufsize < 1			|| suggested_bufsize > 16 * 1024 * 1024) {			fprintf(stderr,				"-b %s: Improper buffer size (1..16M)\n",				optarg);			exit(EX_UNAVAILABLE);		}		break;	case 'c':		opt_check = 1;		break;	case 'd':		opt_debug++;	/* Double -dd means ASN.1 debug */		break;	case 'n':		number_of_iterations = atoi(optarg);		if(number_of_iterations < 1) {			fprintf(stderr,				"-n %s: Improper iterations count\n", optarg);			exit(EX_UNAVAILABLE);		}		break;	case 'p':		opt_print++;		break;	case 's':		opt_stack = atoi(optarg);		if(opt_stack <= 0) {			fprintf(stderr,				"-s %s: Value greater than 0 expected\n",				optarg);			exit(EX_UNAVAILABLE);		}		break;	case 'x':		opt_toxml++;		break;	case 'h':	default:		fprintf(stderr,		"Usage: %s [options] <data.ber> ...\n"		"Where options are:\n"		"  -b <size>    Set the i/o buffer size (default is %ld)\n"		"  -c           Check ASN.1 constraints after decoding\n"		"  -d           Enable debugging (-dd is even better)\n"		"  -n <num>     Process files <num> times\n"		"  -s <size>    Set the stack usage limit\n"		"  -p           Print out the decoded contents\n"		"  -x           Print out as XML\n"		, av[0], (long)suggested_bufsize);		exit(EX_USAGE);	}	ac -= optind;	av += optind;	if(ac < 1) {		fprintf(stderr, "Error: missing filename\n");		exit(EX_USAGE);	}	setvbuf(stdout, 0, _IOLBF, 0);	for(num = 0; num < number_of_iterations; num++) {	  int ac_i;	  /*	   * Process all files in turn.	   */	  for(ac_i = 0; ac_i < ac; ac_i++) {		char *fname = av[ac_i];		void *structure;		/*		 * Decode the encoded structure from file.		 */		structure = data_decode_from_file(pduType,				fname, suggested_bufsize);		if(!structure) {			/* Error message is already printed */			exit(EX_DATAERR);		}		fprintf(stderr, "%s: decoded successfully\n", fname);		if(opt_print) asn_fprint(stdout, pduType, structure);		if(opt_toxml		&& xer_fprint(stdout, pduType, structure)) {			fprintf(stderr, "%s: Cannot convert into XML\n", fname);			exit(EX_UNAVAILABLE);		}		/* Check ASN.1 constraints */		if(opt_check) {			char errbuf[128];			size_t errlen = sizeof(errbuf);			if(asn_check_constraints(pduType, structure,				errbuf, &errlen)) {				fprintf(stderr, "%s: ASN.1 constraint "					"check failed: %s\n", fname, errbuf);				exit(EX_DATAERR);			}		}		pduType->free_struct(pduType, structure, 0);	  }	}	return 0;}static char *buffer;static size_t buf_offset;	/* Offset from the start */static size_t buf_len;		/* Length of meaningful contents */static size_t buf_size;	/* Allocated memory */static off_t buf_shifted;	/* Number of bytes ever shifted */#define	bufptr	(buffer + buf_offset)#define	bufend	(buffer + buf_offset + buf_len)/* * Ensure that the buffer contains at least this amoount of free space. */static void buf_extend(size_t bySize) {	DEBUG("buf_extend(%ld) { o=%ld l=%ld s=%ld }",		(long)bySize, (long)buf_offset, (long)buf_len, (long)buf_size);	if(buf_size >= (buf_offset + buf_len + bySize)) {		return;	/* Nothing to do */	} else if(bySize <= buf_offset) {		DEBUG("\tContents shifted by %ld", (long)buf_offset);		/* Shift the buffer contents */		memmove(buffer, buffer + buf_offset, buf_len);		buf_shifted += buf_offset;		buf_offset = 0;	} else {		size_t newsize = (buf_size << 2) + bySize;		void *p = realloc(buffer, newsize);		if(p) {			buffer = (char *)p;			buf_size = newsize;			DEBUG("\tBuffer reallocated to %ld", (long)newsize);		} else {			perror("realloc()");			exit(EX_OSERR);		}	}}static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *fname, ssize_t suggested_bufsize) {	static char *fbuf;	static ssize_t fbuf_size;	static asn_codec_ctx_t s_codec_ctx;	asn_codec_ctx_t *opt_codec_ctx = 0;	void *structure = 0;	size_t rd;	FILE *fp;	if(opt_stack) {		s_codec_ctx.max_stack_size = opt_stack;		opt_codec_ctx = &s_codec_ctx;	}	DEBUG("Processing file %s", fname);	fp = fopen(fname, "r");	if(!fp) {		fprintf(stderr, "%s: %s\n", fname, strerror(errno));		return 0;	}	/* prepare the file buffer */	if(fbuf_size != suggested_bufsize) {		fbuf = (char *)realloc(fbuf, suggested_bufsize);		if(!fbuf) {			perror("realloc()");			exit(EX_OSERR);		}		fbuf_size = suggested_bufsize;	}	buf_shifted = 0;	buf_offset = 0;	buf_len = 0;	while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) {		asn_dec_rval_t rval;		int using_local_buf;		/*		 * Copy the data over, or use the original buffer.		 */		if(buf_len) {			/* Append the new data into the intermediate buffer */			buf_extend(rd);			memcpy(bufend, fbuf, rd);			buf_len += rd;			rval = ber_decode(opt_codec_ctx, pduType,				(void **)&structure, bufptr, buf_len);			DEBUG("ber_decode(%ld) consumed %ld, code %d",				(long)buf_len, (long)rval.consumed, rval.code);			/*			 * Adjust position inside the source buffer.			 */			assert(rval.consumed <= buf_len);			buf_offset += rval.consumed;			buf_len -= rval.consumed;		} else {			using_local_buf = 1;			/* Feed the chunk of data into a decoder routine */			rval = ber_decode(opt_codec_ctx, pduType,				(void **)&structure, fbuf, rd);			DEBUG("ber_decode(%ld) consumed %ld, code %d",				(long)rd, (long)rval.consumed, rval.code);			/*			 * Switch the remainder into the intermediate buffer.			 */			if(rval.code != RC_FAIL && rval.consumed < rd) {				buf_extend(rd - rval.consumed);				memcpy(bufend,					fbuf + rval.consumed,					rd - rval.consumed);				buf_len = rd - rval.consumed;			}		}		switch(rval.code) {		case RC_OK:			DEBUG("RC_OK, finishing up");			fclose(fp);			return structure;		case RC_WMORE:			DEBUG("RC_WMORE, continuing...");			continue;		case RC_FAIL:			break;		}		break;	}	fclose(fp);	/* Clean up partially decoded structure */	pduType->free_struct(pduType, structure, 0);	fprintf(stderr, "%s: "		"Decode failed past %lld byte\n",		fname, (long long)(buf_shifted + buf_offset));	return 0;}

⌨️ 快捷键说明

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