| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 | 
							- <?php
 
- /*
 
-  * This file is part of the PHPASN1 library.
 
-  *
 
-  * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
 
-  *
 
-  * For the full copyright and license information, please view the LICENSE
 
-  * file that was distributed with this source code.
 
-  */
 
- namespace FG\ASN1;
 
- use Exception;
 
- /**
 
-  * The Identifier encodes the ASN.1 tag (class and number) of the type of a data value.
 
-  *
 
-  * Every identifier whose number is in the range 0 to 30 has the following structure:
 
-  *
 
-  * Bits:    8  7    6    5  4  3  2  1
 
-  *       | Class | P/C |   Tag number  |
 
-  *       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-  *
 
-  * Bits 8 and 7 define the class of this type ( Universal, Application, Context-specific or Private).
 
-  * Bit 6 encoded whether this type is primitive or constructed
 
-  * The remaining bits 5 - 1 encode the tag number
 
-  */
 
- class Identifier
 
- {
 
-     const CLASS_UNIVERSAL        = 0x00;
 
-     const CLASS_APPLICATION      = 0x01;
 
-     const CLASS_CONTEXT_SPECIFIC = 0x02;
 
-     const CLASS_PRIVATE          = 0x03;
 
-     const EOC               = 0x00; // unsupported for now
 
-     const BOOLEAN           = 0x01;
 
-     const INTEGER           = 0x02;
 
-     const BITSTRING         = 0x03;
 
-     const OCTETSTRING       = 0x04;
 
-     const NULL              = 0x05;
 
-     const OBJECT_IDENTIFIER = 0x06;
 
-     const OBJECT_DESCRIPTOR = 0x07;
 
-     const EXTERNAL          = 0x08; // unsupported for now
 
-     const REAL              = 0x09; // unsupported for now
 
-     const ENUMERATED        = 0x0A;
 
-     const EMBEDDED_PDV      = 0x0B; // unsupported for now
 
-     const UTF8_STRING       = 0x0C;
 
-     const RELATIVE_OID      = 0x0D;
 
-     // value 0x0E and 0x0F are reserved for future use
 
-     const SEQUENCE          = 0x30;
 
-     const SET               = 0x31;
 
-     const NUMERIC_STRING    = 0x12;
 
-     const PRINTABLE_STRING  = 0x13;
 
-     const T61_STRING        = 0x14; // sometimes referred to as TeletextString
 
-     const VIDEOTEXT_STRING  = 0x15;
 
-     const IA5_STRING        = 0x16;
 
-     const UTC_TIME          = 0x17;
 
-     const GENERALIZED_TIME  = 0x18;
 
-     const GRAPHIC_STRING    = 0x19;
 
-     const VISIBLE_STRING    = 0x1A;
 
-     const GENERAL_STRING    = 0x1B;
 
-     const UNIVERSAL_STRING  = 0x1C;
 
-     const CHARACTER_STRING  = 0x1D; // Unrestricted character type
 
-     const BMP_STRING        = 0x1E;
 
-     const LONG_FORM         = 0x1F;
 
-     const IS_CONSTRUCTED    = 0x20;
 
-     /**
 
-      * Creates an identifier. Short form identifiers are returned as integers
 
-      * for BC, long form identifiers will be returned as a string of octets.
 
-      *
 
-      * @param int $class
 
-      * @param bool $isConstructed
 
-      * @param int $tagNumber
 
-      *
 
-      * @throws Exception if the given arguments are invalid
 
-      *
 
-      * @return int|string
 
-      */
 
-     public static function create($class, $isConstructed, $tagNumber)
 
-     {
 
-         if (!is_numeric($class) || $class < self::CLASS_UNIVERSAL || $class > self::CLASS_PRIVATE) {
 
-             throw new Exception(sprintf('Invalid class %d given', $class));
 
-         }
 
-         if (!is_bool($isConstructed)) {
 
-             throw new Exception("\$isConstructed must be a boolean value ($isConstructed given)");
 
-         }
 
-         $tagNumber = self::makeNumeric($tagNumber);
 
-         if ($tagNumber < 0) {
 
-             throw new Exception(sprintf('Invalid $tagNumber %d given. You can only use positive integers.', $tagNumber));
 
-         }
 
-         if ($tagNumber < self::LONG_FORM) {
 
-             return ($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($identifierOctet)
 
-     {
 
-         return ($identifierOctet & self::IS_CONSTRUCTED) === self::IS_CONSTRUCTED;
 
-     }
 
-     public static function isLongForm($identifierOctet)
 
-     {
 
-         return ($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($identifier)
 
-     {
 
-         $identifierOctet = self::makeNumeric($identifier);
 
-         $typeName = static::getShortName($identifier);
 
-         if (($identifierOctet & 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($identifier)
 
-     {
 
-         $identifierOctet = self::makeNumeric($identifier);
 
-         switch ($identifierOctet) {
 
-             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($identifier)
 
-     {
 
-         $identifierOctet = self::makeNumeric($identifier);
 
-         if (self::isConstructed($identifierOctet)) {
 
-             $classDescription = 'Constructed ';
 
-         } else {
 
-             $classDescription = 'Primitive ';
 
-         }
 
-         $classBits = $identifierOctet >> 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: {$identifierOctet}";
 
-         }
 
-         return $classDescription;
 
-     }
 
-     /**
 
-      * @param int|string $identifier
 
-      *
 
-      * @return int
 
-      */
 
-     public static function getTagNumber($identifier)
 
-     {
 
-         $firstOctet = self::makeNumeric($identifier);
 
-         $tagNumber = $firstOctet & self::LONG_FORM;
 
-         if ($tagNumber < self::LONG_FORM) {
 
-             return $tagNumber;
 
-         }
 
-         if (is_numeric($identifier)) {
 
-             $identifier = chr($identifier);
 
-         }
 
-         return Base128::decode(substr($identifier, 1));
 
-     }
 
-     public static function isUniversalClass($identifier)
 
-     {
 
-         $identifier = self::makeNumeric($identifier);
 
-         return $identifier >> 6 == self::CLASS_UNIVERSAL;
 
-     }
 
-     public static function isApplicationClass($identifier)
 
-     {
 
-         $identifier = self::makeNumeric($identifier);
 
-         return $identifier >> 6 == self::CLASS_APPLICATION;
 
-     }
 
-     public static function isContextSpecificClass($identifier)
 
-     {
 
-         $identifier = self::makeNumeric($identifier);
 
-         return $identifier >> 6 == self::CLASS_CONTEXT_SPECIFIC;
 
-     }
 
-     public static function isPrivateClass($identifier)
 
-     {
 
-         $identifier = self::makeNumeric($identifier);
 
-         return $identifier >> 6 == self::CLASS_PRIVATE;
 
-     }
 
-     private static function makeNumeric($identifierOctet)
 
-     {
 
-         if (!is_numeric($identifierOctet)) {
 
-             return ord($identifierOctet);
 
-         } else {
 
-             return $identifierOctet;
 
-         }
 
-     }
 
- }
 
 
  |