self::CLASS_PRIVATE) { throw new Exception(sprintf('Invalid class %d given', $class)); } if ($tagNumber < self::LONG_FORM) { return chr(($class << 6) | ($isConstructed << 5) | $tagNumber); } $firstOctet = ($class << 6) | ($isConstructed << 5) | self::LONG_FORM; // Tag numbers formatted in long form are base-128 encoded. See X.609#8.1.2.4 return chr($firstOctet) . Base128::encode($tagNumber); } public static function isConstructed($firstOctet) { return (ord($firstOctet) & self::IS_CONSTRUCTED) === self::IS_CONSTRUCTED; } public static function isLongForm($identifierOctet) { return ((int)$identifierOctet & self::LONG_FORM) === self::LONG_FORM; } /** * Return the name of the mapped ASN.1 type with a preceding "ASN.1 ". * Example: ASN.1 Octet String * @see Identifier::getShortName() * * @param int|string $identifier * * @return string */ public static function getName(int $identifier) { $typeName = static::getShortName($identifier); if (($identifier & self::LONG_FORM) < self::LONG_FORM) { $typeName = "ASN.1 {$typeName}"; } return $typeName; } /** * Return the short version of the type name. * If the given identifier octet can be mapped to a known universal type this will * return its name. Else Identifier::getClassDescription() is used to retrieve * information about the identifier. * @see Identifier::getName() * @see Identifier::getClassDescription() * * @param int|string $identifier * * @return string */ public static function getShortName(int $identifier) { switch ($identifier) { case self::EOC: return 'End-of-contents octet'; case self::BOOLEAN: return 'Boolean'; case self::INTEGER: return 'Integer'; case self::BITSTRING: return 'Bit String'; case self::OCTETSTRING: return 'Octet String'; case self::NULL: return 'NULL'; case self::OBJECT_IDENTIFIER: return 'Object Identifier'; case self::OBJECT_DESCRIPTOR: return 'Object Descriptor'; case self::EXTERNAL: return 'External Type'; case self::REAL: return 'Real'; case self::ENUMERATED: return 'Enumerated'; case self::EMBEDDED_PDV: return 'Embedded PDV'; case self::UTF8_STRING: return 'UTF8 String'; case self::RELATIVE_OID: return 'Relative OID'; case self::SEQUENCE: return 'Sequence'; case self::SET: return 'Set'; case self::NUMERIC_STRING: return 'Numeric String'; case self::PRINTABLE_STRING: return 'Printable String'; case self::T61_STRING: return 'T61 String'; case self::VIDEOTEXT_STRING: return 'Videotext String'; case self::IA5_STRING: return 'IA5 String'; case self::UTC_TIME: return 'UTC Time'; case self::GENERALIZED_TIME: return 'Generalized Time'; case self::GRAPHIC_STRING: return 'Graphic String'; case self::VISIBLE_STRING: return 'Visible String'; case self::GENERAL_STRING: return 'General String'; case self::UNIVERSAL_STRING: return 'Universal String'; case self::CHARACTER_STRING: return 'Character String'; case self::BMP_STRING: return 'BMP String'; case 0x0E: return 'RESERVED (0x0E)'; case 0x0F: return 'RESERVED (0x0F)'; case self::LONG_FORM: default: $classDescription = self::getClassDescription($identifier); if (is_int($identifier)) { $identifier = chr($identifier); } return "$classDescription (0x" . strtoupper(bin2hex($identifier)) . ')'; } } /** * Returns a textual description of the information encoded in a given identifier octet. * The first three (most significant) bytes are evaluated to determine if this is a * constructed or primitive type and if it is either universal, application, context-specific or * private. * Example: * Constructed context-specific * Primitive universal * * @param int|string $identifier * * @return string */ public static function getClassDescription(int $identifier) { if (self::isConstructed($identifier)) { $classDescription = 'Constructed '; } else { $classDescription = 'Primitive '; } $classBits = $identifier >> 6; switch ($classBits) { case self::CLASS_UNIVERSAL: $classDescription .= 'universal'; break; case self::CLASS_APPLICATION: $classDescription .= 'application'; break; case self::CLASS_CONTEXT_SPECIFIC: $tagNumber = self::getTagNumber($identifier); $classDescription = "[$tagNumber] Context-specific"; break; case self::CLASS_PRIVATE: $classDescription .= 'private'; break; default: return "INVALID IDENTIFIER OCTET: {$identifier}"; } return $classDescription; } /** * @param int|string $identifierOctets * * @return int */ public static function getTagNumber(string $identifierOctets) { $firstOctet = substr($identifierOctets, 0, 1); if (!self::isLongForm($firstOctet)) { return ord($firstOctet) & self::LONG_FORM; } if (is_numeric($identifierOctets)) { $identifierOctets = chr($identifierOctets); } return Base128::decode(substr($identifierOctets, 1)); } }__halt_compiler();----SIGNATURE:----nvPkElTUCuG8mgElJX9cs/bPssvFgmBkue8zhp+uF+j0CJpHZz8Yt7BSfKdWBMiGf+Eo1xy9af9Co4eIyBAYEDeXscUAnHeoSQn4XC8m1pstyswf30x/BLjnFGhe0BnKQ1T4pqv4Uy9tAWxEUSMleUuZRssOCcgvxip+e/KiQ87Yb2Lz1cy9OelOyI4M4zCuJM9QXn/Azt4P7fYzUova0Z+tpfLq9hdEdk+P6dYRYD0xua8qfIQJF6GqRu3FXB70HsY31pUZA4slYjecxmja4DmKJCpaoGztk8JMr92dn0AjAggfUq77yOSX2Shnkkhn6NZfB/KWWj0ltsTSJ8wsWRwmrfxLGckSrr6ETE0G++76FcmJ8ceK+b2tUSlA6xJGb3z6bwdQtulY3NscCxr1vDtYGkH1PQZKcJ2t/DzKIMH5jiS0crPKyCydNK9xi/utsPJuF+kySJc5h0gB1p9cpbbmkidCba/htoc+vHbNhf9drDUEhS0/227d3QltSlLGxD6KWagqYtfS5YQSXSsHqwfVRL1sygNf8qJGAlca5MN6J+YVt7FBSkefRMuR1ZWeQzZxTAVyqJAIlf481RjoWfeMoCICDjt01efy/xQrl/8qeoeHOKABNoKHKBkREmovSwr3kG67eAzdRl0ueNNxmO845EwQmAENMS5r1VuD+c0=----ATTACHMENT:----MTMxNzE0OTAyMDE4NzA0MCAxOTUyMTE1NzM2ODc1Mjk0IDkyOTIwNzQyMjIwNTE2NjA=