/** * @param ObjectIdentifier $oid * @return mixed * @throws \Exception */ public static function getKeyFromOid(ObjectIdentifier $oid) { $content = $oid->getContent(); $invertedMap = array_flip(self::$oidMap); if (array_key_exists($content, $invertedMap)) { return $invertedMap[$content]; } throw new \Exception('Unknown Certificate Subject Key Oid'); }
/** * @param ObjectIdentifier $oid * @return string */ public static function getNameByOid(ObjectIdentifier $oid) { $oidString = $oid->getContent(); $invertedMap = array_flip(self::$oidMap); if (array_key_exists($oidString, $invertedMap)) { return $invertedMap[$oidString]; } throw new \RuntimeException('Invalid data: unsupported cipher'); }
/** * @param ObjectIdentifier $oid * @return \Mdanter\Ecc\Primitives\GeneratorPoint */ public static function getGeneratorFromOid(ObjectIdentifier $oid) { $oidString = $oid->getContent(); $invertedMap = array_flip(self::$oidMap); if (array_key_exists($oidString, $invertedMap)) { return CurveFactory::getGeneratorByName($invertedMap[$oidString]); } throw new \RuntimeException('Invalid data: unsupported generator.'); }
/** * @param ObjectIdentifier $oid * @return string */ public static function getKnownAlgorithmFromOid(ObjectIdentifier $oid) { $oidString = $oid->getContent(); $supported = array_flip(self::$oidMap); $known = array_flip(self::$otherOidMap); $all = array_merge($supported, $known); if (array_key_exists($oidString, $all)) { return $all[$oidString]; } throw new \RuntimeException('Unsupported signature algorithm.'); }
/** * @param string $params * @return \Mdanter\Ecc\Curves\NamedCurveFp */ public function parse($params) { $params = str_replace(self::HEADER, '', $params); $params = str_replace(self::FOOTER, '', $params); $oid = ObjectIdentifier::fromBinary(base64_decode($params)); return CurveOidMapper::getCurveFromOid($oid); }
/** * @depends testFromBinary */ public function testFromBinaryWithOffset() { $objectIdentifier = new ObjectIdentifier(OID::CERT_EXT_SUBJECT_ALT_NAME); $originalObject1 = new CertificateExtensions(); $sans1 = new SubjectAlternativeNames(); $sans1->addDomainName(new DNSName('corvespace.de')); $sans1->addIP(new IPAddress('192.168.0.1')); $originalObject1->addSubjectAlternativeNames($sans1); $originalObject2 = new CertificateExtensions(); $sans2 = new SubjectAlternativeNames(); $sans2->addDomainName(new DNSName('google.com')); $originalObject2->addSubjectAlternativeNames($sans2); $binaryData = $originalObject1->getBinary(); $binaryData .= $originalObject2->getBinary(); $offset = 0; $parsedObject = CertificateExtensions::fromBinary($binaryData, $offset); $this->assertEquals($originalObject1, $parsedObject); $offsetAfterFirstObject = $sans1->getObjectLength() + $objectIdentifier->getObjectLength() + 2 + 2 + 2; $this->assertEquals($offsetAfterFirstObject, $offset); $parsedObject = CertificateExtensions::fromBinary($binaryData, $offset); $this->assertEquals($originalObject2, $parsedObject); $this->assertEquals($offsetAfterFirstObject + $sans2->getObjectLength() + $objectIdentifier->getObjectLength() + 2 + 2 + 2, $offset); }
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; }
public static function createObject($tagClass, $tagName, $isConstructed, $value, $lengthForm, $children = []) { $identifier = self::createIdentifier($tagClass, $tagName, $isConstructed); if ($identifier->tagClass === Identifier::CLASS_UNIVERSAL && $identifier->isConstructed === false) { //для простых элементов вызываем конструктор switch ($identifier->getTagNumber()) { case Identifier::BITSTRING: $value = Universal\BitString::encodeValue($value); break; case Identifier::BOOLEAN: $value = Universal\Boolean::encodeValue($value); break; case Identifier::ENUMERATED: $value = Universal\Enumerated::encodeValue($value); break; case Identifier::INTEGER: $value = Universal\Integer::encodeValue($value); break; case Identifier::NULL: $value = Universal\NullObject::encodeValue($value); break; case Identifier::OBJECT_IDENTIFIER: $value = Universal\ObjectIdentifier::encodeValue($value); break; case Identifier::OCTETSTRING: $value = Universal\OctetString::encodeValue($value); break; case Identifier::UTC_TIME: $value = Universal\UTCTime::encodeValue($value); break; case Identifier::GENERALIZED_TIME: $value = Universal\GeneralizedTime::encodeValue($value); break; case Identifier::IA5_STRING: $value = Universal\IA5String::encodeValue($value); break; case Identifier::PRINTABLE_STRING: $value = Universal\PrintableString::encodeValue($value); break; case Identifier::NUMERIC_STRING: $value = Universal\NumericString::encodeValue($value); break; case Identifier::UTF8_STRING: $value = Universal\UTF8String::encodeValue($value); break; case Identifier::UNIVERSAL_STRING: $value = Universal\UniversalString::encodeValue($value); break; case Identifier::CHARACTER_STRING: $value = Universal\CharacterString::encodeValue($value); break; case Identifier::GENERAL_STRING: $value = Universal\GeneralString::encodeValue($value); break; case Identifier::VISIBLE_STRING: $value = Universal\VisibleString::encodeValue($value); break; case Identifier::GRAPHIC_STRING: $value = Universal\GraphicString::encodeValue($value); break; case Identifier::BMP_STRING: $value = Universal\BMPString::encodeValue($value); break; case Identifier::T61_STRING: $value = Universal\T61String::encodeValue($value); break; case Identifier::OBJECT_DESCRIPTOR: $value = Universal\ObjectDescriptor::encodeValue($value); break; default: // At this point the identifier may be >1 byte. if ($identifier->isConstructed) { $value = UnknownConstructedObject::encodeValue($value); } else { $value = UnknownObject::encodeValue($value); } } } if ($children) { $contentOctets = ''; foreach ($children as $child) { $contentOctets .= $child->getBinary(); } } else { $contentOctets = $value; } $contentLength = self::createContentLength($contentOctets, $lengthForm); $content = new Content($contentOctets); if ($identifier->tagClass === Identifier::CLASS_UNIVERSAL) { //для простых элементов вызываем конструктор switch ($identifier->getTagNumber()) { case Identifier::BITSTRING: return new Universal\BitString($identifier, $contentLength, $content, $children); case Identifier::BOOLEAN: return new Universal\Boolean($identifier, $contentLength, $content, $children); case Identifier::ENUMERATED: return new Universal\Enumerated($identifier, $contentLength, $content, $children); case Identifier::INTEGER: return new Universal\Integer($identifier, $contentLength, $content, $children); case Identifier::NULL: return new Universal\NullObject($identifier, $contentLength, $content, $children); case Identifier::OBJECT_IDENTIFIER: return new Universal\ObjectIdentifier($identifier, $contentLength, $content, $children); case Identifier::RELATIVE_OID: return new Universal\RelativeObjectIdentifier($identifier, $contentLength, $content, $children); case Identifier::OCTETSTRING: return new Universal\OctetString($identifier, $contentLength, $content, $children); case Identifier::SEQUENCE: return new Universal\Sequence($identifier, $contentLength, $content, $children); case Identifier::SET: return new Universal\Set($identifier, $contentLength, $content, $children); case Identifier::UTC_TIME: return new Universal\UTCTime($identifier, $contentLength, $content, $children); case Identifier::GENERALIZED_TIME: return new Universal\GeneralizedTime($identifier, $contentLength, $content, $children); case Identifier::IA5_STRING: return new Universal\IA5String($identifier, $contentLength, $content, $children); case Identifier::PRINTABLE_STRING: return new Universal\PrintableString($identifier, $contentLength, $content, $children); case Identifier::NUMERIC_STRING: return new Universal\NumericString($identifier, $contentLength, $content, $children); case Identifier::UTF8_STRING: return new Universal\UTF8String($identifier, $contentLength, $content, $children); case Identifier::UNIVERSAL_STRING: return new Universal\UniversalString($identifier, $contentLength, $content, $children); case Identifier::CHARACTER_STRING: return new Universal\CharacterString($identifier, $contentLength, $content, $children); case Identifier::GENERAL_STRING: return new Universal\GeneralString($identifier, $contentLength, $content, $children); case Identifier::VISIBLE_STRING: return new Universal\VisibleString($identifier, $contentLength, $content, $children); case Identifier::GRAPHIC_STRING: return new Universal\GraphicString($identifier, $contentLength, $content, $children); case Identifier::BMP_STRING: return new Universal\BMPString($identifier, $contentLength, $content, $children); case Identifier::T61_STRING: return new Universal\T61String($identifier, $contentLength, $content, $children); case Identifier::OBJECT_DESCRIPTOR: return new Universal\ObjectDescriptor($identifier, $contentLength, $content, $children); default: // At this point the identifier may be >1 byte. if ($identifier->isConstructed) { return new UnknownConstructedObject($identifier, $contentLength, $content, $children); } else { return new UnknownObject($identifier, $contentLength, $content, $children); } } } if ($identifier->tagClass === Identifier::CLASS_CONTEXT_SPECIFIC) { if ($identifier->isConstructed) { return new ExplicitlyTaggedObject($identifier, $contentLength, $content, $children); } else { return new ImplicitlyTaggedObject($identifier, $contentLength, $content, $children); } } }
/** * @param string $binaryData * @param int $offsetIndex * * @throws ParserException * * @return \FG\ASN1\Object */ public static function fromBinary(&$binaryData, &$offsetIndex = 0) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse binary from data: Offset index larger than input size', $offsetIndex); } $identifierOctet = ord($binaryData[$offsetIndex]); if (Identifier::isContextSpecificClass($identifierOctet) && Identifier::isConstructed($identifierOctet)) { return ExplicitlyTaggedObject::fromBinary($binaryData, $offsetIndex); } switch ($identifierOctet) { case Identifier::BITSTRING: return BitString::fromBinary($binaryData, $offsetIndex); case Identifier::BOOLEAN: return Boolean::fromBinary($binaryData, $offsetIndex); case Identifier::ENUMERATED: return Enumerated::fromBinary($binaryData, $offsetIndex); case Identifier::INTEGER: return Integer::fromBinary($binaryData, $offsetIndex); case Identifier::NULL: return NullObject::fromBinary($binaryData, $offsetIndex); case Identifier::OBJECT_IDENTIFIER: return ObjectIdentifier::fromBinary($binaryData, $offsetIndex); case Identifier::RELATIVE_OID: return RelativeObjectIdentifier::fromBinary($binaryData, $offsetIndex); case Identifier::OCTETSTRING: return OctetString::fromBinary($binaryData, $offsetIndex); case Identifier::SEQUENCE: return Sequence::fromBinary($binaryData, $offsetIndex); case Identifier::SET: return Set::fromBinary($binaryData, $offsetIndex); case Identifier::UTC_TIME: return UTCTime::fromBinary($binaryData, $offsetIndex); case Identifier::GENERALIZED_TIME: return GeneralizedTime::fromBinary($binaryData, $offsetIndex); case Identifier::IA5_STRING: return IA5String::fromBinary($binaryData, $offsetIndex); case Identifier::PRINTABLE_STRING: return PrintableString::fromBinary($binaryData, $offsetIndex); case Identifier::NUMERIC_STRING: return NumericString::fromBinary($binaryData, $offsetIndex); case Identifier::UTF8_STRING: return UTF8String::fromBinary($binaryData, $offsetIndex); case Identifier::UNIVERSAL_STRING: return UniversalString::fromBinary($binaryData, $offsetIndex); case Identifier::CHARACTER_STRING: return CharacterString::fromBinary($binaryData, $offsetIndex); case Identifier::GENERAL_STRING: return GeneralString::fromBinary($binaryData, $offsetIndex); case Identifier::VISIBLE_STRING: return VisibleString::fromBinary($binaryData, $offsetIndex); case Identifier::GRAPHIC_STRING: return GraphicString::fromBinary($binaryData, $offsetIndex); case Identifier::BMP_STRING: return BMPString::fromBinary($binaryData, $offsetIndex); case Identifier::T61_STRING: return T61String::fromBinary($binaryData, $offsetIndex); case Identifier::OBJECT_DESCRIPTOR: return ObjectDescriptor::fromBinary($binaryData, $offsetIndex); default: // At this point the identifier may be >1 byte. if (Identifier::isConstructed($identifierOctet)) { return new UnknownConstructedObject($binaryData, $offsetIndex); } else { $identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $lengthOfUnknownObject = self::parseContentLength($binaryData, $offsetIndex); $offsetIndex += $lengthOfUnknownObject; return new UnknownObject($identifier, $lengthOfUnknownObject); } } }
public function __construct(Identifier $identifier, ContentLength $contentLength, Content $content, array $children = []) { parent::__construct($identifier, $contentLength, $content, $children); $this->setValue($content); }
/** * @expectedException \FG\ASN1\Exception\ParserException * @expectedExceptionMessage ASN.1 Parser Exception at offset 4: Malformed ASN.1 Object Identifier * @depends testFromBinary */ public function testFromBinaryWithMalformedOID() { $binaryData = chr(Identifier::OBJECT_IDENTIFIER); $binaryData .= chr(0x3); $binaryData .= chr(42); $binaryData .= chr(128 | 1); $binaryData .= chr(128 | 1); ObjectIdentifier::fromBinary($binaryData); }
/** * For the real parsing tests look in the test cases of each single ASn object. */ public function testFromBinary() { /* @var BitString $parsedObject */ $binaryData = chr(Identifier::BITSTRING); $binaryData .= chr(0x3); $binaryData .= chr(0x5); $binaryData .= chr(0xff); $binaryData .= chr(0xa0); $expectedObject = new BitString(0xffa0, 5); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof BitString); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); $this->assertEquals($expectedObject->getNumberOfUnusedBits(), $parsedObject->getNumberOfUnusedBits()); /* @var OctetString $parsedObject */ $binaryData = chr(Identifier::OCTETSTRING); $binaryData .= chr(0x2); $binaryData .= chr(0xff); $binaryData .= chr(0xa0); $expectedObject = new OctetString(0xffa0); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof OctetString); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var \FG\ASN1\Universal\Boolean $parsedObject */ $binaryData = chr(Identifier::BOOLEAN); $binaryData .= chr(0x1); $binaryData .= chr(0xff); $expectedObject = new Boolean(true); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof Boolean); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var Enumerated $parsedObject */ $binaryData = chr(Identifier::ENUMERATED); $binaryData .= chr(0x1); $binaryData .= chr(0x3); $expectedObject = new Enumerated(3); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof Enumerated); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var IA5String $parsedObject */ $string = 'Hello Foo World!!!11EinsEins!1'; $binaryData = chr(Identifier::IA5_STRING); $binaryData .= chr(strlen($string)); $binaryData .= $string; $expectedObject = new IA5String($string); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof IA5String); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var \FG\ASN1\Universal\Integer $parsedObject */ $binaryData = chr(Identifier::INTEGER); $binaryData .= chr(0x1); $binaryData .= chr(123); $expectedObject = new Integer(123); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof Integer); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var \FG\ASN1\Universal\NullObject $parsedObject */ $binaryData = chr(Identifier::NULL); $binaryData .= chr(0x0); $expectedObject = new NullObject(); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof NullObject); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var ObjectIdentifier $parsedObject */ $binaryData = chr(Identifier::OBJECT_IDENTIFIER); $binaryData .= chr(0x2); $binaryData .= chr(1 * 40 + 2); $binaryData .= chr(3); $expectedObject = new ObjectIdentifier('1.2.3'); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof ObjectIdentifier); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var PrintableString $parsedObject */ $string = 'This is a test string. #?!%&""'; $binaryData = chr(Identifier::PRINTABLE_STRING); $binaryData .= chr(strlen($string)); $binaryData .= $string; $expectedObject = new PrintableString($string); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof PrintableString); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var GeneralizedTime $parsedObject */ $binaryData = chr(Identifier::GENERALIZED_TIME); $binaryData .= chr(15); $binaryData .= '20120923202316Z'; $expectedObject = new GeneralizedTime('2012-09-23 20:23:16', 'UTC'); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof GeneralizedTime); $this->assertEquals($expectedObject->getContent(), $parsedObject->getContent()); /* @var Sequence $parsedObject */ $binaryData = chr(Identifier::SEQUENCE); $binaryData .= chr(0x6); $binaryData .= chr(Identifier::BOOLEAN); $binaryData .= chr(0x1); $binaryData .= chr(0x0); $binaryData .= chr(Identifier::INTEGER); $binaryData .= chr(0x1); $binaryData .= chr(0x3); $expectedChild1 = new Boolean(false); $expectedChild2 = new Integer(0x3); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof Sequence); $this->assertEquals(2, $parsedObject->getNumberOfChildren()); $children = $parsedObject->getChildren(); $child1 = $children[0]; $child2 = $children[1]; $this->assertEquals($expectedChild1->getContent(), $child1->getContent()); $this->assertEquals($expectedChild2->getContent(), $child2->getContent()); /* @var ExplicitlyTaggedObject $parsedObject */ $taggedObject = new ExplicitlyTaggedObject(0x1, new PrintableString('Hello tagged world')); $binaryData = $taggedObject->getBinary(); $parsedObject = Object::fromBinary($binaryData); $this->assertTrue($parsedObject instanceof ExplicitlyTaggedObject); // An unknown constructed object containing 2 integer children, // first 3 bytes are the identifier. $binaryData = "?�" . chr(Identifier::INTEGER) . "B" . chr(Identifier::INTEGER) . "i"; $offsetIndex = 0; $parsedObject = OBject::fromBinary($binaryData, $offsetIndex); $this->assertTrue($parsedObject instanceof UnknownConstructedObject); $this->assertEquals(substr($binaryData, 0, 3), $parsedObject->getIdentifier()); $this->assertCount(2, $parsedObject->getContent()); $this->assertEquals(strlen($binaryData), $offsetIndex); $this->assertEquals(10, $parsedObject->getObjectLength()); // First 3 bytes are the identifier $binaryData = "��"; $offsetIndex = 0; $parsedObject = Object::fromBinary($binaryData, $offsetIndex); $this->assertTrue($parsedObject instanceof UnknownObject); $this->assertEquals(substr($binaryData, 0, 3), $parsedObject->getIdentifier()); $this->assertEquals('Unparsable Object (1 bytes)', $parsedObject->getContent()); $this->assertEquals(strlen($binaryData), $offsetIndex); $this->assertEquals(5, $parsedObject->getObjectLength()); }