1# 2# This file is part of pyasn1 software. 3# 4# Copyright (c) 2005-2018, 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).clone() 2351 2352 elif currentValue is noValue: 2353 raise error.PyAsn1Error('Component type not defined') 2354 2355 elif not isinstance(value, base.Asn1Item): 2356 if componentTypeLen: 2357 subComponentType = componentType.getTypeByPosition(idx) 2358 if isinstance(subComponentType, base.AbstractSimpleAsn1Item): 2359 value = subComponentType.clone(value=value) 2360 2361 else: 2362 raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__) 2363 2364 elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item): 2365 value = currentValue.clone(value=value) 2366 2367 else: 2368 raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__) 2369 2370 elif (matchTags or matchConstraints) and componentTypeLen: 2371 subComponentType = componentType.getTypeByPosition(idx) 2372 if subComponentType is not noValue: 2373 subtypeChecker = (self.strictConstraints and 2374 subComponentType.isSameTypeWith or 2375 subComponentType.isSuperTypeOf) 2376 2377 if not subtypeChecker(value, matchTags, matchConstraints): 2378 if not componentType[idx].openType: 2379 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) 2380 2381 if verifyConstraints and value.isValue: 2382 try: 2383 self.subtypeSpec(value, idx) 2384 2385 except error.PyAsn1Error: 2386 exType, exValue, exTb = sys.exc_info() 2387 raise exType('%s at %s' % (exValue, self.__class__.__name__)) 2388 2389 if componentTypeLen or idx in self._dynamicNames: 2390 self._componentValues[idx] = value 2391 2392 elif len(self._componentValues) == idx: 2393 self._componentValues.append(value) 2394 self._dynamicNames.addField(idx) 2395 2396 else: 2397 raise error.PyAsn1Error('Component index out of range') 2398 2399 return self 2400 2401 @property 2402 def isValue(self): 2403 """Indicate that |ASN.1| object represents ASN.1 value. 2404 2405 If *isValue* is `False` then this object represents just ASN.1 schema. 2406 2407 If *isValue* is `True` then, in addition to its ASN.1 schema features, 2408 this object can also be used like a Python built-in object (e.g. `int`, 2409 `str`, `dict` etc.). 2410 2411 Returns 2412 ------- 2413 : :class:`bool` 2414 :class:`False` if object represents just ASN.1 schema. 2415 :class:`True` if object represents ASN.1 schema and can be used as a normal value. 2416 2417 Note 2418 ---- 2419 There is an important distinction between PyASN1 schema and value objects. 2420 The PyASN1 schema objects can only participate in ASN.1 schema-related 2421 operations (e.g. defining or testing the structure of the data). Most 2422 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 2423 encoding/decoding serialised ASN.1 contents. 2424 2425 The PyASN1 value objects can **additionally** participate in many operations 2426 involving regular Python objects (e.g. arithmetic, comprehension etc). 2427 """ 2428 componentType = self.componentType 2429 2430 if componentType: 2431 for idx, subComponentType in enumerate(componentType.namedTypes): 2432 if subComponentType.isDefaulted or subComponentType.isOptional: 2433 continue 2434 2435 if not self._componentValues: 2436 return False 2437 2438 componentValue = self._componentValues[idx] 2439 if componentValue is noValue or not componentValue.isValue: 2440 return False 2441 2442 else: 2443 for componentValue in self._componentValues: 2444 if componentValue is noValue or not componentValue.isValue: 2445 return False 2446 2447 return True 2448 2449 def prettyPrint(self, scope=0): 2450 """Return an object representation string. 2451 2452 Returns 2453 ------- 2454 : :class:`str` 2455 Human-friendly object representation. 2456 """ 2457 scope += 1 2458 representation = self.__class__.__name__ + ':\n' 2459 for idx, componentValue in enumerate(self._componentValues): 2460 if componentValue is not noValue: 2461 representation += ' ' * scope 2462 if self.componentType: 2463 representation += self.componentType.getNameByPosition(idx) 2464 else: 2465 representation += self._dynamicNames.getNameByPosition(idx) 2466 representation = '%s=%s\n' % ( 2467 representation, componentValue.prettyPrint(scope) 2468 ) 2469 return representation 2470 2471 def prettyPrintType(self, scope=0): 2472 scope += 1 2473 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) 2474 for idx, componentType in enumerate(self.componentType.values() or self._componentValues): 2475 representation += ' ' * scope 2476 if self.componentType: 2477 representation += '"%s"' % self.componentType.getNameByPosition(idx) 2478 else: 2479 representation += '"%s"' % self._dynamicNames.getNameByPosition(idx) 2480 representation = '%s = %s\n' % ( 2481 representation, componentType.prettyPrintType(scope) 2482 ) 2483 return representation + '\n' + ' ' * (scope - 1) + '}' 2484 2485 # backward compatibility 2486 2487 def setDefaultComponents(self): 2488 return self 2489 2490 def getComponentType(self): 2491 if self._componentTypeLen: 2492 return self.componentType 2493 2494 def getNameByPosition(self, idx): 2495 if self._componentTypeLen: 2496 return self.componentType[idx].name 2497 2498 2499class Sequence(SequenceAndSetBase): 2500 __doc__ = SequenceAndSetBase.__doc__ 2501 2502 #: Set (on class, not on instance) or return a 2503 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2504 #: associated with |ASN.1| type. 2505 tagSet = tag.initTagSet( 2506 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) 2507 ) 2508 2509 #: Set (on class, not on instance) or return a 2510 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2511 #: imposing constraints on |ASN.1| type initialization values. 2512 subtypeSpec = constraint.ConstraintsIntersection() 2513 2514 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2515 #: object imposing constraints on |ASN.1| objects 2516 sizeSpec = constraint.ConstraintsIntersection() 2517 2518 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2519 #: object imposing size constraint on |ASN.1| objects 2520 componentType = namedtype.NamedTypes() 2521 2522 # Disambiguation ASN.1 types identification 2523 typeId = SequenceAndSetBase.getTypeId() 2524 2525 # backward compatibility 2526 2527 def getComponentTagMapNearPosition(self, idx): 2528 if self.componentType: 2529 return self.componentType.getTagMapNearPosition(idx) 2530 2531 def getComponentPositionNearType(self, tagSet, idx): 2532 if self.componentType: 2533 return self.componentType.getPositionNearType(tagSet, idx) 2534 else: 2535 return idx 2536 2537 2538class Set(SequenceAndSetBase): 2539 __doc__ = SequenceAndSetBase.__doc__ 2540 2541 #: Set (on class, not on instance) or return a 2542 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2543 #: associated with |ASN.1| type. 2544 tagSet = tag.initTagSet( 2545 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) 2546 ) 2547 2548 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2549 #: object representing ASN.1 type allowed within |ASN.1| type 2550 componentType = namedtype.NamedTypes() 2551 2552 #: Set (on class, not on instance) or return a 2553 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2554 #: imposing constraints on |ASN.1| type initialization values. 2555 subtypeSpec = constraint.ConstraintsIntersection() 2556 2557 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2558 #: object imposing constraints on |ASN.1| objects 2559 sizeSpec = constraint.ConstraintsIntersection() 2560 2561 # Disambiguation ASN.1 types identification 2562 typeId = SequenceAndSetBase.getTypeId() 2563 2564 def getComponent(self, innerFlag=False): 2565 return self 2566 2567 def getComponentByType(self, tagSet, default=noValue, 2568 instantiate=True, innerFlag=False): 2569 """Returns |ASN.1| type component by ASN.1 tag. 2570 2571 Parameters 2572 ---------- 2573 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 2574 Object representing ASN.1 tags to identify one of 2575 |ASN.1| object component 2576 2577 Keyword Args 2578 ------------ 2579 default: :class:`object` 2580 If set and requested component is a schema object, return the `default` 2581 object instead of the requested component. 2582 2583 instantiate: :class:`bool` 2584 If `True` (default), inner component will be automatically instantiated. 2585 If 'False' either existing component or the `noValue` object will be 2586 returned. 2587 2588 Returns 2589 ------- 2590 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2591 a pyasn1 object 2592 """ 2593 componentValue = self.getComponentByPosition( 2594 self.componentType.getPositionByType(tagSet), 2595 default=default, instantiate=instantiate 2596 ) 2597 if innerFlag and isinstance(componentValue, Set): 2598 # get inner component by inner tagSet 2599 return componentValue.getComponent(innerFlag=True) 2600 else: 2601 # get outer component by inner tagSet 2602 return componentValue 2603 2604 def setComponentByType(self, tagSet, value=noValue, 2605 verifyConstraints=True, 2606 matchTags=True, 2607 matchConstraints=True, 2608 innerFlag=False): 2609 """Assign |ASN.1| type component by ASN.1 tag. 2610 2611 Parameters 2612 ---------- 2613 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 2614 Object representing ASN.1 tags to identify one of 2615 |ASN.1| object component 2616 2617 Keyword Args 2618 ------------ 2619 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2620 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2621 or ASN.1 value object to assign to |ASN.1| component. 2622 2623 verifyConstraints : :class:`bool` 2624 If `False`, skip constraints validation 2625 2626 matchTags: :class:`bool` 2627 If `False`, skip component tags matching 2628 2629 matchConstraints: :class:`bool` 2630 If `False`, skip component constraints matching 2631 2632 innerFlag: :class:`bool` 2633 If `True`, search for matching *tagSet* recursively. 2634 2635 Returns 2636 ------- 2637 self 2638 """ 2639 idx = self.componentType.getPositionByType(tagSet) 2640 2641 if innerFlag: # set inner component by inner tagSet 2642 componentType = self.componentType.getTypeByPosition(idx) 2643 2644 if componentType.tagSet: 2645 return self.setComponentByPosition( 2646 idx, value, verifyConstraints, matchTags, matchConstraints 2647 ) 2648 else: 2649 componentType = self.getComponentByPosition(idx) 2650 return componentType.setComponentByType( 2651 tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag 2652 ) 2653 else: # set outer component by inner tagSet 2654 return self.setComponentByPosition( 2655 idx, value, verifyConstraints, matchTags, matchConstraints 2656 ) 2657 2658 @property 2659 def componentTagMap(self): 2660 if self.componentType: 2661 return self.componentType.tagMapUnique 2662 2663 2664class Choice(Set): 2665 """Create |ASN.1| type. 2666 2667 |ASN.1| objects are mutable and duck-type Python :class:`dict` objects. 2668 2669 Keyword Args 2670 ------------ 2671 componentType: :py:class:`~pyasn1.type.namedtype.NamedType` 2672 Object holding named ASN.1 types allowed within this collection 2673 2674 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 2675 Object representing non-default ASN.1 tag(s) 2676 2677 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2678 Object representing non-default ASN.1 subtype constraint(s) 2679 2680 sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2681 Object representing collection size constraint 2682 2683 Examples 2684 -------- 2685 2686 .. code-block:: python 2687 2688 class Afters(Choice): 2689 ''' 2690 ASN.1 specification: 2691 2692 Afters ::= CHOICE { 2693 cheese [0] IA5String, 2694 dessert [1] IA5String 2695 } 2696 ''' 2697 componentType = NamedTypes( 2698 NamedType('cheese', IA5String().subtype( 2699 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 2700 ), 2701 NamedType('dessert', IA5String().subtype( 2702 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 2703 ) 2704 ) 2705 2706 afters = Afters() 2707 afters['cheese'] = 'Mascarpone' 2708 """ 2709 #: Set (on class, not on instance) or return a 2710 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 2711 #: associated with |ASN.1| type. 2712 tagSet = tag.TagSet() # untagged 2713 2714 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 2715 #: object representing ASN.1 type allowed within |ASN.1| type 2716 componentType = namedtype.NamedTypes() 2717 2718 #: Set (on class, not on instance) or return a 2719 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 2720 #: imposing constraints on |ASN.1| type initialization values. 2721 subtypeSpec = constraint.ConstraintsIntersection() 2722 2723 #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2724 #: object imposing size constraint on |ASN.1| objects 2725 sizeSpec = constraint.ConstraintsIntersection( 2726 constraint.ValueSizeConstraint(1, 1) 2727 ) 2728 2729 # Disambiguation ASN.1 types identification 2730 typeId = Set.getTypeId() 2731 2732 _currentIdx = None 2733 2734 def __eq__(self, other): 2735 if self._componentValues: 2736 return self._componentValues[self._currentIdx] == other 2737 return NotImplemented 2738 2739 def __ne__(self, other): 2740 if self._componentValues: 2741 return self._componentValues[self._currentIdx] != other 2742 return NotImplemented 2743 2744 def __lt__(self, other): 2745 if self._componentValues: 2746 return self._componentValues[self._currentIdx] < other 2747 return NotImplemented 2748 2749 def __le__(self, other): 2750 if self._componentValues: 2751 return self._componentValues[self._currentIdx] <= other 2752 return NotImplemented 2753 2754 def __gt__(self, other): 2755 if self._componentValues: 2756 return self._componentValues[self._currentIdx] > other 2757 return NotImplemented 2758 2759 def __ge__(self, other): 2760 if self._componentValues: 2761 return self._componentValues[self._currentIdx] >= other 2762 return NotImplemented 2763 2764 if sys.version_info[0] <= 2: 2765 def __nonzero__(self): 2766 return self._componentValues and True or False 2767 else: 2768 def __bool__(self): 2769 return self._componentValues and True or False 2770 2771 def __len__(self): 2772 return self._currentIdx is not None and 1 or 0 2773 2774 def __contains__(self, key): 2775 if self._currentIdx is None: 2776 return False 2777 return key == self.componentType[self._currentIdx].getName() 2778 2779 def __iter__(self): 2780 if self._currentIdx is None: 2781 raise StopIteration 2782 yield self.componentType[self._currentIdx].getName() 2783 2784 # Python dict protocol 2785 2786 def values(self): 2787 if self._currentIdx is not None: 2788 yield self._componentValues[self._currentIdx] 2789 2790 def keys(self): 2791 if self._currentIdx is not None: 2792 yield self.componentType[self._currentIdx].getName() 2793 2794 def items(self): 2795 if self._currentIdx is not None: 2796 yield self.componentType[self._currentIdx].getName(), self[self._currentIdx] 2797 2798 def verifySizeSpec(self): 2799 if self._currentIdx is None: 2800 raise error.PyAsn1Error('Component not chosen') 2801 2802 def _cloneComponentValues(self, myClone, cloneValueFlag): 2803 try: 2804 component = self.getComponent() 2805 except error.PyAsn1Error: 2806 pass 2807 else: 2808 if isinstance(component, Choice): 2809 tagSet = component.effectiveTagSet 2810 else: 2811 tagSet = component.tagSet 2812 if isinstance(component, base.AbstractConstructedAsn1Item): 2813 myClone.setComponentByType( 2814 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 2815 ) 2816 else: 2817 myClone.setComponentByType(tagSet, component.clone()) 2818 2819 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 2820 __doc__ = Set.__doc__ 2821 2822 if self._currentIdx is None or self._currentIdx != idx: 2823 return Set.getComponentByPosition(self, idx, default=default, 2824 instantiate=instantiate) 2825 2826 return self._componentValues[idx] 2827 2828 def setComponentByPosition(self, idx, value=noValue, 2829 verifyConstraints=True, 2830 matchTags=True, 2831 matchConstraints=True): 2832 """Assign |ASN.1| type component by position. 2833 2834 Equivalent to Python sequence item assignment operation (e.g. `[]`). 2835 2836 Parameters 2837 ---------- 2838 idx: :class:`int` 2839 Component index (zero-based). Must either refer to existing 2840 component or to N+1 component. In the latter case a new component 2841 type gets instantiated (if *componentType* is set, or given ASN.1 2842 object is taken otherwise) and appended to the |ASN.1| sequence. 2843 2844 Keyword Args 2845 ------------ 2846 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 2847 A Python value to initialize |ASN.1| component with (if *componentType* is set) 2848 or ASN.1 value object to assign to |ASN.1| component. Once a new value is 2849 set to *idx* component, previous value is dropped. 2850 2851 verifyConstraints : :class:`bool` 2852 If `False`, skip constraints validation 2853 2854 matchTags: :class:`bool` 2855 If `False`, skip component tags matching 2856 2857 matchConstraints: :class:`bool` 2858 If `False`, skip component constraints matching 2859 2860 Returns 2861 ------- 2862 self 2863 """ 2864 oldIdx = self._currentIdx 2865 Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints) 2866 self._currentIdx = idx 2867 if oldIdx is not None and oldIdx != idx: 2868 self._componentValues[oldIdx] = noValue 2869 return self 2870 2871 @property 2872 def effectiveTagSet(self): 2873 """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged).""" 2874 if self.tagSet: 2875 return self.tagSet 2876 else: 2877 component = self.getComponent() 2878 return component.effectiveTagSet 2879 2880 @property 2881 def tagMap(self): 2882 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 2883 ASN.1 tags to ASN.1 objects contained within callee. 2884 """ 2885 if self.tagSet: 2886 return Set.tagMap.fget(self) 2887 else: 2888 return self.componentType.tagMapUnique 2889 2890 def getComponent(self, innerFlag=False): 2891 """Return currently assigned component of the |ASN.1| object. 2892 2893 Returns 2894 ------- 2895 : :py:class:`~pyasn1.type.base.PyAsn1Item` 2896 a PyASN1 object 2897 """ 2898 if self._currentIdx is None: 2899 raise error.PyAsn1Error('Component not chosen') 2900 else: 2901 c = self._componentValues[self._currentIdx] 2902 if innerFlag and isinstance(c, Choice): 2903 return c.getComponent(innerFlag) 2904 else: 2905 return c 2906 2907 def getName(self, innerFlag=False): 2908 """Return the name of currently assigned component of the |ASN.1| object. 2909 2910 Returns 2911 ------- 2912 : :py:class:`str` 2913 |ASN.1| component name 2914 """ 2915 if self._currentIdx is None: 2916 raise error.PyAsn1Error('Component not chosen') 2917 else: 2918 if innerFlag: 2919 c = self._componentValues[self._currentIdx] 2920 if isinstance(c, Choice): 2921 return c.getName(innerFlag) 2922 return self.componentType.getNameByPosition(self._currentIdx) 2923 2924 @property 2925 def isValue(self): 2926 """Indicate that |ASN.1| object represents ASN.1 value. 2927 2928 If *isValue* is `False` then this object represents just ASN.1 schema. 2929 2930 If *isValue* is `True` then, in addition to its ASN.1 schema features, 2931 this object can also be used like a Python built-in object (e.g. `int`, 2932 `str`, `dict` etc.). 2933 2934 Returns 2935 ------- 2936 : :class:`bool` 2937 :class:`False` if object represents just ASN.1 schema. 2938 :class:`True` if object represents ASN.1 schema and can be used as a normal value. 2939 2940 Note 2941 ---- 2942 There is an important distinction between PyASN1 schema and value objects. 2943 The PyASN1 schema objects can only participate in ASN.1 schema-related 2944 operations (e.g. defining or testing the structure of the data). Most 2945 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 2946 encoding/decoding serialised ASN.1 contents. 2947 2948 The PyASN1 value objects can **additionally** participate in many operations 2949 involving regular Python objects (e.g. arithmetic, comprehension etc). 2950 """ 2951 if self._currentIdx is None: 2952 return False 2953 2954 componentValue = self._componentValues[self._currentIdx] 2955 2956 return componentValue is not noValue and componentValue.isValue 2957 2958 def clear(self): 2959 self._currentIdx = None 2960 Set.clear(self) 2961 2962 # compatibility stubs 2963 2964 def getMinTagSet(self): 2965 return self.minTagSet 2966 2967 2968class Any(OctetString): 2969 """Create |ASN.1| schema or value object. 2970 2971 |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 2972 :class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|" 2973 serialisation. 2974 2975 Keyword Args 2976 ------------ 2977 value: :class:`str`, :class:`bytes` or |ASN.1| object 2978 string (Python 2) or bytes (Python 3), alternatively unicode object 2979 (Python 2) or string (Python 3) representing character string to be 2980 serialised into octets (note `encoding` parameter) or |ASN.1| object. 2981 2982 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 2983 Object representing non-default ASN.1 tag(s) 2984 2985 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 2986 Object representing non-default ASN.1 subtype constraint(s) 2987 2988 encoding: :py:class:`str` 2989 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or 2990 :class:`str` (Python 3) the payload when |ASN.1| object is used 2991 in text string context. 2992 2993 binValue: :py:class:`str` 2994 Binary string initializer to use instead of the *value*. 2995 Example: '10110011'. 2996 2997 hexValue: :py:class:`str` 2998 Hexadecimal string initializer to use instead of the *value*. 2999 Example: 'DEADBEEF'. 3000 3001 Raises 3002 ------ 3003 :py:class:`~pyasn1.error.PyAsn1Error` 3004 On constraint violation or bad initializer. 3005 3006 Examples 3007 -------- 3008 .. code-block:: python 3009 3010 class Error(Sequence): 3011 ''' 3012 ASN.1 specification: 3013 3014 Error ::= SEQUENCE { 3015 code INTEGER, 3016 parameter ANY DEFINED BY code -- Either INTEGER or REAL 3017 } 3018 ''' 3019 componentType=NamedTypes( 3020 NamedType('code', Integer()), 3021 NamedType('parameter', Any(), 3022 openType=OpenType('code', {1: Integer(), 3023 2: Real()})) 3024 ) 3025 3026 error = Error() 3027 error['code'] = 1 3028 error['parameter'] = Integer(1234) 3029 """ 3030 #: Set (on class, not on instance) or return a 3031 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 3032 #: associated with |ASN.1| type. 3033 tagSet = tag.TagSet() # untagged 3034 3035 #: Set (on class, not on instance) or return a 3036 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 3037 #: imposing constraints on |ASN.1| type initialization values. 3038 subtypeSpec = constraint.ConstraintsIntersection() 3039 3040 # Disambiguation ASN.1 types identification 3041 typeId = OctetString.getTypeId() 3042 3043 @property 3044 def tagMap(self): 3045 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 3046 ASN.1 tags to ASN.1 objects contained within callee. 3047 """ 3048 try: 3049 return self._tagMap 3050 3051 except AttributeError: 3052 self._tagMap = tagmap.TagMap( 3053 {self.tagSet: self}, 3054 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 3055 self 3056 ) 3057 3058 return self._tagMap 3059 3060# XXX 3061# coercion rules? 3062