diff options
Diffstat (limited to 'vendor/fgrosse/phpasn1/lib/ASN1/Universal')
24 files changed, 1338 insertions, 0 deletions
diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BMPString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BMPString.php new file mode 100644 index 0000000..83ec6a9 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BMPString.php @@ -0,0 +1,41 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class BMPString extends AbstractString +{ + /** + * Creates a new ASN.1 BMP String. + * + * BMPString is a subtype of UniversalString that has its own + * unique tag and contains only the characters in the + * Basic Multilingual Plane (those corresponding to the first + * 64K-2 cells, less cells whose encoding is used to address + * characters outside the Basic Multilingual Plane) of ISO/IEC 10646-1. + * + * TODO The encodable characters of this type are not yet checked. + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::BMP_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BitString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BitString.php new file mode 100644 index 0000000..226695c --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/BitString.php @@ -0,0 +1,88 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * 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\ASN1\Exception\ParserException; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; + +class BitString extends OctetString implements Parsable +{ + private $nrOfUnusedBits; + + /** + * Creates a new ASN.1 BitString object. + * + * @param string|int $value Either the hexadecimal value as a string (spaces are allowed - leading 0x is optional) or a numeric value + * @param int $nrOfUnusedBits the number of unused bits in the last octet [optional]. + * + * @throws Exception if the second parameter is no positive numeric value + */ + public function __construct($value, $nrOfUnusedBits = 0) + { + parent::__construct($value); + + if (!is_numeric($nrOfUnusedBits) || $nrOfUnusedBits < 0) { + throw new Exception('BitString: second parameter needs to be a positive number (or zero)!'); + } + + $this->nrOfUnusedBits = $nrOfUnusedBits; + } + + public function getType() + { + return Identifier::BITSTRING; + } + + protected function calculateContentLength() + { + // add one to the length for the first octet which encodes the number of unused bits in the last octet + return parent::calculateContentLength() + 1; + } + + protected function getEncodedValue() + { + // the first octet determines the number of unused bits + $nrOfUnusedBitsOctet = chr($this->nrOfUnusedBits); + $actualContent = parent::getEncodedValue(); + + return $nrOfUnusedBitsOctet.$actualContent; + } + + public function getNumberOfUnusedBits() + { + return $this->nrOfUnusedBits; + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::BITSTRING, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex, 2); + + $nrOfUnusedBits = ord($binaryData[$offsetIndex]); + $value = substr($binaryData, $offsetIndex + 1, $contentLength - 1); + + if ($nrOfUnusedBits > 7 || // no less than 1 used, otherwise non-minimal + ($contentLength - 1) == 1 && $nrOfUnusedBits > 0 || // content length only 1, no + (ord($value[strlen($value)-1])&((1<<$nrOfUnusedBits)-1)) != 0 // unused bits set + ) { + throw new ParserException("Can not parse bit string with invalid padding", $offsetIndex); + } + + $offsetIndex += $contentLength; + + $parsedObject = new self(bin2hex($value), $nrOfUnusedBits); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Boolean.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Boolean.php new file mode 100644 index 0000000..b73c99f --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Boolean.php @@ -0,0 +1,75 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\ASNObject; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +class Boolean extends ASNObject implements Parsable +{ + private $value; + + /** + * @param bool $value + */ + public function __construct($value) + { + $this->value = $value; + } + + public function getType() + { + return Identifier::BOOLEAN; + } + + protected function calculateContentLength() + { + return 1; + } + + protected function getEncodedValue() + { + if ($this->value == false) { + return chr(0x00); + } else { + return chr(0xFF); + } + } + + public function getContent() + { + if ($this->value == true) { + return 'TRUE'; + } else { + return 'FALSE'; + } + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::BOOLEAN, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex); + + if ($contentLength != 1) { + throw new ParserException("An ASN.1 Boolean should not have a length other than one. Extracted length was {$contentLength}", $offsetIndex); + } + + $value = ord($binaryData[$offsetIndex++]); + $booleanValue = $value == 0xFF ? true : false; + + $parsedObject = new self($booleanValue); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/CharacterString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/CharacterString.php new file mode 100644 index 0000000..bfc170d --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/CharacterString.php @@ -0,0 +1,28 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class CharacterString extends AbstractString +{ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::CHARACTER_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Enumerated.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Enumerated.php new file mode 100644 index 0000000..06d04a3 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Enumerated.php @@ -0,0 +1,21 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\Identifier; + +class Enumerated extends Integer +{ + public function getType() + { + return Identifier::ENUMERATED; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralString.php new file mode 100644 index 0000000..fb0346f --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralString.php @@ -0,0 +1,34 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class GeneralString extends AbstractString +{ + /** + * Creates a new ASN.1 GeneralString. + * TODO The encodable characters of this type are not yet checked. + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::GENERAL_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralizedTime.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralizedTime.php new file mode 100644 index 0000000..ca92209 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GeneralizedTime.php @@ -0,0 +1,134 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractTime; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +/** + * This ASN.1 universal type contains date and time information according to ISO 8601. + * + * The type consists of values representing: + * a) a calendar date, as defined in ISO 8601; and + * b) a time of day, to any of the precisions defined in ISO 8601, except for the hours value 24 which shall not be used; and + * c) the local time differential factor as defined in ISO 8601. + * + * Decoding of this type will accept the Basic Encoding Rules (BER) + * The encoding will comply with the Distinguished Encoding Rules (DER). + */ +class GeneralizedTime extends AbstractTime implements Parsable +{ + private $microseconds; + + public function __construct($dateTime = null, $dateTimeZone = 'UTC') + { + parent::__construct($dateTime, $dateTimeZone); + $this->microseconds = $this->value->format('u'); + if ($this->containsFractionalSecondsElement()) { + // DER requires us to remove trailing zeros + $this->microseconds = preg_replace('/([1-9]+)0+$/', '$1', $this->microseconds); + } + } + + public function getType() + { + return Identifier::GENERALIZED_TIME; + } + + protected function calculateContentLength() + { + $contentSize = 15; // YYYYMMDDHHmmSSZ + + if ($this->containsFractionalSecondsElement()) { + $contentSize += 1 + strlen($this->microseconds); + } + + return $contentSize; + } + + public function containsFractionalSecondsElement() + { + return intval($this->microseconds) > 0; + } + + protected function getEncodedValue() + { + $encodedContent = $this->value->format('YmdHis'); + if ($this->containsFractionalSecondsElement()) { + $encodedContent .= ".{$this->microseconds}"; + } + + return $encodedContent.'Z'; + } + + public function __toString() + { + if ($this->containsFractionalSecondsElement()) { + return $this->value->format("Y-m-d\tH:i:s.uP"); + } else { + return $this->value->format("Y-m-d\tH:i:sP"); + } + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::GENERALIZED_TIME, $offsetIndex++); + $lengthOfMinimumTimeString = 14; // YYYYMMDDHHmmSS + $contentLength = self::parseContentLength($binaryData, $offsetIndex, $lengthOfMinimumTimeString); + $maximumBytesToRead = $contentLength; + + $format = 'YmdGis'; + $content = substr($binaryData, $offsetIndex, $contentLength); + $dateTimeString = substr($content, 0, $lengthOfMinimumTimeString); + $offsetIndex += $lengthOfMinimumTimeString; + $maximumBytesToRead -= $lengthOfMinimumTimeString; + + if ($contentLength == $lengthOfMinimumTimeString) { + $localTimeZone = new \DateTimeZone(date_default_timezone_get()); + $dateTime = \DateTime::createFromFormat($format, $dateTimeString, $localTimeZone); + } else { + if ($binaryData[$offsetIndex] == '.') { + $maximumBytesToRead--; // account for the '.' + $nrOfFractionalSecondElements = 1; // account for the '.' + + while ($maximumBytesToRead > 0 + && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != '+' + && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != '-' + && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != 'Z') { + $nrOfFractionalSecondElements++; + $maximumBytesToRead--; + } + + $dateTimeString .= substr($binaryData, $offsetIndex, $nrOfFractionalSecondElements); + $offsetIndex += $nrOfFractionalSecondElements; + $format .= '.u'; + } + + $dateTime = \DateTime::createFromFormat($format, $dateTimeString, new \DateTimeZone('UTC')); + + if ($maximumBytesToRead > 0) { + if ($binaryData[$offsetIndex] == '+' + || $binaryData[$offsetIndex] == '-') { + $dateTime = static::extractTimeZoneData($binaryData, $offsetIndex, $dateTime); + } elseif ($binaryData[$offsetIndex++] != 'Z') { + throw new ParserException('Invalid ISO 8601 Time String', $offsetIndex); + } + } + } + + $parsedObject = new self($dateTime); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GraphicString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GraphicString.php new file mode 100644 index 0000000..4a01d67 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/GraphicString.php @@ -0,0 +1,34 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class GraphicString extends AbstractString +{ + /** + * Creates a new ASN.1 Graphic String. + * TODO The encodable characters of this type are not yet checked. + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::GRAPHIC_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/IA5String.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/IA5String.php new file mode 100644 index 0000000..33a8067 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/IA5String.php @@ -0,0 +1,35 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +/** + * The International Alphabet No.5 (IA5) references the encoding of the ASCII characters. + * + * Each character in the data is encoded as 1 byte. + */ +class IA5String extends AbstractString +{ + public function __construct($string) + { + parent::__construct($string); + for ($i = 1; $i < 128; $i++) { + $this->allowCharacter(chr($i)); + } + } + + public function getType() + { + return Identifier::IA5_STRING; + } +} 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 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * 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; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NullObject.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NullObject.php new file mode 100644 index 0000000..b5293e4 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NullObject.php @@ -0,0 +1,54 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\ASNObject; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +class NullObject extends ASNObject implements Parsable +{ + public function getType() + { + return Identifier::NULL; + } + + protected function calculateContentLength() + { + return 0; + } + + protected function getEncodedValue() + { + return null; + } + + public function getContent() + { + return 'NULL'; + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::NULL, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex); + + if ($contentLength != 0) { + throw new ParserException("An ASN.1 Null should not have a length other than zero. Extracted length was {$contentLength}", $offsetIndex); + } + + $parsedObject = new self(); + $parsedObject->setContentLength(0); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NumericString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NumericString.php new file mode 100644 index 0000000..13fb7c3 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/NumericString.php @@ -0,0 +1,38 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class NumericString extends AbstractString +{ + /** + * Creates a new ASN.1 NumericString. + * + * The following characters are permitted: + * Digits 0,1, ... 9 + * SPACE (space) + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowNumbers(); + $this->allowSpaces(); + } + + public function getType() + { + return Identifier::NUMERIC_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectDescriptor.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectDescriptor.php new file mode 100644 index 0000000..1c5d349 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectDescriptor.php @@ -0,0 +1,26 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\Identifier; + +class ObjectDescriptor extends GraphicString +{ + public function __construct($objectDescription) + { + parent::__construct($objectDescription); + } + + public function getType() + { + return Identifier::OBJECT_DESCRIPTOR; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectIdentifier.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectIdentifier.php new file mode 100644 index 0000000..150ce9c --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ObjectIdentifier.php @@ -0,0 +1,138 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * 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\ASN1\Base128; +use FG\ASN1\OID; +use FG\ASN1\ASNObject; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +class ObjectIdentifier extends ASNObject implements Parsable +{ + protected $subIdentifiers; + protected $value; + + public function __construct($value) + { + $this->subIdentifiers = explode('.', $value); + $nrOfSubIdentifiers = count($this->subIdentifiers); + + for ($i = 0; $i < $nrOfSubIdentifiers; $i++) { + if (is_numeric($this->subIdentifiers[$i])) { + // enforce the integer type + $this->subIdentifiers[$i] = intval($this->subIdentifiers[$i]); + } else { + throw new Exception("[{$value}] is no valid object identifier (sub identifier ".($i + 1).' is not numeric)!'); + } + } + + // Merge the first to arcs of the OID registration tree (per ASN definition!) + if ($nrOfSubIdentifiers >= 2) { + $this->subIdentifiers[1] = ($this->subIdentifiers[0] * 40) + $this->subIdentifiers[1]; + unset($this->subIdentifiers[0]); + } + + $this->value = $value; + } + + public function getContent() + { + return $this->value; + } + + public function getType() + { + return Identifier::OBJECT_IDENTIFIER; + } + + protected function calculateContentLength() + { + $length = 0; + foreach ($this->subIdentifiers as $subIdentifier) { + do { + $subIdentifier = $subIdentifier >> 7; + $length++; + } while ($subIdentifier > 0); + } + + return $length; + } + + protected function getEncodedValue() + { + $encodedValue = ''; + foreach ($this->subIdentifiers as $subIdentifier) { + $encodedValue .= Base128::encode($subIdentifier); + } + + return $encodedValue; + } + + public function __toString() + { + return OID::getName($this->value); + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::OBJECT_IDENTIFIER, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); + + $firstOctet = ord($binaryData[$offsetIndex++]); + $oidString = floor($firstOctet / 40).'.'.($firstOctet % 40); + $oidString .= '.'.self::parseOid($binaryData, $offsetIndex, $contentLength - 1); + + $parsedObject = new self($oidString); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } + + /** + * Parses an object identifier except for the first octet, which is parsed + * differently. This way relative object identifiers can also be parsed + * using this. + * + * @param $binaryData + * @param $offsetIndex + * @param $octetsToRead + * + * @throws ParserException + * + * @return string + */ + protected static function parseOid(&$binaryData, &$offsetIndex, $octetsToRead) + { + $oid = ''; + + while ($octetsToRead > 0) { + $octets = ''; + + do { + if (0 === $octetsToRead) { + throw new ParserException('Malformed ASN.1 Object Identifier', $offsetIndex - 1); + } + + $octetsToRead--; + $octet = $binaryData[$offsetIndex++]; + $octets .= $octet; + } while (ord($octet) & 0x80); + + $oid .= sprintf('%d.', Base128::decode($octets)); + } + + // Remove trailing '.' + return substr($oid, 0, -1) ?: ''; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/OctetString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/OctetString.php new file mode 100644 index 0000000..5d69ae7 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/OctetString.php @@ -0,0 +1,91 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * 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\ASN1\ASNObject; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; + +class OctetString extends ASNObject implements Parsable +{ + protected $value; + + public function __construct($value) + { + if (is_string($value)) { + // remove gaps between hex digits + $value = preg_replace('/\s|0x/', '', $value); + } elseif (is_numeric($value)) { + $value = dechex($value); + } elseif ($value === null) { + return; + } else { + throw new Exception('OctetString: unrecognized input type!'); + } + + if (strlen($value) % 2 != 0) { + // transform values like 1F2 to 01F2 + $value = '0'.$value; + } + + $this->value = $value; + } + + public function getType() + { + return Identifier::OCTETSTRING; + } + + protected function calculateContentLength() + { + return strlen($this->value) / 2; + } + + protected function getEncodedValue() + { + $value = $this->value; + $result = ''; + + //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))); + $value = substr($value, 2); + } + + return $result; + } + + public function getContent() + { + return strtoupper($this->value); + } + + public function getBinaryContent() + { + return $this->getEncodedValue(); + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::OCTETSTRING, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex); + + $value = substr($binaryData, $offsetIndex, $contentLength); + $offsetIndex += $contentLength; + + $parsedObject = new self(bin2hex($value)); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/PrintableString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/PrintableString.php new file mode 100644 index 0000000..fe6d4bc --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/PrintableString.php @@ -0,0 +1,53 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class PrintableString extends AbstractString +{ + /** + * Creates a new ASN.1 PrintableString. + * + * The ITU-T X.680 Table 8 permits the following characters: + * Latin capital letters A,B, ... Z + * Latin small letters a,b, ... z + * Digits 0,1, ... 9 + * SPACE (space) + * APOSTROPHE ' + * LEFT PARENTHESIS ( + * RIGHT PARENTHESIS ) + * PLUS SIGN + + * COMMA , + * HYPHEN-MINUS - + * FULL STOP . + * SOLIDUS / + * COLON : + * EQUALS SIGN = + * QUESTION MARK ? + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowNumbers(); + $this->allowAllLetters(); + $this->allowSpaces(); + $this->allowCharacters("'", '(', ')', '+', '-', '.', ',', '/', ':', '=', '?'); + } + + public function getType() + { + return Identifier::PRINTABLE_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/RelativeObjectIdentifier.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/RelativeObjectIdentifier.php new file mode 100644 index 0000000..2aa9643 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/RelativeObjectIdentifier.php @@ -0,0 +1,57 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * 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\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +class RelativeObjectIdentifier extends ObjectIdentifier implements Parsable +{ + public function __construct($subIdentifiers) + { + $this->value = $subIdentifiers; + $this->subIdentifiers = explode('.', $subIdentifiers); + $nrOfSubIdentifiers = count($this->subIdentifiers); + + for ($i = 0; $i < $nrOfSubIdentifiers; $i++) { + if (is_numeric($this->subIdentifiers[$i])) { + // enforce the integer type + $this->subIdentifiers[$i] = intval($this->subIdentifiers[$i]); + } else { + throw new Exception("[{$subIdentifiers}] is no valid object identifier (sub identifier ".($i + 1).' is not numeric)!'); + } + } + } + + public function getType() + { + return Identifier::RELATIVE_OID; + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::RELATIVE_OID, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); + + try { + $oidString = self::parseOid($binaryData, $offsetIndex, $contentLength); + } catch (ParserException $e) { + throw new ParserException('Malformed ASN.1 Relative Object Identifier', $e->getOffset()); + } + + $parsedObject = new self($oidString); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Sequence.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Sequence.php new file mode 100644 index 0000000..0397cf1 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Sequence.php @@ -0,0 +1,23 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\Construct; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; + +class Sequence extends Construct implements Parsable +{ + public function getType() + { + return Identifier::SEQUENCE; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Set.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Set.php new file mode 100644 index 0000000..6e6d346 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/Set.php @@ -0,0 +1,21 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\Identifier; + +class Set extends Sequence +{ + public function getType() + { + return Identifier::SET; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/T61String.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/T61String.php new file mode 100644 index 0000000..5641864 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/T61String.php @@ -0,0 +1,36 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class T61String extends AbstractString +{ + /** + * Creates a new ASN.1 T61 String. + * TODO The encodable characters of this type are not yet checked. + * + * @see http://en.wikipedia.org/wiki/ITU_T.61 + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::T61_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTCTime.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTCTime.php new file mode 100644 index 0000000..c4d303c --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTCTime.php @@ -0,0 +1,77 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractTime; +use FG\ASN1\Parsable; +use FG\ASN1\Identifier; +use FG\ASN1\Exception\ParserException; + +/** + * This ASN.1 universal type contains the calendar date and time. + * + * The precision is one minute or one second and optionally a + * local time differential from coordinated universal time. + * + * Decoding of this type will accept the Basic Encoding Rules (BER) + * The encoding will comply with the Distinguished Encoding Rules (DER). + */ +class UTCTime extends AbstractTime implements Parsable +{ + public function getType() + { + return Identifier::UTC_TIME; + } + + protected function calculateContentLength() + { + return 13; // Content is a string o the following format: YYMMDDhhmmssZ (13 octets) + } + + protected function getEncodedValue() + { + return $this->value->format('ymdHis').'Z'; + } + + public static function fromBinary(&$binaryData, &$offsetIndex = 0) + { + self::parseIdentifier($binaryData[$offsetIndex], Identifier::UTC_TIME, $offsetIndex++); + $contentLength = self::parseContentLength($binaryData, $offsetIndex, 11); + + $format = 'ymdGi'; + $dateTimeString = substr($binaryData, $offsetIndex, 10); + $offsetIndex += 10; + + // extract optional seconds part + if ($binaryData[$offsetIndex] != 'Z' + && $binaryData[$offsetIndex] != '+' + && $binaryData[$offsetIndex] != '-') { + $dateTimeString .= substr($binaryData, $offsetIndex, 2); + $offsetIndex += 2; + $format .= 's'; + } + + $dateTime = \DateTime::createFromFormat($format, $dateTimeString, new \DateTimeZone('UTC')); + + // extract time zone settings + if ($binaryData[$offsetIndex] == '+' + || $binaryData[$offsetIndex] == '-') { + $dateTime = static::extractTimeZoneData($binaryData, $offsetIndex, $dateTime); + } elseif ($binaryData[$offsetIndex++] != 'Z') { + throw new ParserException('Invalid UTC String', $offsetIndex); + } + + $parsedObject = new self($dateTime); + $parsedObject->setContentLength($contentLength); + + return $parsedObject; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTF8String.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTF8String.php new file mode 100644 index 0000000..cba568d --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UTF8String.php @@ -0,0 +1,34 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class UTF8String extends AbstractString +{ + /** + * Creates a new ASN.1 Universal String. + * TODO The encodable characters of this type are not yet checked. + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::UTF8_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UniversalString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UniversalString.php new file mode 100644 index 0000000..0c3fe1d --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/UniversalString.php @@ -0,0 +1,36 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class UniversalString extends AbstractString +{ + /** + * Creates a new ASN.1 Universal String. + * TODO The encodable characters of this type are not yet checked. + * + * @see http://en.wikipedia.org/wiki/Universal_Character_Set + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::UNIVERSAL_STRING; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/ASN1/Universal/VisibleString.php b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/VisibleString.php new file mode 100644 index 0000000..d9326d3 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/ASN1/Universal/VisibleString.php @@ -0,0 +1,34 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * Copyright © Friedrich Große <friedrich.grosse@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +use FG\ASN1\AbstractString; +use FG\ASN1\Identifier; + +class VisibleString extends AbstractString +{ + /** + * Creates a new ASN.1 Visible String. + * TODO The encodable characters of this type are not yet checked. + * + * @param string $string + */ + public function __construct($string) + { + $this->value = $string; + $this->allowAll(); + } + + public function getType() + { + return Identifier::VISIBLE_STRING; + } +} |