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

📄 generalizedtime.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. */#define	_POSIX_PTHREAD_SEMANTICS	/* for Sun */#define	_REENTRANT			/* for Sun */#include <asn_internal.h>#include <GeneralizedTime.h>#include <time.h>#include <errno.h>#ifndef	__NO_ASSERT_H__#include <assert.h>#endif	/* __NO_ASSERT_H__ */#if	defined(WIN32)#warning PLEASE STOP AND READ!#warning	localtime_r is implemented via localtime(), which may be not thread-safe.#warning	gmtime_r is implemented via gmtime(), which may be not thread-safe.#warning#warning	You must fix the code by inserting appropriate locking#warning	if you want to use asn_GT2time() or asn_UT2time().#warning PLEASE STOP AND READ!static struct tm *localtime_r(const time_t *tloc, struct tm *result) {	struct tm *tm;	if((tm = localtime(tloc)))		return memcpy(result, tm, sizeof(struct tm));	return 0;}static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {	struct tm *tm;	if((tm = gmtime(tloc)))		return memcpy(result, tm, sizeof(struct tm));	return 0;}#define	tzset()	_tzset()#define	putenv()	_putenv()#define	_EMULATE_TIMEGM#endif	/* WIN32 */#if	defined(sun)#define	_EMULATE_TIMEGM#endif/* * Where to look for offset from GMT, Phase I. * Several platforms are known. */#if defined(__FreeBSD__)				\	|| (defined(__GNUC__) && defined(__APPLE_CC__))	\	|| (defined __GLIBC__ && __GLIBC__ >= 2)#undef	HAVE_TM_GMTOFF#define	HAVE_TM_GMTOFF#endif	/* BSDs and newer glibc *//* * Where to look for offset from GMT, Phase II. */#ifdef	HAVE_TM_GMTOFF#define	GMTOFF(tm)	((tm).tm_gmtoff)#else	/* HAVE_TM_GMTOFF */#define	GMTOFF(tm)	(-timezone)#endif	/* HAVE_TM_GMTOFF *//* * Override our GMTOFF decision for other known platforms. */#ifdef __CYGWIN__#undef	GMTOFFstatic long GMTOFF(struct tm a){	struct tm *lt;	time_t local_time, gmt_time;	long zone;	tzset();	gmt_time = time (NULL);	lt = gmtime(&gmt_time);	local_time = mktime(lt);	return (gmt_time - local_time);}#define	_EMULATE_TIMEGM#endif	/* __CYGWIN__ */#ifdef	_EMULATE_TIMEGMstatic time_t timegm(struct tm *tm) {	time_t tloc;	char *tz;	char *buf;	tz = getenv("TZ");	putenv("TZ=UTC");	tzset();	tloc = mktime(tm);	if (tz) {		int bufsize = strlen(tz) + 4;		buf = alloca(bufsize);		snprintf(buf, bufsize, "TZ=%s", tz);	} else {		buf = "TZ=";	}	putenv(buf);	tzset();	return tloc;}#endif	/* _EMULATE_TIMEGM */#ifndef	__NO_ASN_TABLE__/* * GeneralizedTime basic type description. */static ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {	(ASN_TAG_CLASS_UNIVERSAL | (24 << 2)),	/* [UNIVERSAL 24] IMPLICIT ...*/	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2)),  /* [UNIVERSAL 26] IMPLICIT ...*/	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))    /* ... OCTET STRING */};asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {	"GeneralizedTime",	"GeneralizedTime",	OCTET_STRING_free,	GeneralizedTime_print,	GeneralizedTime_constraint, /* Check validity of time */	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */	GeneralizedTime_encode_der,	OCTET_STRING_decode_xer_utf8,	GeneralizedTime_encode_xer,	0, /* Use generic outmost tag fetcher */	asn_DEF_GeneralizedTime_tags,	sizeof(asn_DEF_GeneralizedTime_tags)	  / sizeof(asn_DEF_GeneralizedTime_tags[0]) - 2,	asn_DEF_GeneralizedTime_tags,	sizeof(asn_DEF_GeneralizedTime_tags)	  / sizeof(asn_DEF_GeneralizedTime_tags[0]),	0, 0,	/* No members */	0	/* No specifics */};#endif	/* __NO_ASN_TABLE__ *//* * Check that the time looks like the time. */intGeneralizedTime_constraint(asn_TYPE_descriptor_t *td, const void *sptr,		asn_app_consume_bytes_f *app_errlog, void *app_key) {	const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;	time_t tloc;	errno = EPERM;			/* Just an unlikely error code */	tloc = asn_GT2time(st, 0, 0);	if(tloc == -1 && errno != EPERM) {		_ASN_ERRLOG(app_errlog, app_key,			"%s: Invalid time format: %s (%s:%d)",			td->name, strerror(errno), __FILE__, __LINE__);		return -1;	}	return 0;}asn_enc_rval_tGeneralizedTime_encode_der(asn_TYPE_descriptor_t *td, void *ptr,	int tag_mode, ber_tlv_tag_t tag,	asn_app_consume_bytes_f *cb, void *app_key) {	GeneralizedTime_t *st = (GeneralizedTime_t *)ptr;	asn_enc_rval_t erval;	/* If not canonical DER, re-encode into canonical DER. */	if(st->size && st->buf[st->size-1] != 0x5a) {		struct tm tm;		time_t tloc;		errno = EPERM;		tloc = asn_GT2time(st, &tm, 1);	/* Recognize time */		if(tloc == -1 && errno != EPERM) {			/* Failed to recognize time. Fail completely. */			erval.encoded = -1;			erval.failed_type = td;			erval.structure_ptr = ptr;			return erval;		}		st = asn_time2GT(0, &tm, 1);	/* Save time canonically */		if(!st) {			/* Memory allocation failure. */			erval.encoded = -1;			erval.failed_type = td;			erval.structure_ptr = ptr;			return erval;		}	}	erval = OCTET_STRING_encode_der(td, st, tag_mode, tag, cb, app_key);	if(st != ptr) {		FREEMEM(st->buf);		FREEMEM(st);	}	return erval;}asn_enc_rval_tGeneralizedTime_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) {	OCTET_STRING_t st;	if(flags & XER_F_CANONICAL) {		char buf[32];		struct tm tm;		ssize_t ret;		errno = EPERM;		if(asn_GT2time((GeneralizedTime_t *)sptr, &tm, 1) == -1				&& errno != EPERM)			_ASN_ENCODE_FAILED;			ret = snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",				tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,				tm.tm_hour, tm.tm_min, tm.tm_sec);		assert(ret > 0 && ret < (int)sizeof(buf));			st.buf = (uint8_t *)buf;		st.size = ret;		sptr = &st;	}	return OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,		cb, app_key);}intGeneralizedTime_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,	asn_app_consume_bytes_f *cb, void *app_key) {	const GeneralizedTime_t *st = (const GeneralizedTime_t *)sptr;	(void)td;	/* Unused argument */	(void)ilevel;	/* Unused argument */	if(st && st->buf) {		char buf[32];		struct tm tm;		int ret;		errno = EPERM;		if(asn_GT2time(st, &tm, 1) == -1 && errno != EPERM)			return (cb("<bad-value>", 11, app_key) < 0) ? -1 : 0;		ret = snprintf(buf, sizeof(buf),			"%04d-%02d-%02d %02d:%02d%02d (GMT)",			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,			tm.tm_hour, tm.tm_min, tm.tm_sec);		assert(ret > 0 && ret < (int)sizeof(buf));		return (cb(buf, ret, app_key) < 0) ? -1 : 0;	} else {		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;	}}time_tasn_GT2time(const GeneralizedTime_t *st, struct tm *ret_tm, int as_gmt) {	struct tm tm_s;	uint8_t *buf;	uint8_t *end;	int gmtoff_h = 0;	int gmtoff_m = 0;	int gmtoff = 0;	/* h + m */	int offset_specified = 0;	time_t tloc;	if(!st || !st->buf) {		errno = EINVAL;		return -1;	} else {		buf = st->buf;		end = buf + st->size;	}	if(st->size < 10) {		errno = EINVAL;		return -1;	}	/*	 * Decode first 10 bytes: "AAAAMMJJhh"	 */	memset(&tm_s, 0, sizeof(tm_s));#undef	B2F#undef	B2T#define	B2F(var)	do {					\		unsigned ch = *buf;				\		if(ch < 0x30 && ch > 0x39) {			\			errno = EINVAL;				\			return -1;				\		} else {					\			var = var * 10 + (ch - 0x30);		\			buf++;					\		}						\	} while(0)#define	B2T(var)	B2F(tm_s.var)	B2T(tm_year);	/* 1: A */	B2T(tm_year);	/* 2: A */	B2T(tm_year);	/* 3: A */	B2T(tm_year);	/* 4: A */	B2T(tm_mon);	/* 5: M */	B2T(tm_mon);	/* 6: M */	B2T(tm_mday);	/* 7: J */	B2T(tm_mday);	/* 8: J */	B2T(tm_hour);	/* 9: h */	B2T(tm_hour);	/* 0: h */	if(buf == end) goto local_finish;	/*	 * Parse [mm[ss[(.|,)ffff]]]	 *        ^^	 */	switch(*buf) {	case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:	case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:		tm_s.tm_min = (*buf++) - 0x30;		if(buf == end) { errno = EINVAL; return -1; }		B2T(tm_min);		break;	case 0x2B: case 0x2D:	/* +, - */		goto offset;	case 0x5A:		/* Z */		goto utc_finish;	default:		errno = EINVAL;		return -1;	}	if(buf == end) goto local_finish;	/*	 * Parse [mm[ss[(.|,)ffff]]]	 *           ^^	 */	switch(*buf) {	case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:	case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:		tm_s.tm_sec = (*buf++) - 0x30;		if(buf == end) { errno = EINVAL; return -1; }		B2T(tm_sec);		break;	case 0x2B: case 0x2D:	/* +, - */		goto offset;	case 0x5A:		/* Z */		goto utc_finish;	default:		errno = EINVAL;		return -1;	}	if(buf == end) goto local_finish;	/*	 * Parse [mm[ss[(.|,)ffff]]]	 *               ^ ^	 */	switch(*buf) {	case 0x2C: case 0x2E:	/* (.|,) */		/* Fractions of seconds are not supported		 * by time_t or struct tm. Skip them */		for(buf++; buf < end; buf++) {			switch(*buf) {			case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:			case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:				continue;			default:				break;			}			break;		}	}	if(buf == end) goto local_finish;	switch(*buf) {	case 0x2B: case 0x2D:	/* +, - */		goto offset;	case 0x5A:		/* Z */		goto utc_finish;	default:		errno = EINVAL;		return -1;	}offset:	if(end - buf < 3) {		errno = EINVAL;		return -1;	}	buf++;	B2F(gmtoff_h);	B2F(gmtoff_h);	if(buf[-3] == 0x2D)	/* Negative */		gmtoff = -1;	else		gmtoff = 1;	if((end - buf) == 2) {		B2F(gmtoff_m);		B2F(gmtoff_m);	} else if(end != buf) {		errno = EINVAL;		return -1;	}	gmtoff = gmtoff * (3600 * gmtoff_h + 60 * gmtoff_m);	/* Fall through */utc_finish:	offset_specified = 1;	/* Fall through */local_finish:	/*	 * Validation.	 */	if((tm_s.tm_mon > 12 || tm_s.tm_mon < 1)	|| (tm_s.tm_mday > 31 || tm_s.tm_mday < 1)	|| (tm_s.tm_hour > 23)	|| (tm_s.tm_sec > 60)	) {		errno = EINVAL;		return -1;	}	/* Canonicalize */	tm_s.tm_mon -= 1;	/* 0 - 11 */	tm_s.tm_year -= 1900;	tm_s.tm_isdst = -1;	tm_s.tm_sec -= gmtoff;	/*** AT THIS POINT tm_s is either GMT or local (unknown) ****/	if(offset_specified) {		tloc = timegm(&tm_s);	} else {		/*		 * Without an offset (or "Z"),		 * we can only guess that it is a local zone.		 * Interpret it in this fashion.		 */		tloc = mktime(&tm_s);	}	if(tloc == -1) {		errno = EINVAL;		return -1;	}	if(ret_tm) {		if(as_gmt) {			if(offset_specified) {				*ret_tm = tm_s;			} else {				if(gmtime_r(&tloc, ret_tm) == 0) {					errno = EINVAL;					return -1;				}			}		} else {			if(localtime_r(&tloc, ret_tm) == 0) {				errno = EINVAL;				return -1;			}		}	}	return tloc;}GeneralizedTime_t *asn_time2GT(GeneralizedTime_t *opt_gt, const struct tm *tm, int force_gmt) {	struct tm tm_s;	long gmtoff;	const unsigned int buf_size = 24; /* 4+2+2 +2+2+2 +4 + cushion */	char *buf;	char *p;	int size;	/* Check arguments */	if(!tm) {		errno = EINVAL;		return 0;	}	/* Pre-allocate a buffer of sufficient yet small length */	buf = (char *)MALLOC(buf_size);	if(!buf) return 0;	gmtoff = GMTOFF(*tm);	if(force_gmt && gmtoff) {		tm_s = *tm;		tm_s.tm_sec -= gmtoff;		timegm(&tm_s);	/* Fix the time */		tm = &tm_s;#ifdef	HAVE_TM_GMTOFF		assert(!GMTOFF(tm_s));	/* Will fix itself */#else		gmtoff = 0;		/* Intervention required */#endif	}	size = snprintf(buf, buf_size, "%04d%02d%02d%02d%02d%02d",		tm->tm_year + 1900,		tm->tm_mon + 1,		tm->tm_mday,		tm->tm_hour,		tm->tm_min,		tm->tm_sec	);	assert(size == 14);	p = buf + size;	if(force_gmt) {		*p++ = 0x5a;	/* "Z" */		*p++ = 0;		size++;	} else {		int ret = snprintf(p, buf_size - size, "%+03ld%02ld",			gmtoff / 3600, gmtoff % 3600);		assert(ret >= 5 && ret <= 7);		size += ret;	}	if(opt_gt) {		if(opt_gt->buf)			FREEMEM(opt_gt->buf);	} else {		opt_gt = (GeneralizedTime_t *)CALLOC(1, sizeof *opt_gt);		if(!opt_gt) { free(buf); return 0; }	}	opt_gt->buf = (unsigned char *)buf;	opt_gt->size = size;	return opt_gt;}

⌨️ 快捷键说明

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