Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/asn1/ber.py: 75%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
5# Acknowledgment: Maxence Tury <maxence.tury@ssi.gouv.fr>
6# Acknowledgment: Ralph Broenink
8"""
9Basic Encoding Rules (BER) for ASN.1
10"""
12# Good read: https://luca.ntop.org/Teaching/Appunti/asn1.html
14from scapy.error import warning
15from scapy.compat import chb, orb, bytes_encode
16from scapy.utils import binrepr, inet_aton, inet_ntoa
17from scapy.asn1.asn1 import (
18 ASN1Tag,
19 ASN1_BADTAG,
20 ASN1_BadTag_Decoding_Error,
21 ASN1_Class,
22 ASN1_Class_UNIVERSAL,
23 ASN1_Codecs,
24 ASN1_DECODING_ERROR,
25 ASN1_Decoding_Error,
26 ASN1_Encoding_Error,
27 ASN1_Error,
28 ASN1_Object,
29 _ASN1_ERROR,
30)
32from typing import (
33 Any,
34 AnyStr,
35 Dict,
36 Generic,
37 List,
38 Optional,
39 Tuple,
40 Type,
41 TypeVar,
42 Union,
43 cast,
44)
46##################
47# BER encoding #
48##################
51# [ BER tools ] #
54class BER_Exception(Exception):
55 pass
58class BER_Encoding_Error(ASN1_Encoding_Error):
59 def __init__(self,
60 msg, # type: str
61 encoded=None, # type: Optional[Union[BERcodec_Object[Any], str]] # noqa: E501
62 remaining=b"" # type: bytes
63 ):
64 # type: (...) -> None
65 Exception.__init__(self, msg)
66 self.remaining = remaining
67 self.encoded = encoded
69 def __str__(self):
70 # type: () -> str
71 s = Exception.__str__(self)
72 if isinstance(self.encoded, ASN1_Object):
73 s += "\n### Already encoded ###\n%s" % self.encoded.strshow()
74 else:
75 s += "\n### Already encoded ###\n%r" % self.encoded
76 s += "\n### Remaining ###\n%r" % self.remaining
77 return s
80class BER_Decoding_Error(ASN1_Decoding_Error):
81 def __init__(self,
82 msg, # type: str
83 decoded=None, # type: Optional[Any]
84 remaining=b"" # type: bytes
85 ):
86 # type: (...) -> None
87 Exception.__init__(self, msg)
88 self.remaining = remaining
89 self.decoded = decoded
91 def __str__(self):
92 # type: () -> str
93 s = Exception.__str__(self)
94 if isinstance(self.decoded, ASN1_Object):
95 s += "\n### Already decoded ###\n%s" % self.decoded.strshow()
96 else:
97 s += "\n### Already decoded ###\n%r" % self.decoded
98 s += "\n### Remaining ###\n%r" % self.remaining
99 return s
102class BER_BadTag_Decoding_Error(BER_Decoding_Error,
103 ASN1_BadTag_Decoding_Error):
104 pass
107def BER_len_enc(ll, size=0):
108 # type: (int, Optional[int]) -> bytes
109 from scapy.config import conf
110 if size is None:
111 size = conf.ASN1_default_long_size
112 if ll <= 127 and size == 0:
113 return chb(ll)
114 s = b""
115 while ll or size > 0:
116 s = chb(ll & 0xff) + s
117 ll >>= 8
118 size -= 1
119 if len(s) > 127:
120 raise BER_Exception(
121 "BER_len_enc: Length too long (%i) to be encoded [%r]" %
122 (len(s), s)
123 )
124 return chb(len(s) | 0x80) + s
127def BER_len_dec(s):
128 # type: (bytes) -> Tuple[int, bytes]
129 tmp_len = orb(s[0])
130 if not tmp_len & 0x80:
131 return tmp_len, s[1:]
132 tmp_len &= 0x7f
133 if len(s) <= tmp_len:
134 raise BER_Decoding_Error(
135 "BER_len_dec: Got %i bytes while expecting %i" %
136 (len(s) - 1, tmp_len),
137 remaining=s
138 )
139 ll = 0
140 for c in s[1:tmp_len + 1]:
141 ll <<= 8
142 ll |= orb(c)
143 return ll, s[tmp_len + 1:]
146def BER_num_enc(ll, size=1):
147 # type: (int, int) -> bytes
148 x = [] # type: List[int]
149 while ll or size > 0:
150 x.insert(0, ll & 0x7f)
151 if len(x) > 1:
152 x[0] |= 0x80
153 ll >>= 7
154 size -= 1
155 return b"".join(chb(k) for k in x)
158def BER_num_dec(s, cls_id=0):
159 # type: (bytes, int) -> Tuple[int, bytes]
160 if len(s) == 0:
161 raise BER_Decoding_Error("BER_num_dec: got empty string", remaining=s)
162 x = cls_id
163 for i, c in enumerate(s):
164 c = orb(c)
165 x <<= 7
166 x |= c & 0x7f
167 if not c & 0x80:
168 break
169 if c & 0x80:
170 raise BER_Decoding_Error("BER_num_dec: unfinished number description",
171 remaining=s)
172 return x, s[i + 1:]
175def BER_id_dec(s):
176 # type: (bytes) -> Tuple[int, bytes]
177 # This returns the tag ALONG WITH THE PADDED CLASS+CONSTRUCTIVE INFO.
178 # Let's recall that bits 8-7 from the first byte of the tag encode
179 # the class information, while bit 6 means primitive or constructive.
180 #
181 # For instance, with low-tag-number b'\x81', class would be 0b10
182 # ('context-specific') and tag 0x01, but we return 0x81 as a whole.
183 # For b'\xff\x22', class would be 0b11 ('private'), constructed, then
184 # padding, then tag 0x22, but we return (0xff>>5)*128^1 + 0x22*128^0.
185 # Why the 5-bit-shifting? Because it provides an unequivocal encoding
186 # on base 128 (note that 0xff would equal 1*128^1 + 127*128^0...),
187 # as we know that bits 5 to 1 are fixed to 1 anyway.
188 #
189 # As long as there is no class differentiation, we have to keep this info
190 # encoded in scapy's tag in order to reuse it for packet building.
191 # Note that tags thus may have to be hard-coded with their extended
192 # information, e.g. a SEQUENCE from asn1.py has a direct tag 0x20|16.
193 x = orb(s[0])
194 if x & 0x1f != 0x1f:
195 # low-tag-number
196 return x, s[1:]
197 else:
198 # high-tag-number
199 return BER_num_dec(s[1:], cls_id=x >> 5)
202def BER_id_enc(n):
203 # type: (int) -> bytes
204 if n < 256:
205 # low-tag-number
206 return chb(n)
207 else:
208 # high-tag-number
209 s = BER_num_enc(n)
210 tag = orb(s[0]) # first byte, as an int
211 tag &= 0x07 # reset every bit from 8 to 4
212 tag <<= 5 # move back the info bits on top
213 tag |= 0x1f # pad with 1s every bit from 5 to 1
214 return chb(tag) + s[1:]
216# The functions below provide implicit and explicit tagging support.
219def BER_tagging_dec(s, # type: bytes
220 hidden_tag=None, # type: Optional[int | ASN1Tag]
221 implicit_tag=None, # type: Optional[int]
222 explicit_tag=None, # type: Optional[int]
223 safe=False, # type: Optional[bool]
224 _fname="", # type: str
225 ):
226 # type: (...) -> Tuple[Optional[int], bytes]
227 # We output the 'real_tag' if it is different from the (im|ex)plicit_tag.
228 # 'hidden_tag' is the type tag that is implicited when 'implicit_tag' is used.
229 real_tag = None
230 if len(s) > 0:
231 err_msg = (
232 "BER_tagging_dec: observed tag 0x%.02x does not "
233 "match expected tag 0x%.02x (%s)"
234 )
235 if implicit_tag is not None:
236 ber_id, s = BER_id_dec(s)
237 if ber_id != implicit_tag:
238 if not safe and ber_id != implicit_tag:
239 raise BER_Decoding_Error(err_msg % (
240 ber_id, implicit_tag, _fname),
241 remaining=s)
242 else:
243 real_tag = ber_id
244 s = chb(int(hidden_tag)) + s # type: ignore
245 elif explicit_tag is not None:
246 ber_id, s = BER_id_dec(s)
247 if ber_id != explicit_tag:
248 if not safe:
249 raise BER_Decoding_Error(
250 err_msg % (ber_id, explicit_tag, _fname),
251 remaining=s)
252 else:
253 real_tag = ber_id
254 l, s = BER_len_dec(s)
255 return real_tag, s
258def BER_tagging_enc(s, implicit_tag=None, explicit_tag=None):
259 # type: (bytes, Optional[int], Optional[int]) -> bytes
260 if len(s) > 0:
261 if implicit_tag is not None:
262 s = BER_id_enc(implicit_tag) + s[1:]
263 elif explicit_tag is not None:
264 s = BER_id_enc(explicit_tag) + BER_len_enc(len(s)) + s
265 return s
267# [ BER classes ] #
270class BERcodec_metaclass(type):
271 def __new__(cls,
272 name, # type: str
273 bases, # type: Tuple[type, ...]
274 dct # type: Dict[str, Any]
275 ):
276 # type: (...) -> Type[BERcodec_Object[Any]]
277 c = cast('Type[BERcodec_Object[Any]]',
278 super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct))
279 try:
280 c.tag.register(c.codec, c)
281 except Exception:
282 warning("Error registering %r for %r" % (c.tag, c.codec))
283 return c
286_K = TypeVar('_K')
289class BERcodec_Object(Generic[_K], metaclass=BERcodec_metaclass):
290 codec = ASN1_Codecs.BER
291 tag = ASN1_Class_UNIVERSAL.ANY
293 @classmethod
294 def asn1_object(cls, val):
295 # type: (_K) -> ASN1_Object[_K]
296 return cls.tag.asn1_object(val)
298 @classmethod
299 def check_string(cls, s):
300 # type: (bytes) -> None
301 if not s:
302 raise BER_Decoding_Error(
303 "%s: Got empty object while expecting tag %r" %
304 (cls.__name__, cls.tag), remaining=s
305 )
307 @classmethod
308 def check_type(cls, s):
309 # type: (bytes) -> bytes
310 cls.check_string(s)
311 tag, remainder = BER_id_dec(s)
312 if not isinstance(tag, int) or cls.tag != tag:
313 raise BER_BadTag_Decoding_Error(
314 "%s: Got tag [%i/%#x] while expecting %r" %
315 (cls.__name__, tag, tag, cls.tag), remaining=s
316 )
317 return remainder
319 @classmethod
320 def check_type_get_len(cls, s):
321 # type: (bytes) -> Tuple[int, bytes]
322 s2 = cls.check_type(s)
323 if not s2:
324 raise BER_Decoding_Error("%s: No bytes while expecting a length" %
325 cls.__name__, remaining=s)
326 return BER_len_dec(s2)
328 @classmethod
329 def check_type_check_len(cls, s):
330 # type: (bytes) -> Tuple[int, bytes, bytes]
331 l, s3 = cls.check_type_get_len(s)
332 if len(s3) < l:
333 raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
334 (cls.__name__, len(s3), l), remaining=s)
335 return l, s3[:l], s3[l:]
337 @classmethod
338 def do_dec(cls,
339 s, # type: bytes
340 context=None, # type: Optional[Type[ASN1_Class]]
341 safe=False # type: bool
342 ):
343 # type: (...) -> Tuple[ASN1_Object[Any], bytes]
344 if context is not None:
345 _context = context
346 else:
347 _context = cls.tag.context
348 cls.check_string(s)
349 p, remainder = BER_id_dec(s)
350 if p not in _context:
351 t = s
352 if len(t) > 18:
353 t = t[:15] + b"..."
354 raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" %
355 (p, t), remaining=s)
356 tag = _context[p]
357 codec = cast('Type[BERcodec_Object[_K]]',
358 tag.get_codec(ASN1_Codecs.BER))
359 if codec == BERcodec_Object:
360 # Value type defined as Unknown
361 l, s = BER_num_dec(remainder)
362 return ASN1_BADTAG(s[:l]), s[l:]
363 return codec.dec(s, _context, safe)
365 @classmethod
366 def dec(cls,
367 s, # type: bytes
368 context=None, # type: Optional[Type[ASN1_Class]]
369 safe=False, # type: bool
370 ):
371 # type: (...) -> Tuple[Union[_ASN1_ERROR, ASN1_Object[_K]], bytes]
372 if not safe:
373 return cls.do_dec(s, context, safe)
374 try:
375 return cls.do_dec(s, context, safe)
376 except BER_BadTag_Decoding_Error as e:
377 o, remain = BERcodec_Object.dec(
378 e.remaining, context, safe
379 ) # type: Tuple[ASN1_Object[Any], bytes]
380 return ASN1_BADTAG(o), remain
381 except BER_Decoding_Error as e:
382 return ASN1_DECODING_ERROR(s, exc=e), b""
383 except ASN1_Error as e:
384 return ASN1_DECODING_ERROR(s, exc=e), b""
386 @classmethod
387 def safedec(cls,
388 s, # type: bytes
389 context=None, # type: Optional[Type[ASN1_Class]]
390 ):
391 # type: (...) -> Tuple[Union[_ASN1_ERROR, ASN1_Object[_K]], bytes]
392 return cls.dec(s, context, safe=True)
394 @classmethod
395 def enc(cls, s, size_len=0):
396 # type: (_K, Optional[int]) -> bytes
397 if isinstance(s, (str, bytes)):
398 return BERcodec_STRING.enc(s, size_len=size_len)
399 else:
400 try:
401 return BERcodec_INTEGER.enc(int(s), size_len=size_len) # type: ignore
402 except TypeError:
403 raise TypeError("Trying to encode an invalid value !")
406ASN1_Codecs.BER.register_stem(BERcodec_Object)
409##########################
410# BERcodec objects #
411##########################
413class BERcodec_INTEGER(BERcodec_Object[int]):
414 tag = ASN1_Class_UNIVERSAL.INTEGER
416 @classmethod
417 def enc(cls, i, size_len=0):
418 # type: (int, Optional[int]) -> bytes
419 ls = []
420 while True:
421 ls.append(i & 0xff)
422 if -127 <= i < 0:
423 break
424 if 128 <= i <= 255:
425 ls.append(0)
426 i >>= 8
427 if not i:
428 break
429 s = [chb(int(c)) for c in ls]
430 s.append(BER_len_enc(len(s), size=size_len))
431 s.append(chb(int(cls.tag)))
432 s.reverse()
433 return b"".join(s)
435 @classmethod
436 def do_dec(cls,
437 s, # type: bytes
438 context=None, # type: Optional[Type[ASN1_Class]]
439 safe=False, # type: bool
440 ):
441 # type: (...) -> Tuple[ASN1_Object[int], bytes]
442 l, s, t = cls.check_type_check_len(s)
443 x = 0
444 if s:
445 if orb(s[0]) & 0x80: # negative int
446 x = -1
447 for c in s:
448 x <<= 8
449 x |= orb(c)
450 return cls.asn1_object(x), t
453class BERcodec_BOOLEAN(BERcodec_INTEGER):
454 tag = ASN1_Class_UNIVERSAL.BOOLEAN
457class BERcodec_BIT_STRING(BERcodec_Object[str]):
458 tag = ASN1_Class_UNIVERSAL.BIT_STRING
460 @classmethod
461 def do_dec(cls,
462 s, # type: bytes
463 context=None, # type: Optional[Type[ASN1_Class]]
464 safe=False # type: bool
465 ):
466 # type: (...) -> Tuple[ASN1_Object[str], bytes]
467 # /!\ the unused_bits information is lost after this decoding
468 l, s, t = cls.check_type_check_len(s)
469 if len(s) > 0:
470 unused_bits = orb(s[0])
471 if safe and unused_bits > 7:
472 raise BER_Decoding_Error(
473 "BERcodec_BIT_STRING: too many unused_bits advertised",
474 remaining=s
475 )
476 fs = "".join(binrepr(orb(x)).zfill(8) for x in s[1:])
477 if unused_bits > 0:
478 fs = fs[:-unused_bits]
479 return cls.tag.asn1_object(fs), t
480 else:
481 raise BER_Decoding_Error(
482 "BERcodec_BIT_STRING found no content "
483 "(not even unused_bits byte)",
484 remaining=s
485 )
487 @classmethod
488 def enc(cls, _s, size_len=0):
489 # type: (AnyStr, Optional[int]) -> bytes
490 # /!\ this is DER encoding (bit strings are only zero-bit padded)
491 s = bytes_encode(_s)
492 if len(s) % 8 == 0:
493 unused_bits = 0
494 else:
495 unused_bits = 8 - len(s) % 8
496 s += b"0" * unused_bits
497 s = b"".join(chb(int(b"".join(chb(y) for y in x), 2))
498 for x in zip(*[iter(s)] * 8))
499 s = chb(unused_bits) + s
500 return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
503class BERcodec_STRING(BERcodec_Object[str]):
504 tag = ASN1_Class_UNIVERSAL.STRING
506 @classmethod
507 def enc(cls, _s, size_len=0):
508 # type: (Union[str, bytes], Optional[int]) -> bytes
509 s = bytes_encode(_s)
510 # Be sure we are encoding bytes
511 return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
513 @classmethod
514 def do_dec(cls,
515 s, # type: bytes
516 context=None, # type: Optional[Type[ASN1_Class]]
517 safe=False, # type: bool
518 ):
519 # type: (...) -> Tuple[ASN1_Object[Any], bytes]
520 l, s, t = cls.check_type_check_len(s)
521 return cls.tag.asn1_object(s), t
524class BERcodec_NULL(BERcodec_INTEGER):
525 tag = ASN1_Class_UNIVERSAL.NULL
527 @classmethod
528 def enc(cls, i, size_len=0):
529 # type: (int, Optional[int]) -> bytes
530 if i == 0:
531 return chb(int(cls.tag)) + b"\0"
532 else:
533 return super(cls, cls).enc(i, size_len=size_len)
536class BERcodec_OID(BERcodec_Object[bytes]):
537 tag = ASN1_Class_UNIVERSAL.OID
539 @classmethod
540 def enc(cls, _oid, size_len=0):
541 # type: (AnyStr, Optional[int]) -> bytes
542 oid = bytes_encode(_oid)
543 if oid:
544 lst = [int(x) for x in oid.strip(b".").split(b".")]
545 else:
546 lst = list()
547 if len(lst) >= 2:
548 lst[1] += 40 * lst[0]
549 del lst[0]
550 s = b"".join(BER_num_enc(k) for k in lst)
551 return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
553 @classmethod
554 def do_dec(cls,
555 s, # type: bytes
556 context=None, # type: Optional[Type[ASN1_Class]]
557 safe=False, # type: bool
558 ):
559 # type: (...) -> Tuple[ASN1_Object[bytes], bytes]
560 l, s, t = cls.check_type_check_len(s)
561 lst = []
562 while s:
563 l, s = BER_num_dec(s)
564 lst.append(l)
565 if (len(lst) > 0):
566 lst.insert(0, lst[0] // 40)
567 lst[1] %= 40
568 return (
569 cls.asn1_object(b".".join(str(k).encode('ascii') for k in lst)),
570 t,
571 )
574class BERcodec_ENUMERATED(BERcodec_INTEGER):
575 tag = ASN1_Class_UNIVERSAL.ENUMERATED
578class BERcodec_UTF8_STRING(BERcodec_STRING):
579 tag = ASN1_Class_UNIVERSAL.UTF8_STRING
582class BERcodec_NUMERIC_STRING(BERcodec_STRING):
583 tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING
586class BERcodec_PRINTABLE_STRING(BERcodec_STRING):
587 tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
590class BERcodec_T61_STRING(BERcodec_STRING):
591 tag = ASN1_Class_UNIVERSAL.T61_STRING
594class BERcodec_VIDEOTEX_STRING(BERcodec_STRING):
595 tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING
598class BERcodec_IA5_STRING(BERcodec_STRING):
599 tag = ASN1_Class_UNIVERSAL.IA5_STRING
602class BERcodec_GENERAL_STRING(BERcodec_STRING):
603 tag = ASN1_Class_UNIVERSAL.GENERAL_STRING
606class BERcodec_UTC_TIME(BERcodec_STRING):
607 tag = ASN1_Class_UNIVERSAL.UTC_TIME
610class BERcodec_GENERALIZED_TIME(BERcodec_STRING):
611 tag = ASN1_Class_UNIVERSAL.GENERALIZED_TIME
614class BERcodec_ISO646_STRING(BERcodec_STRING):
615 tag = ASN1_Class_UNIVERSAL.ISO646_STRING
618class BERcodec_UNIVERSAL_STRING(BERcodec_STRING):
619 tag = ASN1_Class_UNIVERSAL.UNIVERSAL_STRING
622class BERcodec_BMP_STRING(BERcodec_STRING):
623 tag = ASN1_Class_UNIVERSAL.BMP_STRING
626class BERcodec_SEQUENCE(BERcodec_Object[Union[bytes, List[BERcodec_Object[Any]]]]): # noqa: E501
627 tag = ASN1_Class_UNIVERSAL.SEQUENCE
629 @classmethod
630 def enc(cls, _ll, size_len=0):
631 # type: (Union[bytes, List[BERcodec_Object[Any]]], Optional[int]) -> bytes
632 if isinstance(_ll, bytes):
633 ll = _ll
634 else:
635 ll = b"".join(x.enc(cls.codec) for x in _ll)
636 return chb(int(cls.tag)) + BER_len_enc(len(ll), size=size_len) + ll
638 @classmethod
639 def do_dec(cls,
640 s, # type: bytes
641 context=None, # type: Optional[Type[ASN1_Class]]
642 safe=False # type: bool
643 ):
644 # type: (...) -> Tuple[ASN1_Object[Union[bytes, List[Any]]], bytes]
645 if context is None:
646 context = cls.tag.context
647 ll, st = cls.check_type_get_len(s) # we may have len(s) < ll
648 s, t = st[:ll], st[ll:]
649 obj = []
650 while s:
651 try:
652 o, remain = BERcodec_Object.dec(
653 s, context, safe
654 ) # type: Tuple[ASN1_Object[Any], bytes]
655 s = remain
656 except BER_Decoding_Error as err:
657 err.remaining += t
658 if err.decoded is not None:
659 obj.append(err.decoded)
660 err.decoded = obj
661 raise
662 obj.append(o)
663 if len(st) < ll:
664 raise BER_Decoding_Error("Not enough bytes to decode sequence",
665 decoded=obj)
666 return cls.asn1_object(obj), t
669class BERcodec_SET(BERcodec_SEQUENCE):
670 tag = ASN1_Class_UNIVERSAL.SET
673class BERcodec_IPADDRESS(BERcodec_STRING):
674 tag = ASN1_Class_UNIVERSAL.IPADDRESS
676 @classmethod
677 def enc(cls, ipaddr_ascii, size_len=0): # type: ignore
678 # type: (str, Optional[int]) -> bytes
679 try:
680 s = inet_aton(ipaddr_ascii)
681 except Exception:
682 raise BER_Encoding_Error("IPv4 address could not be encoded")
683 return chb(int(cls.tag)) + BER_len_enc(len(s), size=size_len) + s
685 @classmethod
686 def do_dec(cls, s, context=None, safe=False):
687 # type: (bytes, Optional[Any], bool) -> Tuple[ASN1_Object[str], bytes]
688 l, s, t = cls.check_type_check_len(s)
689 try:
690 ipaddr_ascii = inet_ntoa(s)
691 except Exception:
692 raise BER_Decoding_Error("IP address could not be decoded",
693 remaining=s)
694 return cls.asn1_object(ipaddr_ascii), t
697class BERcodec_COUNTER32(BERcodec_INTEGER):
698 tag = ASN1_Class_UNIVERSAL.COUNTER32
701class BERcodec_COUNTER64(BERcodec_INTEGER):
702 tag = ASN1_Class_UNIVERSAL.COUNTER64
705class BERcodec_GAUGE32(BERcodec_INTEGER):
706 tag = ASN1_Class_UNIVERSAL.GAUGE32
709class BERcodec_TIME_TICKS(BERcodec_INTEGER):
710 tag = ASN1_Class_UNIVERSAL.TIME_TICKS