From 27e9c56bc178efef9398efd4af199911e6b48a6f Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 27 Dec 2022 13:55:32 +0800 Subject: [PATCH] Update ASN.1 Time --- CMakeLists.txt | 1 - include/gmssl/asn1.h | 3 + src/asn1.c | 232 ++++++++++++++------ src/u_time.c | 496 ------------------------------------------- src/u_time.h | 26 --- tests/asn1test.c | 57 +++++ 6 files changed, 223 insertions(+), 592 deletions(-) delete mode 100644 src/u_time.c delete mode 100644 src/u_time.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9558d01d..717cae73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,6 @@ set(src src/ec.c src/rsa.c src/asn1.c - src/u_time.c src/hex.c src/base64.c src/pem.c diff --git a/include/gmssl/asn1.h b/include/gmssl/asn1.h index f38da00d..4a756307 100644 --- a/include/gmssl/asn1.h +++ b/include/gmssl/asn1.h @@ -198,6 +198,9 @@ int asn1_string_print(FILE *fp, int fmt, int ind, const char *label, int tag, co #define ASN1_UTC_TIME_LEN (sizeof("YYMMDDHHMMSSZ")-1) #define ASN1_GENERALIZED_TIME_LEN (sizeof("YYYYMMDDHHMMSSZ")-1) +int asn1_time_to_str(int utc_time, time_t timestamp, char *str); +int asn1_time_from_str(int utc_time, time_t *timestamp, const char *str); + int asn1_utc_time_to_der_ex(int tag, time_t tv, uint8_t **out, size_t *outlen); int asn1_utc_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, size_t *inlen); #define asn1_utc_time_to_der(tv,out,outlen) asn1_utc_time_to_der_ex(ASN1_TAG_UTCTime,tv,out,outlen) diff --git a/src/asn1.c b/src/asn1.c index a01d9d3c..60999b6e 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -21,10 +21,7 @@ #include #include #include -#define WIN32 // only for use own time functions -#ifdef WIN32 -#include "u_time.h" -#endif + /* @@ -460,6 +457,7 @@ int asn1_integer_to_der_ex(int tag, const uint8_t *a, size_t alen, uint8_t **out int asn1_int_to_der_ex(int tag, int a, uint8_t **out, size_t *outlen) { + int i; uint8_t buf[4] = {0}; size_t len = 0; @@ -789,34 +787,172 @@ int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out return asn1_type_to_der(tag, (const uint8_t *)d, dlen, out, outlen); } +static int is_leap_year(int year) { + return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) ? 1 : 0; +} + +#define val(c) ((c)-'0') + +int asn1_time_from_str(int utc_time, time_t *timestamp, const char *str) +{ + int time_str_len[2] = { 15, 13 }; + int days_per_year[2] = { 365, 366 }; + int days_per_month[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; + int year, month, day, hour, minute, second; + const char *p = str; + int i; + + utc_time &= 1; + for (i = 0; i < time_str_len[utc_time] - 1; i++) { + if (!isdigit(str[i])) { + error_print(); + return -1; + } + } + if (str[i] != 'Z') { + error_print(); + return -1; + } + + if (utc_time) { + year = val(p[0]) * 10 + val(p[1]); + if (year <= 50) { + year += 2000; + } else { + year += 1900; + } + p += 2; + } else { + year = val(p[0]) * 1000 + val(str[1]) * 100 + val(str[2]) * 10 + val(str[3]); + p += 4; + } + if (is_leap_year(year)) { + days_per_month[2] = 29; + } + month = val(p[0]) * 10 + val(p[1]); p += 2; + day = val(p[0]) * 10 + val(p[1]); p += 2; + hour = val(p[0]) * 10 + val(p[1]); p += 2; + minute = val(p[0]) * 10 + val(p[1]); p += 2; + second = val(p[0]) * 10 + val(p[1]); p += 2; + + if (year < 1970 + || month < 1 || month > 12 + || day < 1 || day > days_per_month[month] + || hour < 0 || hour > 23 + || minute < 0 || minute > 59 + || second < 0 || second > 59) { + error_print(); + return -1; + } + + day--; + + while (year-- > 1970) { + day += days_per_year[is_leap_year(year)]; + } + while (month-- > 1) { + day += days_per_month[month]; + } + *timestamp = (time_t)day * 86400 + hour * 3600 + minute * 60 + second; + + return 1; +} + +int asn1_time_to_str(int utc_time, time_t timestamp, char *str) +{ + int days_per_month[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; + int days_per_year[2] = { 365, 366 }; + int max_year[2] = { 9999, 2050 }; + int year, month, second, hour, minute; + time_t day; + char *p = str; + + utc_time &= 1; + day = timestamp / 86400; + second = timestamp % 86400; + + // In UTCTime, year in [1951, 2050], YY <= 50, year = 20YY; YY > 50, year = 19YY + // For Validity, year SHOULD <= 2049 (NOT 2050) + for (year = 1970; year <= max_year[utc_time]; year++) { + if (day < days_per_year[is_leap_year(year)]) { + break; + } + day -= days_per_year[is_leap_year(year)]; + } + if (year > max_year[utc_time]) { + error_print(); + return -1; + } + + day++; + + if (is_leap_year(year)) { + days_per_month[2] = 29; + } + for (month = 1; month <= 12; month++) { + if (day <= days_per_month[month]) { + break; + } + day -= days_per_month[month]; + } + + hour = second / 3600; + second %= 3600; + minute = second / 60; + second %= 60; + + if (utc_time) { + memset(p, '0', 12); + } else { + memset(p, '0', 14); + p[0] += (year / 100) / 10; + p[1] += (year / 100) % 10; + p += 2; + } + + year %= 100; + p[0] += year / 10; + p[1] += year % 10; + p[2] += month / 10; + p[3] += month % 10; + p[4] += day / 10; + p[5] += day % 10; + p[6] += hour / 10; + p[7] += hour % 10; + p[8] += minute / 10; + p[9] += minute % 10; + p[10] += second / 10; + p[11] += second % 10; + p[12] = 'Z'; + + return 1; +} + int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) { struct tm tm_val; char buf[ASN1_UTC_TIME_LEN + 1] = {0}; + int utc_time = 1; if (!outlen) { error_print(); return -1; } -#ifdef WIN32 - GMSSL_gmtime(&a, &tm_val); - asn1_tm_to_utctime(&tm_val, buf); -#else - gmtime_r(&a, &tm_val); - strftime(buf, sizeof(buf), "%y%m%d%H%M%SZ", &tm_val); -#endif - + if (asn1_time_to_str(utc_time, a, buf) != 1) { + error_print(); + return -1; + } if (out && *out) *(*out)++ = tag; (*outlen)++; - asn1_length_to_der(sizeof(buf)-1, out, outlen); + asn1_length_to_der(ASN1_UTC_TIME_LEN, out, outlen); if (out && *out) { - memcpy(*out, buf, sizeof(buf)-1); - (*out) += sizeof(buf)-1; + memcpy(*out, buf, ASN1_UTC_TIME_LEN); + (*out) += ASN1_UTC_TIME_LEN; } - *outlen += sizeof(buf)-1; + *outlen += ASN1_UTC_TIME_LEN; return 1; } @@ -826,20 +962,17 @@ int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *ou { struct tm tm_val; char buf[ASN1_GENERALIZED_TIME_LEN + 1] = {0}; + int utc_time = 0; if (!outlen) { error_print(); return -1; } -#ifdef WIN32 - GMSSL_gmtime(&a, &tm_val); - asn1_tm_to_generalizedtime(&tm_val, buf); -#else - gmtime_r(&a, &tm_val); - strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &tm_val); -#endif - //printf("%s %d: generalized time : %s\n", __FILE__, __LINE__, buf); + if (asn1_time_to_str(utc_time, a, buf) != 1) { + error_print(); + return -1; + } if (out && *out) *(*out)++ = tag; @@ -1143,21 +1276,6 @@ int asn1_ia5_string_from_der_ex(int tag, const char **a, size_t *alen, const uin return asn1_type_from_der(tag, (const uint8_t **)a, alen, in, inlen); } -/* -int hh, mm, ss; -struct tm when = {0}; - -sscanf_s(date, "%d:%d:%d", &hh, &mm, &ss); - - -when.tm_hour = hh; -when.tm_min = mm; -when.tm_sec = ss; - -time_t converted; -converted = mktime(&when); -*/ - int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *pinlen) { const uint8_t *in = *pin; @@ -1178,30 +1296,15 @@ int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *p || (len != sizeof("YYMMDDHHMMSSZ")-1 && len != sizeof("YYMMDDHHMMSS+HHMM")-1)) { return -1; } - memcpy(buf + 2, in, len); + memcpy(buf, in, len); - if (!isdigit(buf[2]) && !isdigit(buf[3])) { - return -1; - } - year = (buf[2] - '0') * 10 + (buf[3] - '0'); - if (year >= 50) { - buf[0] = '1'; - buf[1] = '9'; - } else { - buf[0] = '2'; - buf[1] = '0'; - } if (len == sizeof("YYMMDDHHMMSSZ")-1) { -#ifdef WIN32 - asn1_generalizedtime_to_tm(buf, &tm_val); - *t = GMSSL_timegm(&tm_val); -#else - if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { + if (asn1_time_from_str(1, t, buf) != 1) { + error_print(); return -1; } - *t = timegm(&tm_val); -#endif } else { + error_print(); return -1; } @@ -1234,21 +1337,12 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, s memcpy(buf, in, len); if (len == sizeof("YYYYMMDDHHMMSSZ")-1) { - -#ifdef WIN32 - asn1_generalizedtime_to_tm(buf, &tm_val); - *t = GMSSL_timegm(&tm_val); -#else - if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { + if (asn1_time_from_str(0, t, buf) != 1) { error_print(); return -1; } - *t = timegm(&tm_val); -#endif - - } else { - // TODO: 处理这种情况 + // FIXME: handle "YYYYMMDDHHMMSS+HHMM" error_print(); return -2; } diff --git a/src/u_time.c b/src/u_time.c deleted file mode 100644 index d1fa184a..00000000 --- a/src/u_time.c +++ /dev/null @@ -1,496 +0,0 @@ -#include "u_time.h" - -//convert timestamp to struct tm -int GMSSL_gmtime(const time_t *timep, struct tm *tm_time) -{ - time_t timestamp = *timep; - unsigned int four_year_num; - unsigned int one_year_hours; - - const static unsigned char Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - const static unsigned int ONE_YEAR_HOURS = 8760; - const static unsigned int FOUR_YEAR_HOURS = 35064; - - if (timestamp > 0x7FFFFFFF) - { - return -1; - } - - tm_time->tm_isdst = 0; - - tm_time->tm_sec = (int)(timestamp % 60); - timestamp /= 60; - - tm_time->tm_min = (int)(timestamp % 60); - timestamp /= 60; - - tm_time->tm_wday = (int)(timestamp/24 + 4) % 7; - - four_year_num = timestamp / FOUR_YEAR_HOURS; - - tm_time->tm_year=(four_year_num << 2) + 70; - - timestamp %= FOUR_YEAR_HOURS; - - while (1) - { - one_year_hours = ONE_YEAR_HOURS; - - if ((tm_time->tm_year & 3) == 0) - { - one_year_hours += 24; - } - - if (timestamp < one_year_hours) - { - break; - } - - tm_time->tm_year++; - timestamp -= one_year_hours; - } - - tm_time->tm_hour=(int)(timestamp % 24); - - timestamp /= 24; - timestamp++; - - tm_time->tm_yday = timestamp-1; - - if ((tm_time->tm_year & 3) == 0) - { - if (timestamp > 60) - { - timestamp--; - } - else if (timestamp == 60) - { - tm_time->tm_mon = 1; - tm_time->tm_mday = 29; - return 0; - } - } - - for (tm_time->tm_mon = 0; Days[tm_time->tm_mon] < timestamp; tm_time->tm_mon++) - { - timestamp -= Days[tm_time->tm_mon]; - } - - tm_time->tm_mday = (int)(timestamp); - - return 0; -} - -//convert struct tm to timestamp -time_t GMSSL_timegm(struct tm *tm) -{ - static const int msum [2][12] = { - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, /* normal years */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} /* leap years */ - }; - static const int mlen [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} - }; - static const int tmstr_year= 1900; /* base of 'tm_year' in 'struct tm' */ - static const int epoch_year= 1970; /* unix timestamp epoch */ - static const int base_year= 1601; /* start of a 400-year period: used to be 1601, - but this allows larger range (in 64 bit) - mind you, this is proleptic Gregorian */ - int year, ytmp, dtmp, ytmpe, dtmpe; - int isleapyear; - long long t; - - if (!tm) return -1; - - year = tm->tm_year + tmstr_year; - isleapyear= (year%4==0) - (year%100==0) + (year%400==0); - -/* days between 'current year' and 'epoch_year' has to be calculated - in three steps: */ - -/* 1. days between current year and 'base_year' */ - ytmp = year - base_year; - dtmp = ytmp*365 + ytmp/4 - ytmp/100 + ytmp/400; - -/* 2. days between 'epoch year' and 'base_year' */ - ytmpe = epoch_year - base_year; - dtmpe = ytmpe*365 + ytmpe/4 - ytmpe/100 + ytmpe/400; - -/* 3. days between 'current year' and 'epoch_year' */ - t = dtmp - dtmpe; - - t += msum[isleapyear][tm->tm_mon]; - t += tm->tm_mday-1; - - t = t*24 + tm->tm_hour; - t = t*60 + tm->tm_min; - t = t*60 + tm->tm_sec; - - return t; -} - -//offset to struct tm -int GMSSL_gmtime_adj(struct tm *tm, long offset_sec) -{ - time_t t = GMSSL_timegm(tm); - if(t == -1) - return -1; - - t += offset_sec; - - return GMSSL_gmtime(&t,tm) == 0; -} - -//convert generalizedtime to tm -int asn1_generalizedtime_to_tm(char *gtime,struct tm *tm) -{ - static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - l = strlen(gtime); - a = gtime; - o = 0; - /* - * GENERALIZEDTIME is similar to UTCTIME except the year is represented - * as YYYY. This stuff treats everything as a two digit field so make - * first two fields 00 to 99 - */ - if (l < 13) - goto err; - for (i = 0; i < 7; i++) { - if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n * 100 - 1900; - break; - case 1: - tm->tm_year += n; - break; - case 2: - tm->tm_mon = n - 1; - break; - case 3: - tm->tm_mday = n; - break; - case 4: - tm->tm_hour = n; - break; - case 5: - tm->tm_min = n; - break; - case 6: - tm->tm_sec = n; - break; - } - } - } - /* - * Optional fractional seconds: decimal point followed by one or more - * digits. - */ - if (a[o] == '.') { - if (++o > l) - goto err; - i = o; - while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) - o++; - /* Must have at least one digit after decimal point */ - if (i == o) - goto err; - } - - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '+' ? -1 : 1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 7; i < 9; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 7) - offset = n * 3600; - else if (i == 8) - offset += n * 60; - } - o++; - } - if (offset && !GMSSL_gmtime_adj(tm, offset * offsign)) - return 0; - } else if (a[o]) { - /* Missing time zone information. */ - goto err; - } - return (o == l); - err: - return (0); -} - -//convert utctime to tm -int asn1_utctime_to_tm(struct tm *tm, char *utime) -{ - static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - l = strlen(utime); - a = utime; - o = 0; - - if (l < 11) - goto err; - for (i = 0; i < 6; i++) { - if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n < 50 ? n + 100 : n; - break; - case 1: - tm->tm_mon = n - 1; - break; - case 2: - tm->tm_mday = n; - break; - case 3: - tm->tm_hour = n; - break; - case 4: - tm->tm_min = n; - break; - case 5: - tm->tm_sec = n; - break; - } - } - } - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '+' ? -1 : 1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 6; i < 8; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 6) - offset = n * 3600; - else if (i == 7) - offset += n * 60; - } - o++; - } - if (offset && !GMSSL_gmtime_adj(tm, offset * offsign)) - return 0; - } - return o == l; - err: - return 0; -} - -//convert tm to generalizedtime -int asn1_tm_to_generalizedtime(struct tm *tm, char *gtime) -{ - char p[20] = {0}; - int i = 0, j = 0; - static const int min[6] = { 0, 1, 1, 0, 0, 0 }; - static const int max[6] = { 9999, 12, 31, 23, 59, 59}; - - //year - int year0 = tm->tm_year + 1900; - if(year0 < min[i] || year0 > max[i]) - goto err; - p[j++] = year0 / 1000 + '0'; - year0 = year0 % 1000; - p[j++] = year0 / 100 + '0'; - year0 = year0 % 100; - p[j++] = year0 / 10 + '0'; - year0 = year0 % 10; - p[j++] = year0 + '0'; - i++; - - //month - int mon0 = tm->tm_mon + 1; - if(mon0 < min[i] || mon0>max[i]) - goto err; - p[j++] = mon0 /10 + '0'; - mon0 = mon0%10; - p[j++] = mon0 + '0'; - i++; - - //day - int day0 = tm->tm_mday; - if(day0 < min[i] || day0>max[i]) - goto err; - p[j++] = day0 /10 + '0'; - day0 = day0%10; - p[j++] = day0 + '0'; - i++; - - //hour - int hour0 = tm->tm_hour; - if(hour0 < min[i] || hour0>max[i]) - goto err; - p[j++] = hour0 /10 + '0'; - hour0 = hour0%10; - p[j++] = hour0 + '0'; - i++; - - //min - int min0 = tm->tm_min; - if(min0 < min[i] || min0>max[i]) - goto err; - p[j++] = min0 /10 + '0'; - min0 = min0%10; - p[j++] = min0 + '0'; - i++; - - //sec - int sec0 = tm->tm_sec; - if(sec0 < min[i] || sec0>max[i]) - goto err; - p[j++] = sec0 /10 + '0'; - sec0 = sec0%10; - p[j++] = sec0 + '0'; - - p[j++] = 'Z'; - - memcpy(gtime,p,j); - - return 0; - -err: - return -1; -} - - -//convert asn1 tm to utctime -int asn1_tm_to_utctime(struct tm *tm, char *utime) -{ - char p[20] = {0}; - int i = 0, j = 0; - static const int min[6] = { 0, 1, 1, 0, 0, 0 }; - static const int max[6] = { 99, 12, 31, 23, 59, 59}; - - //year - int year0 = tm->tm_year % 100; - if(year0 < min[i] || year0 > max[i]) - goto err; - p[j++] = year0 / 10 + '0'; - year0 = year0 % 10; - p[j++] = year0 + '0'; - i++; - - //month - int mon0 = tm->tm_mon + 1; - if(mon0 < min[i] || mon0>max[i]) - goto err; - p[j++] = mon0 /10 + '0'; - mon0 = mon0%10; - p[j++] = mon0 + '0'; - i++; - - //day - int day0 = tm->tm_mday; - if(day0 < min[i] || day0>max[i]) - goto err; - p[j++] = day0 /10 + '0'; - day0 = day0%10; - p[j++] = day0 + '0'; - i++; - - //hour - int hour0 = tm->tm_hour; - if(hour0 < min[i] || hour0>max[i]) - goto err; - p[j++] = hour0 /10 + '0'; - hour0 = hour0%10; - p[j++] = hour0 + '0'; - i++; - - //min - int min0 = tm->tm_min; - if(min0 < min[i] || min0>max[i]) - goto err; - p[j++] = min0 /10 + '0'; - min0 = min0%10; - p[j++] = min0 + '0'; - i++; - - //sec - int sec0 = tm->tm_sec; - if(sec0 < min[i] || sec0>max[i]) - goto err; - p[j++] = sec0 /10 + '0'; - sec0 = sec0%10; - p[j++] = sec0 + '0'; - - p[j++] = 'Z'; - memcpy(utime,p,j); - - return 0; - -err: - return -1; -} \ No newline at end of file diff --git a/src/u_time.h b/src/u_time.h deleted file mode 100644 index 2b7cbba0..00000000 --- a/src/u_time.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef GMSSL_U_TIME_H -#define GMSSL_U_TIME_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -#define SECS_PER_DAY (24 * 60 * 60) - -int GMSSL_gmtime(const time_t *timep, struct tm *tm_time); -time_t GMSSL_timegm(struct tm *tm); -int GMSSL_gmtime_adj(struct tm *tm, long offset_sec); -int asn1_generalizedtime_to_tm(char *gtime,struct tm *tm); -int asn1_utctime_to_tm(struct tm *tm, char *utime); -int asn1_tm_to_generalizedtime(struct tm *tm, char *gtime); -int asn1_tm_to_utctime(struct tm *tm, char *utime); - -#if __cplusplus -} -#endif -#endif \ No newline at end of file diff --git a/tests/asn1test.c b/tests/asn1test.c index 5060ec0b..6b5b829a 100644 --- a/tests/asn1test.c +++ b/tests/asn1test.c @@ -497,6 +497,62 @@ static int test_time(void) return 1; } +static int test_asn1_time(void) +{ + time_t tests[] = { + 0, + 31*86400, + (31+28)*86400, + }; + char *utc_time[] = { + "700101000000Z", + "700201000000Z", + "700301000000Z", + }; + char *gen_time[] = { + "19700101000000Z", + "19700201000000Z", + "19700301000000Z", + }; + time_t cur = time(NULL); + time_t ts; + char str[16] = {0}; + int i; + + if (asn1_time_to_str(0, cur, str) != 1 + || asn1_time_from_str(0, &ts, str) != 1 + || ts != cur) { + error_print(); + return -1; + } + + if (asn1_time_to_str(1, cur, str) != 1 + || asn1_time_from_str(1, &ts, str) != 1 + || ts != cur) { + error_print(); + return -1; + } + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + memset(str, 0, sizeof(str)); + if (asn1_time_to_str(1, tests[i], str) != 1 + || strcmp(str, utc_time[i]) != 0) { + error_print(); + return -1; + } + + memset(str, 0, sizeof(str)); + if (asn1_time_to_str(0, tests[i], str) != 1 + || strcmp(str, gen_time[i]) != 0) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + static int test_asn1_utc_time(void) { time_t tests[] = { @@ -588,6 +644,7 @@ int main(void) if (test_asn1_printable_string() != 1) goto err; if (test_asn1_utf8_string() != 1) goto err; if (test_asn1_ia5_string() != 1) goto err; + if (test_asn1_time() != 1) goto err; if (test_asn1_utc_time() != 1) goto err; if (test_asn1_generalized_time() != 1) goto err; printf("%s all tests passed\n", __FILE__);