From b72a36718f1ddf47ea9116d2c3edcf4b0ffb0d5b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 17 Dec 2015 01:41:45 +0200 Subject: [PATCH] TLS: Support longer X.509 serialNumber values This extends the old support from 32 or 64 bit value to full 20 octets maximum (RFC 5280, 4.1.2.2). Signed-off-by: Jouni Malinen --- src/tls/x509v3.c | 22 ++++++++++++---------- src/tls/x509v3.h | 5 ++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index ebb80bd24..9f3959799 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -1401,21 +1401,23 @@ static int x509_parse_tbs_certificate(const u8 *buf, size_t len, /* serialNumber CertificateSerialNumber ::= INTEGER */ if (hdr.class != ASN1_CLASS_UNIVERSAL || - hdr.tag != ASN1_TAG_INTEGER) { + hdr.tag != ASN1_TAG_INTEGER || + hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) { wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for " - "serialNumber; class=%d tag=0x%x", - hdr.class, hdr.tag); + "serialNumber; class=%d tag=0x%x length=%u", + hdr.class, hdr.tag, hdr.length); return -1; } - pos = hdr.payload; - left = hdr.length; - while (left) { - cert->serial_number <<= 8; - cert->serial_number |= *pos++; - left--; + pos = hdr.payload + hdr.length; + while (hdr.length > 0 && hdr.payload[0] == 0) { + hdr.payload++; + hdr.length--; } - wpa_printf(MSG_MSGDUMP, "X509: serialNumber %lu", cert->serial_number); + os_memcpy(cert->serial_number, hdr.payload, hdr.length); + cert->serial_number_len = hdr.length; + wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number, + cert->serial_number_len); /* signature AlgorithmIdentifier */ if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature, diff --git a/src/tls/x509v3.h b/src/tls/x509v3.h index fdfc9d89e..9cd904afa 100644 --- a/src/tls/x509v3.h +++ b/src/tls/x509v3.h @@ -45,10 +45,13 @@ struct x509_name { struct asn1_oid rid; /* registeredID */ }; +#define X509_MAX_SERIAL_NUM_LEN 20 + struct x509_certificate { struct x509_certificate *next; enum { X509_CERT_V1 = 0, X509_CERT_V2 = 1, X509_CERT_V3 = 2 } version; - unsigned long serial_number; + u8 serial_number[X509_MAX_SERIAL_NUM_LEN]; + size_t serial_number_len; struct x509_algorithm_identifier signature; struct x509_name issuer; struct x509_name subject;