From a478b7486074b09337bcb774ad55249bcf7b315d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 30 Mar 2014 01:11:47 -0500 Subject: [PATCH 1/6] ASN1: explicit application tags didn't work (although implicit ones did) --- phpseclib/File/ASN1.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 9c85083d..8627b814 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -1085,7 +1085,12 @@ class File_ASN1 } if (isset($mapping['cast'])) { - $tag = ($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']; + if (isset($mapping['explicit']) || $mapping['type'] == FILE_ASN1_TYPE_CHOICE) { + $value = chr($tag) . $this->_encodeLength(strlen($value)) . $value; + $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; + } else { + $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; + } } return chr($tag) . $this->_encodeLength(strlen($value)) . $value; From c8bf68ac026d5d9dca28f9d3eb045a712248265c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 5 Apr 2014 18:07:35 -0500 Subject: [PATCH 2/6] ASN1: make it so bit string's can have an optional minimum size --- phpseclib/File/ASN1.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 8627b814..fce33fbd 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -972,6 +972,11 @@ class File_ASN1 } } + if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) + { + $size = $mapping['min'] - 1; + } + $offset = 8 - (($size + 1) & 7); $offset = $offset !== 8 ? $offset : 0; From 61cd5e4f5afbf651dfd9feb7d1fa25b9eb91b88e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 10 Apr 2014 13:49:28 -0500 Subject: [PATCH 3/6] ASN1: make developing new ASN.1 scripts a little easier --- phpseclib/File/ASN1.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index fce33fbd..346a0aa0 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -509,7 +509,7 @@ class File_ASN1 */ function asn1map($decoded, $mapping, $special = array()) { - if (isset($mapping['explicit'])) { + if (isset($mapping['explicit']) && is_array($decoded['content'])) { $decoded = $decoded['content'][0]; } @@ -550,7 +550,15 @@ class File_ASN1 case $decoded['type'] == $mapping['type']: break; default: - return null; + // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings, + // let it through + switch (true) { + case $decoded['type'] < 18: // FILE_ASN1_TYPE_NUMERIC_STRING == 18 + case $decoded['type'] > 30: // FILE_ASN1_TYPE_BMP_STRING == 30 + case $mapping['type'] < 18: + case $mapping['type'] > 30: + return null; + } } if (isset($mapping['implicit'])) { From 10be403aff0f9ad1fc501af215572329094f0cde Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Apr 2014 12:01:04 -0500 Subject: [PATCH 4/6] ASN1: CS update --- phpseclib/File/ASN1.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 346a0aa0..da70d415 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -980,8 +980,7 @@ class File_ASN1 } } - if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) - { + if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) { $size = $mapping['min'] - 1; } From 27b3ea40593516196793ba11ba9b88ab20736e42 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 16 Apr 2014 15:18:45 -0500 Subject: [PATCH 5/6] ASN1: add test cases for latest changes --- tests/File/ASN1/DevTest.php | 230 ++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 tests/File/ASN1/DevTest.php diff --git a/tests/File/ASN1/DevTest.php b/tests/File/ASN1/DevTest.php new file mode 100644 index 00000000..7aae152c --- /dev/null +++ b/tests/File/ASN1/DevTest.php @@ -0,0 +1,230 @@ + + * @copyright MMXIII Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +require_once 'File/ASN1.php'; + +class File_ASN1_DevTestCase extends PhpseclibTestCase +{ + // on older versions of File_ASN1 this would yield a PHP Warning + public function testAnyString() + { + $KDC_REP = array( + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array( + 'pvno' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'msg-type' => array( + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'padata' => array( + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'crealm' => array( + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'cname' => array( + 'constant' => 4, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'ticket' => array( + 'constant' => 5, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY), + 'enc-part' => array( + 'constant' => 6, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY) + ) + ); + + $AS_REP = array( + 'class' => FILE_ASN1_CLASS_APPLICATION, + 'cast' => 11, + 'optional' => true, + 'explicit' => true + ) + $KDC_REP; + + $str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' . + '1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' . + 'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' . + 'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' . + 'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' . + '58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' . + 'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' . + 'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' . + 'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' . + '4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' . + '+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy'; + + $asn1 = new File_ASN1(); + $decoded = $asn1->decodeBER(base64_decode($str)); + $result = $asn1->asn1map($decoded[0], $AS_REP); + + $this->assertTrue(is_array($result)); + } + + // on older versions of File_ASN1 this would produce a null instead of an array + public function testIncorrectString() + { + $PA_DATA = array( + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array( + 'padata-type' => array( + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_INTEGER + ), + 'padata-value' => array( + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_OCTET_STRING + ) + ) + ); + + $PrincipalName = array( + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array( + 'name-type' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_INTEGER + ), + 'name-string' => array( + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + 'min' => 0, + 'max' => -1, + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array('type' => FILE_ASN1_TYPE_IA5_STRING) // should be FILE_ASN1_TYPE_GENERAL_STRING + ) + ) + ); + + $Ticket = array( + 'class' => FILE_ASN1_CLASS_APPLICATION, + 'cast' => 1, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array( + 'tkt-vno' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_INTEGER + ), + 'realm' => array( + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY + ), + 'sname' => array( + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY + ), + 'enc-part' => array( + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY + ) + ) + ); + + $KDC_REP = array( + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => array( + 'pvno' => array( + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_INTEGER), + 'msg-type' => array( + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_INTEGER), + 'padata' => array( + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'min' => 0, + 'max' => -1, + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => $PA_DATA), + 'crealm' => array( + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_OCTET_STRING), + 'cname' => array( + 'constant' => 4, + 'optional' => true, + 'explicit' => true) + $PrincipalName, + //'type' => FILE_ASN1_TYPE_ANY), + 'ticket' => array( + 'constant' => 5, + 'optional' => true, + 'implicit' => true, + 'min' => 0, + 'max' => 1, + 'type' => FILE_ASN1_TYPE_SEQUENCE, + 'children' => $Ticket), + 'enc-part' => array( + 'constant' => 6, + 'optional' => true, + 'explicit' => true, + 'type' => FILE_ASN1_TYPE_ANY) + ) + ); + + $AS_REP = array( + 'class' => FILE_ASN1_CLASS_APPLICATION, + 'cast' => 11, + 'optional' => true, + 'explicit' => true + ) + $KDC_REP; + + $str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' . + '1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' . + 'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' . + 'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' . + 'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' . + '58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' . + 'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' . + 'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' . + 'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' . + '4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' . + '+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy'; + + $asn1 = new File_ASN1(); + $decoded = $asn1->decodeBER(base64_decode($str)); + $result = $asn1->asn1map($decoded[0], $AS_REP); + + $this->assertTrue(is_array($result)); + } +} From f970b69a9e381d7c4f1f878fbe48c46097d49359 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 17 Apr 2014 23:53:33 -0500 Subject: [PATCH 6/6] ASN1: test case updates --- tests/File/ASN1/DevTest.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/File/ASN1/DevTest.php b/tests/File/ASN1/DevTest.php index 7aae152c..edfc450f 100644 --- a/tests/File/ASN1/DevTest.php +++ b/tests/File/ASN1/DevTest.php @@ -1,15 +1,18 @@ - * @copyright MMXIII Andreas Fischer + * @author Jim Wigginton + * @copyright MMXIV Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ require_once 'File/ASN1.php'; -class File_ASN1_DevTestCase extends PhpseclibTestCase +class File_ASN1_DevTest extends PhpseclibTestCase { - // on older versions of File_ASN1 this would yield a PHP Warning + /** + * on older versions of File_ASN1 this would yield a PHP Warning + * @group github275 + */ public function testAnyString() { $KDC_REP = array( @@ -76,10 +79,13 @@ class File_ASN1_DevTestCase extends PhpseclibTestCase $decoded = $asn1->decodeBER(base64_decode($str)); $result = $asn1->asn1map($decoded[0], $AS_REP); - $this->assertTrue(is_array($result)); + $this->assertInternalType('array', $result); } - // on older versions of File_ASN1 this would produce a null instead of an array + /** + * on older versions of File_ASN1 this would produce a null instead of an array + * @group github275 + */ public function testIncorrectString() { $PA_DATA = array( @@ -225,6 +231,6 @@ class File_ASN1_DevTestCase extends PhpseclibTestCase $decoded = $asn1->decodeBER(base64_decode($str)); $result = $asn1->asn1map($decoded[0], $AS_REP); - $this->assertTrue(is_array($result)); + $this->assertInternalType('array', $result); } }