diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index e875f4f5..6f5fc8ab 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -351,13 +351,16 @@ class ASN1 switch ($tag) { case self::TYPE_BOOLEAN: // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - if (strlen($content) != 1) { + if ($constructed || strlen($content) != 1) { return false; } $current['content'] = (bool) ord($content[$content_pos]); break; case self::TYPE_INTEGER: case self::TYPE_ENUMERATED: + if ($constructed) { + return false; + } $current['content'] = new BigInteger(substr($content, $content_pos), -256); break; case self::TYPE_REAL: // not currently supported @@ -415,12 +418,15 @@ class ASN1 break; case self::TYPE_NULL: // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - if (strlen($content)) { + if ($constructed || strlen($content)) { return false; } break; case self::TYPE_SEQUENCE: case self::TYPE_SET: + if (!$constructed) { + return false; + } $offset = 0; $current['content'] = array(); $content_len = strlen($content); @@ -441,6 +447,9 @@ class ASN1 } break; case self::TYPE_OBJECT_IDENTIFIER: + if ($constructed) { + return false; + } $current['content'] = $this->_decodeOID(substr($content, $content_pos)); if ($current['content'] === false) { return false; @@ -474,10 +483,16 @@ class ASN1 case self::TYPE_UTF8_STRING: // ???? case self::TYPE_BMP_STRING: + if ($constructed) { + return false; + } $current['content'] = substr($content, $content_pos); break; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: + if ($constructed) { + return false; + } $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag); default: } diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index eeb6774a..35bf877f 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -405,4 +405,17 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $decoded = $asn1->decodeBER($em); $this->assertFalse($decoded[0]); } + + public function testOIDGarbage() + { + $asn1 = new File_ASN1(); + + $em = pack('H*', '3080305c065860864801650304020188888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3080307f067d608648016503040201888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888804207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + } }