ASN1_TIME 和 TIME_T转换

Openssl 代码中提供了函数 ASN1_TIME_set ,把 time_t 格式的时间转化为 ASN1_TIME

函数原型为

ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)

但是没有找到类似 ASN1_TIME_get 函数,把 ASN1_TIME 转化为 time_t

下面是一个ASN1_TIME_get 测试可用

int mypint( const char ** s, int n, int min, int max, int * e)
{
	int retval = 0;
	while (n) {
		if (**s < '0' || **s > '9') { *e = 1; return 0; }
		retval *= 10;
		retval += **s - '0';
		--n; ++(*s);
	}
	if (retval < min || retval > max) *e = 1;
	return retval;
}

time_t ASN1_TIME_get ( ASN1_TIME * a, int *err)
{
char days[2][12] ={{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
				{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }};
	int dummy;
	const char *s;
	int generalized;
	struct tm t;
	int i, year, isleap, offset;
	time_t retval;
	if (err == NULL) 
		err = &dummy;
	if (a->type == V_ASN1_GENERALIZEDTIME) {
		generalized = 1;
	} else if (a->type == V_ASN1_UTCTIME) {
		generalized = 0;
	} else {
		*err = 1;
		return 0;	
	}
	s = (char *)a->data; // Data should be always null terminated
	if (s == NULL || s[a->length] != '\0') {
		*err = 1;
		return 0;
	}
	*err = 0;
	if (generalized) {
		t.tm_year = mypint(&s, 4, 0, 9999, err) - 1900;
	} else {
		t.tm_year = mypint(&s, 2, 0, 99, err);
	if (t.tm_year < 50) 
		t.tm_year += 100;
	}
	t.tm_mon = mypint(&s, 2, 1, 12, err) - 1;
	t.tm_mday = mypint(&s, 2, 1, 31, err);
// NOTE: It's not yet clear, if this implementation is 100% correct
// for GeneralizedTime... but at least misinterpretation is
// impossible --- we just throw an exception
	t.tm_hour = mypint(&s, 2, 0, 23, err);
	t.tm_min = mypint(&s, 2, 0, 59, err);
	if (*s >= '0' && *s <= '9') {
		t.tm_sec = mypint(&s, 2, 0, 59, err);
	} else {
		t.tm_sec = 0;
	}
	if (*err) 
		return 0; // Format violation
	if (generalized) {
		// skip fractional seconds if any
		while (*s == '.' || *s == ',' || (*s >= '0' && *s <= '9')) ++s;
		// special treatment for local time
		if (*s == 0) {
			t.tm_isdst = -1;
			retval = mktime(&t); // Local time is easy :)
			if (retval == (time_t)-1) {
				*err = 2;
				retval = 0;
			}
			return retval;
		}
	}
	if (*s == 'Z') {
		offset = 0;
		++s;
	} else if (*s == '-' || *s == '+') {
		i = (*s++ == '-');
		offset = mypint(&s, 2, 0, 12, err);
		offset *= 60;
		offset += mypint(&s, 2, 0, 59, err);
		if (*err) return 0; // Format violation
		if (i) offset = -offset;
		} else {
		*err = 1;
		return 0;
	}
	if (*s) {
		*err = 1;
		return 0;
	}
// And here comes the hard part --- there's no standard function to
// convert struct tm containing UTC time into time_t without
// messing global timezone settings (breaks multithreading and may
// cause other problems) and thus we have to do this "by hand"
//
// NOTE: Overflow check does not detect too big overflows, but is
// sufficient thanks to the fact that year numbers are limited to four
// digit non-negative values.
	retval = t.tm_sec;
	retval += (t.tm_min - offset) * 60;
	retval += t.tm_hour * 3600;
	retval += (t.tm_mday - 1) * 86400;
	year = t.tm_year + 1900;
	if ( sizeof (time_t) == 4) {
		// This is just to avoid too big overflows being undetected, finer
		// overflow detection is done below.
		if (year < 1900 || year > 2040) *err = 2;
	}
// FIXME: Does POSIX really say, that all years divisible by 4 are
// leap years (for consistency)??? Fortunately, this problem does
// not exist for 32-bit time_t and we should'nt be worried about
// this until the year of 2100 :)
	isleap = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
	for (i = t.tm_mon - 1; i >= 0; --i) retval += days[isleap][i] * 86400;
	retval += (year - 1970) * 31536000;
	if (year < 1970) {
		retval -= ((1970 - year + 2) / 4) * 86400;
		if ( sizeof (time_t) > 4) {
			for (i = 1900; i >= year; i -= 100) {
				if (i % 400 == 0) continue ;
				retval += 86400;
			}
		}
		if (retval >= 0) *err = 2;
	} else {
		retval += ((year - 1970 + 1) / 4) * 86400;
		if ( sizeof (time_t) > 4) {
			for (i = 2100; i < year; i += 100) {
				// The following condition is the reason to
				// start with 2100 instead of 2000
				if (i % 400 == 0) continue ;
				retval -= 86400;
			}
		}
		if (retval < 0) *err = 2;
	}
	if (*err) retval = 0;
	return retval;
}

 头文件大概需要这些:

#include <time.h>
#include <stdlib.h>

#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>

 2) %d-%d-%d %d:%d:%d 格式时间转unix时间戳

time_t strTime2unix(string& timeStamp)  
{  
    struct tm tm;  
    memset(&tm, 0, sizeof(tm));  
      
    sscanf(timeStamp.c_str(), "%d-%d-%d %d:%d:%d",   
           &tm.tm_year, &tm.tm_mon, &tm.tm_mday,  
           &tm.tm_hour, &tm.tm_min, &tm.tm_sec);  
  
    tm.tm_year -= 1900;  
    tm.tm_mon--;  
  
    return mktime(&tm);  
}

参考链接:

   

 http://blog.csdn.net/nanhaizhixin/article/details/8349668

          http://www.eefocus.com/xuefu2009/blog/10-03/187348_f456a.html

          http://www.blogjava.net/Archangelsy/articles/112830.html

          http://zhidao.baidu.com/link?url=65o1q3T71ulItE3-aED6wnoRBtJKd_qe8NGr25t9F0wfSuyjBVV8ERP6Nril7jaE-Zx8EXVsuiLlwmmFz3wCiK

猜你喜欢

转载自blog.csdn.net/weixin_37569048/article/details/85293686