PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / lib / packages / FG / ASN1 / Identifier.php

Identifier.php in Defender Security – Malware Scanner, Login Security & Firewall 6.3.0, at lib/packages/FG/ASN1/Identifier.php

340 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * This file is part of the PHPASN1 library.
4 *
5 * Copyright © Friedrich Große <[email protected]>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 namespace WP_DEFENDER_VENDOR\FG\ASN1;
12
13 use Exception;
14
15 /**
16 * The Identifier encodes the ASN.1 tag (class and number) of the type of a data value.
17 *
18 * Every identifier whose number is in the range 0 to 30 has the following structure:
19 *
20 * Bits: 8 7 6 5 4 3 2 1
21 * | Class | P/C | Tag number |
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 * Bits 8 and 7 define the class of this type ( Universal, Application, Context-specific or Private).
25 * Bit 6 encoded whether this type is primitive or constructed
26 * The remaining bits 5 - 1 encode the tag number
27 */
28 class Identifier
29 {
30 const CLASS_UNIVERSAL = 0x00;
31 const CLASS_APPLICATION = 0x01;
32 const CLASS_CONTEXT_SPECIFIC = 0x02;
33 const CLASS_PRIVATE = 0x03;
34
35 const EOC = 0x00; // unsupported for now
36 const BOOLEAN = 0x01;
37 const INTEGER = 0x02;
38 const BITSTRING = 0x03;
39 const OCTETSTRING = 0x04;
40 const NULL = 0x05;
41 const OBJECT_IDENTIFIER = 0x06;
42 const OBJECT_DESCRIPTOR = 0x07;
43 const EXTERNAL = 0x08; // unsupported for now
44 const REAL = 0x09; // unsupported for now
45 const ENUMERATED = 0x0A;
46 const EMBEDDED_PDV = 0x0B; // unsupported for now
47 const UTF8_STRING = 0x0C;
48 const RELATIVE_OID = 0x0D;
49 // value 0x0E and 0x0F are reserved for future use
50
51 const SEQUENCE = 0x30;
52 const SET = 0x31;
53 const NUMERIC_STRING = 0x12;
54 const PRINTABLE_STRING = 0x13;
55 const T61_STRING = 0x14; // sometimes referred to as TeletextString
56 const VIDEOTEXT_STRING = 0x15;
57 const IA5_STRING = 0x16;
58 const UTC_TIME = 0x17;
59 const GENERALIZED_TIME = 0x18;
60 const GRAPHIC_STRING = 0x19;
61 const VISIBLE_STRING = 0x1A;
62 const GENERAL_STRING = 0x1B;
63 const UNIVERSAL_STRING = 0x1C;
64 const CHARACTER_STRING = 0x1D; // Unrestricted character type
65 const BMP_STRING = 0x1E;
66
67 const LONG_FORM = 0x1F;
68 const IS_CONSTRUCTED = 0x20;
69
70 /**
71 * Creates an identifier. Short form identifiers are returned as integers
72 * for BC, long form identifiers will be returned as a string of octets.
73 *
74 * @param int $class
75 * @param bool $isConstructed
76 * @param int $tagNumber
77 *
78 * @throws Exception if the given arguments are invalid
79 *
80 * @return int|string
81 */
82 public static function create($class, $isConstructed, $tagNumber)
83 {
84 if (!is_numeric($class) || $class < self::CLASS_UNIVERSAL || $class > self::CLASS_PRIVATE) {
85 throw new Exception(sprintf('Invalid class %d given', $class));
86 }
87
88 if (!is_bool($isConstructed)) {
89 throw new Exception("\$isConstructed must be a boolean value ($isConstructed given)");
90 }
91
92 $tagNumber = self::makeNumeric($tagNumber);
93 if ($tagNumber < 0) {
94 throw new Exception(sprintf('Invalid $tagNumber %d given. You can only use positive integers.', $tagNumber));
95 }
96
97 if ($tagNumber < self::LONG_FORM) {
98 return ($class << 6) | ($isConstructed << 5) | $tagNumber;
99 }
100
101 $firstOctet = ($class << 6) | ($isConstructed << 5) | self::LONG_FORM;
102
103 // Tag numbers formatted in long form are base-128 encoded. See X.609#8.1.2.4
104 return chr($firstOctet).Base128::encode($tagNumber);
105 }
106
107 public static function isConstructed($identifierOctet)
108 {
109 return ($identifierOctet & self::IS_CONSTRUCTED) === self::IS_CONSTRUCTED;
110 }
111
112 public static function isLongForm($identifierOctet)
113 {
114 return ($identifierOctet & self::LONG_FORM) === self::LONG_FORM;
115 }
116
117 /**
118 * Return the name of the mapped ASN.1 type with a preceding "ASN.1 ".
119 *
120 * Example: ASN.1 Octet String
121 *
122 * @see Identifier::getShortName()
123 *
124 * @param int|string $identifier
125 *
126 * @return string
127 */
128 public static function getName($identifier)
129 {
130 $identifierOctet = self::makeNumeric($identifier);
131
132 $typeName = static::getShortName($identifier);
133
134 if (($identifierOctet & self::LONG_FORM) < self::LONG_FORM) {
135 $typeName = "ASN.1 {$typeName}";
136 }
137
138 return $typeName;
139 }
140
141 /**
142 * Return the short version of the type name.
143 *
144 * If the given identifier octet can be mapped to a known universal type this will
145 * return its name. Else Identifier::getClassDescription() is used to retrieve
146 * information about the identifier.
147 *
148 * @see Identifier::getName()
149 * @see Identifier::getClassDescription()
150 *
151 * @param int|string $identifier
152 *
153 * @return string
154 */
155 public static function getShortName($identifier)
156 {
157 $identifierOctet = self::makeNumeric($identifier);
158
159 switch ($identifierOctet) {
160 case self::EOC:
161 return 'End-of-contents octet';
162 case self::BOOLEAN:
163 return 'Boolean';
164 case self::INTEGER:
165 return 'Integer';
166 case self::BITSTRING:
167 return 'Bit String';
168 case self::OCTETSTRING:
169 return 'Octet String';
170 case self::NULL:
171 return 'NULL';
172 case self::OBJECT_IDENTIFIER:
173 return 'Object Identifier';
174 case self::OBJECT_DESCRIPTOR:
175 return 'Object Descriptor';
176 case self::EXTERNAL:
177 return 'External Type';
178 case self::REAL:
179 return 'Real';
180 case self::ENUMERATED:
181 return 'Enumerated';
182 case self::EMBEDDED_PDV:
183 return 'Embedded PDV';
184 case self::UTF8_STRING:
185 return 'UTF8 String';
186 case self::RELATIVE_OID:
187 return 'Relative OID';
188 case self::SEQUENCE:
189 return 'Sequence';
190 case self::SET:
191 return 'Set';
192 case self::NUMERIC_STRING:
193 return 'Numeric String';
194 case self::PRINTABLE_STRING:
195 return 'Printable String';
196 case self::T61_STRING:
197 return 'T61 String';
198 case self::VIDEOTEXT_STRING:
199 return 'Videotext String';
200 case self::IA5_STRING:
201 return 'IA5 String';
202 case self::UTC_TIME:
203 return 'UTC Time';
204 case self::GENERALIZED_TIME:
205 return 'Generalized Time';
206 case self::GRAPHIC_STRING:
207 return 'Graphic String';
208 case self::VISIBLE_STRING:
209 return 'Visible String';
210 case self::GENERAL_STRING:
211 return 'General String';
212 case self::UNIVERSAL_STRING:
213 return 'Universal String';
214 case self::CHARACTER_STRING:
215 return 'Character String';
216 case self::BMP_STRING:
217 return 'BMP String';
218
219 case 0x0E:
220 return 'RESERVED (0x0E)';
221 case 0x0F:
222 return 'RESERVED (0x0F)';
223
224 case self::LONG_FORM:
225 default:
226 $classDescription = self::getClassDescription($identifier);
227
228 if (is_int($identifier)) {
229 $identifier = chr($identifier);
230 }
231
232 return "$classDescription (0x".strtoupper(bin2hex($identifier)).')';
233 }
234 }
235
236 /**
237 * Returns a textual description of the information encoded in a given identifier octet.
238 *
239 * The first three (most significant) bytes are evaluated to determine if this is a
240 * constructed or primitive type and if it is either universal, application, context-specific or
241 * private.
242 *
243 * Example:
244 * Constructed context-specific
245 * Primitive universal
246 *
247 * @param int|string $identifier
248 *
249 * @return string
250 */
251 public static function getClassDescription($identifier)
252 {
253 $identifierOctet = self::makeNumeric($identifier);
254
255 if (self::isConstructed($identifierOctet)) {
256 $classDescription = 'Constructed ';
257 } else {
258 $classDescription = 'Primitive ';
259 }
260 $classBits = $identifierOctet >> 6;
261 switch ($classBits) {
262 case self::CLASS_UNIVERSAL:
263 $classDescription .= 'universal';
264 break;
265 case self::CLASS_APPLICATION:
266 $classDescription .= 'application';
267 break;
268 case self::CLASS_CONTEXT_SPECIFIC:
269 $tagNumber = self::getTagNumber($identifier);
270 $classDescription = "[$tagNumber] Context-specific";
271 break;
272 case self::CLASS_PRIVATE:
273 $classDescription .= 'private';
274 break;
275
276 default:
277 return "INVALID IDENTIFIER OCTET: {$identifierOctet}";
278 }
279
280 return $classDescription;
281 }
282
283 /**
284 * @param int|string $identifier
285 *
286 * @return int
287 */
288 public static function getTagNumber($identifier)
289 {
290 $firstOctet = self::makeNumeric($identifier);
291 $tagNumber = $firstOctet & self::LONG_FORM;
292
293 if ($tagNumber < self::LONG_FORM) {
294 return $tagNumber;
295 }
296
297 if (is_numeric($identifier)) {
298 $identifier = chr($identifier);
299 }
300 return Base128::decode(substr($identifier, 1));
301 }
302
303 public static function isUniversalClass($identifier)
304 {
305 $identifier = self::makeNumeric($identifier);
306
307 return $identifier >> 6 == self::CLASS_UNIVERSAL;
308 }
309
310 public static function isApplicationClass($identifier)
311 {
312 $identifier = self::makeNumeric($identifier);
313
314 return $identifier >> 6 == self::CLASS_APPLICATION;
315 }
316
317 public static function isContextSpecificClass($identifier)
318 {
319 $identifier = self::makeNumeric($identifier);
320
321 return $identifier >> 6 == self::CLASS_CONTEXT_SPECIFIC;
322 }
323
324 public static function isPrivateClass($identifier)
325 {
326 $identifier = self::makeNumeric($identifier);
327
328 return $identifier >> 6 == self::CLASS_PRIVATE;
329 }
330
331 private static function makeNumeric($identifierOctet)
332 {
333 if (!is_numeric($identifierOctet)) {
334 return ord($identifierOctet);
335 } else {
336 return $identifierOctet;
337 }
338 }
339 }
340