diff options
author | David Howells <dhowells@redhat.com> | 2016-02-24 09:37:15 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-02-29 09:29:40 -0500 |
commit | ac4cbedfdf55455b4c447f17f0fa027dbf02b2a6 (patch) | |
tree | 45a480b172d5563416a52c2b66f6b04654b0adc9 | |
parent | 06aae592425701851e02bb850cb9f4997f0ae163 (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.c | 8 |
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 | } |