Skip to content

Commit

Permalink
Merge pull request #2 from paragonie/master
Browse files Browse the repository at this point in the history
Stricter content length in ASNObject
  • Loading branch information
frederikbosch authored Apr 29, 2024
2 parents 16ea71d + c6382e2 commit f21be41
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
9 changes: 8 additions & 1 deletion lib/ASN1/ASNObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,14 @@ protected static function parseContentLength(&$binaryData, &$offsetIndex, $minim
if (strlen($binaryData) <= $offsetIndex) {
throw new ParserException('Can not parse content length (long form) from data: Offset index larger than input size', $offsetIndex);
}
$contentLength = $contentLength->shiftLeft(8)->add(ord($binaryData[$offsetIndex++]));
$octet = ord($binaryData[$offsetIndex++]);
if ($i === 0 && $octet === 0) {
throw new ParserException('Content length cannot have leading zero bytes', $offsetIndex);
}
$contentLength = $contentLength->shiftLeft(8)->add($octet);
}
if ($nrOfLengthOctets < 2 && $contentLength->compare(0x80) < 0) {
throw new ParserException('Extended length used for short message', $offsetIndex);
}

if ($contentLength->compare(PHP_INT_MAX) > 0) {
Expand Down
3 changes: 3 additions & 0 deletions lib/ASN1/AbstractTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ abstract class AbstractTime extends ASNObject
public function __construct($dateTime = null, $dateTimeZone = 'UTC')
{
if ($dateTime == null || is_string($dateTime)) {
if (is_null($dateTime)) {
$dateTime = 'NOW';
}
$timeZone = new DateTimeZone($dateTimeZone);
$dateTimeObject = new DateTime($dateTime, $timeZone);
if ($dateTimeObject == false) {
Expand Down
16 changes: 13 additions & 3 deletions lib/ASN1/Universal/OctetString.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,25 @@ public function getType()

protected function calculateContentLength()
{
if (is_null($this->value)) {
return 0;
}
return strlen($this->value) / 2;
}

protected function getEncodedValue()
{
$value = $this->value;
if (is_null($value)) {
return '';
}
// This appears to expect hex strings but sometimes is populated by binary data
$result = '';

//Actual content
// Actual content
while (strlen($value) >= 2) {
// get the hex value byte by byte from the string and and add it to binary result
$result .= chr(hexdec(substr($value, 0, 2)));
// get the hex value byte by byte from the string and add it to binary result
$result .= @chr(hexdec(substr($value, 0, 2)));
$value = substr($value, 2);
}

Expand All @@ -67,6 +74,9 @@ protected function getEncodedValue()

public function getContent()
{
if (is_null($this->value)) {
return '';
}
return strtoupper($this->value);
}

Expand Down
16 changes: 16 additions & 0 deletions tests/ASN1/ObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,22 @@ public function testFromBinaryExceedsMaxInt()
ASNObject::fromBinary($bin);
}

public function testWithLeadingZeroes()
{
$this->expectException(ParserException::class);
$this->expectExceptionMessage("ASN.1 Parser Exception at offset 3: Content length cannot have leading zero bytes");
$bin = hex2bin('30820066023100814cc9a70febda342d4ada87fc39426f403d5e89808428460c1eca60c897bfd6728da14673854673d7d297ea944a15e202310084f5ef11d22f22d0548af6a50dbf2f6a1bb9054585af5e600c49cf35b1e69b712754dd781c837355ddd41c752193a7cd');
ASNObject::fromBinary($bin);
}

public function testExtendedFormShortLength()
{
$this->expectException(ParserException::class);
$this->expectExceptionMessage('ASN.1 Parser Exception at offset 3: Extended length used for short message');
$bin = hex2bin('30814502202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e18022100b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db');
ASNObject::fromBinary($bin);
}

/**
* @depends testFromBinary
*/
Expand Down

0 comments on commit f21be41

Please sign in to comment.