Submit
Path:
~
/
/
usr
/
local
/
psa
/
admin
/
plib
/
modules
/
platform360
/
vendor
/
spomky-labs
/
pki-framework
/
src
/
ASN1
/
Component
/
File Content:
Length.php
<?php declare (strict_types=1); namespace Platform360\SpomkyLabs\Pki\ASN1\Component; use Platform360\Brick\Math\BigInteger; use DomainException; use LogicException; use Platform360\SpomkyLabs\Pki\ASN1\Exception\DecodeException; use Platform360\SpomkyLabs\Pki\ASN1\Feature\Encodable; use Platform360\SpomkyLabs\Pki\ASN1\Util\BigInt; use function count; use function mb_strlen; use function ord; use function sprintf; /** * Class to represent BER/DER length octets. */ final class Length implements Encodable { /** * Length. */ private readonly BigInt $_length; /** * @param BigInteger|int $length Length * @param bool $_indefinite Whether length is indefinite */ private function __construct(BigInteger|int $length, private readonly bool $_indefinite = \false) { $this->_length = BigInt::create($length); } public static function create(BigInteger|int $length, bool $_indefinite = \false) : self { return new self($length, $_indefinite); } /** * Decode length component from DER data. * * @param string $data DER encoded data * @param null|int $offset Reference to the variable that contains offset * into the data where to start parsing. * Variable is updated to the offset next to the * parsed length component. If null, start from offset 0. */ public static function fromDER(string $data, ?int &$offset = null) : self { $idx = $offset ?? 0; $datalen = mb_strlen($data, '8bit'); if ($idx >= $datalen) { throw new DecodeException('Unexpected end of data while decoding length.'); } $indefinite = \false; $byte = ord($data[$idx++]); // bits 7 to 1 $length = 0x7f & $byte; // long form if ((0x80 & $byte) !== 0) { if ($length === 0) { $indefinite = \true; } else { if ($idx + $length > $datalen) { throw new DecodeException('Unexpected end of data while decoding long form length.'); } $length = self::decodeLongFormLength($length, $data, $idx); } } if (isset($offset)) { $offset = $idx; } return self::create($length, $indefinite); } /** * Decode length from DER. * * Throws an exception if length doesn't match with expected or if data doesn't contain enough bytes. * * Requirement of definite length is relaxed contrary to the specification (sect. 10.1). * * @param string $data DER data * @param int $offset Reference to the offset variable * @param null|int $expected Expected length, null to bypass checking * @see self::fromDER */ public static function expectFromDER(string $data, int &$offset, ?int $expected = null) : self { $idx = $offset; $length = self::fromDER($data, $idx); // if certain length was expected if (isset($expected)) { if ($length->isIndefinite()) { throw new DecodeException(sprintf('Expected length %d, got indefinite.', $expected)); } if ($expected !== $length->intLength()) { throw new DecodeException(sprintf('Expected length %d, got %d.', $expected, $length->intLength())); } } // check that enough data is available if (!$length->isIndefinite() && mb_strlen($data, '8bit') < $idx + $length->intLength()) { throw new DecodeException(sprintf('Length %d overflows data, %d bytes left.', $length->intLength(), mb_strlen($data, '8bit') - $idx)); } $offset = $idx; return $length; } public function toDER() : string { $bytes = []; if ($this->_indefinite) { $bytes[] = 0x80; } else { $num = $this->_length->getValue(); // long form if ($num->isGreaterThan(127)) { $octets = []; for (; $num->isGreaterThan(0); $num = $num->shiftedRight(8)) { $octets[] = BigInteger::of(0xff)->and($num)->toInt(); } $count = count($octets); // first octet must not be 0xff if ($count >= 127) { throw new DomainException('Too many length octets.'); } $bytes[] = 0x80 | $count; foreach (\array_reverse($octets) as $octet) { $bytes[] = $octet; } } else { $bytes[] = $num->toInt(); } } return \pack('C*', ...$bytes); } /** * Get the length. * * @return string Length as an integer string */ public function length() : string { if ($this->_indefinite) { throw new LogicException('Length is indefinite.'); } return $this->_length->base10(); } /** * Get the length as an integer. */ public function intLength() : int { if ($this->_indefinite) { throw new LogicException('Length is indefinite.'); } return $this->_length->toInt(); } /** * Whether length is indefinite. */ public function isIndefinite() : bool { return $this->_indefinite; } /** * Decode long form length. * * @param int $length Number of octets * @param string $data Data * @param int $offset reference to the variable containing offset to the data */ private static function decodeLongFormLength(int $length, string $data, int &$offset) : BigInteger { // first octet must not be 0xff (spec 8.1.3.5c) if ($length === 127) { throw new DecodeException('Invalid number of length octets.'); } $num = BigInteger::of(0); while (--$length >= 0) { $byte = ord($data[$offset++]); $num = $num->shiftedLeft(8)->or($byte); } return $num; } }
Edit
Rename
Chmod
Delete
FILE
FOLDER
INFO
Name
Size
Permission
Action
Identifier.php
7041 bytes
0644
Length.php
6098 bytes
0644
N4ST4R_ID | Naxtarrr