diff --git a/include/gmssl/digest.h b/include/gmssl/digest.h index 043d6b2a..18a9d697 100644 --- a/include/gmssl/digest.h +++ b/include/gmssl/digest.h @@ -16,8 +16,10 @@ #include #include #include +#ifdef ENABLE_BROKEN_CRYPTO #include #include +#endif #include @@ -37,8 +39,10 @@ typedef struct DIGEST_CTX DIGEST_CTX; struct DIGEST_CTX { union { SM3_CTX sm3_ctx; -// MD5_CTX md5_ctx; +#ifdef ENABLE_BROKEN_CRYPTO + MD5_CTX md5_ctx; SHA1_CTX sha1_ctx; +#endif SHA224_CTX sha224_ctx; SHA256_CTX sha256_ctx; SHA384_CTX sha384_ctx; @@ -58,8 +62,10 @@ struct DIGEST { }; const DIGEST *DIGEST_sm3(void); -//const DIGEST *DIGEST_md5(void); +#ifdef ENABLE_BROKEN_CRYPTO +const DIGEST *DIGEST_md5(void); const DIGEST *DIGEST_sha1(void); +#endif const DIGEST *DIGEST_sha224(void); const DIGEST *DIGEST_sha256(void); const DIGEST *DIGEST_sha384(void); diff --git a/src/asn1.c b/src/asn1.c index fc56efb7..32716f27 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -20,27 +20,12 @@ #include #include #include -#include +#include #ifdef WIN32 -time_t timegm(struct tm* timeptr) -{ -#error "Not implemented" - return 0; -} - -struct tm* gmtime_r(const time_t* clock, struct tm* result) -{ -#error "Not implemented" - return NULL; -} - -char* strptime(const char* buf, const char* format, struct tm* timeptr) -{ -#error "Not implemented" - return NULL; -} +#include "u_time.h" #endif + /* ## 返回值 @@ -808,15 +793,21 @@ int asn1_ia5_string_to_der_ex(int tag, const char *d, size_t dlen, uint8_t **out 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]; + char buf[ASN1_UTC_TIME_LEN + 1] = {0}; 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 (out && *out) *(*out)++ = tag; @@ -835,15 +826,20 @@ int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen) { struct tm tm_val; - char buf[ASN1_GENERALIZED_TIME_LEN + 1]; + char buf[ASN1_GENERALIZED_TIME_LEN + 1] = {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 (out && *out) @@ -1197,14 +1193,18 @@ int asn1_utc_time_from_der_ex(int tag, time_t *t, const uint8_t **pin, size_t *p buf[1] = '0'; } if (len == sizeof("YYMMDDHHMMSSZ")-1) { - // 这里应该自己写一个函数来解析 - if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { // 注意:这个函数在Windows上没有!! +#ifdef WIN32 + asn1_generalizedtime_to_tm(&tm_val, buf); + *t = GMSSL_timegm(&tm_val); +#else + if (!strptime(buf, "%Y%m%d%H%M%SZ", &tm_val)) { return -1; } + *t = timegm(&tm_val); +#endif } else { return -1; } - *t = timegm(&tm_val); // FIXME: Windows ! *pin = in + len; *pinlen = inlen - len; @@ -1235,16 +1235,25 @@ 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)) { error_print(); return -1; } + *t = timegm(&tm_val); +#endif + + } else { // TODO: 处理这种情况 error_print(); return -2; } - *t = timegm(&tm_val); + *pin = in + len; *pinlen = inlen - len; return 1; diff --git a/src/digest.c b/src/digest.c index fa38f05e..ba23d077 100644 --- a/src/digest.c +++ b/src/digest.c @@ -24,8 +24,10 @@ typedef struct { DIGEST_TABLE digest_table[] = { { OID_sm3, "sm3", "SM3" }, -// { OID_md5, "md5", "MD5" }, +#ifdef ENABLE_BROKEN_CRYPTO + { OID_md5, "md5", "MD5" }, { OID_sha1, "sha1", "SHA-1" }, +#endif { OID_sha224, "sha224", "SHA-224" }, { OID_sha256, "sha256", "SHA-256" }, { OID_sha384, "sha384", "SHA-384" }, @@ -93,12 +95,12 @@ const DIGEST *digest_from_name(const char *name) { if (!strcmp(name, "sm3") || !strcmp(name, "SM3")) { return DIGEST_sm3(); - /* +#ifdef ENABLE_BROKEN_CRYPTO } else if (!strcmp(name, "md5") || !strcmp(name, "MD5")) { return DIGEST_md5(); - */ } else if (!strcmp(name, "sha1") || !strcmp(name, "SHA1")) { return DIGEST_sha1(); +#endif } else if (!strcmp(name, "sha224") || !strcmp(name, "SHA224")) { return DIGEST_sha224(); } else if (!strcmp(name, "sha256") || !strcmp(name, "SHA256")) { @@ -160,7 +162,8 @@ const DIGEST *DIGEST_sm3(void) return &sm3_digest_object; } -/* +#ifdef ENABLE_BROKEN_CRYPTO + #include static int md5_digest_init(DIGEST_CTX *ctx) @@ -207,7 +210,6 @@ const DIGEST *DIGEST_md5(void) { return &md5_digest_object; } -*/ #include @@ -256,6 +258,7 @@ const DIGEST *DIGEST_sha1(void) { return &sha1_digest_object; } +#endif #include diff --git a/src/sdf/sdf.c b/src/sdf/sdf.c old mode 100644 new mode 100755 diff --git a/src/sdf/sdf.h b/src/sdf/sdf.h old mode 100644 new mode 100755 diff --git a/src/sdf/sdf_dummy.c b/src/sdf/sdf_dummy.c old mode 100644 new mode 100755 diff --git a/src/sdf/sdf_ext.c b/src/sdf/sdf_ext.c old mode 100644 new mode 100755 diff --git a/src/sdf/sdf_ext.h b/src/sdf/sdf_ext.h old mode 100644 new mode 100755 index 5b4e0cc8..242fe5ee --- a/src/sdf/sdf_ext.h +++ b/src/sdf/sdf_ext.h @@ -1,4 +1,4 @@ -/* +/* * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may diff --git a/src/sdf/sdf_int.h b/src/sdf/sdf_int.h old mode 100644 new mode 100755 index d07522ff..87eb562d --- a/src/sdf/sdf_int.h +++ b/src/sdf/sdf_int.h @@ -13,6 +13,10 @@ #include "sdf.h" +#ifdef WIN32 +#include +#endif + typedef int (*SDF_OpenDevice_FuncPtr)( void **phDeviceHandle); @@ -346,7 +350,11 @@ typedef int (*SDF_DeleteObject_FuncPtr)( typedef struct sdf_method_st { char *name; +#ifdef WIN32 + HMODULE dso; +#else void *dso; +#endif SDF_OpenDevice_FuncPtr OpenDevice; SDF_CloseDevice_FuncPtr CloseDevice; SDF_OpenSession_FuncPtr OpenSession; diff --git a/src/sdf/sdf_lib.c b/src/sdf/sdf_lib.c old mode 100644 new mode 100755 diff --git a/src/sdf/sdf_meth.c b/src/sdf/sdf_meth.c old mode 100644 new mode 100755 index b26fd467..39dd6c28 --- a/src/sdf/sdf_meth.c +++ b/src/sdf/sdf_meth.c @@ -11,13 +11,22 @@ #include #include #include +#ifdef WIN32 +#include +#else #include +#endif #include "sdf_int.h" #define SDFerr(a,b) +#ifdef WIN32 +#define SDF_METHOD_BIND_FUNCTION_EX(func,name) \ + sdf->func = (SDF_##func##_FuncPtr)GetProcAddress(sdf->dso, "SDF_"#name) +#else #define SDF_METHOD_BIND_FUNCTION_EX(func,name) \ sdf->func = (SDF_##func##_FuncPtr)dlsym(sdf->dso, "SDF_"#name) +#endif #define SDF_METHOD_BIND_FUNCTION(func) \ SDF_METHOD_BIND_FUNCTION_EX(func,func) @@ -33,11 +42,18 @@ SDF_METHOD *SDF_METHOD_load_library(const char *so_path) } memset(sdf, 0, sizeof(*sdf)); - if (!(sdf->dso = dlopen(so_path, RTLD_LAZY))) { +#ifdef WIN32 + if ((sdf->dso = LoadLibraryA(so_path)) == NULL) { + goto end; + } + +#else + if (!(sdf->dso = dlopen(so_path, 0/*RTLD_LAZY*/))) { // FIXME: dlfcn.h, dlopen, RTLD_LAZY not in windows! fprintf(stderr, "%s %d: %s\n", __FILE__, __LINE__, dlerror()); SDFerr(SDF_F_SDF_METHOD_LOAD_LIBRARY, SDF_R_DSO_LOAD_FAILURE); goto end; } +#endif SDF_METHOD_BIND_FUNCTION(OpenDevice); SDF_METHOD_BIND_FUNCTION(CloseDevice); diff --git a/src/sdf/sdf_sansec.c b/src/sdf/sdf_sansec.c old mode 100644 new mode 100755 diff --git a/src/sdf/sdf_sansec.h b/src/sdf/sdf_sansec.h old mode 100644 new mode 100755 diff --git a/src/skf/skf.c b/src/skf/skf.c old mode 100644 new mode 100755 diff --git a/src/skf/skf.h b/src/skf/skf.h old mode 100644 new mode 100755 diff --git a/src/skf/skf_dummy.c b/src/skf/skf_dummy.c old mode 100644 new mode 100755 diff --git a/src/skf/skf_ext.c b/src/skf/skf_ext.c old mode 100644 new mode 100755 diff --git a/src/skf/skf_ext.h b/src/skf/skf_ext.h old mode 100644 new mode 100755 diff --git a/src/skf/skf_int.h b/src/skf/skf_int.h old mode 100644 new mode 100755 index d1929ce7..9e8cc0f3 --- a/src/skf/skf_int.h +++ b/src/skf/skf_int.h @@ -14,6 +14,10 @@ #include "../sgd.h" #include "skf.h" +#ifdef WIN32 +#include +#endif + typedef ULONG (DEVAPI *SKF_WaitForDevEvent_FuncPtr)( LPSTR szDevName, @@ -472,7 +476,11 @@ typedef ULONG (DEVAPI *SKF_CloseHandle_FuncPtr)( typedef struct skf_method_st { char *name; +#ifdef WIN32 + HMODULE dso; +#else void *dso; +#endif SKF_WaitForDevEvent_FuncPtr WaitForDevEvent; SKF_CancelWaitForDevEvent_FuncPtr CancelWaitForDevEvent; SKF_EnumDev_FuncPtr EnumDev; diff --git a/src/skf/skf_lib.c b/src/skf/skf_lib.c old mode 100644 new mode 100755 index bd6354c8..1656e574 --- a/src/skf/skf_lib.c +++ b/src/skf/skf_lib.c @@ -23,7 +23,7 @@ extern SKF_VENDOR skf_wisec; #define SKFerr(f,e) -ULONG SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) +ULONG DEVAPI SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) { if (skf_method) { SKF_METHOD_free(skf_method); @@ -47,7 +47,7 @@ ULONG SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) return SAR_OK; } -ULONG SKF_UnloadLibrary(void) +ULONG DEVAPI SKF_UnloadLibrary(void) { SKF_METHOD_free(skf_method); skf_method = NULL; @@ -126,7 +126,7 @@ static unsigned long skf_get_error_reason(ULONG ulError) return 0; } -ULONG SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr) +ULONG DEVAPI SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr) { unsigned long reason; diff --git a/src/skf/skf_meth.c b/src/skf/skf_meth.c old mode 100644 new mode 100755 index 601ba2e5..1cba2019 --- a/src/skf/skf_meth.c +++ b/src/skf/skf_meth.c @@ -11,15 +11,24 @@ #include #include #include +#ifdef WIN32 +#include +#else #include +#endif #include "skf.h" #include "skf_ext.h" #include "skf_int.h" #define SKFerr(e,r) +#ifdef WIN32 +#define SKF_METHOD_BIND_FUNCTION_EX(func,name) \ + skf->func = (SKF_##func##_FuncPtr)GetProcAddress(skf->dso, "SKF_"#name) +#else #define SKF_METHOD_BIND_FUNCTION_EX(func,name) \ skf->func = (SKF_##func##_FuncPtr)dlsym(skf->dso, "SKF_"#name) +#endif #define SKF_METHOD_BIND_FUNCTION(func) \ SKF_METHOD_BIND_FUNCTION_EX(func,func) @@ -34,10 +43,17 @@ SKF_METHOD *SKF_METHOD_load_library(const char *so_path) SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); goto end; } - if (!(skf->dso = dlopen(so_path, RTLD_LAZY))) { +#ifdef WIN32 + if ((skf->dso = LoadLibraryA(so_path)) == NULL) { + goto end; + } + +#else + if (!(skf->dso = dlopen(so_path, 0/*RTLD_LAZY*/))) {//FIXME:dlopen not in windows SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, SKF_R_DSO_LOAD_FAILURE); goto end; } +#endif SKF_METHOD_BIND_FUNCTION(WaitForDevEvent); SKF_METHOD_BIND_FUNCTION(CancelWaitForDevEvent); diff --git a/src/skf/skf_prn.c b/src/skf/skf_prn.c old mode 100644 new mode 100755 index df201b62..8ceaba3e --- a/src/skf/skf_prn.c +++ b/src/skf/skf_prn.c @@ -48,7 +48,7 @@ static char *skf_algor_name(ULONG ulAlgID) return NULL; } -ULONG SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) +ULONG DEVAPI SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) { if (!szDevStateName) { return SAR_INDATALENERR; @@ -72,7 +72,7 @@ ULONG SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) return SAR_OK; } -ULONG SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName) +ULONG DEVAPI SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName) { switch (ulContainerType) { case SKF_CONTAINER_TYPE_UNDEF: @@ -130,7 +130,7 @@ static table_item_t skf_pkey_caps[] = { { SGD_SM2_3, "sm2encrypt" } }; -ULONG SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) +ULONG DEVAPI SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) { size_t i, n; int fmt = 0, ind = 4; @@ -205,7 +205,7 @@ ULONG SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) return SAR_OK; } -ULONG SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) +ULONG DEVAPI SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) { int fmt = 0, ind = 4; format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); @@ -215,7 +215,7 @@ ULONG SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) return SAR_OK; } -ULONG SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) +ULONG DEVAPI SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) { int fmt = 0, ind = 4; format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); @@ -231,7 +231,7 @@ ULONG SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) return SAR_OK; } -ULONG SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) +ULONG DEVAPI SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) { int fmt = 0, ind = 4; format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); @@ -240,7 +240,7 @@ ULONG SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) return SAR_OK; } -ULONG SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) +ULONG DEVAPI SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) { int fmt = 0, ind = 4; format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); @@ -248,7 +248,7 @@ ULONG SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) return SAR_OK; } -ULONG SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) +ULONG DEVAPI SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) { int fmt = 0, ind = 4; format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); @@ -259,7 +259,7 @@ ULONG SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) return SAR_OK; } -ULONG SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob) +ULONG DEVAPI SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob) { int fmt = 0, ind = 4; format_bytes(fp, fmt, ind, "r", blob->r, ECC_MAX_XCOORDINATE_BITS_LEN/8); diff --git a/src/skf/skf_wisec.c b/src/skf/skf_wisec.c old mode 100644 new mode 100755 diff --git a/src/skf/skf_wisec.h b/src/skf/skf_wisec.h old mode 100644 new mode 100755 diff --git a/src/u_time.c b/src/u_time.c new file mode 100644 index 00000000..e265840d --- /dev/null +++ b/src/u_time.c @@ -0,0 +1,496 @@ +#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(struct tm *tm, char *gtime) +{ + 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 new file mode 100644 index 00000000..533cc470 --- /dev/null +++ b/src/u_time.h @@ -0,0 +1,26 @@ +#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(struct tm *tm,char *gtime); +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/digesttest.c b/tests/digesttest.c index 8c9051ac..34f01d28 100644 --- a/tests/digesttest.c +++ b/tests/digesttest.c @@ -15,8 +15,10 @@ #include const char *digests[] = { -// "md5", +#ifdef ENABLE_BROKEN_CRYPTO + "md5", "sha1", +#endif "sm3", "sha224", "sha256", diff --git a/tests/hash_drbgtest.c b/tests/hash_drbgtest.c index 01bf98f3..da4e6be1 100644 --- a/tests/hash_drbgtest.c +++ b/tests/hash_drbgtest.c @@ -36,6 +36,8 @@ int main(void) { +// currently we only has SHA-1 test suites +#ifdef ENABLE_BROKEN_CRYPTO HASH_DRBG drbg; uint8_t entropy[sizeof(EntropyInput)/2]; @@ -87,6 +89,6 @@ int main(void) printf("%02x", out[i]); } printf("\n"); - +#endif return 0; } diff --git a/tests/hkdftest.c b/tests/hkdftest.c index 42858fc9..9754e655 100644 --- a/tests/hkdftest.c +++ b/tests/hkdftest.c @@ -78,6 +78,7 @@ static struct { "b8a11f5c5ee1879ec3454e5f3c738d2d" "9d201395faa4b61a96c8", }, +#ifdef ENABLE_BROKEN_CRYPTO { // test 4 "sha1", @@ -141,6 +142,7 @@ static struct { "b3bae548aa53d423b0d1f27ebba6f5e5" "673a081d70cce7acfc48", }, +#endif }; int test_hkdf(void) diff --git a/tests/pbkdf2test.c b/tests/pbkdf2test.c index 26cbefb4..15a1eba5 100644 --- a/tests/pbkdf2test.c +++ b/tests/pbkdf2test.c @@ -101,6 +101,8 @@ void test(void) static int test_pbkdf2_genkey(void) { +// FIXME: currently we only has SHA-1 tests, replace with SHA-256 +#ifdef ENABLE_BROKEN_CRYPTO int i; uint8_t key[64]; uint8_t buf[64]; @@ -123,7 +125,7 @@ static int test_pbkdf2_genkey(void) fprintf(stderr, "test_pbkdf2_genkey test %d ok\n", i); } } - +#endif printf("%s() ok\n", __FUNCTION__); return 0; }