aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-07-20 12:53:17 +0200
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-07-20 12:53:17 +0200
commitd3875b13a986dd30d2c281b4f450a4e015e3c7a9 (patch)
tree5c03a52f817db509c807b9a102467588dff94c7c
parent0fcfd0f5a38ec08417bcf536019d4809f6e672ac (diff)
downloadstrongswan-d3875b13a986dd30d2c281b4f450a4e015e3c7a9.tar.bz2
strongswan-d3875b13a986dd30d2c281b4f450a4e015e3c7a9.tar.xz
The RDN parser vulnerability discovered by Orange Labs research team
was not completely fixed in version 4.2.16. Some more modifications had to be applied to the asn1_length() function.
-rw-r--r--src/libstrongswan/asn1/asn1.c25
-rw-r--r--src/pluto/asn1.c23
2 files changed, 36 insertions, 12 deletions
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index e45e6cae9..fb6adcb62 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -225,25 +225,32 @@ u_int asn1_length(chunk_t *blob)
u_char n;
size_t len;
- /* advance from tag field on to length field */
- blob->ptr++;
- blob->len--;
+ if (blob->len < 2)
+ {
+ DBG2("insufficient number of octets to parse ASN.1 length");
+ return ASN1_INVALID_LENGTH;
+ }
- /* read first octet of length field */
- n = *blob->ptr++;
- blob->len--;
+ /* read length field, skip tag and length */
+ n = blob->ptr[1];
+ *blob = chunk_skip(*blob, 2);
if ((n & 0x80) == 0)
- {/* single length octet */
+ { /* single length octet */
+ if (n > blob->len)
+ {
+ DBG2("length is larger than remaining blob size");
+ return ASN1_INVALID_LENGTH;
+ }
return n;
}
/* composite length, determine number of length octets */
n &= 0x7f;
- if (n > blob->len)
+ if (n == 0 || n > blob->len)
{
- DBG2("number of length octets is larger than ASN.1 object");
+ DBG2("number of length octets invalid");
return ASN1_INVALID_LENGTH;
}
diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c
index ac93a89e0..a9fde029f 100644
--- a/src/pluto/asn1.c
+++ b/src/pluto/asn1.c
@@ -153,6 +153,14 @@ asn1_length(chunk_t *blob)
u_char n;
size_t len;
+ if (blob->len < 2)
+ {
+ DBG(DBG_PARSING,
+ DBG_log("insufficient number of octets to parse ASN.1 length")
+ )
+ return ASN1_INVALID_LENGTH;
+ }
+
/* advance from tag field on to length field */
blob->ptr++;
blob->len--;
@@ -161,16 +169,25 @@ asn1_length(chunk_t *blob)
n = *blob->ptr++;
blob->len--;
- if ((n & 0x80) == 0) /* single length octet */
+ if ((n & 0x80) == 0)
+ { /* single length octet */
+ if (n > blob->len)
+ {
+ DBG(DBG_PARSING,
+ DBG_log("length is larger than remaining blob size")
+ )
+ return ASN1_INVALID_LENGTH;
+ }
return n;
+ }
/* composite length, determine number of length octets */
n &= 0x7f;
- if (n > blob->len)
+ if (n == 0 || n > blob->len)
{
DBG(DBG_PARSING,
- DBG_log("number of length octets is larger than ASN.1 object")
+ DBG_log("number of length octets invalid")
)
return ASN1_INVALID_LENGTH;
}