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 || | 
