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:----aG63BI2qVG25+2Y3F8C6O6JXlGZyGo7+Vy4dNUwqO30Z5Ia9wv7hWX1fAzPmVYKeeJqS1JIzu+8npOYKlaQWUvuD0rvFDPFcKAc90m73jepHIWG+SyCHkXCS/jW/idgXoZ9vB1rmiLRyci6cG0xg/uWjuqg8YqmBbCwWmWogaANF2rdhA6nD7EzeioDq0ebsDy8ogLiSblC+RCwhzkI1vy8cL+fE0cA7Syn8MA0+kOtSh1GfOHBFo5kFpl5ZOjAueP2odWP5IDTt44MN4yUM8kWsYH8+5MQDUL5bswW26KyYONz7kv9zlpi2NKMfmNY7voep2JLRCBLxO4+K0DLOMdqG0CWug+Gf/7wKKuItf7035ch3ztfySlkAd3oNmcyTlNzbAQ/ibfuwHfhd3MEnfgxszTr2lRTDyvqoBM64V23+mcKk0sxBSiqQG6P99lhsYklNt/cGBfHmoG/ZsHHEFqQQX/Tu4uNprmfPdDzlAS2st9YA0c72hNXtxLwS25m753mXPr36rRN8BAm2zMiQYF1//cWEpd4KYTTK7BD0JT4KKBWrrL5K4h1si/zClPBOnwwcXYRECZq5cNt3v4BpLtBykVR953fanuYjDJ59LgJVrvPPwANkBBDVZHmmrZx7dt2WtBD+bc5JkVKtTkPC/BjarkobZasi2Ijf4CSqdYI=----ATTACHMENT:----NjkwMjIwODkyNDI0NjM5OSAzNTg3MTY5NzAxMDcyMTc1IDg0NTU4ODg5NDM3NTAwMDU=