![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/spomky-labs/pki-framework/src/X501/ASN1/ |
<?php declare(strict_types=1); namespace SpomkyLabs\Pki\X501\ASN1; use ArrayIterator; use function count; use Countable; use IteratorAggregate; use SpomkyLabs\Pki\ASN1\Type\Constructed\Set; use SpomkyLabs\Pki\ASN1\Type\UnspecifiedType; use SpomkyLabs\Pki\X501\ASN1\AttributeValue\AttributeValue; use Stringable; use UnexpectedValueException; /** * Implements *RelativeDistinguishedName* ASN.1 type. * * @see https://www.itu.int/ITU-T/formal-language/itu-t/x/x501/2012/InformationFramework.html#InformationFramework.RelativeDistinguishedName */ final class RDN implements Countable, IteratorAggregate, Stringable { /** * Attributes. * * @var AttributeTypeAndValue[] */ private readonly array $_attribs; /** * @param AttributeTypeAndValue ...$attribs One or more attributes */ private function __construct(AttributeTypeAndValue ...$attribs) { if (count($attribs) === 0) { throw new UnexpectedValueException('RDN must have at least one AttributeTypeAndValue.'); } $this->_attribs = $attribs; } public function __toString(): string { return $this->toString(); } public static function create(AttributeTypeAndValue ...$attribs): self { return new self(...$attribs); } /** * Convenience method to initialize RDN from AttributeValue objects. * * @param AttributeValue ...$values One or more attributes */ public static function fromAttributeValues(AttributeValue ...$values): self { $attribs = array_map( static fn (AttributeValue $value) => AttributeTypeAndValue::create(AttributeType::create( $value->oid() ), $value), $values ); return self::create(...$attribs); } /** * Initialize from ASN.1. */ public static function fromASN1(Set $set): self { $attribs = array_map( static fn (UnspecifiedType $el) => AttributeTypeAndValue::fromASN1($el->asSequence()), $set->elements() ); return self::create(...$attribs); } /** * Generate ASN.1 structure. */ public function toASN1(): Set { $elements = array_map(static fn (AttributeTypeAndValue $tv) => $tv->toASN1(), $this->_attribs); return Set::create(...$elements)->sortedSetOf(); } /** * Get name-component string conforming to RFC 2253. * * @see https://tools.ietf.org/html/rfc2253#section-2.2 */ public function toString(): string { $parts = array_map(static fn (AttributeTypeAndValue $tv) => $tv->toString(), $this->_attribs); return implode('+', $parts); } /** * Check whether RDN is semantically equal to other. * * @param RDN $other Object to compare to */ public function equals(self $other): bool { // if attribute count doesn't match if (count($this) !== count($other)) { return false; } $attribs1 = $this->_attribs; $attribs2 = $other->_attribs; // if there's multiple attributes, sort using SET OF rules if (count($attribs1) > 1) { $attribs1 = self::fromASN1($this->toASN1())->_attribs; $attribs2 = self::fromASN1($other->toASN1())->_attribs; } for ($i = count($attribs1) - 1; $i >= 0; --$i) { $tv1 = $attribs1[$i]; $tv2 = $attribs2[$i]; if (! $tv1->equals($tv2)) { return false; } } return true; } /** * Get all AttributeTypeAndValue objects. * * @return AttributeTypeAndValue[] */ public function all(): array { return $this->_attribs; } /** * Get all AttributeTypeAndValue objects of the given attribute type. * * @param string $name Attribute OID or name * * @return AttributeTypeAndValue[] */ public function allOf(string $name): array { $oid = AttributeType::attrNameToOID($name); $attribs = array_filter($this->_attribs, static fn (AttributeTypeAndValue $tv) => $tv->oid() === $oid); return array_values($attribs); } /** * @see \Countable::count() */ public function count(): int { return count($this->_attribs); } /** * @see \IteratorAggregate::getIterator() */ public function getIterator(): ArrayIterator { return new ArrayIterator($this->_attribs); } }