From bc041130b0365992c25cc5b995c1c56b31e4a212 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Mon, 21 Nov 2016 15:38:02 +0000 Subject: [PATCH] Correctly handle leap year in x509_date_is_valid() This patch ensures that invalid dates on leap years with 100 or 400 years intervals are handled correctly. --- ChangeLog | 3 +++ library/x509.c | 14 ++++++++++---- tests/suites/test_suite_x509parse.data | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e74dcea8..da29d7077 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,9 @@ Bugfix * Parse signature algorithm extension when renegotiating. Previously, renegotiated handshakes would only accept signatures using SHA-1 regardless of the peer's preferences, or fail if SHA-1 was disabled. + * Fix leap year calculation in x509_date_is_valid() to ensure that invalid + dates on leap years with 100 and 400 intervals are handled correctly. Found + by Nicholas Wilson. #694 = mbed TLS 2.1.9 branch released 2017-08-10 diff --git a/library/x509.c b/library/x509.c index e87ba69da..3cfa1d1e9 100644 --- a/library/x509.c +++ b/library/x509.c @@ -491,9 +491,10 @@ static int x509_parse_int( unsigned char **p, size_t n, int *res ) return( 0 ); } -static int x509_date_is_valid(const mbedtls_x509_time *t) +static int x509_date_is_valid(const mbedtls_x509_time *t ) { int ret = MBEDTLS_ERR_X509_INVALID_DATE; + int month_len; CHECK_RANGE( 0, 9999, t->year ); CHECK_RANGE( 0, 23, t->hour ); @@ -503,17 +504,22 @@ static int x509_date_is_valid(const mbedtls_x509_time *t) switch( t->mon ) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: - CHECK_RANGE( 1, 31, t->day ); + month_len = 31; break; case 4: case 6: case 9: case 11: - CHECK_RANGE( 1, 30, t->day ); + month_len = 30; break; case 2: - CHECK_RANGE( 1, 28 + (t->year % 4 == 0), t->day ); + if( ( !( t->year % 4 ) && t->year % 100 ) || + !( t->year % 400 ) ) + month_len = 29; + else + month_len = 28; break; default: return( ret ); } + CHECK_RANGE( 1, month_len, t->day ); return( 0 ); } diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index e337ed7cf..53e8a44da 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -1620,3 +1620,18 @@ X509 Get time (UTC invalid character in sec) depends_on:MBEDTLS_X509_USE_C x509_get_time:MBEDTLS_ASN1_UTC_TIME:"0011302359n0Z":MBEDTLS_ERR_X509_INVALID_DATE:0:0:0:0:0:0 +X509 Get time (Generalized Time invalid leap year multiple of 4 and 100) +depends_on:MBEDTLS_X509_USE_C +x509_get_time:MBEDTLS_ASN1_GENERALIZED_TIME:"19000229000000Z":MBEDTLS_ERR_X509_INVALID_DATE:0:0:0:0:0:0 + +X509 Get time (Generalized Time year multiple of 4 and not multiple of 100) +depends_on:MBEDTLS_X509_USE_C +x509_get_time:MBEDTLS_ASN1_GENERALIZED_TIME:"19920229000000Z":0:1992:2:29:0:0:0 + +X509 Get time (Generalized Time year multiple of 400) +depends_on:MBEDTLS_X509_USE_C +x509_get_time:MBEDTLS_ASN1_GENERALIZED_TIME:"20000229000000Z":0:2000:2:29:0:0:0 + +X509 Get time (Generalized Time invalid leap year not multiple of 4, 100 or 400) +depends_on:MBEDTLS_X509_USE_C +x509_get_time:MBEDTLS_ASN1_GENERALIZED_TIME:"19910229000000Z":MBEDTLS_ERR_X509_INVALID_DATE:0:0:0:0:0:0