From 19985dbb8c0aa66dc4bf7905abc1148de909097d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Tue, 11 Jan 2022 12:35:47 +0100 Subject: prvi-commit --- .../fgrosse/phpasn1/lib/ASN1/Universal/Integer.php | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 vendor/fgrosse/phpasn1/lib/ASN1/Universal/Integer.php (limited to 'vendor/fgrosse/phpasn1/lib/ASN1/Universal/Integer.php') diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Integer.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Integer.php new file mode 100644 index 0000000..fe3806b --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Integer.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use Exception; +use FG\Utility\BigInteger; +use FG\ASN1\Exception\ParserException; +use FG\ASN1\ASNObject; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; + +class Integer extends ASNObject implements Parsable +{ + /** @var int */ + private $value; + + /** + * @param int $value + * + * @throws Exception if the value is not numeric + */ + public function __construct($value) + { + if (is_numeric($value) == false) { + throw new Exception("Invalid VALUE [{$value}] for ASN1_INTEGER"); + } + $this->value = $value; + } + + public function getType() + { + return Identifier::INTEGER; + } + + public function getContent() + { + return $this->value; + } + + protected function calculateContentLength() + { + return strlen($this->getEncodedValue()); + } + + protected function getEncodedValue() + { + $value = BigInteger::create($this->value, 10); + $negative = $value->compare(0) < 0; + if ($negative) { + $value = $value->absoluteValue(); + $limit = 0x80; + } else { + $limit = 0x7f; + } + + $mod = 0xff+1; + $values = []; + while($value->compare($limit) > 0) { + $values[] = $value->modulus($mod)->toInteger(); + $value = $value->shiftRight(8); + } + + $values[] = $value->modulus($mod)->toInteger(); + $numValues = count($values); + + if ($negative) { + for ($i = 0; $i < $numValues; $i++) { + $values[$i] = 0xff - $values[$i]; + } + for ($i = 0; $i < $numValues; $i++) { + $values[$i] += 1; + if ($values[$i] <= 0xff) { + break; + } + assert($i != $numValues - 1); + $values[$i] = 0; + } + if ($values[$numValues - 1] == 0x7f) { + $values[] = 0xff; + } + } + $values = array_reverse($values); + $r = pack("C*", ...$values); + return $r; + } + + private static function ensureMinimalEncoding($binaryData, $offsetIndex) + { + // All the first nine bits cannot equal 0 or 1, which would + // be non-minimal encoding for positive and negative integers respectively + if ((ord($binaryData[$offsetIndex]) == 0x00 && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0) || + (ord($binaryData[$offsetIndex]) == 0xff && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0x80)) { + throw new ParserException("Integer not minimally encoded", $offsetIndex); + } + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + $parsedObject = new static(0); + self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); + + if ($contentLength > 1) { + self::ensureMinimalEncoding($binaryData, $offsetIndex); + } + $isNegative = (ord($binaryData[$offsetIndex]) & 0x80) != 0x00; + $number = BigInteger::create(ord($binaryData[$offsetIndex++]) & 0x7F); + + for ($i = 0; $i < $contentLength - 1; $i++) { + $number = $number->multiply(0x100)->add(ord($binaryData[$offsetIndex++])); + } + + if ($isNegative) { + $number = $number->subtract(BigInteger::create(2)->toPower(8 * $contentLength - 1)); + } + + $parsedObject = new static((string)$number); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} -- cgit v1.2.3