![]() 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/X509/Certificate/Extension/ |
<?php declare(strict_types=1); namespace SpomkyLabs\Pki\X509\Certificate\Extension; use function array_key_exists; use SpomkyLabs\Pki\ASN1\Element; use SpomkyLabs\Pki\ASN1\Type\Constructed\Sequence; use SpomkyLabs\Pki\ASN1\Type\Primitive\Boolean; use SpomkyLabs\Pki\ASN1\Type\Primitive\ObjectIdentifier; use SpomkyLabs\Pki\ASN1\Type\Primitive\OctetString; use Stringable; /** * Base class for certificate extensions. * * @see https://tools.ietf.org/html/rfc5280#section-4.2 * @see https://tools.ietf.org/html/rfc5280#section-4.1 */ abstract class Extension implements Stringable { // OID's from standard certificate extensions public const OID_OBSOLETE_AUTHORITY_KEY_IDENTIFIER = '2.5.29.1'; public const OID_OBSOLETE_KEY_ATTRIBUTES = '2.5.29.2'; public const OID_OBSOLETE_CERTIFICATE_POLICIES = '2.5.29.3'; public const OID_OBSOLETE_KEY_USAGE_RESTRICTION = '2.5.29.4'; public const OID_OBSOLETE_POLICY_MAPPING = '2.5.29.5'; public const OID_OBSOLETE_SUBTREES_CONSTRAINT = '2.5.29.6'; public const OID_OBSOLETE_SUBJECT_ALT_NAME = '2.5.29.7'; public const OID_OBSOLETE_ISSUER_ALT_NAME = '2.5.29.8'; public const OID_SUBJECT_DIRECTORY_ATTRIBUTES = '2.5.29.9'; public const OID_OBSOLETE_BASIC_CONSTRAINTS = '2.5.29.10'; public const OID_SUBJECT_KEY_IDENTIFIER = '2.5.29.14'; public const OID_KEY_USAGE = '2.5.29.15'; public const OID_PRIVATE_KEY_USAGE_PERIOD = '2.5.29.16'; public const OID_SUBJECT_ALT_NAME = '2.5.29.17'; public const OID_ISSUER_ALT_NAME = '2.5.29.18'; public const OID_BASIC_CONSTRAINTS = '2.5.29.19'; public const OID_CRL_NUMBER = '2.5.29.20'; public const OID_REASON_CODE = '2.5.29.21'; public const OID_OBSOLETE_EXPIRATION_DATE = '2.5.29.22'; public const OID_INSTRUCTION_CODE = '2.5.29.23'; public const OID_INVALIDITY_DATE = '2.5.29.24'; public const OID_OBSOLETE_CRL_DISTRIBUTION_POINTS = '2.5.29.25'; public const OID_OBSOLETE_ISSUING_DISTRIBUTION_POINT = '2.5.29.26'; public const OID_DELTA_CRL_INDICATOR = '2.5.29.27'; public const OID_ISSUING_DISTRIBUTION_POINT = '2.5.29.28'; public const OID_CERTIFICATE_ISSUER = '2.5.29.29'; public const OID_NAME_CONSTRAINTS = '2.5.29.30'; public const OID_CRL_DISTRIBUTION_POINTS = '2.5.29.31'; public const OID_CERTIFICATE_POLICIES = '2.5.29.32'; public const OID_POLICY_MAPPINGS = '2.5.29.33'; public const OID_OBSOLETE_POLICY_CONSTRAINTS = '2.5.29.34'; public const OID_AUTHORITY_KEY_IDENTIFIER = '2.5.29.35'; public const OID_POLICY_CONSTRAINTS = '2.5.29.36'; public const OID_EXT_KEY_USAGE = '2.5.29.37'; public const OID_AUTHORITY_ATTRIBUTE_IDENTIFIER = '2.5.29.38'; public const OID_ROLE_SPEC_CERT_IDENTIFIER = '2.5.29.39'; public const OID_CRL_STREAM_IDENTIFIER = '2.5.29.40'; public const OID_BASIC_ATT_CONSTRAINTS = '2.5.29.41'; public const OID_DELEGATED_NAME_CONSTRAINTS = '2.5.29.42'; public const OID_TIME_SPECIFICATION = '2.5.29.43'; public const OID_CRL_SCOPE = '2.5.29.44'; public const OID_STATUS_REFERRALS = '2.5.29.45'; public const OID_FRESHEST_CRL = '2.5.29.46'; public const OID_ORDERED_LIST = '2.5.29.47'; public const OID_ATTRIBUTE_DESCRIPTOR = '2.5.29.48'; public const OID_USER_NOTICE = '2.5.29.49'; public const OID_SOA_IDENTIFIER = '2.5.29.50'; public const OID_BASE_UPDATE_TIME = '2.5.29.51'; public const OID_ACCEPTABLE_CERT_POLICIES = '2.5.29.52'; public const OID_DELTA_INFO = '2.5.29.53'; public const OID_INHIBIT_ANY_POLICY = '2.5.29.54'; public const OID_TARGET_INFORMATION = '2.5.29.55'; public const OID_NO_REV_AVAIL = '2.5.29.56'; public const OID_ACCEPTABLE_PRIVILEGE_POLICIES = '2.5.29.57'; public const OID_TO_BE_REVOKED = '2.5.29.58'; public const OID_REVOKED_GROUPS = '2.5.29.59'; public const OID_EXPIRED_CERTS_ON_CRL = '2.5.29.60'; public const OID_INDIRECT_ISSUER = '2.5.29.61'; public const OID_NO_ASSERTION = '2.5.29.62'; public const OID_AA_ISSUING_DISTRIBUTION_POINT = '2.5.29.63'; public const OID_ISSUED_ON_BEHALF_OF = '2.5.29.64'; public const OID_SINGLE_USE = '2.5.29.65'; public const OID_GROUP_AC = '2.5.29.66'; public const OID_ALLOWED_ATT_ASS = '2.5.29.67'; public const OID_ATTRIBUTE_MAPPINGS = '2.5.29.68'; public const OID_HOLDER_NAME_CONSTRAINTS = '2.5.29.69'; // OID's from private certificate extensions arc public const OID_AUTHORITY_INFORMATION_ACCESS = '1.3.6.1.5.5.7.1.1'; public const OID_AA_CONTROLS = '1.3.6.1.5.5.7.1.6'; public const OID_SUBJECT_INFORMATION_ACCESS = '1.3.6.1.5.5.7.1.11'; public const OID_LOGOTYPE = '1.3.6.1.5.5.7.1.12'; /** * Mapping from extension ID to implementation class name. * * @internal * * @var array<string, string> */ private const MAP_OID_TO_CLASS = [ self::OID_AUTHORITY_KEY_IDENTIFIER => AuthorityKeyIdentifierExtension::class, self::OID_SUBJECT_KEY_IDENTIFIER => SubjectKeyIdentifierExtension::class, self::OID_KEY_USAGE => KeyUsageExtension::class, self::OID_CERTIFICATE_POLICIES => CertificatePoliciesExtension::class, self::OID_POLICY_MAPPINGS => PolicyMappingsExtension::class, self::OID_SUBJECT_ALT_NAME => SubjectAlternativeNameExtension::class, self::OID_ISSUER_ALT_NAME => IssuerAlternativeNameExtension::class, self::OID_SUBJECT_DIRECTORY_ATTRIBUTES => SubjectDirectoryAttributesExtension::class, self::OID_BASIC_CONSTRAINTS => BasicConstraintsExtension::class, self::OID_NAME_CONSTRAINTS => NameConstraintsExtension::class, self::OID_POLICY_CONSTRAINTS => PolicyConstraintsExtension::class, self::OID_EXT_KEY_USAGE => ExtendedKeyUsageExtension::class, self::OID_CRL_DISTRIBUTION_POINTS => CRLDistributionPointsExtension::class, self::OID_INHIBIT_ANY_POLICY => InhibitAnyPolicyExtension::class, self::OID_FRESHEST_CRL => FreshestCRLExtension::class, self::OID_NO_REV_AVAIL => NoRevocationAvailableExtension::class, self::OID_TARGET_INFORMATION => TargetInformationExtension::class, self::OID_AUTHORITY_INFORMATION_ACCESS => AuthorityInformationAccessExtension::class, self::OID_AA_CONTROLS => AAControlsExtension::class, self::OID_SUBJECT_INFORMATION_ACCESS => SubjectInformationAccessExtension::class, ]; /** * Mapping from extensions ID to short name. * * @internal * * @var array<string, string> */ private const MAP_OID_TO_NAME = [ self::OID_AUTHORITY_KEY_IDENTIFIER => 'authorityKeyIdentifier', self::OID_SUBJECT_KEY_IDENTIFIER => 'subjectKeyIdentifier', self::OID_KEY_USAGE => 'keyUsage', self::OID_PRIVATE_KEY_USAGE_PERIOD => 'privateKeyUsagePeriod', self::OID_CERTIFICATE_POLICIES => 'certificatePolicies', self::OID_POLICY_MAPPINGS => 'policyMappings', self::OID_SUBJECT_ALT_NAME => 'subjectAltName', self::OID_ISSUER_ALT_NAME => 'issuerAltName', self::OID_SUBJECT_DIRECTORY_ATTRIBUTES => 'subjectDirectoryAttributes', self::OID_BASIC_CONSTRAINTS => 'basicConstraints', self::OID_NAME_CONSTRAINTS => 'nameConstraints', self::OID_POLICY_CONSTRAINTS => 'policyConstraints', self::OID_EXT_KEY_USAGE => 'extKeyUsage', self::OID_CRL_DISTRIBUTION_POINTS => 'cRLDistributionPoints', self::OID_INHIBIT_ANY_POLICY => 'inhibitAnyPolicy', self::OID_FRESHEST_CRL => 'freshestCRL', self::OID_NO_REV_AVAIL => 'noRevAvail', self::OID_TARGET_INFORMATION => 'targetInformation', self::OID_AUTHORITY_INFORMATION_ACCESS => 'authorityInfoAccess', self::OID_AA_CONTROLS => 'aaControls', self::OID_SUBJECT_INFORMATION_ACCESS => 'subjectInfoAccess', self::OID_LOGOTYPE => 'logotype', ]; /** * @param string $oid Extension OID * @param bool $critical Whether extension is critical */ protected function __construct( private readonly string $oid, private readonly bool $critical ) { } public function __toString(): string { return $this->extensionName(); } /** * Initialize from ASN.1. */ public static function fromASN1(Sequence $seq): self { $idx = 0; $extnID = $seq->at($idx++) ->asObjectIdentifier() ->oid(); $critical = false; if ($seq->has($idx, Element::TYPE_BOOLEAN)) { $critical = $seq->at($idx++) ->asBoolean() ->value(); } $data = $seq->at($idx) ->asOctetString() ->string(); if (array_key_exists($extnID, self::MAP_OID_TO_CLASS)) { $cls = self::MAP_OID_TO_CLASS[$extnID]; return $cls::fromDER($data, $critical); } return UnknownExtension::fromRawString($extnID, $critical, $data); } /** * Get extension OID. */ public function oid(): string { return $this->oid; } /** * Check whether extension is critical. */ public function isCritical(): bool { return $this->critical; } /** * Generate ASN.1 structure. */ public function toASN1(): Sequence { $elements = [ObjectIdentifier::create($this->oid)]; if ($this->critical) { $elements[] = Boolean::create(true); } $elements[] = $this->extnValue(); return Sequence::create(...$elements); } /** * Get short name of the extension. */ public function extensionName(): string { if (array_key_exists($this->oid, self::MAP_OID_TO_NAME)) { return self::MAP_OID_TO_NAME[$this->oid]; } return $this->oid(); } /** * Get ASN.1 structure of the extension value. */ abstract protected function valueASN1(): Element; /** * Parse extension value from DER. * * @param string $data DER data * @param bool $critical Whether extension is critical */ abstract protected static function fromDER(string $data, bool $critical): static; /** * Get the extnValue element. */ protected function extnValue(): OctetString { return OctetString::create($this->valueASN1()->toDER()); } }