X.509: Fix leap year handling again
authorDavid Howells <dhowells@redhat.com>
Wed, 24 Feb 2016 14:37:15 +0000 (14:37 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Apr 2016 16:08:46 +0000 (09:08 -0700)
commit ac4cbedfdf55455b4c447f17f0fa027dbf02b2a6 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
crypto/asymmetric_keys/x509_cert_parser.c

index 021d39c0ba75a8ce3c8c6cb4ea2c41cddd954ad7..13c4e5a5fe8c47b546bc34cbc109279dfa81fb4a 100644 (file)
@@ -494,7 +494,7 @@ int x509_decode_time(time64_t *_t,  size_t hdrlen,
                     unsigned char tag,
                     const unsigned char *value, size_t vlen)
 {
-       static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30,
+       static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
                                                       31, 31, 30, 31, 30, 31 };
        const unsigned char *p = value;
        unsigned year, mon, day, hour, min, sec, mon_len;
@@ -540,9 +540,9 @@ int x509_decode_time(time64_t *_t,  size_t hdrlen,
                if (year % 4 == 0) {
                        mon_len = 29;
                        if (year % 100 == 0) {
-                               year /= 100;
-                               if (year % 4 != 0)
-                                       mon_len = 28;
+                               mon_len = 28;
+                               if (year % 400 == 0)
+                                       mon_len = 29;
                        }
                }
        }