]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
TLS: Be more careful in X.509 Time parsing
authorJouni Malinen <jouni@codeaurora.org>
Sun, 9 Jun 2019 01:41:15 +0000 (04:41 +0300)
committerJouni Malinen <jouni@codeaurora.org>
Tue, 11 Jun 2019 03:34:19 +0000 (06:34 +0300)
sscanf() can apparently read beyond the end of the buffer even if the
maximum length of the integer is specified in the format string. Replace
this parsing mechanism with helper functions that use sscanf() with NUL
terminated string to avoid this.

Credit to OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15158
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/tls/x509v3.c

index fa4d44229622dc9ece412be3fa43e7fa9125d475..d74b3a275ba72b17cddf5add74921c33464d61da 100644 (file)
@@ -538,9 +538,43 @@ done:
 }
 
 
+static int parse_uint2(const char *pos, size_t len)
+{
+       char buf[3];
+       int ret;
+
+       if (len < 2)
+               return -1;
+       buf[0] = pos[0];
+       buf[1] = pos[1];
+       buf[2] = 0x00;
+       if (sscanf(buf, "%2d", &ret) != 1)
+               return -1;
+       return ret;
+}
+
+
+static int parse_uint4(const char *pos, size_t len)
+{
+       char buf[5];
+       int ret;
+
+       if (len < 4)
+               return -1;
+       buf[0] = pos[0];
+       buf[1] = pos[1];
+       buf[2] = pos[2];
+       buf[3] = pos[3];
+       buf[4] = 0x00;
+       if (sscanf(buf, "%4d", &ret) != 1)
+               return -1;
+       return ret;
+}
+
+
 int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
 {
-       const char *pos;
+       const char *pos, *end;
        int year, month, day, hour, min, sec;
 
        /*
@@ -554,6 +588,7 @@ int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
         */
 
        pos = (const char *) buf;
+       end = pos + len;
 
        switch (asn1_tag) {
        case ASN1_TAG_UTCTIME:
@@ -562,7 +597,8 @@ int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
                                          "UTCTime format", buf, len);
                        return -1;
                }
-               if (sscanf(pos, "%02d", &year) != 1) {
+               year = parse_uint2(pos, end - pos);
+               if (year < 0) {
                        wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
                                          "UTCTime year", buf, len);
                        return -1;
@@ -579,7 +615,8 @@ int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
                                          "GeneralizedTime format", buf, len);
                        return -1;
                }
-               if (sscanf(pos, "%04d", &year) != 1) {
+               year = parse_uint4(pos, end - pos);
+               if (year < 0) {
                        wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
                                          "GeneralizedTime year", buf, len);
                        return -1;
@@ -592,35 +629,40 @@ int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
                return -1;
        }
 
-       if (sscanf(pos, "%02d", &month) != 1) {
+       month = parse_uint2(pos, end - pos);
+       if (month < 0) {
                wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
                                  "(month)", buf, len);
                return -1;
        }
        pos += 2;
 
-       if (sscanf(pos, "%02d", &day) != 1) {
+       day = parse_uint2(pos, end - pos);
+       if (day < 0) {
                wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
                                  "(day)", buf, len);
                return -1;
        }
        pos += 2;
 
-       if (sscanf(pos, "%02d", &hour) != 1) {
+       hour = parse_uint2(pos, end - pos);
+       if (hour < 0) {
                wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
                                  "(hour)", buf, len);
                return -1;
        }
        pos += 2;
 
-       if (sscanf(pos, "%02d", &min) != 1) {
+       min = parse_uint2(pos, end - pos);
+       if (min < 0) {
                wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
                                  "(min)", buf, len);
                return -1;
        }
        pos += 2;
 
-       if (sscanf(pos, "%02d", &sec) != 1) {
+       sec = parse_uint2(pos, end - pos);
+       if (sec < 0) {
                wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
                                  "(sec)", buf, len);
                return -1;