public function testGetBinary() { $tag = 0x1; $string = new PrintableString('test'); $expectedType = chr(Identifier::create(Identifier::CLASS_CONTEXT_SPECIFIC, $isConstructed = true, $tag)); $expectedLength = chr($string->getObjectLength()); $encodedStringObject = $string->getBinary(); $object = new ExplicitlyTaggedObject($tag, $string); $this->assertBinaryEquals($expectedType . $expectedLength . $encodedStringObject, $object->getBinary()); }
public function __construct($dateTime = null, $dateTimeZone = 'UTC') { if ($dateTime == null || is_string($dateTime)) { $timeZone = new DateTimeZone($dateTimeZone); $dateTimeObject = new DateTime($dateTime, $timeZone); if ($dateTimeObject == false) { $errorMessage = $this->getLastDateTimeErrors(); $className = Identifier::getName($this->getType()); throw new Exception(sprintf("Could not create %s from date time string '%s': %s", $className, $dateTime, $errorMessage)); } $dateTime = $dateTimeObject; } elseif (!$dateTime instanceof DateTime) { throw new Exception('Invalid first argument for some instance of ASN_AbstractTime constructor'); } $this->value = $dateTime; }
function printObject(Object $object, $depth = 0) { $treeSymbol = ''; $depthString = str_repeat('─', $depth); if ($depth > 0) { $treeSymbol = '├'; } $name = Identifier::getShortName($object->getType()); echo "{$treeSymbol}{$depthString}{$name} : "; echo $object->__toString() . PHP_EOL; $content = $object->getContent(); if (is_array($content)) { foreach ($object as $child) { printObject($child, $depth + 1); } } }
function printObject(Object $object, $depth = 0) { $treeSymbol = ''; $depthString = str_repeat('━', $depth); if ($depth > 0) { $treeSymbol = '┣'; } $name = strtoupper(Identifier::getShortName($object->getType())); echo "{$treeSymbol}{$depthString}<b>{$name}</b> : "; echo $object->__toString() . '<br/>'; $content = $object->getContent(); if (is_array($content)) { foreach ($object as $child) { printObject($child, $depth + 1); } } }
public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $firstIdentifierOctet = ord($identifier); assert(Identifier::isContextSpecificClass($firstIdentifierOctet)); assert(Identifier::isConstructed($firstIdentifierOctet)); $tag = Identifier::getTagNumber($identifier); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $offsetIndexOfDecoratedObject = $offsetIndex; $decoratedObject = Object::fromBinary($binaryData, $offsetIndex); if ($decoratedObject->getObjectLength() != $contentLength) { throw new ParserException("Context-Specific explicitly tagged object [{$tag}] starting at offset {$offsetIndexOfDecoratedObject} is longer than allowed in the outer tag", $offsetIndexOfDecoratedObject); } $parsedObject = new self($tag, $decoratedObject); $parsedObject->setContentLength($contentLength); return $parsedObject; }
/** * @param OutputInterface $output * @param Object $object * @param int $depth * @return void * @throws \FG\ASN1\Exception\NotImplementedException */ private function printObject(OutputInterface $output, Object $object, $depth = 0) { $treeSymbol = ''; $depthString = str_repeat('─', $depth); if ($depth > 0) { $treeSymbol = '├'; } $name = Identifier::getShortName($object->getType()); $output->write("{$treeSymbol}{$depthString}<comment>{$name}</comment> : "); $output->writeln($object->__toString()); $content = $object->getContent(); if (is_array($content)) { foreach ($object as $child) { $this->printObject($output, $child, $depth + 1); } } }
function printObject(Object $object, $depth = 0) { $name = strtoupper(Identifier::getShortName($object->getType())); $treeSymbol = ''; $depthString = str_repeat('━', $depth); if ($depth > 0) { $treeSymbol = '┣'; $name = ' ' . $name; } echo "{$treeSymbol}{$depthString}{$name} : "; echo $object->__toString() . PHP_EOL; $content = $object->getContent(); if ($content instanceof Object) { printObject($content, $depth + 1); } elseif (is_array($content)) { foreach ($object as $child) { printObject($child, $depth + 1); } } }
protected static function parseIdentifier($identifierOctet, $expectedIdentifier, $offsetForExceptionHandling) { if (is_string($identifierOctet) || is_numeric($identifierOctet) == false) { $identifierOctet = ord($identifierOctet); } if ($identifierOctet != $expectedIdentifier) { $message = 'Can not create an ' . Identifier::getName($expectedIdentifier) . ' from an ' . Identifier::getName($identifierOctet); throw new ParserException($message, $offsetForExceptionHandling); } }
protected static function parseBinaryIdentifier($binaryData, &$offsetIndex) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse identifier from data: Offset index larger than input size', $offsetIndex); } $identifier = $binaryData[$offsetIndex++]; if (Identifier::isLongForm(ord($identifier)) == false) { return $identifier; } while (true) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse identifier (long form) from data: Offset index larger than input size', $offsetIndex); } $nextOctet = $binaryData[$offsetIndex++]; $identifier .= $nextOctet; if ((ord($nextOctet) & 0x80) === 0) { // the most significant bit is 0 to we have reached the end of the identifier break; } } return $identifier; }
public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $firstIdentifierOctet = ord($identifier); assert(Identifier::isContextSpecificClass($firstIdentifierOctet), 'identifier octet should indicate context specific class'); assert(Identifier::isConstructed($firstIdentifierOctet), 'identifier octet should indicate constructed object'); $tag = Identifier::getTagNumber($identifier); $totalContentLength = self::parseContentLength($binaryData, $offsetIndex); $remainingContentLength = $totalContentLength; $offsetIndexOfDecoratedObject = $offsetIndex; $decoratedObjects = []; while ($remainingContentLength > 0) { $nextObject = Object::fromBinary($binaryData, $offsetIndex); $remainingContentLength -= $nextObject->getObjectLength(); $decoratedObjects[] = $nextObject; } if ($remainingContentLength != 0) { throw new ParserException("Context-Specific explicitly tagged object [{$tag}] starting at offset {$offsetIndexOfDecoratedObject} specifies a length of {$totalContentLength} octets but {$remainingContentLength} remain after parsing the content", $offsetIndexOfDecoratedObject); } $parsedObject = new self($tag, ...$decoratedObjects); $parsedObject->setContentLength($totalContentLength); return $parsedObject; }
protected static function parseBinaryIdentifier($binaryData, &$offsetIndex) { $identifier = $binaryData[$offsetIndex++]; if (Identifier::isLongForm(ord($identifier)) == false) { return $identifier; } while (true) { $nextOctet = $binaryData[$offsetIndex++]; $identifier .= $nextOctet; if ((ord($nextOctet) & 0x80) === 0) { // the most significant bit is 0 to we have reached the end of the identifier break; } } return $identifier; }
protected function checkString() { $stringLength = $this->getContentLength(); for ($i = 0; $i < $stringLength; $i++) { if (in_array($this->value[$i], $this->allowedCharacters) == false) { $typeName = Identifier::getName($this->getType()); throw new Exception("Could not create a {$typeName} from the character sequence '{$this->value}'."); } } }
// (see ITU-T X.509 section 7 "Public-keys and public-key certificates" for cert structure) /* @var Sequence $rootObject */ assert($rootObject->getType() == Identifier::SEQUENCE); $topLevelContainer = $rootObject->getChildren(); $certificateInfo = $topLevelContainer[0]; /* @var Sequence $certificateInfo */ assert($certificateInfo->getType() == Identifier::SEQUENCE); // there need to be at least 8 child elements if the certificate extensions field is present assert($certificateInfo->getNumberofChildren() >= 8); $certInfoFields = $certificateInfo->getChildren(); $certExtensions = $certInfoFields[7]; // check if this is really the certificate extensions sequence /* @var \FG\ASN1\Object $certExtensions */ $certExtensionsType = $certExtensions->getType(); assert(Identifier::isContextSpecificClass($certExtensionsType)); assert(Identifier::getTagNumber($certExtensions->getType()) == 3); // this should contain a sequence of extensions $certExtensions = $certExtensions->getFirstChild(); assert($certExtensions->getType() == Identifier::SEQUENCE); // now check all extensions and search for the SAN /** @var \FG\ASN1\Object $extensionSequence */ foreach ($certExtensions as $extensionSequence) { assert($extensionSequence->getType() == Identifier::SEQUENCE); assert($extensionSequence->getNumberofChildren() >= 2); $extensionSequenceChildren = $extensionSequence->getChildren(); $objectIdentifier = $extensionSequenceChildren[0]; /* @var ObjectIdentifier $objectIdentifier */ assert($objectIdentifier->getType() == Identifier::OBJECT_IDENTIFIER); if ($objectIdentifier->getContent() == OID::CERT_EXT_SUBJECT_ALT_NAME) { // now we have the wanted octet string $octetString = $extensionSequenceChildren[1];