From e258e001fae139432af071ca4d7f4e42717eaeba Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 25 Aug 2014 10:12:56 -0500 Subject: [PATCH 1/7] ASN1: rewrite _decode_der this rewrite makes phpseclib better able to handle indef lengths, which had previously been untested. --- phpseclib/File/ASN1.php | 431 ++++++++++++++++++++-------------------- 1 file changed, 220 insertions(+), 211 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 2774e7e8..31cc517e 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -272,7 +272,8 @@ class File_ASN1 } $this->encoded = $encoded; - return $this->_decode_ber($encoded); + // encapsulate in an array for BC with the old decodeBER + return array($this->_decode_ber($encoded)); } /** @@ -287,215 +288,233 @@ class File_ASN1 * @return Array * @access private */ - function _decode_ber(&$encoded, $start = 0) + function _decode_ber($encoded, $start = 0) { - $decoded = array(); + $current = array('start' => $start); - while ( strlen($encoded) ) { - $current = array('start' => $start); + $type = ord($this->_string_shift($encoded)); + $start++; - $type = ord($this->_string_shift($encoded)); - $start++; + $constructed = ($type >> 5) & 1; - $constructed = ($type >> 5) & 1; - - $tag = $type & 0x1F; - if ($tag == 0x1F) { - $tag = 0; - // process septets (since the eighth bit is ignored, it's not an octet) - do { - $loop = ord($encoded[0]) >> 7; - $tag <<= 7; - $tag |= ord($this->_string_shift($encoded)) & 0x7F; - $start++; - } while ( $loop ); - } - - // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 - $length = ord($this->_string_shift($encoded)); - $start++; - if ( $length == 0x80 ) { // indefinite length - // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all - // immediately available." -- paragraph 8.1.3.2.c - //if ( !$constructed ) { - // return false; - //} - $length = strlen($encoded); - } elseif ( $length & 0x80 ) { // definite length, long form - // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only - // support it up to four. - $length&= 0x7F; - $temp = $this->_string_shift($encoded, $length); - // tags of indefinite length don't really have a header length; this length includes the tag - $current+= array('headerlength' => $length + 2); - $start+= $length; - extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); - } else { - $current+= array('headerlength' => 2); - } - - // End-of-content, see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 - if (!$type && !$length) { - return $decoded; - } - $content = $this->_string_shift($encoded, $length); - - /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 - built-in types. It defines an application-independent data type that must be distinguishable from all other - data types. The other three classes are user defined. The APPLICATION class distinguishes data types that - have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within - a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the - alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this - data type; the term CONTEXT-SPECIFIC does not appear. - - -- http://www.obj-sys.com/asn1tutorial/node12.html */ - $class = ($type >> 6) & 3; - switch ($class) { - case FILE_ASN1_CLASS_APPLICATION: - case FILE_ASN1_CLASS_PRIVATE: - case FILE_ASN1_CLASS_CONTEXT_SPECIFIC: - $decoded[] = array( - 'type' => $class, - 'constant' => $tag, - 'content' => $constructed ? $this->_decode_ber($content, $start) : $content, - 'length' => $length + $start - $current['start'] - ) + $current; - $start+= $length; - continue 2; - } - - $current+= array('type' => $tag); - - // decode UNIVERSAL tags - switch ($tag) { - case FILE_ASN1_TYPE_BOOLEAN: - // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - //if (strlen($content) != 1) { - // return false; - //} - $current['content'] = (bool) ord($content[0]); - break; - case FILE_ASN1_TYPE_INTEGER: - case FILE_ASN1_TYPE_ENUMERATED: - $current['content'] = new Math_BigInteger($content, -256); - break; - case FILE_ASN1_TYPE_REAL: // not currently supported - return false; - case FILE_ASN1_TYPE_BIT_STRING: - // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, - // the number of unused bits in the final subsequent octet. The number shall be in the range zero to - // seven. - if (!$constructed) { - $current['content'] = $content; - } else { - $temp = $this->_decode_ber($content, $start); - $length-= strlen($content); - $last = count($temp) - 1; - for ($i = 0; $i < $last; $i++) { - // all subtags should be bit strings - //if ($temp[$i]['type'] != FILE_ASN1_TYPE_BIT_STRING) { - // return false; - //} - $current['content'].= substr($temp[$i]['content'], 1); - } - // all subtags should be bit strings - //if ($temp[$last]['type'] != FILE_ASN1_TYPE_BIT_STRING) { - // return false; - //} - $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); - } - break; - case FILE_ASN1_TYPE_OCTET_STRING: - if (!$constructed) { - $current['content'] = $content; - } else { - $temp = $this->_decode_ber($content, $start); - $length-= strlen($content); - for ($i = 0, $size = count($temp); $i < $size; $i++) { - // all subtags should be octet strings - //if ($temp[$i]['type'] != FILE_ASN1_TYPE_OCTET_STRING) { - // return false; - //} - $current['content'].= $temp[$i]['content']; - } - // $length = - } - break; - case FILE_ASN1_TYPE_NULL: - // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - //if (strlen($content)) { - // return false; - //} - break; - case FILE_ASN1_TYPE_SEQUENCE: - case FILE_ASN1_TYPE_SET: - $current['content'] = $this->_decode_ber($content, $start); - break; - case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: - $temp = ord($this->_string_shift($content)); - $current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40); - $valuen = 0; - // process septets - while (strlen($content)) { - $temp = ord($this->_string_shift($content)); - $valuen <<= 7; - $valuen |= $temp & 0x7F; - if (~$temp & 0x80) { - $current['content'].= ".$valuen"; - $valuen = 0; - } - } - // the eighth bit of the last byte should not be 1 - //if ($temp >> 7) { - // return false; - //} - break; - /* Each character string type shall be encoded as if it had been declared: - [UNIVERSAL x] IMPLICIT OCTET STRING - - -- X.690-0207.pdf#page=23 (paragraph 8.21.3) - - Per that, we're not going to do any validation. If there are any illegal characters in the string, - we don't really care */ - case FILE_ASN1_TYPE_NUMERIC_STRING: - // 0,1,2,3,4,5,6,7,8,9, and space - case FILE_ASN1_TYPE_PRINTABLE_STRING: - // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, - // hyphen, full stop, solidus, colon, equal sign, question mark - case FILE_ASN1_TYPE_TELETEX_STRING: - // The Teletex character set in CCITT's T61, space, and delete - // see http://en.wikipedia.org/wiki/Teletex#Character_sets - case FILE_ASN1_TYPE_VIDEOTEX_STRING: - // The Videotex character set in CCITT's T.100 and T.101, space, and delete - case FILE_ASN1_TYPE_VISIBLE_STRING: - // Printing character sets of international ASCII, and space - case FILE_ASN1_TYPE_IA5_STRING: - // International Alphabet 5 (International ASCII) - case FILE_ASN1_TYPE_GRAPHIC_STRING: - // All registered G sets, and space - case FILE_ASN1_TYPE_GENERAL_STRING: - // All registered C and G sets, space and delete - case FILE_ASN1_TYPE_UTF8_STRING: - // ???? - case FILE_ASN1_TYPE_BMP_STRING: - $current['content'] = $content; - break; - case FILE_ASN1_TYPE_UTC_TIME: - case FILE_ASN1_TYPE_GENERALIZED_TIME: - $current['content'] = $this->_decodeTime($content, $tag); - default: - - } - - $start+= $length; - $decoded[] = $current + array('length' => $start - $current['start']); + $tag = $type & 0x1F; + if ($tag == 0x1F) { + $tag = 0; + // process septets (since the eighth bit is ignored, it's not an octet) + do { + $loop = ord($encoded[0]) >> 7; + $tag <<= 7; + $tag |= ord($this->_string_shift($encoded)) & 0x7F; + $start++; + } while ( $loop ); } - return $decoded; + // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 + $length = ord($this->_string_shift($encoded)); + $start++; + if ( $length == 0x80 ) { // indefinite length + // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all + // immediately available." -- paragraph 8.1.3.2.c + $length = strlen($encoded); + } elseif ( $length & 0x80 ) { // definite length, long form + // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only + // support it up to four. + $length&= 0x7F; + $temp = $this->_string_shift($encoded, $length); + // tags of indefinte length don't really have a header length; this length includes the tag + $current+= array('headerlength' => $length + 2); + $start+= $length; + extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); + } else { + $current+= array('headerlength' => 2); + } + + $content = $this->_string_shift($encoded, $length); + + // at this point $length can be overwritten. it's only accurate for definite length things as is + + /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 + built-in types. It defines an application-independent data type that must be distinguishable from all other + data types. The other three classes are user defined. The APPLICATION class distinguishes data types that + have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within + a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the + alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this + data type; the term CONTEXT-SPECIFIC does not appear. + + -- http://www.obj-sys.com/asn1tutorial/node12.html */ + $class = ($type >> 6) & 3; + switch ($class) { + 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; + } + + $start+= $length; + + return array( + 'type' => $class, + 'constant' => $tag, + // the array encapsulation is for BC with the old format + 'content' => array($newcontent), + // 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. + 'length' => $start - $current['start'] + ) + $current; + } + + $current+= array('type' => $tag); + + // decode UNIVERSAL tags + switch ($tag) { + case FILE_ASN1_TYPE_BOOLEAN: + // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 + //if (strlen($content) != 1) { + // return false; + //} + $current['content'] = (bool) ord($content[0]); + break; + case FILE_ASN1_TYPE_INTEGER: + case FILE_ASN1_TYPE_ENUMERATED: + $current['content'] = new Math_BigInteger($content, -256); + break; + case FILE_ASN1_TYPE_REAL: // not currently supported + return false; + case FILE_ASN1_TYPE_BIT_STRING: + // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, + // the number of unused bits in the final subsequent octet. The number shall be in the range zero to + // seven. + if (!$constructed) { + $current['content'] = $content; + } else { + $temp = $this->_decode_ber($content, $start); + $length-= strlen($content); + $last = count($temp) - 1; + for ($i = 0; $i < $last; $i++) { + // all subtags should be bit strings + //if ($temp[$i]['type'] != FILE_ASN1_TYPE_BIT_STRING) { + // return false; + //} + $current['content'].= substr($temp[$i]['content'], 1); + } + // all subtags should be bit strings + //if ($temp[$last]['type'] != FILE_ASN1_TYPE_BIT_STRING) { + // return false; + //} + $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); + } + break; + case FILE_ASN1_TYPE_OCTET_STRING: + if (!$constructed) { + $current['content'] = $content; + } else { + $current['content'] = ''; + $length = 0; + while (substr($content, 0, 2) != "\0\0") { + $temp = $this->_decode_ber($content, $length + $start); + $this->_string_shift($content, $temp['length']); + // all subtags should be octet strings + //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) { + // return false; + //} + $current['content'].= $temp['content']; + $length+= $temp['length']; + } + if (substr($content, 0, 2) == "\0\0") { + $length+= 2; // +2 for the EOC + } + } + break; + case FILE_ASN1_TYPE_NULL: + // "The contents octets shall not contain any octets." -- paragraph 8.8.2 + //if (strlen($content)) { + // return false; + //} + break; + case FILE_ASN1_TYPE_SEQUENCE: + case FILE_ASN1_TYPE_SET: + $offset = 0; + $current['content'] = array(); + while (strlen($content)) { + // if indefinite length construction was used and we have an end-of-content string next + // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 + if (!isset($current['headerlength']) && substr($content, 0, 2) == "\0\0") { + $length = $offset + 2; // +2 for the EOC + break 2; + } + $temp = $this->_decode_ber($content, $start + $offset); + $this->_string_shift($content, $temp['length']); + $current['content'][] = $temp; + $offset+= $temp['length']; + } + break; + case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: + $temp = ord($this->_string_shift($content)); + $current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40); + $valuen = 0; + // process septets + while (strlen($content)) { + $temp = ord($this->_string_shift($content)); + $valuen <<= 7; + $valuen |= $temp & 0x7F; + if (~$temp & 0x80) { + $current['content'].= ".$valuen"; + $valuen = 0; + } + } + // the eighth bit of the last byte should not be 1 + //if ($temp >> 7) { + // return false; + //} + break; + /* Each character string type shall be encoded as if it had been declared: + [UNIVERSAL x] IMPLICIT OCTET STRING + + -- X.690-0207.pdf#page=23 (paragraph 8.21.3) + + Per that, we're not going to do any validation. If there are any illegal characters in the string, + we don't really care */ + case FILE_ASN1_TYPE_NUMERIC_STRING: + // 0,1,2,3,4,5,6,7,8,9, and space + case FILE_ASN1_TYPE_PRINTABLE_STRING: + // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, + // hyphen, full stop, solidus, colon, equal sign, question mark + case FILE_ASN1_TYPE_TELETEX_STRING: + // The Teletex character set in CCITT's T61, space, and delete + // see http://en.wikipedia.org/wiki/Teletex#Character_sets + case FILE_ASN1_TYPE_VIDEOTEX_STRING: + // The Videotex character set in CCITT's T.100 and T.101, space, and delete + case FILE_ASN1_TYPE_VISIBLE_STRING: + // Printing character sets of international ASCII, and space + case FILE_ASN1_TYPE_IA5_STRING: + // International Alphabet 5 (International ASCII) + case FILE_ASN1_TYPE_GRAPHIC_STRING: + // All registered G sets, and space + case FILE_ASN1_TYPE_GENERAL_STRING: + // All registered C and G sets, space and delete + case FILE_ASN1_TYPE_UTF8_STRING: + // ???? + case FILE_ASN1_TYPE_BMP_STRING: + $current['content'] = $content; + break; + case FILE_ASN1_TYPE_UTC_TIME: + case FILE_ASN1_TYPE_GENERALIZED_TIME: + $current['content'] = $this->_decodeTime($content, $tag); + default: + } + + $start+= $length; + + // ie. length is the length of the full TLV encoding - it's not just the length of the value + return $current + array('length' => $start - $current['start']); } /** - * ASN.1 Decode + * ASN.1 Map * * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format. * @@ -805,16 +824,6 @@ class File_ASN1 return $this->_encode_der($source, $mapping, null, $special); } - /** - * ASN.1 Encode (Helper function) - * - * @param String $source - * @param Array $mapping - * @param Integer $idx - * @param Array $special - * @return String - * @access private - */ /** * ASN.1 Encode (Helper function) * From 3bb123c3d525829ab57a86206d94c9aa24ed4fd8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 30 Aug 2014 19:44:12 -0500 Subject: [PATCH 2/7] ASN1: CS adjustment (rm whitespace at eol) --- phpseclib/File/ASN1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 31cc517e..4bdf13ea 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -313,7 +313,7 @@ class File_ASN1 $length = ord($this->_string_shift($encoded)); $start++; if ( $length == 0x80 ) { // indefinite length - // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all + // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all // immediately available." -- paragraph 8.1.3.2.c $length = strlen($encoded); } elseif ( $length & 0x80 ) { // definite length, long form From 871e1a3070bd79e1a8c26679358edc659031b7c8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Sep 2014 00:29:04 -0500 Subject: [PATCH 3/7] ASN1: add unit tests for indefinite length decoding --- .../File/{ASN1/DevTest.php => ASN1Test.php} | 37 +++++++++++++++++- tests/Unit/File/FE.pdf.p7m | Bin 0 -> 14223 bytes 2 files changed, 36 insertions(+), 1 deletion(-) rename tests/Unit/File/{ASN1/DevTest.php => ASN1Test.php} (81%) create mode 100644 tests/Unit/File/FE.pdf.p7m diff --git a/tests/Unit/File/ASN1/DevTest.php b/tests/Unit/File/ASN1Test.php similarity index 81% rename from tests/Unit/File/ASN1/DevTest.php rename to tests/Unit/File/ASN1Test.php index d0d51042..cededfbe 100644 --- a/tests/Unit/File/ASN1/DevTest.php +++ b/tests/Unit/File/ASN1Test.php @@ -233,4 +233,39 @@ class Unit_File_ASN1_DevTest extends PhpseclibTestCase $this->assertInternalType('array', $result); } -} + + /** + * older versions of File_ASN1 didn't handle indefinite length tags very well + */ + public function testIndefiniteLength() + { + $asn1 = new File_ASN1(); + $decoded = $asn1->decodeBER(file_get_contents('tests/Unit/File/FE.pdf.p7m')); + $this->assertEquals(count($decoded[0]['content'][1]['content'][0]['content']), 5); // older versions would have returned 3 + } + + public function testDefiniteLength() + { + // the following base64-encoded string is the X.509 cert from + $str = 'MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM' . + 'MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg' . + 'THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x' . + 'MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh' . + 'MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw' . + 'FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC' . + 'gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy' . + 'wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B' . + 'd3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM' . + 'BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl' . + 'LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF' . + 'BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw' . + 'Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0' . + 'ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF' . + 'AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp' . + 'ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le' . + 'IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q=='; + $asn1 = new File_ASN1(); + $decoded = $asn1->decodeBER(base64_decode($str)); + $this->assertEquals(count($decoded[0]['content']), 3); + } +} \ No newline at end of file diff --git a/tests/Unit/File/FE.pdf.p7m b/tests/Unit/File/FE.pdf.p7m new file mode 100644 index 0000000000000000000000000000000000000000..6b9127156081130ac66dc8ed8cc8afe3af42fe28 GIT binary patch literal 14223 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 G;{O1AiE;P< literal 0 HcmV?d00001 From 36b4b13863e5f3631cdd8fed7ab1ebaa17dc0c64 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Sep 2014 00:36:43 -0500 Subject: [PATCH 4/7] ASN1: cs adjustments to unit test --- tests/Unit/File/ASN1Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index cededfbe..827f9935 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -268,4 +268,4 @@ class Unit_File_ASN1_DevTest extends PhpseclibTestCase $decoded = $asn1->decodeBER(base64_decode($str)); $this->assertEquals(count($decoded[0]['content']), 3); } -} \ No newline at end of file +} From 34866bf095d449dfeb570d8f1479734e13403fda Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Sep 2014 19:30:42 -0500 Subject: [PATCH 5/7] ASN1: unit test adjustments --- tests/Unit/File/{ => ASN1}/FE.pdf.p7m | Bin tests/Unit/File/ASN1Test.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/Unit/File/{ => ASN1}/FE.pdf.p7m (100%) diff --git a/tests/Unit/File/FE.pdf.p7m b/tests/Unit/File/ASN1/FE.pdf.p7m similarity index 100% rename from tests/Unit/File/FE.pdf.p7m rename to tests/Unit/File/ASN1/FE.pdf.p7m diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 827f9935..62526fd7 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -7,7 +7,7 @@ require_once 'File/ASN1.php'; -class Unit_File_ASN1_DevTest extends PhpseclibTestCase +class Unit_File_ASN1Test extends PhpseclibTestCase { /** * on older versions of File_ASN1 this would yield a PHP Warning From 8293b66136ee3cd00d54a809fcc6f564bc89f655 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Sep 2014 20:28:07 -0500 Subject: [PATCH 6/7] ASN1: another unit test update --- tests/Unit/File/ASN1Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 62526fd7..c07aef59 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -240,7 +240,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase public function testIndefiniteLength() { $asn1 = new File_ASN1(); - $decoded = $asn1->decodeBER(file_get_contents('tests/Unit/File/FE.pdf.p7m')); + $decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/tests/Unit/File/ASN1/FE.pdf.p7m')); $this->assertEquals(count($decoded[0]['content'][1]['content'][0]['content']), 5); // older versions would have returned 3 } From bb6d5d9bc03ddcd83bde1b8ac68171c803f3aa62 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Sep 2014 20:54:24 -0500 Subject: [PATCH 7/7] ASN1: one more unit test change --- tests/Unit/File/ASN1Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index c07aef59..fa2b150e 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -240,7 +240,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase public function testIndefiniteLength() { $asn1 = new File_ASN1(); - $decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/tests/Unit/File/ASN1/FE.pdf.p7m')); + $decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/ASN1/FE.pdf.p7m')); $this->assertEquals(count($decoded[0]['content'][1]['content'][0]['content']), 5); // older versions would have returned 3 }