phpseclib/tests/Unit/File/ASN1Test.php

345 lines
14 KiB
PHP
Raw Normal View History

<?php
/**
2014-04-18 04:53:33 +00:00
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
2014-12-10 00:53:05 +00:00
use phpseclib\File\ASN1;
2014-09-04 00:30:42 +00:00
class Unit_File_ASN1Test extends PhpseclibTestCase
{
2014-04-18 04:53:33 +00:00
/**
* on older versions of \phpseclib\File\ASN1 this would yield a PHP Warning
2015-03-29 16:07:17 +00:00
* @group github275
*/
public function testAnyString()
{
$KDC_REP = array(
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
'pvno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'msg-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'padata' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'crealm' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'cname' => array(
'constant' => 4,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'ticket' => array(
'constant' => 5,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY),
'enc-part' => array(
'constant' => 6,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY)
)
);
$AS_REP = array(
2014-12-10 00:53:05 +00:00
'class' => 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';
2014-12-10 00:53:05 +00:00
$asn1 = new ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$result = $asn1->asn1map($decoded[0], $AS_REP);
2014-04-18 04:53:33 +00:00
$this->assertInternalType('array', $result);
}
2014-04-18 04:53:33 +00:00
/**
* on older versions of \phpseclib\File\ASN1 this would produce a null instead of an array
2015-03-29 16:07:17 +00:00
* @group github275
*/
public function testIncorrectString()
{
$PA_DATA = array(
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
'padata-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_INTEGER
),
'padata-value' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_OCTET_STRING
)
)
);
$PrincipalName = array(
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
'name-type' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_INTEGER
),
'name-string' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'min' => 0,
'max' => -1,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array('type' => ASN1::TYPE_IA5_STRING) // should be \phpseclib\File\ASN1::TYPE_GENERAL_STRING
)
)
);
$Ticket = array(
2014-12-10 00:53:05 +00:00
'class' => ASN1::CLASS_APPLICATION,
'cast' => 1,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
'tkt-vno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_INTEGER
),
'realm' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY
),
'sname' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY
),
'enc-part' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY
)
)
);
$KDC_REP = array(
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
'pvno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_INTEGER),
'msg-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_INTEGER),
'padata' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
'min' => 0,
'max' => -1,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => $PA_DATA),
'crealm' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_OCTET_STRING),
'cname' => array(
'constant' => 4,
'optional' => true,
'explicit' => true) + $PrincipalName,
2014-12-10 00:53:05 +00:00
//'type' => ASN1::TYPE_ANY),
'ticket' => array(
'constant' => 5,
'optional' => true,
'implicit' => true,
'min' => 0,
'max' => 1,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => $Ticket),
'enc-part' => array(
'constant' => 6,
'optional' => true,
'explicit' => true,
2014-12-10 00:53:05 +00:00
'type' => ASN1::TYPE_ANY)
)
);
$AS_REP = array(
2014-12-10 00:53:05 +00:00
'class' => 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';
2014-12-10 00:53:05 +00:00
$asn1 = new ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$result = $asn1->asn1map($decoded[0], $AS_REP);
2014-04-18 04:53:33 +00:00
$this->assertInternalType('array', $result);
}
/**
* older versions of ASN1 didn't handle indefinite length tags very well
2015-03-29 16:07:17 +00:00
*/
public function testIndefiniteLength()
{
2014-12-10 00:53:05 +00:00
$asn1 = new ASN1();
2014-09-04 01:54:24 +00:00
$decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/ASN1/FE.pdf.p7m'));
$this->assertCount(5, $decoded[0]['content'][1]['content'][0]['content']); // older versions would have returned 3
}
public function testDefiniteLength()
{
// the following base64-encoded string is the X.509 cert from <http://phpseclib.sourceforge.net/x509/decoder.php>
$str = 'MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM' .
'MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg' .
'THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x' .
'MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh' .
'MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw' .
'FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC' .
'gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy' .
'wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B' .
'd3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM' .
'BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl' .
'LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF' .
'BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw' .
'Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0' .
'ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF' .
'AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp' .
'ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le' .
'IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==';
2014-12-10 00:53:05 +00:00
$asn1 = new ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$this->assertCount(3, $decoded[0]['content']);
}
/**
2015-03-29 16:07:17 +00:00
* @group github477
*/
2014-09-24 05:07:49 +00:00
public function testContextSpecificNonConstructed()
{
2014-12-10 00:53:05 +00:00
$asn1 = new ASN1();
$decoded = $asn1->decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv'));
$this->assertInternalType('string', $decoded[0]['content'][0]['content']);
}
/**
2015-03-29 16:07:17 +00:00
* @group github602
*/
public function testEmptyContextTag()
{
$asn1 = new ASN1();
$decoded = $asn1->decodeBER("\xa0\x00");
$this->assertInternalType('array', $decoded);
$this->assertCount(0, $decoded[0]['content']);
}
/**
* @group github1027
*/
public function testInfiniteLoop()
{
2016-08-28 15:45:31 +00:00
$asn1 = new ASN1();
$data = base64_decode('MD6gJQYKKwYBBAGCNxQCA6AXDBVvZmZpY2VAY2VydGRpZ2l0YWwucm+BFW9mZmljZUBjZXJ0ZGlnaXRhbC5ybw==');
$asn1->decodeBER($data);
}
public function testApplicationTag()
{
$map = array(
2018-04-15 15:27:46 +00:00
'type' => ASN1::TYPE_SEQUENCE,
'children' => array(
// technically, default implies optional, but we'll define it as being optional, none-the-less, just to
// reenforce that fact
'version' => array(
2018-04-15 15:27:46 +00:00
// if class isn't present it's assumed to be ASN1::CLASS_UNIVERSAL or
// (if constant is present) ASN1::CLASS_CONTEXT_SPECIFIC
'class' => ASN1::CLASS_APPLICATION,
'cast' => 2,
'optional' => true,
'explicit' => true,
'default' => 'v1',
2018-04-15 15:27:46 +00:00
'type' => ASN1::TYPE_INTEGER,
'mapping' => array('v1', 'v2', 'v3')
)
)
);
$data = array('version' => 'v3');
2018-04-15 15:27:46 +00:00
$asn1 = new ASN1();
$str = $asn1->encodeDER($data, $map);
$decoded = $asn1->decodeBER($str);
$arr = $asn1->asn1map($decoded[0], $map);
$this->assertSame($data, $arr);
}
/**
* @group github1296
*/
public function testInvalidCertificate()
{
$data = 'a' . base64_decode('MD6gJQYKKwYBBAGCNxQCA6AXDBVvZmZpY2VAY2VydGRpZ2l0YWwucm+BFW9mZmljZUBjZXJ0ZGlnaXRhbC5ybw==');
$asn1 = new File_ASN1();
$asn1->decodeBER($data);
}
2014-09-03 05:36:43 +00:00
}