From c9634952d5a3c63afd9dbba6e731c3724a1cc71b Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 30 Apr 2021 15:04:09 -0700 Subject: [PATCH 1/3] Fix to handle time rollover in TLS v1.3 diff calculation. --- src/tls.c | 11 ++++++++--- src/tls13.c | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tls.c b/src/tls.c index 3ffa417f7..6a076bf79 100644 --- a/src/tls.c +++ b/src/tls.c @@ -10360,7 +10360,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #if defined(HAVE_SESSION_TICKET) if (ssl->options.resuming && ssl->session.ticketLen > 0) { WOLFSSL_SESSION* sess = &ssl->session; - word32 milli; + word32 now, milli; if (sess->ticketLen > MAX_PSK_ID_LEN) { WOLFSSL_MSG("Session ticket length for PSK ext is too large"); @@ -10373,8 +10373,13 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) ret = SetCipherSpecs(ssl); if (ret != 0) return ret; - milli = TimeNowInMilliseconds() - sess->ticketSeen + - sess->ticketAdd; + now = TimeNowInMilliseconds(); + if (now < sess->ticketSeen) + milli = (0xFFFFFFFFU - sess->ticketSeen) + now; + else + milli = now - sess->ticketSeen; + milli += sess->ticketAdd; + /* Pre-shared key is mandatory extension for resumption. */ ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, milli, ssl->specs.mac_algorithm, diff --git a/src/tls13.c b/src/tls13.c index fd686a747..f510dfd01 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3540,7 +3540,10 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, now = TimeNowInMilliseconds(); if (now == (word32)GETTIME_ERROR) return now; - diff = now - ssl->session.ticketSeen; + if (now < ssl->session.ticketSeen) + diff = (0xFFFFFFFFU - ssl->session.ticketSeen) + now; + else + diff = now - ssl->session.ticketSeen; diff -= current->ticketAge - ssl->session.ticketAdd; /* Check session and ticket age timeout. * Allow +/- 1000 milliseconds on ticket age. From f8ecd4b441fa9361598424290b9a34952bf1c54c Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 30 Apr 2021 15:04:31 -0700 Subject: [PATCH 2/3] Fixes for building with `NO_ASN_TIME`. If used with TLS user must supply `LowResTimer` and `TimeNowInMilliseconds`. --- src/internal.c | 5 +++++ src/ssl.c | 15 +++++++++++++++ src/tls13.c | 9 ++++++++- tests/api.c | 8 +++++--- wolfcrypt/src/asn.c | 9 ++++++++- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index d5d56c36a..a1d1c5541 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7922,7 +7922,12 @@ ProtocolVersion MakeDTLSv1_2(void) return (word32)XTIME(0); } #endif +#else + /* user must supply timer function to return elapsed seconds: + * word32 LowResTimer(void); + */ #endif /* !NO_ASN_TIME */ + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) diff --git a/src/ssl.c b/src/ssl.c index d1116648c..db50daedf 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26459,7 +26459,9 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) int ret = 0; int depth = 0; int error; +#ifndef NO_ASN_TIME byte *afterDate, *beforeDate; +#endif WOLFSSL_ENTER("wolfSSL_X509_verify_cert"); @@ -26486,6 +26488,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) #endif } + #ifndef NO_ASN_TIME error = 0; /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or ASN_BEFORE_DATE_E if there are no additional errors found in the @@ -26511,6 +26514,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) ctx->store->verify_cb(0, ctx); #endif } + #endif /* OpenSSL returns 0 when a chain can't be built */ if (ret == ASN_NO_SIGNER_E) @@ -29092,10 +29096,14 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at) wolfSSL_ASN1_OBJECT_free(at->value.object); break; case V_ASN1_UTCTIME: + #ifndef NO_ASN_TIME wolfSSL_ASN1_TIME_free(at->value.utctime); + #endif break; case V_ASN1_GENERALIZEDTIME: + #ifndef NO_ASN_TIME wolfSSL_ASN1_TIME_free(at->value.generalizedtime); + #endif break; case V_ASN1_UTF8STRING: case V_ASN1_PRINTABLESTRING: @@ -30757,16 +30765,23 @@ int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a) * returns WOLFSSL_SUCCESS (1) if correct otherwise WOLFSSL_FAILURE (0) */ int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a) { +#ifndef NO_ASN_TIME char buf[MAX_TIME_STRING_SZ]; +#endif WOLFSSL_ENTER("wolfSSL_ASN1_TIME_check"); +#ifndef NO_ASN_TIME /* if can parse the WOLFSSL_ASN1_TIME passed in then consider syntax good */ if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)a, buf, MAX_TIME_STRING_SZ) == NULL) { return WOLFSSL_FAILURE; } return WOLFSSL_SUCCESS; +#else + (void)a; + return WOLFSSL_FAILURE; +#endif } #endif /* !NO_ASN_TIME */ diff --git a/src/tls13.c b/src/tls13.c index f510dfd01..7f9288c4f 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1272,7 +1272,8 @@ end: return ret; } -#ifdef HAVE_SESSION_TICKET +#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) +#ifndef NO_ASN_TIME #if defined(USER_TICKS) #if 0 word32 TimeNowInMilliseconds(void) @@ -1528,6 +1529,12 @@ end: return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000); } #endif +#else + /* user must supply time in milliseconds function: + * word32 TimeNowInMilliseconds(void); + * The response is milliseconds elapsed + */ +#endif /* !NO_ASN_TIME */ #endif /* HAVE_SESSION_TICKET || !NO_PSK */ diff --git a/tests/api.c b/tests/api.c index a12309654..44aef6844 100644 --- a/tests/api.c +++ b/tests/api.c @@ -41925,7 +41925,7 @@ static void test_wolfSSL_RSA_verify(void) #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ - defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) + defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) static void test_openssl_make_self_signed_certificate(EVP_PKEY* pkey) { X509* x509 = NULL; @@ -42006,7 +42006,8 @@ static void test_openssl_generate_key_and_cert(void) BN_free(exponent); - #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) + #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \ + defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) test_openssl_make_self_signed_certificate(pkey); #endif } @@ -42030,7 +42031,8 @@ static void test_openssl_generate_key_and_cert(void) AssertIntNE(EC_KEY_generate_key(ec_key), 0); AssertIntNE(EVP_PKEY_assign_EC_KEY(pkey, ec_key), 0); - #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) + #if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \ + defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) test_openssl_make_self_signed_certificate(pkey); #endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 010be3f53..5c08cf486 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -12429,6 +12429,7 @@ int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen, #ifdef WOLFSSL_CERT_GEN +#ifndef NO_ASN_TIME static WC_INLINE byte itob(int number) { return (byte)number + 0x30; @@ -12462,7 +12463,7 @@ static void SetTime(struct tm* date, byte* output) output[i] = 'Z'; /* Zulu profile */ } - +#endif #ifdef WOLFSSL_ALT_NAMES @@ -13358,6 +13359,7 @@ int SetName(byte* output, word32 outputSz, CertName* name) * return size in bytes written to output, 0 on error */ static int SetValidity(byte* output, int daysValid) { +#ifndef NO_ASN_TIME byte before[MAX_DATE_SIZE]; byte after[MAX_DATE_SIZE]; @@ -13427,6 +13429,11 @@ static int SetValidity(byte* output, int daysValid) XMEMCPY(output + seqSz + beforeSz, after, afterSz); return seqSz + beforeSz + afterSz; +#else + (void)output; + (void)daysValid; + return NOT_COMPILED_IN; +#endif } /* encode info from cert into DER encoded format */ From 6c131e3e8b81c9e78390c8d37f887c1cd2599a9f Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 6 May 2021 14:46:35 -0700 Subject: [PATCH 3/3] Fix off by 1 in rollover calculation. --- src/tls.c | 2 +- src/tls13.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tls.c b/src/tls.c index 6a076bf79..b4f43b073 100644 --- a/src/tls.c +++ b/src/tls.c @@ -10375,7 +10375,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) return ret; now = TimeNowInMilliseconds(); if (now < sess->ticketSeen) - milli = (0xFFFFFFFFU - sess->ticketSeen) + now; + milli = (0xFFFFFFFFU - sess->ticketSeen) + 1 + now; else milli = now - sess->ticketSeen; milli += sess->ticketAdd; diff --git a/src/tls13.c b/src/tls13.c index 7f9288c4f..daff56177 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3548,7 +3548,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, if (now == (word32)GETTIME_ERROR) return now; if (now < ssl->session.ticketSeen) - diff = (0xFFFFFFFFU - ssl->session.ticketSeen) + now; + diff = (0xFFFFFFFFU - ssl->session.ticketSeen) + 1 + now; else diff = now - ssl->session.ticketSeen; diff -= current->ticketAge - ssl->session.ticketAdd;