Skip to content

Commit

Permalink
Support ASN.1 tag encoding with values greater than 30.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmauv authored and terrafrost committed Jan 24, 2025
1 parent 658ee70 commit a02712f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
14 changes: 13 additions & 1 deletion phpseclib/File/ASN1.php
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,19 @@ private static function encode_der($source, array $mapping, $idx = null, array $
an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)."
*/
if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
if ($child['constant'] <= 30) {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
} else {
$constant = $child['constant'];
$subtag = '';
while ($constant > 0) {
$subtagvalue = $constant & 0x7F;
$subtag = (chr(0x80 | $subtagvalue)) . $subtag;
$constant = $constant >> 7;
}
$subtag[strlen($subtag) - 1] = $subtag[strlen($subtag) - 1] & chr(0x7F);
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | 0x1f) . $subtag;
}
$temp = $subtag . self::encodeLength(strlen($temp)) . $temp;
} else {
$subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
Expand Down
26 changes: 26 additions & 0 deletions tests/Unit/File/ASN1Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,32 @@ public function testApplicationTag()
$this->assertSame($data, $arr);
}

public function testBigApplicationTag(): void
{
$map = [
'type' => ASN1::TYPE_SEQUENCE,
'children' => [
'demo' => [
'constant' => 0xFFFFFFFF,
'optional' => true,
'explicit' => true,
'default' => 'v1',
'type' => ASN1::TYPE_INTEGER,
'mapping' => ['v1', 'v2', 'v3'],
],
],
];

$data = ['demo' => 'v3'];

$str = ASN1::encodeDER($data, $map);

$decoded = ASN1::decodeBER($str);
$arr = ASN1::asn1map($decoded[0], $map);

$this->assertSame($data, $arr);
}

/**
* @group github1296
*/
Expand Down

0 comments on commit a02712f

Please sign in to comment.