1# 2# This file is part of pyasn1 software. 3# 4# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> 5# License: http://snmplabs.com/pyasn1/license.html 6# 7import math 8import sys 9 10from pyasn1 import error 11from pyasn1.codec.ber import eoo 12from pyasn1.compat import binary 13from pyasn1.compat import integer 14from pyasn1.compat import octets 15from pyasn1.type import base 16from pyasn1.type import constraint 17from pyasn1.type import namedtype 18from pyasn1.type import namedval 19from pyasn1.type import tag 20from pyasn1.type import tagmap 21 22NoValue = base.NoValue 23noValue = NoValue() 24 25__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null', 26 'ObjectIdentifier', 'Real', 'Enumerated', 27 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf', 28 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any', 29 'NoValue', 'noValue'] 30 31# "Simple" ASN.1 types (yet incomplete) 32 33 34class Integer(base.AbstractSimpleAsn1Item): 35 """Create |ASN.1| type or object. 36 37 |ASN.1| objects are immutable and duck-type Python :class:`int` objects. 38 39 Keyword Args 40 ------------ 41 value: :class:`int`, :class:`str` or |ASN.1| object 42 Python integer or string literal or |ASN.1| class instance. 43 44 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 45 Object representing non-default ASN.1 tag(s) 46 47 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 48 Object representing non-default ASN.1 subtype constraint(s) 49 50 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 51 Object representing non-default symbolic aliases for numbers 52 53 Raises 54 ------ 55 :py:class:`~pyasn1.error.PyAsn1Error` 56 On constraint violation or bad initializer. 57 58 Examples 59 -------- 60 61 .. code-block:: python 62 63 class ErrorCode(Integer): 64 ''' 65 ASN.1 specification: 66 67 ErrorCode ::= 68 INTEGER { disk-full(1), no-disk(-1), 69 disk-not-formatted(2) } 70 71 error ErrorCode ::= disk-full 72 ''' 73 namedValues = NamedValues( 74 ('disk-full', 1), ('no-disk', -1), 75 ('disk-not-formatted', 2) 76 ) 77 78 error = ErrorCode('disk-full') 79 """ 80 #: Set (on class, not on instance) or return a 81 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 82 #: associated with |ASN.1| type. 83 tagSet = tag.initTagSet( 84 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02) 85 ) 86 87 #: Set (on class, not on instance) or return a 88 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 89 #: imposing constraints on |ASN.1| type initialization values. 90 subtypeSpec = constraint.ConstraintsIntersection() 91 92 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 93 #: representing symbolic aliases for numbers 94 namedValues = namedval.NamedValues() 95 96 # Optimization for faster codec lookup 97 typeId = base.AbstractSimpleAsn1Item.getTypeId() 98 99 def __init__(self, value=noValue, **kwargs): 100 if 'namedValues' not in kwargs: 101 kwargs['namedValues'] = self.namedValues 102 103 base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs) 104 105 def __and__(self, value): 106 return self.clone(self._value & value) 107 108 def __rand__(self, value): 109 return self.clone(value & self._value) 110 111 def __or__(self, value): 112 return self.clone(self._value | value) 113 114 def __ror__(self, value): 115 return self.clone(value | self._value) 116 117 def __xor__(self, value): 118 return self.clone(self._value ^ value) 119 120 def __rxor__(self, value): 121 return self.clone(value ^ self._value) 122 123 def __lshift__(self, value): 124 return self.clone(self._value << value) 125 126 def __rshift__(self, value): 127 return self.clone(self._value >> value) 128 129 def __add__(self, value): 130 return self.clone(self._value + value) 131 132 def __radd__(self, value): 133 return self.clone(value + self._value) 134 135 def __sub__(self, value): 136 return self.clone(self._value - value) 137 138 def __rsub__(self, value): 139 return self.clone(value - self._value) 140 141 def __mul__(self, value): 142 return self.clone(self._value * value) 143 144 def __rmul__(self, value): 145 return self.clone(value * self._value) 146 147 def __mod__(self, value): 148 return self.clone(self._value % value) 149 150 def __rmod__(self, value): 151 return self.clone(value % self._value) 152 153 def __pow__(self, value, modulo=None): 154 return self.clone(pow(self._value, value, modulo)) 155 156 def __rpow__(self, value): 157 return self.clone(pow(value, self._value)) 158 159 def __floordiv__(self, value): 160 return self.clone(self._value // value) 161 162 def __rfloordiv__(self, value): 163 return self.clone(value // self._value) 164 165 if sys.version_info[0] <= 2: 166 def __div__(self, value): 167 if isinstance(value, float): 168 return Real(self._value / value) 169 else: 170 return self.clone(self._value / value) 171 172 def __rdiv__(self, value): 173 if isinstance(value, float): 174 return Real(value / self._value) 175 else: 176 return self.clone(value / self._value) 177 else: 178 def __truediv__(self, value): 179 return Real(self._value / value) 180 181 def __rtruediv__(self, value): 182 return Real(value / self._value) 183 184 def __divmod__(self, value): 185 return self.clone(divmod(self._value, value)) 186 187 def __rdivmod__(self, value): 188 return self.clone(divmod(value, self._value)) 189 190 __hash__ = base.AbstractSimpleAsn1Item.__hash__ 191 192 def __int__(self): 193 return int(self._value) 194 195 if sys.version_info[0] <= 2: 196 def __long__(self): 197 return long(self._value) 198 199 def __float__(self): 200 return float(self._value) 201 202 def __abs__(self): 203 return self.clone(abs(self._value)) 204 205 def __index__(self): 206 return int(self._value) 207 208 def __pos__(self): 209 return self.clone(+self._value) 210 211 def __neg__(self): 212 return self.clone(-self._value) 213 214 def __invert__(self): 215 return self.clone(~self._value) 216 217 def __round__(self, n=0): 218 r = round(self._value, n) 219 if n: 220 return self.clone(r) 221 else: 222 return r 223 224 def __floor__(self): 225 return math.floor(self._value) 226 227 def __ceil__(self): 228 return math.ceil(self._value) 229 230 if sys.version_info[0:2] > (2, 5): 231 def __trunc__(self): 232 return self.clone(math.trunc(self._value)) 233 234 def __lt__(self, value): 235 return self._value < value 236 237 def __le__(self, value): 238 return self._value <= value 239 240 def __eq__(self, value): 241 return self._value == value 242 243 def __ne__(self, value): 244 return self._value != value 245 246 def __gt__(self, value): 247 return self._value > value 248 249 def __ge__(self, value): 250 return self._value >= value 251 252 def prettyIn(self, value): 253 try: 254 return int(value) 255 256 except ValueError: 257 try: 258 return self.namedValues[value] 259 260 except KeyError: 261 raise error.PyAsn1Error( 262 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1]) 263 ) 264 265 def prettyOut(self, value): 266 try: 267 return str(self.namedValues[value]) 268 269 except KeyError: 270 return str(value) 271 272 # backward compatibility 273 274 def getNamedValues(self): 275 return self.namedValues 276 277 278class Boolean(Integer): 279 """Create |ASN.1| type or object. 280 281 |ASN.1| objects are immutable and duck-type Python :class:`int` objects. 282 283 Keyword Args 284 ------------ 285 value: :class:`int`, :class:`str` or |ASN.1| object 286 Python integer or boolean or string literal or |ASN.1| class instance. 287 288 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 289 Object representing non-default ASN.1 tag(s) 290 291 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 292 Object representing non-default ASN.1 subtype constraint(s) 293 294 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 295 Object representing non-default symbolic aliases for numbers 296 297 Raises 298 ------ 299 :py:class:`~pyasn1.error.PyAsn1Error` 300 On constraint violation or bad initializer. 301 302 Examples 303 -------- 304 .. code-block:: python 305 306 class RoundResult(Boolean): 307 ''' 308 ASN.1 specification: 309 310 RoundResult ::= BOOLEAN 311 312 ok RoundResult ::= TRUE 313 ko RoundResult ::= FALSE 314 ''' 315 ok = RoundResult(True) 316 ko = RoundResult(False) 317 """ 318 #: Set (on class, not on instance) or return a 319 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 320 #: associated with |ASN.1| type. 321 tagSet = tag.initTagSet( 322 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01), 323 ) 324 325 #: Set (on class, not on instance) or return a 326 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 327 #: imposing constraints on |ASN.1| type initialization values. 328 subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1) 329 330 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 331 #: representing symbolic aliases for numbers 332 namedValues = namedval.NamedValues(('False', 0), ('True', 1)) 333 334 # Optimization for faster codec lookup 335 typeId = Integer.getTypeId() 336 337if sys.version_info[0] < 3: 338 SizedIntegerBase = long 339else: 340 SizedIntegerBase = int 341 342 343class SizedInteger(SizedIntegerBase): 344 bitLength = leadingZeroBits = None 345 346 def setBitLength(self, bitLength): 347 self.bitLength = bitLength 348 self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0) 349 return self 350 351 def __len__(self): 352 if self.bitLength is None: 353 self.setBitLength(integer.bitLength(self)) 354 355 return self.bitLength 356 357 358class BitString(base.AbstractSimpleAsn1Item): 359 """Create |ASN.1| schema or value object. 360 361 |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple 362 of bits) and :class:`int` objects. 363 364 Keyword Args 365 ------------ 366 value: :class:`int`, :class:`str` or |ASN.1| object 367 Python integer or string literal representing binary or hexadecimal 368 number or sequence of integer bits or |ASN.1| object. 369 370 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 371 Object representing non-default ASN.1 tag(s) 372 373 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 374 Object representing non-default ASN.1 subtype constraint(s) 375 376 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 377 Object representing non-default symbolic aliases for numbers 378 379 binValue: :py:class:`str` 380 Binary string initializer to use instead of the *value*. 381 Example: '10110011'. 382 383 hexValue: :py:class:`str` 384 Hexadecimal string initializer to use instead of the *value*. 385 Example: 'DEADBEEF'. 386 387 Raises 388 ------ 389 :py:class:`~pyasn1.error.PyAsn1Error` 390 On constraint violation or bad initializer. 391 392 Examples 393 -------- 394 .. code-block:: python 395 396 class Rights(BitString): 397 ''' 398 ASN.1 specification: 399 400 Rights ::= BIT STRING { user-read(0), user-write(1), 401 group-read(2), group-write(3), 402 other-read(4), other-write(5) } 403 404 group1 Rights ::= { group-read, group-write } 405 group2 Rights ::= '0011'B 406 group3 Rights ::= '3'H 407 ''' 408 namedValues = NamedValues( 409 ('user-read', 0), ('user-write', 1), 410 ('group-read', 2), ('group-write', 3), 411 ('other-read', 4), ('other-write', 5) 412 ) 413 414 group1 = Rights(('group-read', 'group-write')) 415 group2 = Rights('0011') 416 group3 = Rights(0x3) 417 """ 418 #: Set (on class, not on instance) or return a 419 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 420 #: associated with |ASN.1| type. 421 tagSet = tag.initTagSet( 422 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03) 423 ) 424 425 #: Set (on class, not on instance) or return a 426 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 427 #: imposing constraints on |ASN.1| type initialization values. 428 subtypeSpec = constraint.ConstraintsIntersection() 429 430 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 431 #: representing symbolic aliases for numbers 432 namedValues = namedval.NamedValues() 433 434 # Optimization for faster codec lookup 435 typeId = base.AbstractSimpleAsn1Item.getTypeId() 436 437 defaultBinValue = defaultHexValue = noValue 438 439 def __init__(self, value=noValue, **kwargs): 440 if value is noValue: 441 if kwargs: 442 try: 443 value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True) 444 445 except KeyError: 446 pass 447 448 try: 449 value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True) 450 451 except KeyError: 452 pass 453 454 if value is noValue: 455 if self.defaultBinValue is not noValue: 456 value = self.fromBinaryString(self.defaultBinValue, internalFormat=True) 457 458 elif self.defaultHexValue is not noValue: 459 value = self.fromHexString(self.defaultHexValue, internalFormat=True) 460 461 if 'namedValues' not in kwargs: 462 kwargs['namedValues'] = self.namedValues 463 464 base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs) 465 466 def __str__(self): 467 return self.asBinary() 468 469 def __eq__(self, other): 470 other = self.prettyIn(other) 471 return self is other or self._value == other and len(self._value) == len(other) 472 473 def __ne__(self, other): 474 other = self.prettyIn(other) 475 return self._value != other or len(self._value) != len(other) 476 477 def __lt__(self, other): 478 other = self.prettyIn(other) 479 return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other 480 481 def __le__(self, other): 482 other = self.prettyIn(other) 483 return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other 484 485 def __gt__(self, other): 486 other = self.prettyIn(other) 487 return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other 488 489 def __ge__(self, other): 490 other = self.prettyIn(other) 491 return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other 492 493 # Immutable sequence object protocol 494 495 def __len__(self): 496 return len(self._value) 497 498 def __getitem__(self, i): 499 if i.__class__ is slice: 500 return self.clone([self[x] for x in range(*i.indices(len(self)))]) 501 else: 502 length = len(self._value) - 1 503 if i > length or i < 0: 504 raise IndexError('bit index out of range') 505 return (self._value >> (length - i)) & 1 506 507 def __iter__(self): 508 length = len(self._value) 509 while length: 510 length -= 1 511 yield (self._value >> length) & 1 512 513 def __reversed__(self): 514 return reversed(tuple(self)) 515 516 # arithmetic operators 517 518 def __add__(self, value): 519 value = self.prettyIn(value) 520 return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value))) 521 522 def __radd__(self, value): 523 value = self.prettyIn(value) 524 return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value))) 525 526 def __mul__(self, value): 527 bitString = self._value 528 while value > 1: 529 bitString <<= len(self._value) 530 bitString |= self._value 531 value -= 1 532 return self.clone(bitString) 533 534 def __rmul__(self, value): 535 return self * value 536 537 def __lshift__(self, count): 538 return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count)) 539 540 def __rshift__(self, count): 541 return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count))) 542 543 def __int__(self): 544 return self._value 545 546 def __float__(self): 547 return float(self._value) 548 549 if sys.version_info[0] < 3: 550 def __long__(self): 551 return self._value 552 553 def asNumbers(self): 554 """Get |ASN.1| value as a sequence of 8-bit integers. 555 556 If |ASN.1| object length is not a multiple of 8, result 557 will be left-padded with zeros. 558 """ 559 return tuple(octets.octs2ints(self.asOctets())) 560 561 def asOctets(self): 562 """Get |ASN.1| value as a sequence of octets. 563 564 If |ASN.1| object length is not a multiple of 8, result 565 will be left-padded with zeros. 566 """ 567 return integer.to_bytes(self._value, length=len(self)) 568 569 def asInteger(self): 570 """Get |ASN.1| value as a single integer value. 571 """ 572 return self._value 573 574 def asBinary(self): 575 """Get |ASN.1| value as a text string of bits. 576 """ 577 binString = binary.bin(self._value)[2:] 578 return '0' * (len(self._value) - len(binString)) + binString 579 580 @classmethod 581 def fromHexString(cls, value, internalFormat=False, prepend=None): 582 """Create a |ASN.1| object initialized from the hex string. 583 584 Parameters 585 ---------- 586 value: :class:`str` 587 Text string like 'DEADBEEF' 588 """ 589 try: 590 value = SizedInteger(value, 16).setBitLength(len(value) * 4) 591 592 except ValueError: 593 raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1])) 594 595 if prepend is not None: 596 value = SizedInteger( 597 (SizedInteger(prepend) << len(value)) | value 598 ).setBitLength(len(prepend) + len(value)) 599 600 if not internalFormat: 601 value = cls(value) 602 603 return value 604 605 @classmethod 606 def fromBinaryString(cls, value, internalFormat=False, prepend=None): 607 """Create a |ASN.1| object initialized from a string of '0' and '1'. 608 609 Parameters 610 ---------- 611 value: :class:`str` 612 Text string like '1010111' 613 """ 614 try: 615 value = SizedInteger(value or '0', 2).setBitLength(len(value)) 616 617 except ValueError: 618 raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1])) 619 620 if prepend is not None: 621 value = SizedInteger( 622 (SizedInteger(prepend) << len(value)) | value 623 ).setBitLength(len(prepend) + len(value)) 624 625 if not internalFormat: 626 value = cls(value) 627 628 return value 629 630 @classmethod 631 def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0): 632 """Create a |ASN.1| object initialized from a string. 633 634 Parameters 635 ---------- 636 value: :class:`str` (Py2) or :class:`bytes` (Py3) 637 Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3) 638 """ 639 value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding) 640 641 if prepend is not None: 642 value = SizedInteger( 643 (SizedInteger(prepend) << len(value)) | value 644 ).setBitLength(len(prepend) + len(value)) 645 646 if not internalFormat: 647 value = cls(value) 648 649 return value 650 651 def prettyIn(self, value): 652 if isinstance(value, SizedInteger): 653 return value 654 elif octets.isStringType(value): 655 if not value: 656 return SizedInteger(0).setBitLength(0) 657 658 elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated) 659 if value[-2:] == '\'B': 660 return self.fromBinaryString(value[1:-2], internalFormat=True) 661 elif value[-2:] == '\'H': 662 return self.fromHexString(value[1:-2], internalFormat=True) 663 else: 664 raise error.PyAsn1Error( 665 'Bad BIT STRING value notation %s' % (value,) 666 ) 667 668 elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active' 669 names = [x.strip() for x in value.split(',')] 670 671 try: 672 673 bitPositions = [self.namedValues[name] for name in names] 674 675 except KeyError: 676 raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,)) 677 678 rightmostPosition = max(bitPositions) 679 680 number = 0 681 for bitPosition in bitPositions: 682 number |= 1 << (rightmostPosition - bitPosition) 683 684 return SizedInteger(number).setBitLength(rightmostPosition + 1) 685 686 elif value.startswith('0x'): 687 return self.fromHexString(value[2:], internalFormat=True) 688 689 elif value.startswith('0b'): 690 return self.fromBinaryString(value[2:], internalFormat=True) 691 692 else: # assume plain binary string like '1011' 693 return self.fromBinaryString(value, internalFormat=True) 694 695 elif isinstance(value, (tuple, list)): 696 return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True) 697 698 elif isinstance(value, BitString): 699 return SizedInteger(value).setBitLength(len(value)) 700 701 elif isinstance(value, intTypes): 702 return SizedInteger(value) 703 704 else: 705 raise error.PyAsn1Error( 706 'Bad BitString initializer type \'%s\'' % (value,) 707 ) 708 709 710try: 711 # noinspection PyStatementEffect 712 all 713 714except NameError: # Python 2.4 715 # noinspection PyShadowingBuiltins 716 def all(iterable): 717 for element in iterable: 718 if not element: 719 return False 720 return True 721 722 723class OctetString(base.AbstractSimpleAsn1Item): 724 """Create |ASN.1| schema or value object. 725 726 |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`. 727 When used in Unicode context, |ASN.1| type assumes "|encoding|" serialisation. 728 729 Keyword Args 730 ------------ 731 value: :class:`str`, :class:`bytes` or |ASN.1| object 732 string (Python 2) or bytes (Python 3), alternatively unicode object 733 (Python 2) or string (Python 3) representing character string to be 734 serialised into octets (note `encoding` parameter) or |ASN.1| object. 735 736 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 737 Object representing non-default ASN.1 tag(s) 738 739 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 740 Object representing non-default ASN.1 subtype constraint(s) 741 742 encoding: :py:class:`str` 743 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or 744 :class:`str` (Python 3) the payload when |ASN.1| object is used 745 in text string context. 746 747 binValue: :py:class:`str` 748 Binary string initializer to use instead of the *value*. 749 Example: '10110011'. 750 751 hexValue: :py:class:`str` 752 Hexadecimal string initializer to use instead of the *value*. 753 Example: 'DEADBEEF'. 754 755 Raises 756 ------ 757 :py:class:`~pyasn1.error.PyAsn1Error` 758 On constraint violation or bad initializer. 759 760 Examples 761 -------- 762 .. code-block:: python 763 764 class Icon(OctetString): 765 ''' 766 ASN.1 specification: 767 768 Icon ::= OCTET STRING 769 770 icon1 Icon ::= '001100010011001000110011'B 771 icon2 Icon ::= '313233'H 772 ''' 773 icon1 = Icon.fromBinaryString('001100010011001000110011') 774 icon2 = Icon.fromHexString('313233') 775 """ 776 #: Set (on class, not on instance) or return a 777 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 778 #: associated with |ASN.1| type. 779 tagSet = tag.initTagSet( 780 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04) 781 ) 782 783 #: Set (on class, not on instance) or return a 784 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 785 #: imposing constraints on |ASN.1| type initialization values. 786 subtypeSpec = constraint.ConstraintsIntersection() 787 788 # Optimization for faster codec lookup 789 typeId = base.AbstractSimpleAsn1Item.getTypeId() 790 791 defaultBinValue = defaultHexValue = noValue 792 encoding = 'iso-8859-1' 793 794 def __init__(self, value=noValue, **kwargs): 795 if kwargs: 796 if value is noValue: 797 try: 798 value = self.fromBinaryString(kwargs.pop('binValue')) 799 800 except KeyError: 801 pass 802 803 try: 804 value = self.fromHexString(kwargs.pop('hexValue')) 805 806 except KeyError: 807 pass 808 809 if value is noValue: 810 if self.defaultBinValue is not noValue: 811 value = self.fromBinaryString(self.defaultBinValue) 812 813 elif self.defaultHexValue is not noValue: 814 value = self.fromHexString(self.defaultHexValue) 815 816 if 'encoding' not in kwargs: 817 kwargs['encoding'] = self.encoding 818 819 base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs) 820 821 if sys.version_info[0] <= 2: 822 def prettyIn(self, value): 823 if isinstance(value, str): 824 return value 825 elif isinstance(value, unicode): 826 try: 827 return value.encode(self.encoding) 828 except (LookupError, UnicodeEncodeError): 829 raise error.PyAsn1Error( 830 "Can't encode string '%s' with codec %s" % (value, self.encoding) 831 ) 832 elif isinstance(value, (tuple, list)): 833 try: 834 return ''.join([chr(x) for x in value]) 835 except ValueError: 836 raise error.PyAsn1Error( 837 "Bad %s initializer '%s'" % (self.__class__.__name__, value) 838 ) 839 else: 840 return str(value) 841 842 def __str__(self): 843 return str(self._value) 844 845 def __unicode__(self): 846 try: 847 return self._value.decode(self.encoding) 848 849 except UnicodeDecodeError: 850 raise error.PyAsn1Error( 851 "Can't decode string '%s' with codec %s" % (self._value, self.encoding) 852 ) 853 854 def asOctets(self): 855 return str(self._value) 856 857 def asNumbers(self): 858 return tuple([ord(x) for x in self._value]) 859 860 else: 861 def prettyIn(self, value): 862 if isinstance(value, bytes): 863 return value 864 elif isinstance(value, str): 865 try: 866 return value.encode(self.encoding) 867 except UnicodeEncodeError: 868 raise error.PyAsn1Error( 869 "Can't encode string '%s' with '%s' codec" % (value, self.encoding) 870 ) 871 elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way 872 return value.asOctets() 873 elif isinstance(value, base.AbstractSimpleAsn1Item): # this mostly targets Integer objects 874 return self.prettyIn(str(value)) 875 elif isinstance(value, (tuple, list)): 876 return self.prettyIn(bytes(value)) 877 else: 878 return bytes(value) 879 880 def __str__(self): 881 try: 882 return self._value.decode(self.encoding) 883 884 except UnicodeDecodeError: 885 raise error.PyAsn1Error( 886 "Can't decode string '%s' with '%s' codec at '%s'" % (self._value, self.encoding, self.__class__.__name__) 887 ) 888 889 def __bytes__(self): 890 return bytes(self._value) 891 892 def asOctets(self): 893 return bytes(self._value) 894 895 def asNumbers(self): 896 return tuple(self._value) 897 898 # 899 # Normally, `.prettyPrint()` is called from `__str__()`. Historically, 900 # OctetString.prettyPrint() used to return hexified payload 901 # representation in cases when non-printable content is present. At the 902 # same time `str()` used to produce either octet-stream (Py2) or 903 # text (Py3) representations. 904 # 905 # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is 906 # reversed to preserve the original behaviour. 907 # 908 # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness 909 # and end up with just `__str__()` producing hexified representation while 910 # both text and octet-stream representation should only be requested via 911 # the `.asOctets()` method. 912 # 913 # Note: ASN.1 OCTET STRING is never mean to contain text! 914 # 915 916 def prettyOut(self, value): 917 return value 918 919 def prettyPrint(self, scope=0): 920 # first see if subclass has its own .prettyOut() 921 value = self.prettyOut(self._value) 922 923 if value is not self._value: 924 return value 925 926 numbers = self.asNumbers() 927 928 for x in numbers: 929 # hexify if needed 930 if x < 32 or x > 126: 931 return '0x' + ''.join(('%.2x' % x for x in numbers)) 932 else: 933 # this prevents infinite recursion 934 return OctetString.__str__(self) 935 936 @staticmethod 937 def fromBinaryString(value): 938 """Create a |ASN.1| object initialized from a string of '0' and '1'. 939 940 Parameters 941 ---------- 942 value: :class:`str` 943 Text string like '1010111' 944 """ 945 bitNo = 8 946 byte = 0 947 r = [] 948 for v in value: 949 if bitNo: 950 bitNo -= 1 951 else: 952 bitNo = 7 953 r.append(byte) 954 byte = 0 955 if v in ('0', '1'): 956 v = int(v) 957 else: 958 raise error.PyAsn1Error( 959 'Non-binary OCTET STRING initializer %s' % (v,) 960 ) 961 byte |= v << bitNo 962 963 r.append(byte) 964 965 return octets.ints2octs(r) 966 967 @staticmethod 968 def fromHexString(value): 969 """Create a |ASN.1| object initialized from the hex string. 970 971 Parameters 972 ---------- 973 value: :class:`str` 974 Text string like 'DEADBEEF' 975 """ 976 r = [] 977 p = [] 978 for v in value: 979 if p: 980 r.append(int(p + v, 16)) 981 p = None 982 else: 983 p = v 984 if p: 985 r.append(int(p + '0', 16)) 986 987 return octets.ints2octs(r) 988 989 # Immutable sequence object protocol 990 991 def __len__(self): 992 return len(self._value) 993 994 def __getitem__(self, i): 995 if i.__class__ is slice: 996 return self.clone(self._value[i]) 997 else: 998 return self._value[i] 999 1000 def __iter__(self): 1001 return iter(self._value) 1002 1003 def __contains__(self, value): 1004 return value in self._value 1005 1006 def __add__(self, value): 1007 return self.clone(self._value + self.prettyIn(value)) 1008 1009 def __radd__(self, value): 1010 return self.clone(self.prettyIn(value) + self._value) 1011 1012 def __mul__(self, value): 1013 return self.clone(self._value * value) 1014 1015 def __rmul__(self, value): 1016 return self * value 1017 1018 def __int__(self): 1019 return int(self._value) 1020 1021 def __float__(self): 1022 return float(self._value) 1023 1024 def __reversed__(self): 1025 return reversed(self._value) 1026 1027 1028class Null(OctetString): 1029 """Create |ASN.1| schema or value object. 1030 1031 |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty). 1032 1033 Keyword Args 1034 ------------ 1035 value: :class:`str` or :py:class:`~pyasn1.type.univ.Null` object 1036 Python empty string literal or any object that evaluates to `False` 1037 1038 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1039 Object representing non-default ASN.1 tag(s) 1040 1041 Raises 1042 ------ 1043 :py:class:`~pyasn1.error.PyAsn1Error` 1044 On constraint violation or bad initializer. 1045 1046 Examples 1047 -------- 1048 .. code-block:: python 1049 1050 class Ack(Null): 1051 ''' 1052 ASN.1 specification: 1053 1054 Ack ::= NULL 1055 ''' 1056 ack = Ack('') 1057 """ 1058 1059 #: Set (on class, not on instance) or return a 1060 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1061 #: associated with |ASN.1| type. 1062 tagSet = tag.initTagSet( 1063 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05) 1064 ) 1065 subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs('')) 1066 1067 # Optimization for faster codec lookup 1068 typeId = OctetString.getTypeId() 1069 1070 def prettyIn(self, value): 1071 if value: 1072 return value 1073 1074 return octets.str2octs('') 1075 1076if sys.version_info[0] <= 2: 1077 intTypes = (int, long) 1078else: 1079 intTypes = (int,) 1080 1081numericTypes = intTypes + (float,) 1082 1083 1084class ObjectIdentifier(base.AbstractSimpleAsn1Item): 1085 """Create |ASN.1| schema or value object. 1086 1087 |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers). 1088 1089 Keyword Args 1090 ------------ 1091 value: :class:`tuple`, :class:`str` or |ASN.1| object 1092 Python sequence of :class:`int` or string literal or |ASN.1| object. 1093 1094 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1095 Object representing non-default ASN.1 tag(s) 1096 1097 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1098 Object representing non-default ASN.1 subtype constraint(s) 1099 1100 Raises 1101 ------ 1102 :py:class:`~pyasn1.error.PyAsn1Error` 1103 On constraint violation or bad initializer. 1104 1105 Examples 1106 -------- 1107 .. code-block:: python 1108 1109 class ID(ObjectIdentifier): 1110 ''' 1111 ASN.1 specification: 1112 1113 ID ::= OBJECT IDENTIFIER 1114 1115 id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) } 1116 id-bp ID ::= { id-edims 11 } 1117 ''' 1118 id_edims = ID('2.6.7') 1119 id_bp = id_edims + (11,) 1120 """ 1121 #: Set (on class, not on instance) or return a 1122 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1123 #: associated with |ASN.1| type. 1124 tagSet = tag.initTagSet( 1125 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06) 1126 ) 1127 1128 #: Set (on class, not on instance) or return a 1129 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 1130 #: imposing constraints on |ASN.1| type initialization values. 1131 subtypeSpec = constraint.ConstraintsIntersection() 1132 1133 # Optimization for faster codec lookup 1134 typeId = base.AbstractSimpleAsn1Item.getTypeId() 1135 1136 def __add__(self, other): 1137 return self.clone(self._value + other) 1138 1139 def __radd__(self, other): 1140 return self.clone(other + self._value) 1141 1142 def asTuple(self): 1143 return self._value 1144 1145 # Sequence object protocol 1146 1147 def __len__(self): 1148 return len(self._value) 1149 1150 def __getitem__(self, i): 1151 if i.__class__ is slice: 1152 return self.clone(self._value[i]) 1153 else: 1154 return self._value[i] 1155 1156 def __iter__(self): 1157 return iter(self._value) 1158 1159 def __contains__(self, value): 1160 return value in self._value 1161 1162 def index(self, suboid): 1163 return self._value.index(suboid) 1164 1165 def isPrefixOf(self, other): 1166 """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object. 1167 1168 Parameters 1169 ---------- 1170 other: |ASN.1| object 1171 |ASN.1| object 1172 1173 Returns 1174 ------- 1175 : :class:`bool` 1176 :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object 1177 or :class:`False` otherwise. 1178 """ 1179 l = len(self) 1180 if l <= len(other): 1181 if self._value[:l] == other[:l]: 1182 return True 1183 return False 1184 1185 def prettyIn(self, value): 1186 if isinstance(value, ObjectIdentifier): 1187 return tuple(value) 1188 elif octets.isStringType(value): 1189 if '-' in value: 1190 raise error.PyAsn1Error( 1191 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) 1192 ) 1193 try: 1194 return tuple([int(subOid) for subOid in value.split('.') if subOid]) 1195 except ValueError: 1196 raise error.PyAsn1Error( 1197 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) 1198 ) 1199 1200 try: 1201 tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0]) 1202 1203 except (ValueError, TypeError): 1204 raise error.PyAsn1Error( 1205 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) 1206 ) 1207 1208 if len(tupleOfInts) == len(value): 1209 return tupleOfInts 1210 1211 raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__)) 1212 1213 def prettyOut(self, value): 1214 return '.'.join([str(x) for x in value]) 1215 1216 1217class Real(base.AbstractSimpleAsn1Item): 1218 """Create |ASN.1| schema or value object. 1219 1220 |ASN.1| objects are immutable and duck-type Python :class:`float` objects. 1221 Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its 1222 elements are mantissa, base and exponent. 1223 1224 Keyword Args 1225 ------------ 1226 value: :class:`tuple`, :class:`float` or |ASN.1| object 1227 Python sequence of :class:`int` (representing mantissa, base and 1228 exponent) or float instance or *Real* class instance. 1229 1230 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1231 Object representing non-default ASN.1 tag(s) 1232 1233 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1234 Object representing non-default ASN.1 subtype constraint(s) 1235 1236 Raises 1237 ------ 1238 :py:class:`~pyasn1.error.PyAsn1Error` 1239 On constraint violation or bad initializer. 1240 1241 Examples 1242 -------- 1243 .. code-block:: python 1244 1245 class Pi(Real): 1246 ''' 1247 ASN.1 specification: 1248 1249 Pi ::= REAL 1250 1251 pi Pi ::= { mantissa 314159, base 10, exponent -5 } 1252 1253 ''' 1254 pi = Pi((314159, 10, -5)) 1255 """ 1256 binEncBase = None # binEncBase = 16 is recommended for large numbers 1257 1258 try: 1259 _plusInf = float('inf') 1260 _minusInf = float('-inf') 1261 _inf = _plusInf, _minusInf 1262 1263 except ValueError: 1264 # Infinity support is platform and Python dependent 1265 _plusInf = _minusInf = None 1266 _inf = () 1267 1268 #: Set (on class, not on instance) or return a 1269 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1270 #: associated with |ASN.1| type. 1271 tagSet = tag.initTagSet( 1272 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09) 1273 ) 1274 1275 #: Set (on class, not on instance) or return a 1276 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 1277 #: imposing constraints on |ASN.1| type initialization values. 1278 subtypeSpec = constraint.ConstraintsIntersection() 1279 1280 # Optimization for faster codec lookup 1281 typeId = base.AbstractSimpleAsn1Item.getTypeId() 1282 1283 @staticmethod 1284 def __normalizeBase10(value): 1285 m, b, e = value 1286 while m and m % 10 == 0: 1287 m /= 10 1288 e += 1 1289 return m, b, e 1290 1291 def prettyIn(self, value): 1292 if isinstance(value, tuple) and len(value) == 3: 1293 if (not isinstance(value[0], numericTypes) or 1294 not isinstance(value[1], intTypes) or 1295 not isinstance(value[2], intTypes)): 1296 raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,)) 1297 if (isinstance(value[0], float) and 1298 self._inf and value[0] in self._inf): 1299 return value[0] 1300 if value[1] not in (2, 10): 1301 raise error.PyAsn1Error( 1302 'Prohibited base for Real value: %s' % (value[1],) 1303 ) 1304 if value[1] == 10: 1305 value = self.__normalizeBase10(value) 1306 return value 1307 elif isinstance(value, intTypes): 1308 return self.__normalizeBase10((value, 10, 0)) 1309 elif isinstance(value, float) or octets.isStringType(value): 1310 if octets.isStringType(value): 1311 try: 1312 value = float(value) 1313 except ValueError: 1314 raise error.PyAsn1Error( 1315 'Bad real value syntax: %s' % (value,) 1316 ) 1317 if self._inf and value in self._inf: 1318 return value 1319 else: 1320 e = 0 1321 while int(value) != value: 1322 value *= 10 1323 e -= 1 1324 return self.__normalizeBase10((int(value), 10, e)) 1325 elif isinstance(value, Real): 1326 return tuple(value) 1327 raise error.PyAsn1Error( 1328 'Bad real value syntax: %s' % (value,) 1329 ) 1330 1331 def prettyPrint(self, scope=0): 1332 try: 1333 return self.prettyOut(float(self)) 1334 1335 except OverflowError: 1336 return '<overflow>' 1337 1338 @property 1339 def isPlusInf(self): 1340 """Indicate PLUS-INFINITY object value 1341 1342 Returns 1343 ------- 1344 : :class:`bool` 1345 :class:`True` if calling object represents plus infinity 1346 or :class:`False` otherwise. 1347 1348 """ 1349 return self._value == self._plusInf 1350 1351 @property 1352 def isMinusInf(self): 1353 """Indicate MINUS-INFINITY object value 1354 1355 Returns 1356 ------- 1357 : :class:`bool` 1358 :class:`True` if calling object represents minus infinity 1359 or :class:`False` otherwise. 1360 """ 1361 return self._value == self._minusInf 1362 1363 @property 1364 def isInf(self): 1365 return self._value in self._inf 1366 1367 def __add__(self, value): 1368 return self.clone(float(self) + value) 1369 1370 def __radd__(self, value): 1371 return self + value 1372 1373 def __mul__(self, value): 1374 return self.clone(float(self) * value) 1375 1376 def __rmul__(self, value): 1377 return self * value 1378 1379 def __sub__(self, value): 1380 return self.clone(float(self) - value) 1381 1382 def __rsub__(self, value): 1383 return self.clone(value - float(self)) 1384 1385 def __mod__(self, value): 1386 return self.clone(float(self) % value) 1387 1388 def __rmod__(self, value): 1389 return self.clone(value % float(self)) 1390 1391 def __pow__(self, value, modulo=None): 1392 return self.clone(pow(float(self), value, modulo)) 1393 1394 def __rpow__(self, value): 1395 return self.clone(pow(value, float(self))) 1396 1397 if sys.version_info[0] <= 2: 1398 def __div__(self, value): 1399 return self.clone(float(self) / value) 1400 1401 def __rdiv__(self, value): 1402 return self.clone(value / float(self)) 1403 else: 1404 def __truediv__(self, value): 1405 return self.clone(float(self) / value) 1406 1407 def __rtruediv__(self, value): 1408 return self.clone(value / float(self)) 1409 1410 def __divmod__(self, value): 1411 return self.clone(float(self) // value) 1412 1413 def __rdivmod__(self, value): 1414 return self.clone(value // float(self)) 1415 1416 def __int__(self): 1417 return int(float(self)) 1418 1419 if sys.version_info[0] <= 2: 1420 def __long__(self): 1421 return long(float(self)) 1422 1423 def __float__(self): 1424 if self._value in self._inf: 1425 return self._value 1426 else: 1427 return float( 1428 self._value[0] * pow(self._value[1], self._value[2]) 1429 ) 1430 1431 def __abs__(self): 1432 return self.clone(abs(float(self))) 1433 1434 def __pos__(self): 1435 return self.clone(+float(self)) 1436 1437 def __neg__(self): 1438 return self.clone(-float(self)) 1439 1440 def __round__(self, n=0): 1441 r = round(float(self), n) 1442 if n: 1443 return self.clone(r) 1444 else: 1445 return r 1446 1447 def __floor__(self): 1448 return self.clone(math.floor(float(self))) 1449 1450 def __ceil__(self): 1451 return self.clone(math.ceil(float(self))) 1452 1453 if sys.version_info[0:2] > (2, 5): 1454 def __trunc__(self): 1455 return self.clone(math.trunc(float(self))) 1456 1457 def __lt__(self, value): 1458 return float(self) < value 1459 1460 def __le__(self, value): 1461 return float(self) <= value 1462 1463 def __eq__(self, value): 1464 return float(self) == value 1465 1466 def __ne__(self, value): 1467 return float(self) != value 1468 1469 def __gt__(self, value): 1470 return float(self) > value 1471 1472 def __ge__(self, value): 1473 return float(self) >= value 1474 1475 if sys.version_info[0] <= 2: 1476 def __nonzero__(self): 1477 return bool(float(self)) 1478 else: 1479 def __bool__(self): 1480 return bool(float(self)) 1481 1482 __hash__ = base.AbstractSimpleAsn1Item.__hash__ 1483 1484 def __getitem__(self, idx): 1485 if self._value in self._inf: 1486 raise error.PyAsn1Error('Invalid infinite value operation') 1487 else: 1488 return self._value[idx] 1489 1490 # compatibility stubs 1491 1492 def isPlusInfinity(self): 1493 return self.isPlusInf 1494 1495 def isMinusInfinity(self): 1496 return self.isMinusInf 1497 1498 def isInfinity(self): 1499 return self.isInf 1500 1501 1502class Enumerated(Integer): 1503 """Create |ASN.1| type or object. 1504 1505 |ASN.1| objects are immutable and duck-type Python :class:`int` objects. 1506 1507 Keyword Args 1508 ------------ 1509 value: :class:`int`, :class:`str` or |ASN.1| object 1510 Python integer or string literal or |ASN.1| class instance. 1511 1512 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1513 Object representing non-default ASN.1 tag(s) 1514 1515 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1516 Object representing non-default ASN.1 subtype constraint(s) 1517 1518 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 1519 Object representing non-default symbolic aliases for numbers 1520 1521 Raises 1522 ------ 1523 :py:class:`~pyasn1.error.PyAsn1Error` 1524 On constraint violation or bad initializer. 1525 1526 Examples 1527 -------- 1528 1529 .. code-block:: python 1530 1531 class RadioButton(Enumerated): 1532 ''' 1533 ASN.1 specification: 1534 1535 RadioButton ::= ENUMERATED { button1(0), button2(1), 1536 button3(2) } 1537 1538 selected-by-default RadioButton ::= button1 1539 ''' 1540 namedValues = NamedValues( 1541 ('button1', 0), ('button2', 1), 1542 ('button3', 2) 1543 ) 1544 1545 selected_by_default = RadioButton('button1') 1546 """ 1547 #: Set (on class, not on instance) or return a 1548 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1549 #: associated with |ASN.1| type. 1550 tagSet = tag.initTagSet( 1551 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A) 1552 ) 1553 1554 #: Set (on class, not on instance) or return a 1555 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 1556 #: imposing constraints on |ASN.1| type initialization values. 1557 subtypeSpec = constraint.ConstraintsIntersection() 1558 1559 # Optimization for faster codec lookup 1560 typeId = Integer.getTypeId() 1561 1562 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 1563 #: representing symbolic aliases for numbers 1564 namedValues = namedval.NamedValues() 1565 1566 1567# "Structured" ASN.1 types 1568 1569class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item): 1570 """Create |ASN.1| type. 1571 1572 |ASN.1| objects are mutable and duck-type Python :class:`list` objects. 1573 1574 Keyword Args 1575 ------------ 1576 componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 1577 A pyasn1 object representing ASN.1 type allowed within |ASN.1| type 1578 1579 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1580 Object representing non-default ASN.1 tag(s) 1581 1582 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1583 Object representing non-default ASN.1 subtype constraint(s) 1584 1585 sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1586 Object representing collection size constraint 1587 1588 Examples 1589 -------- 1590 1591 .. code-block:: python 1592 1593 class LotteryDraw(SequenceOf): # SetOf is similar 1594 ''' 1595 ASN.1 specification: 1596 1597 LotteryDraw ::= SEQUENCE OF INTEGER 1598 ''' 1599 componentType = Integer() 1600 1601 lotteryDraw = LotteryDraw() 1602 lotteryDraw.extend([123, 456, 789]) 1603 """ 1604 def __init__(self, *args, **kwargs): 1605 # support positional params for backward compatibility 1606 if args: 1607 for key, value in zip(('componentType', 'tagSet', 1608 'subtypeSpec', 'sizeSpec'), args): 1609 if key in kwargs: 1610 raise error.PyAsn1Error('Conflicting positional and keyword params!') 1611 kwargs['componentType'] = value 1612 1613 base.AbstractConstructedAsn1Item.__init__(self, **kwargs) 1614 1615 # Python list protocol 1616 1617 def __getitem__(self, idx): 1618 try: 1619 return self.getComponentByPosition(idx) 1620 1621 except error.PyAsn1Error: 1622 raise IndexError(sys.exc_info()[1]) 1623 1624 def __setitem__(self, idx, value): 1625 try: 1626 self.setComponentByPosition(idx, value) 1627 1628 except error.PyAsn1Error: 1629 raise IndexError(sys.exc_info()[1]) 1630 1631 def clear(self): 1632 self._componentValues = [] 1633 1634 def append(self, value): 1635 self[len(self)] = value 1636 1637 def count(self, value): 1638 return self._componentValues.count(value) 1639 1640 def extend(self, values): 1641 for value in values: 1642 self.append(value) 1643 1644 def index(self, value, start=0, stop=None): 1645 if stop is None: 1646 stop = len(self) 1647 try: 1648 return self._componentValues.index(value, start, stop) 1649 1650 except error.PyAsn1Error: 1651 raise ValueError(sys.exc_info()[1]) 1652 1653 def reverse(self): 1654 self._componentValues.reverse() 1655 1656 def sort(self, key=None, reverse=False): 1657 self._componentValues.sort(key=key, reverse=reverse) 1658 1659 def __iter__(self): 1660 return iter(self._componentValues) 1661 1662 def _cloneComponentValues(self, myClone, cloneValueFlag): 1663 for idx, componentValue in enumerate(self._componentValues): 1664 if componentValue is not noValue: 1665 if isinstance(componentValue, base.AbstractConstructedAsn1Item): 1666 myClone.setComponentByPosition( 1667 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 1668 ) 1669 else: 1670 myClone.setComponentByPosition(idx, componentValue.clone()) 1671 1672 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 1673 """Return |ASN.1| type component value by position. 1674 1675 Equivalent to Python sequence subscription operation (e.g. `[]`). 1676 1677 Parameters 1678 ---------- 1679 idx : :class:`int` 1680 Component index (zero-based). Must either refer to an existing 1681 component or to N+1 component (if *componentType* is set). In the latter 1682 case a new component type gets instantiated and appended to the |ASN.1| 1683 sequence. 1684 1685 Keyword Args 1686 ------------ 1687 default: :class:`object` 1688 If set and requested component is a schema object, return the `default` 1689 object instead of the requested component. 1690 1691 instantiate: :class:`bool` 1692 If `True` (default), inner component will be automatically instantiated. 1693 If 'False' either existing component or the `noValue` object will be 1694 returned. 1695 1696 Returns 1697 ------- 1698 : :py:class:`~pyasn1.type.base.PyAsn1Item` 1699 Instantiate |ASN.1| component type or return existing component value 1700 1701 Examples 1702 -------- 1703 1704 .. code-block:: python 1705 1706 # can also be SetOf 1707 class MySequenceOf(SequenceOf): 1708 componentType = OctetString() 1709 1710 s = MySequenceOf() 1711 1712 # returns component #0 with `.isValue` property False 1713 s.getComponentByPosition(0) 1714 1715 # returns None 1716 s.getComponentByPosition(0, default=None) 1717 1718 s.clear() 1719 1720 # returns noValue 1721 s.getComponentByPosition(0, instantiate=False) 1722 1723 # sets component #0 to OctetString() ASN.1 schema 1724 # object and returns it 1725 s.getComponentByPosition(0, instantiate=True) 1726 1727 # sets component #0 to ASN.1 value object 1728 s.setComponentByPosition(0, 'ABCD') 1729 1730 # returns OctetString('ABCD') value object 1731 s.getComponentByPosition(0, instantiate=False) 1732 1733 s.clear() 1734 1735 # returns noValue 1736 s.getComponentByPosition(0, instantiate=False) 1737 """ 1738 try: 1739 componentValue = self._componentValues[idx] 1740 1741 except IndexError: 1742 if not instantiate: 1743 return default 1744 1745 self.setComponentByPosition(idx) 1746 1747 componentValue = self._componentValues[idx] 1748 1749 if default is noValue or componentValue.isValue: 1750 return componentValue 1751 else: 1752 return default 1753 1754 def setComponentByPosition(self, idx, value=noValue, 1755 verifyConstraints=True, 1756 matchTags=True, 1757 matchConstraints=True): 1758 """Assign |ASN.1| type component by position. 1759 1760 Equivalent to Python sequence item assignment operation (e.g. `[]`) 1761 or list.append() (when idx == len(self)). 1762 1763 Parameters 1764 ---------- 1765 idx: :class:`int` 1766 Component index (zero-based). Must either refer to existing 1767 component or to N+1 component. In the latter case a new component 1768 type gets instantiated (if *componentType* is set, or given ASN.1 1769 object is taken otherwise) and appended to the |ASN.1| sequence. 1770 1771 Keyword Args 1772 ------------ 1773 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 1774 A Python value to initialize |ASN.1| component with (if *componentType* is set) 1775 or ASN.1 value object to assign to |ASN.1| component. 1776 1777 verifyConstraints: :class:`bool` 1778 If `False`, skip constraints validation 1779 1780 matchTags: :class:`bool` 1781 If `False`, skip component tags matching 1782 1783 matchConstraints: :class:`bool` 1784 If `False`, skip component constraints matching 1785 1786 Returns 1787 ------- 1788 self 1789 1790 Raises 1791 ------ 1792 IndexError: 1793 When idx > len(self) 1794 """ 1795 componentType = self.componentType 1796 1797 try: 1798 currentValue = self._componentValues[idx] 1799 except IndexError: 1800 currentValue = noValue 1801 1802 if len(self._componentValues) < idx: 1803 raise error.PyAsn1Error('Component index out of range') 1804 1805 if value is noValue: 1806 if componentType is not None: 1807 value = componentType.clone() 1808 elif currentValue is noValue: 1809 raise error.PyAsn1Error('Component type not defined') 1810 elif not isinstance(value, base.Asn1Item): 1811 if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item): 1812 value = componentType.clone(value=value) 1813 elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item): 1814 value = currentValue.clone(value=value) 1815 else: 1816 raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self)) 1817 elif componentType is not None: 1818 if self.strictConstraints: 1819 if not componentType.isSameTypeWith(value, matchTags, matchConstraints): 1820 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) 1821 else: 1822 if not componentType.isSuperTypeOf(value, matchTags, matchConstraints): 1823 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) 1824 1825 if verifyConstraints and value.isValue: 1826 try: 1827 self.subtypeSpec(value, idx) 1828 1829 except error.PyAsn1Error: 1830 exType, exValue, exTb = sys.exc_info() 1831 raise exType('%s at %s' % (exValue, self.__class__.__name__)) 1832 1833 if currentValue is noValue: 1834 self._componentValues.append(value) 1835 else: 1836 self._componentValues[idx] = value 1837 1838 return self 1839 1840 @property 1841 def componentTagMap(self): 1842 if self.componentType is not None: 1843 return self.componentType.tagMap 1844 1845 def prettyPrint(self, scope=0): 1846 scope += 1 1847 representation = self.__class__.__name__ + ':\n' 1848 for idx, componentValue in enumerate(self._componentValues): 1849 representation += ' ' * scope 1850 if (componentValue is noValue and 1851 self.componentType is not None): 1852 representation += '<empty>' 1853 else: 1854 representation += componentValue.prettyPrint(scope) 1855 return representation 1856 1857 def prettyPrintType(self, scope=0): 1858 scope += 1 1859 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) 1860 if self.componentType is not None: 1861 representation += ' ' * scope 1862 representation += self.componentType.prettyPrintType(scope) 1863 return representation + '\n' + ' ' * (scope - 1) + '}' 1864 1865 1866 @property 1867 def isValue(self): 1868 """Indicate that |ASN.1| object represents ASN.1 value. 1869 1870 If *isValue* is `False` then this object represents just ASN.1 schema. 1871 1872 If *isValue* is `True` then, in addition to its ASN.1 schema features, 1873 this object can also be used like a Python built-in object (e.g. `int`, 1874 `str`, `dict` etc.). 1875 1876 Returns 1877 ------- 1878 : :class:`bool` 1879 :class:`False` if object represents just ASN.1 schema. 1880 :class:`True` if object represents ASN.1 schema and can be used as a normal value. 1881 1882 Note 1883 ---- 1884 There is an important distinction between PyASN1 schema and value objects. 1885 The PyASN1 schema objects can only participate in ASN.1 schema-related 1886 operations (e.g. defining or testing the structure of the data). Most 1887 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 1888 encoding/decoding serialised ASN.1 contents. 1889 1890 The PyASN1 value objects can **additionally** participate in many operations 1891 involving regular Python objects (e.g. arithmetic, comprehension etc). 1892 """ 1893 for componentValue in self._componentValues: 1894 if componentValue is noValue or not componentValue.isValue: 1895 return False 1896 1897 return True 1898 1899 1900class SequenceOf(SequenceOfAndSetOfBase): 1901 __doc__ = SequenceOfAndSetOfBase.__doc__ 1902 1903 #: Set (on class, not on instance) or return a 1904 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1905 #: associated with |ASN.1| type. 1906 tagSet = tag.initTagSet( 1907 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) 1908 ) 1909 1910 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 1911 #: object representing ASN.1 type allowed within |ASN.1| type 1912 componentType = None 1913 1914 #: Set (on class, not on instance) or return a 1915 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 1916 #: imposing constraints on |ASN.1| type initialization values. 1917 subtypeSpec = constraint.ConstraintsIntersection() 1918 1919 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1920 #: object imposing size constraint on |ASN.1| objects 1921 sizeSpec = constraint.ConstraintsIntersection() 1922 1923 # Disambiguation ASN.1 types identification 1924 typeId = SequenceOfAndSetOfBase.getTypeId() 1925 1926 1927class SetOf(SequenceOfAndSetOfBase): 1928 __doc__ = SequenceOfAndSetOfBase.__doc__ 1929 1930 #: Set (on class, not on instance) or return a 1931 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 1932 #: associated with |ASN.1| type. 1933 tagSet = tag.initTagSet( 1934 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) 1935 ) 1936 1937 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 1938 #: object representing ASN.1 type allowed within |ASN.1| type 1939 componentType = None 1940 1941 #: Set (on class, not on instance) or return a 1942 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 1943 #: imposing constraints on |ASN.1| type initialization values. 1944 subtypeSpec = constraint.ConstraintsIntersection() 1945 1946 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1947 #: object imposing size constraint on |ASN.1| objects 1948 sizeSpec = constraint.ConstraintsIntersection() 1949 1950 # Disambiguation ASN.1 types identification 1951 typeId = SequenceOfAndSetOfBase.getTypeId() 1952 1953 1954class SequenceAndSetBase(base.AbstractConstructedAsn1Item): 1955 """Create |ASN.1| type. 1956 1957 |ASN.1| objects are mutable and duck-type Python :class:`dict` objects. 1958 1959 Keyword Args 1960 ------------ 1961 componentType: :py:class:`~pyasn1.type.namedtype.NamedType` 1962 Object holding named ASN.1 types allowed within this collection 1963 1964 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 1965 Object representing non-default ASN.1 tag(s) 1966 1967 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1968 Object representing non-default ASN.1 subtype constraint(s) 1969 1970 sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 1971 Object representing collection size constraint 1972 1973 Examples 1974 -------- 1975 1976 .. code-block:: python 1977 1978 class Description(Sequence): # Set is similar 1979 ''' 1980 ASN.1 specification: 1981 1982 Description ::= SEQUENCE { 1983 surname IA5String, 1984 first-name IA5String OPTIONAL, 1985 age INTEGER DEFAULT 40 1986 } 1987 ''' 1988 componentType = NamedTypes( 1989 NamedType('surname', IA5String()), 1990 OptionalNamedType('first-name', IA5String()), 1991 DefaultedNamedType('age', Integer(40)) 1992 ) 1993 1994 descr = Description() 1995 descr['surname'] = 'Smith' 1996 descr['first-name'] = 'John' 1997 """ 1998 #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes` 1999 #: object representing named ASN.1 types allowed within |ASN.1| type 2000 componentType = namedtype.NamedTypes() 2001 2002 2003 class DynamicNames(object): 2004 """Fields names/positions mapping for component-less objects""" 2005 def __init__(self): 2006 self._keyToIdxMap = {} 2007 self._idxToKeyMap = {} 2008 2009 def __len__(self): 2010 return len(self._keyToIdxMap) 2011 2012 def __contains__(self, item): 2013 return item in self._keyToIdxMap or item in self._idxToKeyMap 2014 2015 def __iter__(self): 2016 return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap))) 2017 2018 def __getitem__(self, item): 2019 try: 2020 return self._keyToIdxMap[item] 2021 2022 except KeyError: 2023 return self._idxToKeyMap[item] 2024 2025 def getNameByPosition(self, idx): 2026 try: 2027 return self._idxToKeyMap[idx] 2028 2029 except KeyError: 2030 raise error.PyAsn1Error('Type position out of range') 2031 2032 def getPositionByName(self, name): 2033 try: 2034 return self._keyToIdxMap[name] 2035 2036 except KeyError: 2037 raise error.PyAsn1Error('Name %s not found' % (name,)) 2038 2039 def addField(self, idx): 2040 self._keyToIdxMap['field-%d' % idx] = idx 2041 self._idxToKeyMap[idx] = 'field-%d' % idx 2042 2043 2044 def __init__(self, **kwargs): 2045 base.AbstractConstructedAsn1Item.__init__(self, **kwargs) 2046 self._componentTypeLen = len(self.componentType) 2047 self._dynamicNames = self._componentTypeLen or self.DynamicNames() 2048 2049 def __getitem__(self, idx): 2050 if octets.isStringType(idx): 2051 try: 2052 return self.getComponentByName(idx) 2053 2054 except error.PyAsn1Error: 2055 # duck-typing dict 2056 raise KeyError(sys.exc_info()[1]) 2057 2058 else: 2059 try: 2060 return self.getComponentByPosition(idx) 2061 2062 except error.PyAsn1Error: 2063 # duck-typing list 2064 raise IndexError(sys.exc_info()[1]) 2065 2066 def __setitem__(self, idx, value): 2067 if octets.isStringType(idx): 2068 try: 2069 self.setComponentByName(idx, value) 2070 2071 except error.PyAsn1Error: 2072 # duck-typing dict 2073 raise KeyError(sys.exc_info()[1]) 2074 2075 else: 2076 try: 2077 self.setComponentByPosition(idx, value) 2078 2079 except error.PyAsn1Error: 2080 # duck-typing list 2081 raise IndexError(sys.exc_info()[1]) 2082 2083 def __contains__(self, key): 2084 if self._componentTypeLen: 2085 return key in self.componentType 2086 else: 2087 return key in self._dynamicNames 2088 2089 def __iter__(self): 2090 return iter(self.componentType or self._dynamicNames) 2091 2092 # Python dict protocol 2093 2094 def values(self): 2095 for idx in range(self._componentTypeLen or len(self._dynamicNames)): 2096 yield self[idx] 2097 2098 def keys(self): 2099 return iter(self) 2100 2101 def items(self): 2102 for idx in range(self._componentTypeLen or len(self._dynamicNames)): 2103 if self._componentTypeLen: 2104 yield self.componentType[idx].name, self[idx] 2105 else: 2106 yield self._dynamicNames[idx], self[idx] 2107 2108 def update(self, *iterValue, **mappingValue): 2109 for k, v in iterValue: 2110 self[k] = v 2111 for k in mappingValue: 2112 self[k] = mappingValue[k] 2113 2114 def clear(self): 2115 self._componentValues = [] 2116 self._dynamicNames = self.DynamicNames() 2117 2118 def _cloneComponentValues(self, myClone, cloneValueFlag): 2119 for idx, componentValue in enumerate(self._componentValues): 2120 if componentValue is not noValue: 2121 if isinstance(componentValue, base.AbstractConstructedAsn1Item): 2122 myClone.setComponentByPosition( 2123 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 2124 ) 2125 else: 2126 myClone.setComponentByPosition(idx, componentValue.clone()) 2127 2128 def getComponentByName(self, name, default=noValue, instantiate=True): 2129 """Returns |ASN.1| type component by name. 2130 2131 Equivalent to Python :class:`dict` subscription operation (e.g. `[]`). 2132 2133 Parameters 2134 ---------- 2135 name: :class:`str` 2136 |ASN.1| type component name 2137 2138 Keyword Args 2139 ------------ 2140 default: :class:`object` 2141 If set and requested component is a schema object, return the `default` 2142 object instead of the requested component. 2143 2144 instantiate: :class:`bool` 2145 If `True` (default), inner component will be automatically instantiated. 2146 If 'False' either existing component or the `noValue` object will be 2147 returned. 2148 2149 Returns 2150 ------- 2151 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2152 Instantiate |ASN.1| component type or return existing component value 2153 """ 2154 if self._componentTypeLen: 2155 idx = self.componentType.getPositionByName(name) 2156 else: 2157 try: 2158 idx = self._dynamicNames.getPositionByName(name) 2159 2160 except KeyError: 2161 raise error.PyAsn1Error('Name %s not found' % (name,)) 2162 2163 return self.getComponentByPosition(idx, default=default, instantiate=instantiate) 2164 2165 def setComponentByName(self, name, value=noValue, 2166 verifyConstraints=True, 2167 matchTags=True, 2168 matchConstraints=True): 2169 """Assign |ASN.1| type component by name. 2170 2171 Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`). 2172 2173 Parameters 2174 ---------- 2175 name: :class:`str` 2176 |ASN.1| type component name 2177 2178 Keyword Args 2179 ------------ 2180 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2181 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2182 or ASN.1 value object to assign to |ASN.1| component. 2183 2184 verifyConstraints: :class:`bool` 2185 If `False`, skip constraints validation 2186 2187 matchTags: :class:`bool` 2188 If `False`, skip component tags matching 2189 2190 matchConstraints: :class:`bool` 2191 If `False`, skip component constraints matching 2192 2193 Returns 2194 ------- 2195 self 2196 """ 2197 if self._componentTypeLen: 2198 idx = self.componentType.getPositionByName(name) 2199 else: 2200 try: 2201 idx = self._dynamicNames.getPositionByName(name) 2202 2203 except KeyError: 2204 raise error.PyAsn1Error('Name %s not found' % (name,)) 2205 2206 return self.setComponentByPosition( 2207 idx, value, verifyConstraints, matchTags, matchConstraints 2208 ) 2209 2210 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 2211 """Returns |ASN.1| type component by index. 2212 2213 Equivalent to Python sequence subscription operation (e.g. `[]`). 2214 2215 Parameters 2216 ---------- 2217 idx: :class:`int` 2218 Component index (zero-based). Must either refer to an existing 2219 component or (if *componentType* is set) new ASN.1 schema object gets 2220 instantiated. 2221 2222 Keyword Args 2223 ------------ 2224 default: :class:`object` 2225 If set and requested component is a schema object, return the `default` 2226 object instead of the requested component. 2227 2228 instantiate: :class:`bool` 2229 If `True` (default), inner component will be automatically instantiated. 2230 If 'False' either existing component or the `noValue` object will be 2231 returned. 2232 2233 Returns 2234 ------- 2235 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2236 a PyASN1 object 2237 2238 Examples 2239 -------- 2240 2241 .. code-block:: python 2242 2243 # can also be Set 2244 class MySequence(Sequence): 2245 componentType = NamedTypes( 2246 NamedType('id', OctetString()) 2247 ) 2248 2249 s = MySequence() 2250 2251 # returns component #0 with `.isValue` property False 2252 s.getComponentByPosition(0) 2253 2254 # returns None 2255 s.getComponentByPosition(0, default=None) 2256 2257 s.clear() 2258 2259 # returns noValue 2260 s.getComponentByPosition(0, instantiate=False) 2261 2262 # sets component #0 to OctetString() ASN.1 schema 2263 # object and returns it 2264 s.getComponentByPosition(0, instantiate=True) 2265 2266 # sets component #0 to ASN.1 value object 2267 s.setComponentByPosition(0, 'ABCD') 2268 2269 # returns OctetString('ABCD') value object 2270 s.getComponentByPosition(0, instantiate=False) 2271 2272 s.clear() 2273 2274 # returns noValue 2275 s.getComponentByPosition(0, instantiate=False) 2276 """ 2277 try: 2278 componentValue = self._componentValues[idx] 2279 2280 except IndexError: 2281 componentValue = noValue 2282 2283 if not instantiate: 2284 if componentValue is noValue or not componentValue.isValue: 2285 return default 2286 else: 2287 return componentValue 2288 2289 if componentValue is noValue: 2290 self.setComponentByPosition(idx) 2291 2292 componentValue = self._componentValues[idx] 2293 2294 if default is noValue or componentValue.isValue: 2295 return componentValue 2296 else: 2297 return default 2298 2299 def setComponentByPosition(self, idx, value=noValue, 2300 verifyConstraints=True, 2301 matchTags=True, 2302 matchConstraints=True): 2303 """Assign |ASN.1| type component by position. 2304 2305 Equivalent to Python sequence item assignment operation (e.g. `[]`). 2306 2307 Parameters 2308 ---------- 2309 idx : :class:`int` 2310 Component index (zero-based). Must either refer to existing 2311 component (if *componentType* is set) or to N+1 component 2312 otherwise. In the latter case a new component of given ASN.1 2313 type gets instantiated and appended to |ASN.1| sequence. 2314 2315 Keyword Args 2316 ------------ 2317 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2318 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2319 or ASN.1 value object to assign to |ASN.1| component. 2320 2321 verifyConstraints : :class:`bool` 2322 If `False`, skip constraints validation 2323 2324 matchTags: :class:`bool` 2325 If `False`, skip component tags matching 2326 2327 matchConstraints: :class:`bool` 2328 If `False`, skip component constraints matching 2329 2330 Returns 2331 ------- 2332 self 2333 """ 2334 componentType = self.componentType 2335 componentTypeLen = self._componentTypeLen 2336 2337 try: 2338 currentValue = self._componentValues[idx] 2339 2340 except IndexError: 2341 currentValue = noValue 2342 if componentTypeLen: 2343 if componentTypeLen < idx: 2344 raise error.PyAsn1Error('component index out of range') 2345 2346 self._componentValues = [noValue] * componentTypeLen 2347 2348 if value is noValue: 2349 if componentTypeLen: 2350 value = componentType.getTypeByPosition(idx) 2351 if isinstance(value, base.AbstractConstructedAsn1Item): 2352 value = value.clone(cloneValueFlag=componentType[idx].isDefaulted) 2353 2354 elif currentValue is noValue: 2355 raise error.PyAsn1Error('Component type not defined') 2356 2357 elif not isinstance(value, base.Asn1Item): 2358 if componentTypeLen: 2359 subComponentType = componentType.getTypeByPosition(idx) 2360 if isinstance(subComponentType, base.AbstractSimpleAsn1Item): 2361 value = subComponentType.clone(value=value) 2362 2363 else: 2364 raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__) 2365 2366 elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item): 2367 value = currentValue.clone(value=value) 2368 2369 else: 2370 raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__) 2371 2372 elif (matchTags or matchConstraints) and componentTypeLen: 2373 subComponentType = componentType.getTypeByPosition(idx) 2374 if subComponentType is not noValue: 2375 subtypeChecker = (self.strictConstraints and 2376 subComponentType.isSameTypeWith or 2377 subComponentType.isSuperTypeOf) 2378 2379 if not subtypeChecker(value, matchTags, matchConstraints): 2380 if not componentType[idx].openType: 2381 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) 2382 2383 if verifyConstraints and value.isValue: 2384 try: 2385 self.subtypeSpec(value, idx) 2386 2387 except error.PyAsn1Error: 2388 exType, exValue, exTb = sys.exc_info() 2389 raise exType('%s at %s' % (exValue, self.__class__.__name__)) 2390 2391 if componentTypeLen or idx in self._dynamicNames: 2392 self._componentValues[idx] = value 2393 2394 elif len(self._componentValues) == idx: 2395 self._componentValues.append(value) 2396 self._dynamicNames.addField(idx) 2397 2398 else: 2399 raise error.PyAsn1Error('Component index out of range') 2400 2401 return self 2402 2403 @property 2404 def isValue(self): 2405 """Indicate that |ASN.1| object represents ASN.1 value. 2406 2407 If *isValue* is `False` then this object represents just ASN.1 schema. 2408 2409 If *isValue* is `True` then, in addition to its ASN.1 schema features, 2410 this object can also be used like a Python built-in object (e.g. `int`, 2411 `str`, `dict` etc.). 2412 2413 Returns 2414 ------- 2415 : :class:`bool` 2416 :class:`False` if object represents just ASN.1 schema. 2417 :class:`True` if object represents ASN.1 schema and can be used as a normal value. 2418 2419 Note 2420 ---- 2421 There is an important distinction between PyASN1 schema and value objects. 2422 The PyASN1 schema objects can only participate in ASN.1 schema-related 2423 operations (e.g. defining or testing the structure of the data). Most 2424 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 2425 encoding/decoding serialised ASN.1 contents. 2426 2427 The PyASN1 value objects can **additionally** participate in many operations 2428 involving regular Python objects (e.g. arithmetic, comprehension etc). 2429 """ 2430 componentType = self.componentType 2431 2432 if componentType: 2433 for idx, subComponentType in enumerate(componentType.namedTypes): 2434 if subComponentType.isDefaulted or subComponentType.isOptional: 2435 continue 2436 2437 if not self._componentValues: 2438 return False 2439 2440 componentValue = self._componentValues[idx] 2441 if componentValue is noValue or not componentValue.isValue: 2442 return False 2443 2444 else: 2445 for componentValue in self._componentValues: 2446 if componentValue is noValue or not componentValue.isValue: 2447 return False 2448 2449 return True 2450 2451 def prettyPrint(self, scope=0): 2452 """Return an object representation string. 2453 2454 Returns 2455 ------- 2456 : :class:`str` 2457 Human-friendly object representation. 2458 """ 2459 scope += 1 2460 representation = self.__class__.__name__ + ':\n' 2461 for idx, componentValue in enumerate(self._componentValues): 2462 if componentValue is not noValue and componentValue.isValue: 2463 representation += ' ' * scope 2464 if self.componentType: 2465 representation += self.componentType.getNameByPosition(idx) 2466 else: 2467 representation += self._dynamicNames.getNameByPosition(idx) 2468 representation = '%s=%s\n' % ( 2469 representation, componentValue.prettyPrint(scope) 2470 ) 2471 return representation 2472 2473 def prettyPrintType(self, scope=0): 2474 scope += 1 2475 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) 2476 for idx, componentType in enumerate(self.componentType.values() or self._componentValues): 2477 representation += ' ' * scope 2478 if self.componentType: 2479 representation += '"%s"' % self.componentType.getNameByPosition(idx) 2480 else: 2481 representation += '"%s"' % self._dynamicNames.getNameByPosition(idx) 2482 representation = '%s = %s\n' % ( 2483 representation, componentType.prettyPrintType(scope) 2484 ) 2485 return representation + '\n' + ' ' * (scope - 1) + '}' 2486 2487 # backward compatibility 2488 2489 def setDefaultComponents(self): 2490 return self 2491 2492 def getComponentType(self): 2493 if self._componentTypeLen: 2494 return self.componentType 2495 2496 def getNameByPosition(self, idx): 2497 if self._componentTypeLen: 2498 return self.componentType[idx].name 2499 2500 2501class Sequence(SequenceAndSetBase): 2502 __doc__ = SequenceAndSetBase.__doc__ 2503 2504 #: Set (on class, not on instance) or return a 2505 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2506 #: associated with |ASN.1| type. 2507 tagSet = tag.initTagSet( 2508 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) 2509 ) 2510 2511 #: Set (on class, not on instance) or return a 2512 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2513 #: imposing constraints on |ASN.1| type initialization values. 2514 subtypeSpec = constraint.ConstraintsIntersection() 2515 2516 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2517 #: object imposing constraints on |ASN.1| objects 2518 sizeSpec = constraint.ConstraintsIntersection() 2519 2520 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2521 #: object imposing size constraint on |ASN.1| objects 2522 componentType = namedtype.NamedTypes() 2523 2524 # Disambiguation ASN.1 types identification 2525 typeId = SequenceAndSetBase.getTypeId() 2526 2527 # backward compatibility 2528 2529 def getComponentTagMapNearPosition(self, idx): 2530 if self.componentType: 2531 return self.componentType.getTagMapNearPosition(idx) 2532 2533 def getComponentPositionNearType(self, tagSet, idx): 2534 if self.componentType: 2535 return self.componentType.getPositionNearType(tagSet, idx) 2536 else: 2537 return idx 2538 2539 2540class Set(SequenceAndSetBase): 2541 __doc__ = SequenceAndSetBase.__doc__ 2542 2543 #: Set (on class, not on instance) or return a 2544 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2545 #: associated with |ASN.1| type. 2546 tagSet = tag.initTagSet( 2547 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) 2548 ) 2549 2550 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2551 #: object representing ASN.1 type allowed within |ASN.1| type 2552 componentType = namedtype.NamedTypes() 2553 2554 #: Set (on class, not on instance) or return a 2555 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2556 #: imposing constraints on |ASN.1| type initialization values. 2557 subtypeSpec = constraint.ConstraintsIntersection() 2558 2559 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2560 #: object imposing constraints on |ASN.1| objects 2561 sizeSpec = constraint.ConstraintsIntersection() 2562 2563 # Disambiguation ASN.1 types identification 2564 typeId = SequenceAndSetBase.getTypeId() 2565 2566 def getComponent(self, innerFlag=False): 2567 return self 2568 2569 def getComponentByType(self, tagSet, default=noValue, 2570 instantiate=True, innerFlag=False): 2571 """Returns |ASN.1| type component by ASN.1 tag. 2572 2573 Parameters 2574 ---------- 2575 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 2576 Object representing ASN.1 tags to identify one of 2577 |ASN.1| object component 2578 2579 Keyword Args 2580 ------------ 2581 default: :class:`object` 2582 If set and requested component is a schema object, return the `default` 2583 object instead of the requested component. 2584 2585 instantiate: :class:`bool` 2586 If `True` (default), inner component will be automatically instantiated. 2587 If 'False' either existing component or the `noValue` object will be 2588 returned. 2589 2590 Returns 2591 ------- 2592 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2593 a pyasn1 object 2594 """ 2595 componentValue = self.getComponentByPosition( 2596 self.componentType.getPositionByType(tagSet), 2597 default=default, instantiate=instantiate 2598 ) 2599 if innerFlag and isinstance(componentValue, Set): 2600 # get inner component by inner tagSet 2601 return componentValue.getComponent(innerFlag=True) 2602 else: 2603 # get outer component by inner tagSet 2604 return componentValue 2605 2606 def setComponentByType(self, tagSet, value=noValue, 2607 verifyConstraints=True, 2608 matchTags=True, 2609 matchConstraints=True, 2610 innerFlag=False): 2611 """Assign |ASN.1| type component by ASN.1 tag. 2612 2613 Parameters 2614 ---------- 2615 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 2616 Object representing ASN.1 tags to identify one of 2617 |ASN.1| object component 2618 2619 Keyword Args 2620 ------------ 2621 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2622 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2623 or ASN.1 value object to assign to |ASN.1| component. 2624 2625 verifyConstraints : :class:`bool` 2626 If `False`, skip constraints validation 2627 2628 matchTags: :class:`bool` 2629 If `False`, skip component tags matching 2630 2631 matchConstraints: :class:`bool` 2632 If `False`, skip component constraints matching 2633 2634 innerFlag: :class:`bool` 2635 If `True`, search for matching *tagSet* recursively. 2636 2637 Returns 2638 ------- 2639 self 2640 """ 2641 idx = self.componentType.getPositionByType(tagSet) 2642 2643 if innerFlag: # set inner component by inner tagSet 2644 componentType = self.componentType.getTypeByPosition(idx) 2645 2646 if componentType.tagSet: 2647 return self.setComponentByPosition( 2648 idx, value, verifyConstraints, matchTags, matchConstraints 2649 ) 2650 else: 2651 componentType = self.getComponentByPosition(idx) 2652 return componentType.setComponentByType( 2653 tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag 2654 ) 2655 else: # set outer component by inner tagSet 2656 return self.setComponentByPosition( 2657 idx, value, verifyConstraints, matchTags, matchConstraints 2658 ) 2659 2660 @property 2661 def componentTagMap(self): 2662 if self.componentType: 2663 return self.componentType.tagMapUnique 2664 2665 2666class Choice(Set): 2667 """Create |ASN.1| type. 2668 2669 |ASN.1| objects are mutable and duck-type Python :class:`dict` objects. 2670 2671 Keyword Args 2672 ------------ 2673 componentType: :py:class:`~pyasn1.type.namedtype.NamedType` 2674 Object holding named ASN.1 types allowed within this collection 2675 2676 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 2677 Object representing non-default ASN.1 tag(s) 2678 2679 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2680 Object representing non-default ASN.1 subtype constraint(s) 2681 2682 sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2683 Object representing collection size constraint 2684 2685 Examples 2686 -------- 2687 2688 .. code-block:: python 2689 2690 class Afters(Choice): 2691 ''' 2692 ASN.1 specification: 2693 2694 Afters ::= CHOICE { 2695 cheese [0] IA5String, 2696 dessert [1] IA5String 2697 } 2698 ''' 2699 componentType = NamedTypes( 2700 NamedType('cheese', IA5String().subtype( 2701 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 2702 ), 2703 NamedType('dessert', IA5String().subtype( 2704 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 2705 ) 2706 ) 2707 2708 afters = Afters() 2709 afters['cheese'] = 'Mascarpone' 2710 """ 2711 #: Set (on class, not on instance) or return a 2712 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2713 #: associated with |ASN.1| type. 2714 tagSet = tag.TagSet() # untagged 2715 2716 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2717 #: object representing ASN.1 type allowed within |ASN.1| type 2718 componentType = namedtype.NamedTypes() 2719 2720 #: Set (on class, not on instance) or return a 2721 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2722 #: imposing constraints on |ASN.1| type initialization values. 2723 subtypeSpec = constraint.ConstraintsIntersection() 2724 2725 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2726 #: object imposing size constraint on |ASN.1| objects 2727 sizeSpec = constraint.ConstraintsIntersection( 2728 constraint.ValueSizeConstraint(1, 1) 2729 ) 2730 2731 # Disambiguation ASN.1 types identification 2732 typeId = Set.getTypeId() 2733 2734 _currentIdx = None 2735 2736 def __eq__(self, other): 2737 if self._componentValues: 2738 return self._componentValues[self._currentIdx] == other 2739 return NotImplemented 2740 2741 def __ne__(self, other): 2742 if self._componentValues: 2743 return self._componentValues[self._currentIdx] != other 2744 return NotImplemented 2745 2746 def __lt__(self, other): 2747 if self._componentValues: 2748 return self._componentValues[self._currentIdx] < other 2749 return NotImplemented 2750 2751 def __le__(self, other): 2752 if self._componentValues: 2753 return self._componentValues[self._currentIdx] <= other 2754 return NotImplemented 2755 2756 def __gt__(self, other): 2757 if self._componentValues: 2758 return self._componentValues[self._currentIdx] > other 2759 return NotImplemented 2760 2761 def __ge__(self, other): 2762 if self._componentValues: 2763 return self._componentValues[self._currentIdx] >= other 2764 return NotImplemented 2765 2766 if sys.version_info[0] <= 2: 2767 def __nonzero__(self): 2768 return self._componentValues and True or False 2769 else: 2770 def __bool__(self): 2771 return self._componentValues and True or False 2772 2773 def __len__(self): 2774 return self._currentIdx is not None and 1 or 0 2775 2776 def __contains__(self, key): 2777 if self._currentIdx is None: 2778 return False 2779 return key == self.componentType[self._currentIdx].getName() 2780 2781 def __iter__(self): 2782 if self._currentIdx is None: 2783 raise StopIteration 2784 yield self.componentType[self._currentIdx].getName() 2785 2786 # Python dict protocol 2787 2788 def values(self): 2789 if self._currentIdx is not None: 2790 yield self._componentValues[self._currentIdx] 2791 2792 def keys(self): 2793 if self._currentIdx is not None: 2794 yield self.componentType[self._currentIdx].getName() 2795 2796 def items(self): 2797 if self._currentIdx is not None: 2798 yield self.componentType[self._currentIdx].getName(), self[self._currentIdx] 2799 2800 def verifySizeSpec(self): 2801 if self._currentIdx is None: 2802 raise error.PyAsn1Error('Component not chosen') 2803 2804 def _cloneComponentValues(self, myClone, cloneValueFlag): 2805 try: 2806 component = self.getComponent() 2807 except error.PyAsn1Error: 2808 pass 2809 else: 2810 if isinstance(component, Choice): 2811 tagSet = component.effectiveTagSet 2812 else: 2813 tagSet = component.tagSet 2814 if isinstance(component, base.AbstractConstructedAsn1Item): 2815 myClone.setComponentByType( 2816 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 2817 ) 2818 else: 2819 myClone.setComponentByType(tagSet, component.clone()) 2820 2821 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 2822 __doc__ = Set.__doc__ 2823 2824 if self._currentIdx is None or self._currentIdx != idx: 2825 return Set.getComponentByPosition(self, idx, default=default, 2826 instantiate=instantiate) 2827 2828 return self._componentValues[idx] 2829 2830 def setComponentByPosition(self, idx, value=noValue, 2831 verifyConstraints=True, 2832 matchTags=True, 2833 matchConstraints=True): 2834 """Assign |ASN.1| type component by position. 2835 2836 Equivalent to Python sequence item assignment operation (e.g. `[]`). 2837 2838 Parameters 2839 ---------- 2840 idx: :class:`int` 2841 Component index (zero-based). Must either refer to existing 2842 component or to N+1 component. In the latter case a new component 2843 type gets instantiated (if *componentType* is set, or given ASN.1 2844 object is taken otherwise) and appended to the |ASN.1| sequence. 2845 2846 Keyword Args 2847 ------------ 2848 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2849 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2850 or ASN.1 value object to assign to |ASN.1| component. Once a new value is 2851 set to *idx* component, previous value is dropped. 2852 2853 verifyConstraints : :class:`bool` 2854 If `False`, skip constraints validation 2855 2856 matchTags: :class:`bool` 2857 If `False`, skip component tags matching 2858 2859 matchConstraints: :class:`bool` 2860 If `False`, skip component constraints matching 2861 2862 Returns 2863 ------- 2864 self 2865 """ 2866 oldIdx = self._currentIdx 2867 Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints) 2868 self._currentIdx = idx 2869 if oldIdx is not None and oldIdx != idx: 2870 self._componentValues[oldIdx] = noValue 2871 return self 2872 2873 @property 2874 def effectiveTagSet(self): 2875 """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged).""" 2876 if self.tagSet: 2877 return self.tagSet 2878 else: 2879 component = self.getComponent() 2880 return component.effectiveTagSet 2881 2882 @property 2883 def tagMap(self): 2884 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 2885 ASN.1 tags to ASN.1 objects contained within callee. 2886 """ 2887 if self.tagSet: 2888 return Set.tagMap.fget(self) 2889 else: 2890 return self.componentType.tagMapUnique 2891 2892 def getComponent(self, innerFlag=False): 2893 """Return currently assigned component of the |ASN.1| object. 2894 2895 Returns 2896 ------- 2897 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2898 a PyASN1 object 2899 """ 2900 if self._currentIdx is None: 2901 raise error.PyAsn1Error('Component not chosen') 2902 else: 2903 c = self._componentValues[self._currentIdx] 2904 if innerFlag and isinstance(c, Choice): 2905 return c.getComponent(innerFlag) 2906 else: 2907 return c 2908 2909 def getName(self, innerFlag=False): 2910 """Return the name of currently assigned component of the |ASN.1| object. 2911 2912 Returns 2913 ------- 2914 : :py:class:`str` 2915 |ASN.1| component name 2916 """ 2917 if self._currentIdx is None: 2918 raise error.PyAsn1Error('Component not chosen') 2919 else: 2920 if innerFlag: 2921 c = self._componentValues[self._currentIdx] 2922 if isinstance(c, Choice): 2923 return c.getName(innerFlag) 2924 return self.componentType.getNameByPosition(self._currentIdx) 2925 2926 @property 2927 def isValue(self): 2928 """Indicate that |ASN.1| object represents ASN.1 value. 2929 2930 If *isValue* is `False` then this object represents just ASN.1 schema. 2931 2932 If *isValue* is `True` then, in addition to its ASN.1 schema features, 2933 this object can also be used like a Python built-in object (e.g. `int`, 2934 `str`, `dict` etc.). 2935 2936 Returns 2937 ------- 2938 : :class:`bool` 2939 :class:`False` if object represents just ASN.1 schema. 2940 :class:`True` if object represents ASN.1 schema and can be used as a normal value. 2941 2942 Note 2943 ---- 2944 There is an important distinction between PyASN1 schema and value objects. 2945 The PyASN1 schema objects can only participate in ASN.1 schema-related 2946 operations (e.g. defining or testing the structure of the data). Most 2947 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 2948 encoding/decoding serialised ASN.1 contents. 2949 2950 The PyASN1 value objects can **additionally** participate in many operations 2951 involving regular Python objects (e.g. arithmetic, comprehension etc). 2952 """ 2953 if self._currentIdx is None: 2954 return False 2955 2956 componentValue = self._componentValues[self._currentIdx] 2957 2958 return componentValue is not noValue and componentValue.isValue 2959 2960 def clear(self): 2961 self._currentIdx = None 2962 Set.clear(self) 2963 2964 # compatibility stubs 2965 2966 def getMinTagSet(self): 2967 return self.minTagSet 2968 2969 2970class Any(OctetString): 2971 """Create |ASN.1| schema or value object. 2972 2973 |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 2974 :class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|" 2975 serialisation. 2976 2977 Keyword Args 2978 ------------ 2979 value: :class:`str`, :class:`bytes` or |ASN.1| object 2980 string (Python 2) or bytes (Python 3), alternatively unicode object 2981 (Python 2) or string (Python 3) representing character string to be 2982 serialised into octets (note `encoding` parameter) or |ASN.1| object. 2983 2984 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 2985 Object representing non-default ASN.1 tag(s) 2986 2987 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2988 Object representing non-default ASN.1 subtype constraint(s) 2989 2990 encoding: :py:class:`str` 2991 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or 2992 :class:`str` (Python 3) the payload when |ASN.1| object is used 2993 in text string context. 2994 2995 binValue: :py:class:`str` 2996 Binary string initializer to use instead of the *value*. 2997 Example: '10110011'. 2998 2999 hexValue: :py:class:`str` 3000 Hexadecimal string initializer to use instead of the *value*. 3001 Example: 'DEADBEEF'. 3002 3003 Raises 3004 ------ 3005 :py:class:`~pyasn1.error.PyAsn1Error` 3006 On constraint violation or bad initializer. 3007 3008 Examples 3009 -------- 3010 .. code-block:: python 3011 3012 class Error(Sequence): 3013 ''' 3014 ASN.1 specification: 3015 3016 Error ::= SEQUENCE { 3017 code INTEGER, 3018 parameter ANY DEFINED BY code -- Either INTEGER or REAL 3019 } 3020 ''' 3021 componentType=NamedTypes( 3022 NamedType('code', Integer()), 3023 NamedType('parameter', Any(), 3024 openType=OpenType('code', {1: Integer(), 3025 2: Real()})) 3026 ) 3027 3028 error = Error() 3029 error['code'] = 1 3030 error['parameter'] = Integer(1234) 3031 """ 3032 #: Set (on class, not on instance) or return a 3033 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 3034 #: associated with |ASN.1| type. 3035 tagSet = tag.TagSet() # untagged 3036 3037 #: Set (on class, not on instance) or return a 3038 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 3039 #: imposing constraints on |ASN.1| type initialization values. 3040 subtypeSpec = constraint.ConstraintsIntersection() 3041 3042 # Disambiguation ASN.1 types identification 3043 typeId = OctetString.getTypeId() 3044 3045 @property 3046 def tagMap(self): 3047 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 3048 ASN.1 tags to ASN.1 objects contained within callee. 3049 """ 3050 try: 3051 return self._tagMap 3052 3053 except AttributeError: 3054 self._tagMap = tagmap.TagMap( 3055 {self.tagSet: self}, 3056 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 3057 self 3058 ) 3059 3060 return self._tagMap 3061 3062# XXX 3063# coercion rules? 3064