diff options
Diffstat (limited to 'src/tls/x509v3.c')
-rw-r--r-- | src/tls/x509v3.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index fa4d44229622d..1bd5aa009fb59 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -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; @@ -773,6 +815,7 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, struct asn1_hdr hdr; unsigned long value; size_t left; + const u8 *end_seq; /* * BasicConstraints ::= SEQUENCE { @@ -794,6 +837,7 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, if (hdr.length == 0) return 0; + end_seq = hdr.payload + hdr.length; if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || hdr.class != ASN1_CLASS_UNIVERSAL) { wpa_printf(MSG_DEBUG, "X509: Failed to parse " @@ -802,22 +846,16 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, } if (hdr.tag == ASN1_TAG_BOOLEAN) { - if (hdr.length != 1) { - wpa_printf(MSG_DEBUG, "X509: Unexpected " - "Boolean length (%u) in BasicConstraints", - hdr.length); - return -1; - } cert->ca = hdr.payload[0]; - if (hdr.length == pos + len - hdr.payload) { + pos = hdr.payload + hdr.length; + if (pos >= end_seq) { + /* No optional pathLenConstraint */ wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d", cert->ca); return 0; } - - if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length, - &hdr) < 0 || + if (asn1_get_next(pos, end_seq - pos, &hdr) < 0 || hdr.class != ASN1_CLASS_UNIVERSAL) { wpa_printf(MSG_DEBUG, "X509: Failed to parse " "BasicConstraints"); @@ -1263,11 +1301,6 @@ static int x509_parse_extension(struct x509_certificate *cert, } if (hdr.tag == ASN1_TAG_BOOLEAN) { - if (hdr.length != 1) { - wpa_printf(MSG_DEBUG, "X509: Unexpected " - "Boolean length (%u)", hdr.length); - return -1; - } critical_ext = hdr.payload[0]; pos = hdr.payload; if (asn1_get_next(pos, end - pos, &hdr) < 0 || |