private function assertTypeId($expectedTypeId, Object $object) { $actualType = $object->getType(); if ($expectedTypeId != $actualType) { throw new Exception("Expected type ({$expectedTypeId}) does not match actual type ({$actualType}"); } }
public function testREADME_decoding() { $base64String = 'MBgCAwHiQAEB/woBARYLSGVsbG8gd29ybGQxODAYAgMB4kABAf8KAQEWC0hlbGxvIHdvcmxkBQAGBiqBegEQCQYJKoZIhvcNAQEBEwdGb28gYmFy'; $binaryData = base64_decode($base64String); $asnObject = Object::fromBinary($binaryData); $this->assertInstanceOf(Sequence::class, $asnObject); }
/** * @param array $children * * @return array */ private function loadPKCS8(array $children) { $binary = hex2bin($children[2]->getContent()); $asnObject = Object::fromBinary($binary); Assertion::isInstanceOf($asnObject, Sequence::class); return $asnObject->getChildren(); }
public function __construct(Identifier $identifier, ContentLength $contentLength, Content $content, array $children = []) { parent::__construct($identifier, $contentLength, $content, $children); if (!$this->identifier->isConstructed) { $this->setValue($content); } }
/** * @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) { $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); } } }
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) { $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); } } }
/** * @param \Jose\Object\JWKInterface $key * @param string $data * * @return string */ private function getOpenSSLSignature(JWKInterface $key, $data) { $pem = (new ECKey($key))->toPEM(); $result = openssl_sign($data, $signature, $pem, $this->getHashAlgorithm()); Assertion::true($result, 'Signature failed'); $asn = Object::fromBinary($signature); Assertion::isInstanceOf($asn, Sequence::class, 'Invalid signature'); $res = ''; foreach ($asn->getChildren() as $child) { Assertion::isInstanceOf($child, Integer::class, 'Invalid signature'); $res .= str_pad($this->convertDecToHex($child->getContent()), $this->getSignaturePartLength(), '0', STR_PAD_LEFT); } return $this->convertHexToBin($res); }
/** * @param $data * * @throws \Exception * @throws \FG\ASN1\Exception\ParserException * * @return array */ private function loadPEM($data) { $data = base64_decode(preg_replace('#-.*-|\\r|\\n#', '', $data)); $asnObject = Object::fromBinary($data); if (!$asnObject instanceof Sequence) { throw new \Exception('Unable to load the key'); } $children = $asnObject->getChildren(); if (4 === count($children)) { return $this->loadPrivatePEM($children); } elseif (2 === count($children)) { return $this->loadPublicPEM($children); } throw new \Exception('Unable to load the key'); }
public function parse($binaryData) { $asnObject = Object::fromBinary($binaryData); if (!$asnObject instanceof Sequence || $asnObject->getNumberofChildren() != 2) { throw new \RuntimeException('Invalid data.'); } $children = $asnObject->getChildren(); $oid = $children[0]->getChildren()[0]; $curveOid = $children[0]->getChildren()[1]; $encodedKey = $children[1]; if ($oid->getContent() !== DerPublicKeySerializer::X509_ECDSA_OID) { throw new \RuntimeException('Invalid data: non X509 data.'); } $generator = CurveOidMapper::getGeneratorFromOid($curveOid); return $this->parseKey($generator, $encodedKey->getContent()); }
/** * @param string $data * {@inheritDoc} * @see \Mdanter\Ecc\Serializer\PrivateKeySerializerInterface::parse() * @throws \FG\ASN1\Exception\ParserException */ public function parse($data) { $asnObject = Object::fromBinary($data); if (!$asnObject instanceof Sequence || $asnObject->getNumberofChildren() !== 4) { throw new \RuntimeException('Invalid data.'); } $children = $asnObject->getChildren(); $version = $children[0]; if ($version->getContent() != 1) { throw new \RuntimeException('Invalid data: only version 1 (RFC5915) keys are supported.'); } $key = $this->adapter->hexDec($children[1]->getContent()); $oid = $children[2]->getContent(); $generator = CurveOidMapper::getGeneratorFromOid($oid); return $generator->getPrivateKeyFrom($key); }
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 string $binary * @return Signature * @throws \FG\ASN1\Exception\ParserException */ public function parse($binary) { $object = Object::fromBinary($binary); if ($object->getType() !== Identifier::SEQUENCE) { throw new \RuntimeException('Failed to parse signature'); } $content = $object->getContent(); if (count($content) !== 2) { throw new \RuntimeException('Failed to parse signature'); } /** @var \FG\ASN1\Universal\Integer $r */ /** @var \FG\ASN1\Universal\Integer $s */ list($r, $s) = $content; if ($r->getType() !== Identifier::INTEGER || $s->getType() !== Identifier::INTEGER) { throw new \RuntimeException('Failed to parse signature'); } return new Signature($r->getContent(), $s->getContent()); }
/** * @param string $binaryData * @param int $offsetIndex * * @throws \FG\ASN1\Exception\ParserException */ public function __construct($binaryData, &$offsetIndex) { $startPos = $offsetIndex - 2; $this->identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $children = []; $octetsToRead = $this->contentLength; while ($octetsToRead > 0) { $newChild = Object::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } $children = []; if (null != $contentLength) { $octetsToRead = $contentLength; while ($octetsToRead > 0) { $newChild = Object::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } } else { /*try {*/ for (;;) { $newChild = Object::fromBinary($binaryData, $offsetIndex); if ($newChild instanceof EOC) { break; } $children[] = $newChild; } $contentLength = abs($startPos - $offsetIndex); // undefined lengths are represented as negative values /* } catch (\Exception $e) { $e->getMessage(); }*/ } $this->contentLength = $contentLength; parent::__construct(...$children); }
public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], 0xa0, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $octetsToRead = $contentLength; $parsedObject = new self(); while ($octetsToRead > 0) { $initialOffset = $offsetIndex; // used to calculate how much bits have been read self::parseIdentifier($binaryData[$offsetIndex], Identifier::SEQUENCE, $offsetIndex++); self::parseContentLength($binaryData, $offsetIndex); $objectIdentifier = ObjectIdentifier::fromBinary($binaryData, $offsetIndex); $oidString = $objectIdentifier->getContent(); if ($oidString == OID::PKCS9_EXTENSION_REQUEST) { $attribute = CertificateExtensions::fromBinary($binaryData, $offsetIndex); } else { $attribute = Object::fromBinary($binaryData, $offsetIndex); } $parsedObject->addAttribute($objectIdentifier, $attribute); $octetsToRead -= $offsetIndex - $initialOffset; } $parsedObject->setContentLength($contentLength); return $parsedObject; }
/** * @param string $binaryData * @param int $offsetIndex * * @throws Exception\ParserException * * @return Construct|static */ public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(); self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $children = []; $octetsToRead = $contentLength; while ($octetsToRead > 0) { $newChild = Object::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } $parsedObject->addChildren($children); $parsedObject->setContentLength($contentLength); return $parsedObject; }
/** * @param $binaryData * @param int $offsetIndex * @param Identifier $identifier * @param ContentLength $contentLength * @return Object[] * @throws ParserException */ public static function parseChildren(&$binaryData, &$offsetIndex = 0, ContentLength $contentLength) { $children = []; if (!is_nan($contentLength->length)) { $octetsToRead = $contentLength->length; while ($octetsToRead > 0) { $newChild = Object::fromBinary($binaryData, $offsetIndex); if (is_null($newChild)) { throw new ParserException('Children not found', $offsetIndex); } $octetsToRead -= $newChild->contentLength->length + strlen($newChild->identifier->binaryData) + strlen($newChild->contentLength->binaryData); $children[] = $newChild; } } else { /*try {*/ for (;;) { $newChild = Object::fromBinary($binaryData, $offsetIndex); if ($newChild instanceof EOC) { break; } $children[] = $newChild; } } return $children; }
<?php /* * This file is part of the PHPASN1 library. * * Copyright © Friedrich Große <*****@*****.**> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ use FG\ASN1\Object; require_once __DIR__ . '/../vendor/autoload.php'; require_once 'shared.php'; $hex = 'a02b302906092a864886f70d01090e311c301a30180603551d110411300f820d636f72766573706163652e6465'; $asn = Object::fromBinary(hex2bin($hex)); printObject($asn);
/** * @expectedException \FG\ASN1\Exception\ParserException * @expectedExceptionMessage ASN.1 Parser Exception at offset 10: Can not parse binary from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryThrowsException() { $binaryData = 0x0; $offset = 10; Object::fromBinary($binaryData, $offset); }
public function __construct(Identifier $identifier, ContentLength $contentLength, Content $content, array $children) { parent::__construct($identifier, $contentLength, $content, $children); $this->value = $content->binaryData; }
/** * @param string $binaryData * @param int $offsetIndex * * @throws Exception\ParserException * * @return Construct|static */ public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(); $startPos = $offsetIndex; self::parseBinaryIdentifier($binaryData, $offsetIndex); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $children = []; if (null != $contentLength) { $octetsToRead = $contentLength; while ($octetsToRead > 0) { $newChild = Object::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } } else { /*try {*/ for (;;) { $newChild = Object::fromBinary($binaryData, $offsetIndex); if ($newChild instanceof EOC) { break; } $children[] = $newChild; } $contentLength = abs($startPos - $offsetIndex); // undefined lengths are represented as negative values /* } catch (\Exception $e) { $e->getMessage(); }*/ } $parsedObject->addChildren($children); $parsedObject->setContentLength($contentLength); return $parsedObject; }
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; }
BgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU5nEIMEUT5mMd1WepmviwgK7dIzww GQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB /wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAKZl6bAeaID3b/ic4aztL8ZZI7vi D3A9otUKx6v1Xe63zDPR+DiWSnxb9m+l8OPtnWkcLkzEIM/IMWorHKUAJ/J871D0 Qx+0/HbkcrjMtVu/dNrtb9Z9CXup66ZvxTPcpEziq0/n2yw8QdBaa+lli65Qcwcy tzMQK6WQTRYfvVCIX9AKcPKxwx1DLH+7hL/bERB1lUDu59Jx6fQfqJrFVOY2N8c0 MGvurfoHGmEoyCMIyvmIMu4+/wSNEE/sSDp4lZ6zuF6rf1m0GiLdTX2XJE+gfvep JTFmp4S3WFqkszKvaxBIT+jV0XKTNDwnO+dpExwU4jZUh18CdEFkIUuQb0gFF8B7 WJFVpNdsRqZRPBz83BW1Kjo0yAmaoTrGNmG0p6Qf3K2zbk1+Jik3VZq4rvKoTi20 6RvLA2//cMNfkYPsuqvoHGe2e0GOLtIB63wJzloWROpb72ohEHsvCKullIJVSuiS 9sfTBAenHCyndgAEd4T3npTUdaiNumVEm5ilZId7LAYekJhkgFu3vlcl8blBJKjE skVTp7JpBmdXCL/G/6H2SFjca4JMOAy3DxwlGdgneIaXazHs5nBK/BgKPIyPzZ4w secxBTTCNgI48YezK3GDkn65cmlnkt6F6Mf0MwoDaXTuB88Jycbwb5ihKnHEJIsO draiRBZruwMPwPIP'; $binaryData = base64_decode($base64String); $asnObject = Object::fromBinary($binaryData); ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>PHPASN1 Examples</title> <meta name="description" content="How to parse binary ASN.1 data with PHPASN1"> <meta name="author" content="Friedrich Große"> </head> <body> <p>Got <?php echo strlen($binaryData); ?> byte of binary data: </p>
BgEFBQcwAYYcaHR0cDovL29jc3AuY2VydGlzaWduLmNvbS5icjANBgkqhkiG9w0B AQsFAAOCAgEAyfdKIKDLGZyOhAsycAgJ7RZyn4/2tN29bd+rLwtkvp/9XJGRCAob fkLU8UACGzbVHT/bB7sOKIiHvp8CgGyoU/1veo5a1yGMFQobQWGcdEYBOd+6Ax6U FEOc+Ti+LsXsUA5tRbzTwfXJFFOIgFDgrXl7V4JGjSI3GdyoiEECR9OfM/UFYtr/ pD194Xh6G0lSCuP9xOKpOJ7qk24mcfObcGxooMxmktkt0bevzx5w84RtXJfbube+ p6o7JP06T6JJTGfIUfNKYU8wJ6CV9eUHEMDLHMoH6wnYK7d8rHcAbSoTJGMFlSYZ OqJrWAbKAPjraFNeNaH675u//Ck127kJVidcuRwtkLZV/OIlQaw/4QSp90QWQOQg AsOWC9+h8v/RcCYTJpWM22MCq3Xk67nz+mXO8e7LKpzHEh2sjX3gkfw4h80zYfT7 kTsNXVdxAHXiIahKNeRUT8fGhxvyOA0RqAXQBUaOyLyGYWRJ7Is5IqAAU6XiBHYe oJ3v8BTGYzIK2Ud5dZ23yzBp2ejdQzQX1ETpJoEdgELToHmfBXTkI+7ne59wSRkH beQXoK5y0U3gh1vIz/53GG0QMuCvq9r9xTMERcFJcpQUxJ2RjwxIFHlIFbNwCeiW I3DmZaXdR169kRoPIqkV3QIREs/yHBvkxXrwDt416stUnQ8KsxAEatE='; try { $binaryData = base64_decode($base64); //hexdump($binaryData, false); $rootObject = Object::fromBinary($binaryData); //printObject($rootObject); // first navigate to the certificate extensions // (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 */
public function __construct(Identifier $identifier, ContentLength $contentLength, Content $content, array $children = []) { parent::__construct($identifier, $contentLength, $content, $children); }
KnpsUiNLmQN3HSn9dwk9rCHulrP8LL97l//H2KSCvOvSfk1XeN7ADSyWMC6ZPBD/ 7WVnQo7GgMAA0Qhz+nIIFA5AyuFEbRiff+L5EEl+Bg6R9tgx+QUt9JXxF260dkAb iKBmPcJldl2/GEmz6RAXhMwJnN35tbdzw0LVLzsypr0CAwEAAaAsMBMGCSqGSIb3 DQEJAjEGDAR0ZXN0MBUGCSqGSIb3DQEJBzEIDAYxMjM0NTYwDQYJKoZIhvcNAQEF BQADggEBACqZ5+3GP7QbTJAqnUloMRBJGYZl0/EyW6dAMoq7E+RiR2OlJGXgP+ga DPv7Wa4jZiYmf2CZCWKP+WvTvcg4AQq5h7hhAN+u+s8kk0lIjYjnkKRAedGYKDUO fPD9WowISru3RB1xyxlvgeZS6WoA6TD8REVa1UyFoNzUewvsrNVkKSHh1xk/+ePx 2Ovvrcg9pAWY4K8FvMRdFQKnEud9CAoMxqz3kszhxDW6rcr2mgFPSrKi5WNj+Scg Tqod8xbB753JWjEbG6Hui9LIMihTX3ZJ0c2GB0buhEgz49y83X/byFHSGGSQpzxX qXDFVov9UZ+sGy8CJ5ahII79yrfKpxY= '; try { echo 'Input 1:' . PHP_EOL; printObject(Object::fromBinary(base64_decode($input1))); } catch (Exception $exception) { echo "ERROR: " . $exception->getMessage(); } echo PHP_EOL; try { echo 'Input 2:' . PHP_EOL; printObject(Object::fromBinary(base64_decode($input2))); } catch (Exception $exception) { echo "ERROR: " . $exception->getMessage(); } echo PHP_EOL; try { echo 'Input 3:' . PHP_EOL; printObject(Object::fromBinary(base64_decode($input3))); } catch (Exception $exception) { echo "ERROR: " . $exception->getMessage(); }
/** * @param string $certificate * @return Certificate * @throws \Exception * @throws \FG\ASN1\Exception\ParserException */ public function parse($certificate) { $certificate = str_replace(CertificateSerializer::HEADER, '', $certificate); $certificate = str_replace(CertificateSerializer::FOOTER, '', $certificate); $binary = base64_decode($certificate); $asnObject = Object::fromBinary($binary); if (!$asnObject instanceof Sequence || $asnObject->getNumberOfChildren() !== 3) { throw new \InvalidArgumentException('Invalid data.'); } // Parse Certificate Info $children = $asnObject->getChildren(); if (!$children[0] instanceof Sequence) { throw new \InvalidArgumentException('Invalid data: certificate info'); } $info = $this->parseCertificateInfo($children[0]); // Parse Signature Algorithm $sigSection = $children[1]; if (!$sigSection instanceof Sequence) { throw new \Exception('Invaid sig algo section'); } $sigAlg = $this->parseSigAlg($sigSection); // Parse Signature if (!$children[2] instanceof BitString) { throw new \Exception('Invalid signature'); } $signature = $this->sigSer->parse(hex2bin($children[2]->getContent())); return new Certificate($info, $sigAlg, $signature); }
/** * @param \FG\ASN1\Object $children * * @throws \Exception * * @return string */ private function getD(Object $children) { if (!$children instanceof OctetString) { throw new \Exception('Unable to load the key'); } return $children->getContent(); }