diff --git a/src/ssl.c b/src/ssl.c index 411cea572..ead0271f2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10735,7 +10735,13 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) #ifdef OPENSSL_EXTRA /* needed for wolfSSL_X509_d21 function */ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl) { - DerBuffer* cert = ssl->buffers.certificate; + DerBuffer* cert; + + if (ssl == NULL) { + return NULL; + } + + cert = ssl->buffers.certificate; return wolfSSL_X509_d2i(NULL, cert->buffer, cert->length); } #endif /* OPENSSL_EXTRA */ @@ -11759,6 +11765,67 @@ int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime) } +#if defined(WOLFSSL_MYSQL_COMPATIBLE) +char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, char* buf, int len) +{ + struct tm t; + int idx = 0; + int format; + int dateLen; + byte* date = (byte*)time; + + WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string"); + + if (time == NULL || buf == NULL || len < 5) { + WOLFSSL_MSG("Bad argument"); + return NULL; + } + + format = *date; date++; + dateLen = *date; date++; + if (dateLen > len) { + return "error"; + } + + if (!ExtractDate(date, format, &t, &idx)) { + return "error"; + } + + if (date[idx] != 'Z') { + WOLFSSL_MSG("UTCtime, not Zulu") ; + return "Not Zulu"; + } + + /* place month in buffer */ + buf[0] = '\0'; + switch(t.tm_mon) { + case 0: XSTRNCAT(buf, "Jan ", 4); break; + case 1: XSTRNCAT(buf, "Feb ", 4); break; + case 2: XSTRNCAT(buf, "Mar ", 4); break; + case 3: XSTRNCAT(buf, "Apr ", 4); break; + case 4: XSTRNCAT(buf, "May ", 4); break; + case 5: XSTRNCAT(buf, "Jun ", 4); break; + case 6: XSTRNCAT(buf, "Jul ", 4); break; + case 7: XSTRNCAT(buf, "Aug ", 4); break; + case 8: XSTRNCAT(buf, "Sep ", 4); break; + case 9: XSTRNCAT(buf, "Oct ", 4); break; + case 10: XSTRNCAT(buf, "Nov ", 4); break; + case 11: XSTRNCAT(buf, "Dec ", 4); break; + default: + return "error"; + + } + idx = 4; /* use idx now for char buffer */ + buf[idx] = ' '; + + XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT", + t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900); + + return buf; +} +#endif /* WOLFSSL_MYSQL_COMPATIBLE */ + + int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a, const WOLFSSL_ASN1_INTEGER* b) { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 915776b1c..e5fc798e0 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3000,6 +3000,35 @@ static INLINE int DateLessThan(const struct tm* a, const struct tm* b) return DateGreaterThan(b,a); } + +int ExtractDate(const unsigned char* date, unsigned char format, + struct tm* certTime, int* idx) +{ + XMEMSET(certTime, 0, sizeof(struct tm)); + + if (format == ASN_UTC_TIME) { + if (btoi(date[0]) >= 5) + certTime->tm_year = 1900; + else + certTime->tm_year = 2000; + } + else { /* format == GENERALIZED_TIME */ + certTime->tm_year += btoi(date[*idx++]) * 1000; + certTime->tm_year += btoi(date[*idx++]) * 100; + } + + /* adjust tm_year, tm_mon */ + GetTime((int*)&certTime->tm_year, date, idx); certTime->tm_year -= 1900; + GetTime((int*)&certTime->tm_mon, date, idx); certTime->tm_mon -= 1; + GetTime((int*)&certTime->tm_mday, date, idx); + GetTime((int*)&certTime->tm_hour, date, idx); + GetTime((int*)&certTime->tm_min, date, idx); + GetTime((int*)&certTime->tm_sec, date, idx); + + return 1; +} + + /* like atoi but only use first byte */ /* Make sure before and after dates are valid */ int ValidateDate(const byte* date, byte format, int dateType) @@ -3021,26 +3050,10 @@ int ValidateDate(const byte* date, byte format, int dateType) #endif ltime = XTIME(0); - XMEMSET(&certTime, 0, sizeof(certTime)); - - if (format == ASN_UTC_TIME) { - if (btoi(date[0]) >= 5) - certTime.tm_year = 1900; - else - certTime.tm_year = 2000; + if (!ExtractDate(date, format, &certTime, &i)) { + WOLFSSL_MSG("Error extracting the date"); + return 0; } - else { /* format == GENERALIZED_TIME */ - certTime.tm_year += btoi(date[i++]) * 1000; - certTime.tm_year += btoi(date[i++]) * 100; - } - - /* adjust tm_year, tm_mon */ - GetTime((int*)&certTime.tm_year, date, &i); certTime.tm_year -= 1900; - GetTime((int*)&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; - GetTime((int*)&certTime.tm_mday, date, &i); - GetTime((int*)&certTime.tm_hour, date, &i); - GetTime((int*)&certTime.tm_min, date, &i); - GetTime((int*)&certTime.tm_sec, date, &i); if ((date[i] == '+') || (date[i] == '-')) { WOLFSSL_MSG("Using time differential, not Zulu") ; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2c20f4238..30e33fcea 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1643,6 +1643,10 @@ WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, WOLFSSL_API void wolfSSL_cert_service(void); #endif +#if defined(WOLFSSL_MYSQL_COMPATIBLE) +WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time, + char* buf, int len); +#endif /* WOLFSSL_MYSQL_COMPATIBLE */ #ifdef OPENSSL_EXTRA /*lighttp compatibility */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index dd54ffb5b..de105ab30 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -610,6 +610,8 @@ WOLFSSL_LOCAL void FreeTrustedPeerTable(TrustedPeerCert**, int, void*); WOLFSSL_LOCAL int ToTraditional(byte* buffer, word32 length); WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int); +WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, + struct tm* certTime, int* idx); WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); /* ASN.1 helper functions */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index db9897a1d..2c134d542 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -217,6 +217,14 @@ #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) #endif + #if defined(WOLFSSL_MYSQL_COMPATIBLE) + #ifndef USE_WINDOWS_API + #define XSNPRINTF snprintf + #else + #define XSNPRINTF _snprintf + #endif + #endif /* WOLFSSL_MYSQL_COMPATIBLE */ + #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_ALPN) /* use only Thread Safe version of strtok */ #ifndef USE_WINDOWS_API