diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 4bdf13ea..eaa47eff 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -347,10 +347,15 @@ class File_ASN1 case FILE_ASN1_CLASS_APPLICATION: case FILE_ASN1_CLASS_PRIVATE: case FILE_ASN1_CLASS_CONTEXT_SPECIFIC: - $newcontent = $this->_decode_ber($content, $start); - $length = $newcontent['length']; - if (substr($content, $length, 2) == "\0\0") { - $length+= 2; + if ($constructed) { + $newcontent = $this->_decode_ber($content, $start); + $length = $newcontent['length']; + if (substr($content, $length, 2) == "\0\0") { + $length+= 2; + } + + // the array encapsulation is for BC with the old format + $content = array($newcontent); } $start+= $length; @@ -359,7 +364,7 @@ class File_ASN1 'type' => $class, 'constant' => $tag, // the array encapsulation is for BC with the old format - 'content' => array($newcontent), + 'content' => $content, // the only time when $content['headerlength'] isn't defined is when the length is indefinite. // the absence of $content['headerlength'] is how we know if something is indefinite or not. // technically, it could be defined to be 2 and then another indicator could be used but whatever. diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 4565edbd..5a5e6efb 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -268,4 +268,14 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $decoded = $asn1->decodeBER(base64_decode($str)); $this->assertCount(3, $decoded[0]['content']); } + + /** + * @group github477 + */ + public function testContextSpecificNonConstructed() + { + $asn1 = new File_ASN1(); + $decoded = $asn1->decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv')); + $this->assertInternalType('string', $decoded[0]['content'][0]['content']); + } }