aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-02-24 09:37:15 -0500
committerDavid Howells <dhowells@redhat.com>2016-02-29 09:29:40 -0500
commitac4cbedfdf55455b4c447f17f0fa027dbf02b2a6 (patch)
tree45a480b172d5563416a52c2b66f6b04654b0adc9
parent06aae592425701851e02bb850cb9f4997f0ae163 (diff)
X.509: Fix leap year handling again
There are still a couple of minor issues in the X.509 leap year handling: (1) To avoid doing a modulus-by-400 in addition to a modulus-by-100 when determining whether the year is a leap year or not, I divided the year by 100 after doing the modulus-by-100, thereby letting the compiler do one instruction for both, and then did a modulus-by-4. Unfortunately, I then passed the now-modified year value to mktime64() to construct a time value. Since this isn't a fast path and since mktime64() does a bunch of divisions, just condense down to "% 400". It's also easier to read. (2) The default month length for any February where the year doesn't divide by four exactly is obtained from the month_length[] array where the value is 29, not 28. This is fixed by altering the table. Reported-by: Rudolf Polzer <rpolzer@google.com> Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: David Woodhouse <David.Woodhouse@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> cc: stable@vger.kernel.org
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 7502029e3385..794cf0eac2c9 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -471,7 +471,7 @@ int x509_decode_time(time64_t *_t, size_t hdrlen,
471 unsigned char tag, 471 unsigned char tag,
472 const unsigned char *value, size_t vlen) 472 const unsigned char *value, size_t vlen)
473{ 473{
474 static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30, 474 static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
475 31, 31, 30, 31, 30, 31 }; 475 31, 31, 30, 31, 30, 31 };
476 const unsigned char *p = value; 476 const unsigned char *p = value;
477 unsigned year, mon, day, hour, min, sec, mon_len; 477 unsigned year, mon, day, hour, min, sec, mon_len;
@@ -517,9 +517,9 @@ int x509_decode_time(time64_t *_t, size_t hdrlen,
517 if (year % 4 == 0) { 517 if (year % 4 == 0) {
518 mon_len = 29; 518 mon_len = 29;
519 if (year % 100 == 0) { 519 if (year % 100 == 0) {
520 year /= 100; 520 mon_len = 28;
521 if (year % 4 != 0) 521 if (year % 400 == 0)
522 mon_len = 28; 522 mon_len = 29;
523 } 523 }
524 } 524 }
525 } 525 }