deleted file mode 100644
--- a/third_party/python/pyasn1/CHANGES
+++ /dev/null
@@ -1,278 +0,0 @@
-Revision 0.1.7
---------------
-
-- License updated to vanilla BSD 2-Clause to ease package use
- (http://opensource.org/licenses/BSD-2-Clause).
-- Test suite made discoverable by unittest/unittest2 discovery feature.
-- Fix to decoder working on indefinite length substrate -- end-of-octets
- marker is now detected by both tag and value. Otherwise zero values may
- interfere with end-of-octets marker.
-- Fix to decoder to fail in cases where tagFormat indicates inappropriate
- format for the type (e.g. BOOLEAN is always PRIMITIVE, SET is always
- CONSTRUCTED and OCTET STRING is either of the two)
-- Fix to REAL type encoder to force primitive encoding form encoding.
-- Fix to CHOICE decoder to handle explicitly tagged, indefinite length
- mode encoding
-- Fix to REAL type decoder to handle negative REAL values correctly. Test
- case added.
-
-Revision 0.1.6
---------------
-
-- The compact (valueless) way of encoding zero INTEGERs introduced in
- 0.1.5 seems to fail miserably as the world is filled with broken
- BER decoders. So we had to back off the *encoder* for a while.
- There's still the IntegerEncoder.supportCompactZero flag which
- enables compact encoding form whenever it evaluates to True.
-- Report package version on debugging code initialization.
-
-Revision 0.1.5
---------------
-
-- Documentation updated and split into chapters to better match
- web-site contents.
-- Make prettyPrint() working for non-initialized pyasn1 data objects. It
- used to throw an exception.
-- Fix to encoder to produce empty-payload INTEGER values for zeros
-- Fix to decoder to support empty-payload INTEGER and REAL values
-- Fix to unit test suites imports to be able to run each from
- their current directory
-
-Revision 0.1.4
---------------
-
-- Built-in codec debugging facility added
-- Added some more checks to ObjectIdentifier BER encoder catching
- posible 2^8 overflow condition by two leading sub-OIDs
-- Implementations overriding the AbstractDecoder.valueDecoder method
- changed to return the rest of substrate behind the item being processed
- rather than the unprocessed substrate within the item (which is usually
- empty).
-- Decoder's recursiveFlag feature generalized as a user callback function
- which is passed an uninitialized object recovered from substrate and
- its uninterpreted payload.
-- Catch inappropriate substrate type passed to decoder.
-- Expose tagMap/typeMap/Decoder objects at DER decoder to uniform API.
-- Obsolete __init__.MajorVersionId replaced with __init__.__version__
- which is now in-sync with distutils.
-- Package classifiers updated.
-- The __init__.py's made non-empty (rumors are that they may be optimized
- out by package managers).
-- Bail out gracefully whenever Python version is older than 2.4.
-- Fix to Real codec exponent encoding (should be in 2's complement form),
- some more test cases added.
-- Fix in Boolean truth testing built-in methods
-- Fix to substrate underrun error handling at ObjectIdentifier BER decoder
-- Fix to BER Boolean decoder that allows other pre-computed
- values besides 0 and 1
-- Fix to leading 0x80 octet handling in DER/CER/DER ObjectIdentifier decoder.
- See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
-
-Revision 0.1.3
---------------
-
-- Include class name into asn1 value constraint violation exception.
-- Fix to OctetString.prettyOut() method that looses leading zero when
- building hex string.
-
-Revision 0.1.2
---------------
-
-- Fix to __long__() to actually return longs on py2k
-- Fix to OctetString.__str__() workings of a non-initialized object.
-- Fix to quote initializer of OctetString.__repr__()
-- Minor fix towards ObjectIdentifier.prettyIn() reliability
-- ObjectIdentifier.__str__() is aliased to prettyPrint()
-- Exlicit repr() calls replaced with '%r'
-
-Revision 0.1.1
---------------
-
-- Hex/bin string initializer to OctetString object reworked
- (in a backward-incompatible manner)
-- Fixed float() infinity compatibility issue (affects 2.5 and earlier)
-- Fixed a bug/typo at Boolean CER encoder.
-- Major overhawl for Python 2.4 -- 3.2 compatibility:
- + get rid of old-style types
- + drop string module usage
- + switch to rich comparation
- + drop explicit long integer type use
- + map()/filter() replaced with list comprehension
- + apply() replaced with */**args
- + switched to use 'key' sort() callback function
- + support both __nonzero__() and __bool__() methods
- + modified not to use py3k-incompatible exception syntax
- + getslice() operator fully replaced with getitem()
- + dictionary operations made 2K/3K compatible
- + base type for encoding substrate and OctetString-based types
- is now 'bytes' when running py3k and 'str' otherwise
- + OctetString and derivatives now unicode compliant.
- + OctetString now supports two python-neutral getters: asOcts() & asInts()
- + print OctetString content in hex whenever it is not printable otherwise
- + in test suite, implicit relative import replaced with the absolute one
- + in test suite, string constants replaced with numerics
-
-Revision 0.0.13
----------------
-
-- Fix to base10 normalization function that loops on univ.Real(0)
-
-Revision 0.0.13b
-----------------
-
-- ASN.1 Real type is now supported properly.
-- Objects of Constructed types now support __setitem__()
-- Set/Sequence objects can now be addressed by their field names (string index)
- and position (integer index).
-- Typo fix to ber.SetDecoder code that prevented guided decoding operation.
-- Fix to explicitly tagged items decoding support.
-- Fix to OctetString.prettyPrint() to better handle non-printable content.
-- Fix to repr() workings of Choice objects.
-
-Revision 0.0.13a
-----------------
-
-- Major codec re-design.
-- Documentation significantly improved.
-- ASN.1 Any type is now supported.
-- All example ASN.1 modules moved to separate pyasn1-modules package.
-- Fix to initial sub-OID overflow condition detection an encoder.
-- BitString initialization value verification improved.
-- The Set/Sequence.getNameByPosition() method implemented.
-- Fix to proper behaviour of PermittedAlphabetConstraint object.
-- Fix to improper Boolean substrate handling at CER/DER decoders.
-- Changes towards performance improvement:
- + all dict.has_key() & dict.get() invocations replaced with modern syntax
- (this breaks compatibility with Python 2.1 and older).
- + tag and tagset caches introduced to decoder
- + decoder code improved to prevent unnecessary pyasn1 objects creation
- + allow disabling components verification when setting components to
- structured types, this is used by decoder whilst running in guided mode.
- + BER decoder for integer values now looks up a small set of pre-computed
- substrate values to save on decoding.
- + a few pre-computed values configured to ObjectIdentifier BER encoder.
- + ChoiceDecoder split-off SequenceOf one to save on unnecessary checks.
- + replace slow hasattr()/getattr() calls with isinstance() introspection.
- + track the number of initialized components of Constructed types to save
- on default/optional components initialization.
- + added a shortcut ObjectIdentifier.asTuple() to be used instead of
- __getitem__() in hotspots.
- + use Tag.asTuple() and pure integers at tag encoder.
- + introduce and use in decoder the baseTagSet attribute of the built-in
- ASN.1 types.
-
-Revision 0.0.12a
-----------------
-
-- The individual tag/length/value processing methods of
- encoder.AbstractItemEncoder renamed (leading underscore stripped)
- to promote overloading in cases where partial substrate processing
- is required.
-- The ocsp.py, ldap.py example scripts added.
-- Fix to univ.ObjectIdentifier input value handler to disallow negative
- sub-IDs.
-
-Revision 0.0.11a
-----------------
-
-- Decoder can now treat values of unknown types as opaque OctetString.
-- Fix to Set/SetOf type decoder to handle uninitialized scalar SetOf
- components correctly.
-
-Revision 0.0.10a
-----------------
-
-- API versioning mechanics retired (pyasn1.v1 -> pyasn1) what makes
- it possible to zip-import pyasn1 sources (used by egg and py2exe).
-
-Revision 0.0.9a
----------------
-
-- Allow any non-zero values in Boolean type BER decoder, as it's in
- accordnance with the standard.
-
-Revision 0.0.8a
----------------
-
-- Integer.__index__() now supported (for Python 2.5+).
-- Fix to empty value encoding in BitString encoder, test case added.
-- Fix to SequenceOf decoder that prevents it skipping possible Choice
- typed inner component.
-- Choice.getName() method added for getting currently set component
- name.
-- OctetsString.prettyPrint() does a single str() against its value
- eliminating an extra quotes.
-
-Revision 0.0.7a
----------------
-
-- Large tags (>31) now supported by codecs.
-- Fix to encoder to properly handle explicitly tagged untagged items.
-- All possible value lengths (up to 256^126) now supported by encoders.
-- Fix to Tag class constructor to prevent negative IDs.
-
-Revision 0.0.6a
----------------
-
-- Make use of setuptools.
-- Constraints derivation verification (isSuperTypeOf()/isSubTypeOf()) fixed.
-- Fix to constraints comparation logic -- can't cmp() hash values as it
- may cause false positives due to hash conflicts.
-
-Revision 0.0.5a
----------------
-
-- Integer BER codec reworked fixing negative values encoding bug.
-- clone() and subtype() methods of Constructed ASN.1 classes now
- accept optional cloneValueFlag flag which controls original value
- inheritance. The default is *not* to inherit original value for
- performance reasons (this may affect backward compatibility).
- Performance penalty may be huge on deeply nested Constructed objects
- re-creation.
-- Base ASN.1 types (pyasn1.type.univ.*) do not have default values
- anymore. They remain uninitialized acting as ASN.1 types. In
- this model, initialized ASN.1 types represent either types with
- default value installed or a type instance.
-- Decoders' prototypes are now class instances rather than classes.
- This is to simplify initial value installation to decoder's
- prototype value.
-- Bugfix to BitString BER decoder (trailing bits not regarded).
-- Bugfix to Constraints use as mapping keys.
-- Bugfix to Integer & BitString clone() methods
-- Bugix to the way to distinguish Set from SetOf at CER/DER SetOfEncoder
-- Adjustments to make it running on Python 1.5.
-- In tests, substrate constants converted from hex escaped literals into
- octals to overcome indefinite hex width issue occuring in young Python.
-- Minor performance optimization of TagSet.isSuperTagSetOf() method
-- examples/sshkey.py added
-
-Revision 0.0.4a
----------------
-
-* Asn1ItemBase.prettyPrinter() -> *.prettyPrint()
-
-Revision 0.0.3a
----------------
-
-* Simple ASN1 objects now hash to their Python value and don't
- depend upon tag/constraints/etc.
-* prettyIn & prettyOut methods of SimplleAsn1Object become public
-* many syntax fixes
-
-Revision 0.0.2a
----------------
-
-* ConstraintsIntersection.isSuperTypeOf() and
- ConstraintsIntersection.hasConstraint() implemented
-* Bugfix to NamedValues initialization code
-* +/- operators added to NamedValues objects
-* Integer.__abs__() & Integer.subtype() added
-* ObjectIdentifier.prettyOut() fixes
-* Allow subclass components at SequenceAndSetBase
-* AbstractConstraint.__cmp__() dropped
-* error.Asn1Error replaced with error.PyAsn1Error
-
-Revision 0.0.1a
----------------
-
-* Initial public alpha release
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/CHANGES.rst
@@ -0,0 +1,576 @@
+
+Revision 0.3.7, released 04-10-2017
+-----------------------------------
+
+- Fixed ASN.1 time types pickling/deepcopy'ing
+
+Revision 0.3.6, released 21-09-2017
+-----------------------------------
+
+- End-of-octets encoding optimized at ASN.1 encoders
+- The __getitem__/__setitem__ behavior of Set/Sequence and SetOf/SequenceOf
+ objects aligned with the canonical Mapping and Sequence protocols in part
+- Fixed crash in ASN.1 encoder when encoding an explicitly tagged
+ component of a Sequence
+
+Revision 0.3.5, released 16-09-2017
+-----------------------------------
+
+- Codecs signatures unified and pass the options kwargs through the
+ call chain
+- Explicit tag encoding optimized to avoid unnecessary copying
+- End-of-octets sentinel encoding optimized
+- Refactored ASN.1 codecs properties to silently enforce proper
+ length and chunk size encoding modes
+- Fixed DER encoder to always produce primitive encoding
+- Fixed crash at SequenceOf native decoder
+- Fixed Real.prettyPrint() to fail gracefully on overflow
+- Fixed a couple of crashes when debug mode is enabled
+
+Revision 0.3.4, released 07-09-2017
+-----------------------------------
+
+- Fixed Native encoder to handle SEQUENCE/SET objects without
+ the componentType property
+- Added missing component-less SEQUENCE/SET objects dict duck-typing support
+- Fixed unnecessary duplicate tags detection at NamesType.tagMap
+- Fixed crash at SEQUENCE and SEQUENCE OF CER encoder when running
+ in schemaless mode
+- Fixed Character types instantiation from OctetString type -- double
+ unicode decoding may have scrambled the data
+
+Revision 0.3.3, released 27-08-2017
+-----------------------------------
+
+- Improved ASN.1 types instantiation performance
+- Improved BER/CER/DER decoder performance by not unconditionally casting
+ substrate into str/bytes.
+- Fixed exponential index size growth bug when building ambiguous
+ NamedTypes tree
+- Fixed constructed types decoding failure at BER codec if running
+ in schema-less mode
+- Fixed crash on prettyPrint'ing a SEQUENCE with no defined components
+- Fixed SetOf ordering at CER/DER encoder
+- Fixed crash on conditional binascii module import
+- Fix to TagSet hash value build
+
+Revision 0.3.2, released 04-08-2017
+-----------------------------------
+
+- Fixed SequenceOf/SetOf types initialization syntax to remain
+ backward compatible with pyasn1 0.2.*
+- Rectified thread safety issues by moving lazy, run-time computation
+ into object initializer.
+- Fixed .isValue property to return True for empty SetOf/SequenceOf
+ objects
+- Fixed GeneralizedTime/UTCTime CER/DER codecs to actually get invoked
+- Fixed DER/CER encoders handling optional SEQUENCE/SET fields containing
+ nested SEQUENCE/SET with optional fields.
+- Fixed crash in SequenceOf/SetOf pretty printing and decoding (in some
+ cases)
+- Fixed documentation markup issues.
+
+Revision 0.3.1, released 26-07-2017
+-----------------------------------
+
+- ASN.1 types __init__(), .clone() and .subtype() signatures
+ refactored into keyword arguments to simplify their signatures.
+- ASN.1 types initialization refactored to minimize the use of
+ relatively expensive isNoValue() call
+- Lazily pre-populate list of values of Sequence/Set/Choice types
+- NamedTypes comparison made more efficient
+- More efficient constraints computation and code clean up
+- The __getitem__() implementation of some ASN.1 types & tag object
+ refactored for better performance
+- BER/CER/DER value encoders refactored to produce either tuple of
+ bytes or octet-stream depending on what is more optimal
+- Reduced the frequency of expensive isinstance() calls
+- Tag-related classes optimized, refactored into properties and
+ documented.
+- The NamedValues implementation refactored to mimic Python dict, its use
+ in ASN.1 types refactored into properties and better documented.
+ WARNING: this change introduces a deviation from original API.
+- NamedType family of classes overhauled, optimized and documented.
+- The `componentType` attribute of constructed ASN.1 types turned
+ read-only on instances.
+- Sequence/Set DER/CER/DER decoder optimized to skip the case of
+ reordered components handling when not necessary.
+- Tags and constraints-related getter methods refactored into read-only
+ instance attributes.
+- The .hasValue() method refactored into .isValue property. All ASN.1
+ objects now support them, not just scalars.
+- The Real.{isInfinity, isPlusInfinity, isMinusInfinity} methods
+ refactored into properties and renamed into IsInf, IsPlusInf and isMinusInf
+- The end-of-octets type refactored to ensure it is a singleton. Codecs
+ changed to rely on that for better performance.
+- Codecs lookup made more efficient at BER/CER/DER decoder main loop by
+ assigning `typeId` to every ASN.1 type, not just ambiguous ones.
+- The .getComponent*() methods of constructed ASN.1 types changed
+ to lazily instantiate underlying type rather than return `None`.
+ This should simplify its API as initialization like `X[0][1] = 2` becomes
+ possible.
+ WARNING: this change introduces a deviation from the original API.
+- The .setComponent*() methods of SetOf/SequenceOf types changed not
+ to allow uninitialized "holes" inside the sequences of their components.
+ They now behave similarly to Python lists.
+ WARNING: this change introduces a deviation from the original API.
+- Default and optional components en/decoding of Constructed type
+ refactored towards better efficiency and more control.
+- OctetsString and Any decoder optimized to avoid creating ASN.1
+ objects for chunks of substrate. Instead they now join substrate
+ chunks together and create ASN.1 object from it just once.
+- The GeneralizedTime and UTCTime types now support to/from Python
+ datetime object conversion.
+- Unit tests added for the `compat` sub-package.
+- Fixed BitString named bits initialization bug.
+- Fixed non-functional tag cache (when running Python 2) at DER decoder.
+- Fixed chunked encoding restriction on DER encoder.
+- Fixed SET components ordering at DER encoder.
+- Fixed BIT STRING & OCTET STRING encoding to be always non-chunked (e.g.
+ primitive) at DER encoder
+- Fixed `compat.integer.from_bytes()` behaviour on empty input.
+
+Revision 0.2.3, released 25-02-2017
+-----------------------------------
+
+- Improved SEQUENCE/SET/CHOICE decoding performance by maintaining a single shared
+ NamedType object for all instances of SEQUENCE/SET object.
+- Improved INTEGER encoding/decoding by switching to Python's built-in
+ integer serialization functions.
+- Improved BitString performance by rebasing it onto Python int type and leveraging
+ fast Integer serialization functions.
+- BitString type usability improved in many ways: for example bitshifting and
+ numeric operation on BitString is now possible.
+- Minor ObjectIdentifier type performance optimization.
+- ASN.1 character types refactored to keep unicode contents internally
+ (rather than serialized octet stream) and duck-type it directly.
+- ASN.1 OctetString initialized from a Python object performs bytes()
+ on it when running on Python 3 (used to do str() which is probably
+ less logical).
+- Missing support for NoValue.__sizeof__ added.
+- Added checks to make sure SEQUENCE/SET components being assigned
+ match the prototypes.
+- Setter methods for constructed types consistently accept matchTags
+ and matchConstraints flags to control the strictness of inner
+ components compatibility verification. Previously, these checks
+ were tied to verifyConstraints flag, now they are all independent.
+- General documentation improvements here and there.
+- Fix to __reversed__() magic to make it returning an iterator.
+- Test suite simplified and unified.
+- The __all__ variable added to most of the Python modules.
+- The "test" directory renamed into "tests" not to collide with
+ the "test" module.
+
+Revision 0.2.2, released 07-02-2017
+-----------------------------------
+
+- FIX TO A SECURITY WEAKNESS: define length only decoders could have successfully
+ processed indefinite length serialization.
+- FIX TO A SECURITY WEAKNESS: canonical decoders (CER/DER) may have successfully
+ consumed non-canonical variations of (otherwise valid) serialization.
+- Broken Enumerated subtyping fixed.
+
+Revision 0.2.1, released 05-02-2017
+-----------------------------------
+
+- FIX TO A SECURITY WEAKNESS: BER decoder improperly cached long tags.
+- New "native" codec implemented to transform pyasn1 types to Python built-in types and back.
+- Switched to new-style classes.
+- Sphinx documentation added.
+- BitString improvements:
+
+ * simple string of binary digits is now supported as initializer
+ * default str() yields string of binary digits (used to yield str(tuple())
+ * binValue and hexValue initializers added
+ * .asNumbers(), .asOctets() and asInteger() representation added
+
+- Components of constructed ASN.1 types can now be populated with
+ uninitialized ASN.1 objects by assigning either noValue sentinel or
+ setupComponent() function return in addition to now-legacy None sentinel.
+ This should improve code readability.
+- NoValue class improved to become a singleton and catch more kinds
+ of access to it.
+- Compatibility wrappers str2octs() and oct2strs() fixed to run over
+ iso-8859-1 encoding.
+- Integer changed to emit Real instance if division produces a float.
+- True division operation now supported by Integer type.
+- The __contains__(), __reverse__() methods implemented for container types
+- Iterator protocol support implemented for all container types.
+ Warning, warning, warning: this change may potentially affect backward
+ compatibility when:
+
+ * user class overrides __getitem__() without overriding __iter__()
+ * when user code iterates over SEQUENCE object to get its components (now keys will be yielded)
+
+- Almost complete Python list and dict protocols added to SequenceOf/SetOf and
+ Sequence/Set respectively
+- Fix to divmod operation implementation in Integer type.
+- Fix to IntegerDecoder's precomputed value map on Python 3.
+- Fix to base ASN.1 types to run in "unicode_literals" mode.
+- Fix to composite constraints "+" operands ordering (AbstractConstraintSet.__radd__)
+- Fix to constraints merge in .subtype() -- on merge existing constraints are
+ expanded to accommodate new constraints, not the other way round. When existing
+ constraints are wrapped in ConstraintsIntersection composite, additional
+ constraints being added on subtyping effectively further narrow the set of
+ allowed values, which aligns well with the notion of subtyping.
+- Fix to NamedTypes methods to handle .getTagMap() returning None
+- Fix to Set/Sequence.setDefaultComponents() to return self
+- Copyright notice added to non-trivial source code files.
+- Author's email changed, copyright extended to 2017
+
+Revision 0.1.9, released 28-09-2015
+-----------------------------------
+
+- Wheel distribution format now supported.
+- Extensions added to text files, CVS attic flushed.
+- Fix to make uninitialized pyasn1 objects failing properly on hash().
+- Fix to ObjectIdentifier initialization from unicode string.
+- Fix to CER/DER Boolean decoder - fail on non single-octet payload.
+
+Revision 0.1.8, released 22-06-2015
+-----------------------------------
+
+- ObjectIdentifier codec fixed to work properly with arc 0 and arc 2 values.
+- Explicit limit on ObjectIdentifier arc value size removed.
+- Unicode initializer support added to OctetString type and derivatives.
+- New prettyPrintType() abstract method implemented to base pyasn1 types
+ to facilitate encoding errors analysis.
+- The __str__() method implemented to Tag, TagSet and TagMap classes to
+ ease encoding errors troubleshooting.
+ easing encoding errors
+- Fix to SEQUENCE and SET types to give them their private componentTypes
+ collection (which is a NamedTypes object) so that they won't collide in
+ a MT execution environment.
+- Missing T61String,ISO646String character types and ObjectDescriptor useful
+ type added.
+- Distribute is gone, switched to setuptools completely.
+- Missing NamedValues.__repr__() added.
+- The base.NoValue() class, that indicates uninitialized ASN.1 object,
+ made public.
+- The base.NoValue() class instances now support __repr__() what makes
+ possible to perform repr() on uninitialized pyasn1 types objects.
+- When comparing ASN.1 types, by-tag and/or by-constraints matching
+ can now be performed with the isSuperTypeOf()/isSameTypeWith() optional
+ flags.
+- Constructed types now verify their consistency by invoking
+ isSameTypeWith(matchTags=True, matchConstraints=False) and
+ isSuperTypeOf(matchTags=False, matchConstraints=True) for each of their
+ components rather than isSuperTypeOf() as it used to be. Constriants check
+ could be enforced to isSameTypeWith() with the strictConstraints=True
+ constructed classes attribute.
+- Constructed types can now be initialized with new .setComponents() method
+ which accepts both var-args and keyword-args. Default repr() modified to
+ reflect this change.
+- NamedTypes() and NamedValues() made comparable.
+- Test coverage extended to cover pyasn1 types __repr__() function.
+- The abs(Integer()) & abs(Real()) operation now returns respective pyasn1
+ type, not a Python type.
+- More Python magic methods implementations added to Integer & Real classes
+ (e.g. __pos__, __neg__, __round__, __floor__, __ceil__, __trunc__)
+- The Integer.__invert__ Python magic method implemented.
+- The OctetString.__int__() and .__float__() magic methods implemented.
+- Handle the case of null writer at Debug printer.
+- BitString encoder/decoder performance improved.
+- Built-in debugging is now based on Python logging module.
+- Fix to NamedType.__repr__() to work properly.
+- Fixes to __repr__() implementation of many built-in ASN.1 types to take into
+ account all of their initializers such as tagSet, subtypeSpec etc.
+- String typed float initializer to REAL type now supported.
+- Float typed mantissa initializer to REAL type for base 2 added.
+- Encoding bases 8 and 16 support for REAL type binary encoder added.
+- More strict CER/DER encoders added for GeneralizedTime and UTCTime types.
+- Asn1Item.hasValue() added to easily distinguish initalized ASN.1 objects
+ from uninitialized ones (e.g. pure types).
+- Fix to REAL type binary decoder to handle different bases and scale factor.
+- Fix to TagSet.repr() to include [obsolete] baseTag information.
+- Fix to broken REAL type decoding handling.
+- Fix to BitString and OctetString decoders dealing with constructed
+ encoding -- it used to be possible to embed other types in substrate.
+- DER codec hardened not to tolerate indefinite length encoding/decoding.
+- Fix to end-of-octest sentinel handling:
+
+ + require strict two-zeros sentinel encoding
+ + recognize EOO sentinel only when explicitly requested by caller
+ of the decoder via allowEoo=True parameter (warning: API change)
+
+Revision 0.1.7
+--------------
+
+- License updated to vanilla BSD 2-Clause to ease package use
+ (http://opensource.org/licenses/BSD-2-Clause).
+- Test suite made discoverable by unittest/unittest2 discovery feature.
+- Fix to decoder working on indefinite length substrate -- end-of-octets
+ marker is now detected by both tag and value. Otherwise zero values may
+ interfere with end-of-octets marker.
+- Fix to decoder to fail in cases where tagFormat indicates inappropriate
+ format for the type (e.g. BOOLEAN is always PRIMITIVE, SET is always
+ CONSTRUCTED and OCTET STRING is either of the two)
+- Fix to REAL type encoder to force primitive encoding form encoding.
+- Fix to CHOICE decoder to handle explicitly tagged, indefinite length
+ mode encoding
+- Fix to REAL type decoder to handle negative REAL values correctly. Test
+ case added.
+
+Revision 0.1.6
+--------------
+
+- The compact (valueless) way of encoding zero INTEGERs introduced in
+ 0.1.5 seems to fail miserably as the world is filled with broken
+ BER decoders. So we had to back off the *encoder* for a while.
+ There's still the IntegerEncoder.supportCompactZero flag which
+ enables compact encoding form whenever it evaluates to True.
+- Report package version on debugging code initialization.
+
+Revision 0.1.5
+--------------
+
+- Documentation updated and split into chapters to better match
+ web-site contents.
+- Make prettyPrint() working for non-initialized pyasn1 data objects. It
+ used to throw an exception.
+- Fix to encoder to produce empty-payload INTEGER values for zeros
+- Fix to decoder to support empty-payload INTEGER and REAL values
+- Fix to unit test suites imports to be able to run each from
+ their current directory
+
+Revision 0.1.4
+--------------
+
+- Built-in codec debugging facility added
+- Added some more checks to ObjectIdentifier BER encoder catching
+ posible 2^8 overflow condition by two leading sub-OIDs
+- Implementations overriding the AbstractDecoder.valueDecoder method
+ changed to return the rest of substrate behind the item being processed
+ rather than the unprocessed substrate within the item (which is usually
+ empty).
+- Decoder's recursiveFlag feature generalized as a user callback function
+ which is passed an uninitialized object recovered from substrate and
+ its uninterpreted payload.
+- Catch inappropriate substrate type passed to decoder.
+- Expose tagMap/typeMap/Decoder objects at DER decoder to uniform API.
+- Obsolete __init__.MajorVersionId replaced with __init__.__version__
+ which is now in-sync with distutils.
+- Package classifiers updated.
+- The __init__.py's made non-empty (rumors are that they may be optimized
+ out by package managers).
+- Bail out gracefully whenever Python version is older than 2.4.
+- Fix to Real codec exponent encoding (should be in 2's complement form),
+ some more test cases added.
+- Fix in Boolean truth testing built-in methods
+- Fix to substrate underrun error handling at ObjectIdentifier BER decoder
+- Fix to BER Boolean decoder that allows other pre-computed
+ values besides 0 and 1
+- Fix to leading 0x80 octet handling in DER/CER/DER ObjectIdentifier decoder.
+ See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
+
+Revision 0.1.3
+--------------
+
+- Include class name into asn1 value constraint violation exception.
+- Fix to OctetString.prettyOut() method that looses leading zero when
+ building hex string.
+
+Revision 0.1.2
+--------------
+
+- Fix to __long__() to actually return longs on py2k
+- Fix to OctetString.__str__() workings of a non-initialized object.
+- Fix to quote initializer of OctetString.__repr__()
+- Minor fix towards ObjectIdentifier.prettyIn() reliability
+- ObjectIdentifier.__str__() is aliased to prettyPrint()
+- Exlicit repr() calls replaced with '%r'
+
+Revision 0.1.1
+--------------
+
+- Hex/bin string initializer to OctetString object reworked
+ (in a backward-incompatible manner)
+- Fixed float() infinity compatibility issue (affects 2.5 and earlier)
+- Fixed a bug/typo at Boolean CER encoder.
+- Major overhawl for Python 2.4 -- 3.2 compatibility:
+ + get rid of old-style types
+ + drop string module usage
+ + switch to rich comparation
+ + drop explicit long integer type use
+ + map()/filter() replaced with list comprehension
+ + apply() replaced with \*/\*\*args
+ + switched to use 'key' sort() callback function
+ + support both __nonzero__() and __bool__() methods
+ + modified not to use py3k-incompatible exception syntax
+ + getslice() operator fully replaced with getitem()
+ + dictionary operations made 2K/3K compatible
+ + base type for encoding substrate and OctetString-based types
+ is now 'bytes' when running py3k and 'str' otherwise
+ + OctetString and derivatives now unicode compliant.
+ + OctetString now supports two python-neutral getters: asOcts() & asInts()
+ + print OctetString content in hex whenever it is not printable otherwise
+ + in test suite, implicit relative import replaced with the absolute one
+ + in test suite, string constants replaced with numerics
+
+Revision 0.0.13
+---------------
+
+- Fix to base10 normalization function that loops on univ.Real(0)
+
+Revision 0.0.13b
+----------------
+
+- ASN.1 Real type is now supported properly.
+- Objects of Constructed types now support __setitem__()
+- Set/Sequence objects can now be addressed by their field names (string index)
+ and position (integer index).
+- Typo fix to ber.SetDecoder code that prevented with schema decoding
+ operation.
+- Fix to explicitly tagged items decoding support.
+- Fix to OctetString.prettyPrint() to better handle non-printable content.
+- Fix to repr() workings of Choice objects.
+
+Revision 0.0.13a
+----------------
+
+- Major codec re-design.
+- Documentation significantly improved.
+- ASN.1 Any type is now supported.
+- All example ASN.1 modules moved to separate pyasn1-modules package.
+- Fix to initial sub-OID overflow condition detection an encoder.
+- BitString initialization value verification improved.
+- The Set/Sequence.getNameByPosition() method implemented.
+- Fix to proper behaviour of PermittedAlphabetConstraint object.
+- Fix to improper Boolean substrate handling at CER/DER decoders.
+- Changes towards performance improvement:
+
+ + all dict.has_key() & dict.get() invocations replaced with modern syntax
+ (this breaks compatibility with Python 2.1 and older).
+ + tag and tagset caches introduced to decoder
+ + decoder code improved to prevent unnecessary pyasn1 objects creation
+ + allow disabling components verification when setting components to
+ structured types, this is used by decoder whilst running with schema
+ mode.
+ + BER decoder for integer values now looks up a small set of pre-computed
+ substrate values to save on decoding.
+ + a few pre-computed values configured to ObjectIdentifier BER encoder.
+ + ChoiceDecoder split-off SequenceOf one to save on unnecessary checks.
+ + replace slow hasattr()/getattr() calls with isinstance() introspection.
+ + track the number of initialized components of Constructed types to save
+ on default/optional components initialization.
+ + added a shortcut ObjectIdentifier.asTuple() to be used instead of
+ __getitem__() in hotspots.
+ + use Tag.asTuple() and pure integers at tag encoder.
+ + introduce and use in decoder the baseTagSet attribute of the built-in
+ ASN.1 types.
+
+Revision 0.0.12a
+----------------
+
+- The individual tag/length/value processing methods of
+ encoder.AbstractItemEncoder renamed (leading underscore stripped)
+ to promote overloading in cases where partial substrate processing
+ is required.
+- The ocsp.py, ldap.py example scripts added.
+- Fix to univ.ObjectIdentifier input value handler to disallow negative
+ sub-IDs.
+
+Revision 0.0.11a
+----------------
+
+- Decoder can now treat values of unknown types as opaque OctetString.
+- Fix to Set/SetOf type decoder to handle uninitialized scalar SetOf
+ components correctly.
+
+Revision 0.0.10a
+----------------
+
+- API versioning mechanics retired (pyasn1.v1 -> pyasn1) what makes
+ it possible to zip-import pyasn1 sources (used by egg and py2exe).
+
+Revision 0.0.9a
+---------------
+
+- Allow any non-zero values in Boolean type BER decoder, as it's in
+ accordnance with the standard.
+
+Revision 0.0.8a
+---------------
+
+- Integer.__index__() now supported (for Python 2.5+).
+- Fix to empty value encoding in BitString encoder, test case added.
+- Fix to SequenceOf decoder that prevents it skipping possible Choice
+ typed inner component.
+- Choice.getName() method added for getting currently set component
+ name.
+- OctetsString.prettyPrint() does a single str() against its value
+ eliminating an extra quotes.
+
+Revision 0.0.7a
+---------------
+
+- Large tags (>31) now supported by codecs.
+- Fix to encoder to properly handle explicitly tagged untagged items.
+- All possible value lengths (up to 256^126) now supported by encoders.
+- Fix to Tag class constructor to prevent negative IDs.
+
+Revision 0.0.6a
+---------------
+
+- Make use of setuptools.
+- Constraints derivation verification (isSuperTypeOf()/isSubTypeOf()) fixed.
+- Fix to constraints comparation logic -- can't cmp() hash values as it
+ may cause false positives due to hash conflicts.
+
+Revision 0.0.5a
+---------------
+
+- Integer BER codec reworked fixing negative values encoding bug.
+- clone() and subtype() methods of Constructed ASN.1 classes now
+ accept optional cloneValueFlag flag which controls original value
+ inheritance. The default is *not* to inherit original value for
+ performance reasons (this may affect backward compatibility).
+ Performance penalty may be huge on deeply nested Constructed objects
+ re-creation.
+- Base ASN.1 types (pyasn1.type.univ.*) do not have default values
+ anymore. They remain uninitialized acting as ASN.1 types. In
+ this model, initialized ASN.1 types represent either types with
+ default value installed or a type instance.
+- Decoders' prototypes are now class instances rather than classes.
+ This is to simplify initial value installation to decoder's
+ prototype value.
+- Bugfix to BitString BER decoder (trailing bits not regarded).
+- Bugfix to Constraints use as mapping keys.
+- Bugfix to Integer & BitString clone() methods
+- Bugix to the way to distinguish Set from SetOf at CER/DER SetOfEncoder
+- Adjustments to make it running on Python 1.5.
+- In tests, substrate constants converted from hex escaped literals into
+ octals to overcome indefinite hex width issue occuring in young Python.
+- Minor performance optimization of TagSet.isSuperTagSetOf() method
+- examples/sshkey.py added
+
+Revision 0.0.4a
+---------------
+
+* Asn1ItemBase.prettyPrinter() -> \*.prettyPrint()
+
+Revision 0.0.3a
+---------------
+
+* Simple ASN1 objects now hash to their Python value and don't
+ depend upon tag/constraints/etc.
+* prettyIn & prettyOut methods of SimplleAsn1Object become public
+* many syntax fixes
+
+Revision 0.0.2a
+---------------
+
+* ConstraintsIntersection.isSuperTypeOf() and
+ ConstraintsIntersection.hasConstraint() implemented
+* Bugfix to NamedValues initialization code
+* +/- operators added to NamedValues objects
+* Integer.__abs__() & Integer.subtype() added
+* ObjectIdentifier.prettyOut() fixes
+* Allow subclass components at SequenceAndSetBase
+* AbstractConstraint.__cmp__() dropped
+* error.Asn1Error replaced with error.PyAsn1Error
+
+Revision 0.0.1a
+---------------
+
+* Initial public alpha release
deleted file mode 100644
--- a/third_party/python/pyasn1/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2005-2013, Ilya Etingof <ilya@glas.net>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/LICENSE.rst
@@ -0,0 +1,24 @@
+Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
--- a/third_party/python/pyasn1/MANIFEST.in
+++ b/third_party/python/pyasn1/MANIFEST.in
@@ -1,3 +1,5 @@
-include CHANGES README LICENSE THANKS TODO
-recursive-include test *.py
-recursive-include doc *.html
+include *.rst *.md
+recursive-include tests *.py
+recursive-include doc Makefile *.rst conf.py
+prune doc/build
+prune doc/source/.templates
\ No newline at end of file
--- a/third_party/python/pyasn1/PKG-INFO
+++ b/third_party/python/pyasn1/PKG-INFO
@@ -1,26 +1,33 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
Name: pyasn1
-Version: 0.1.7
+Version: 0.3.7
Summary: ASN.1 types and codecs
-Home-page: http://sourceforge.net/projects/pyasn1/
-Author: Ilya Etingof <ilya@glas.net>
-Author-email: ilya@glas.net
+Home-page: https://github.com/etingof/pyasn1
+Author: Ilya Etingof <etingof@gmail.com>
+Author-email: etingof@gmail.com
License: BSD
-Description: A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
+Description: Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Telecommunications Industry
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Communications
-Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
deleted file mode 100644
--- a/third_party/python/pyasn1/README
+++ /dev/null
@@ -1,68 +0,0 @@
-
-ASN.1 library for Python
-------------------------
-
-This is an implementation of ASN.1 types and codecs in Python programming
-language. It has been first written to support particular protocol (SNMP)
-but then generalized to be suitable for a wide range of protocols
-based on ASN.1 specification.
-
-FEATURES
---------
-
-* Generic implementation of ASN.1 types (X.208)
-* Fully standard compliant BER/CER/DER codecs
-* 100% Python, works with Python 2.4 up to Python 3.3 (beta 1)
-* MT-safe
-
-MISFEATURES
------------
-
-* No ASN.1 compiler (by-hand ASN.1 spec compilation into Python code required)
-* Codecs are not restartable
-
-INSTALLATION
-------------
-
-The pyasn1 package uses setuptools/distutils for installation. Thus do
-either:
-
-$ easy_install pyasn1
-
-or
-
-$ tar zxf pyasn1-0.1.3.tar.gz
-$ cd pyasn1-0.1.3
-$ python setup.py install
-$ cd test
-$ python suite.py # run unit tests
-
-OPERATION
----------
-
-Perhaps a typical use would involve [by-hand] compilation of your ASN.1
-specification into pyasn1-backed Python code at your application.
-
-For more information on pyasn1 APIs, please, refer to the
-doc/pyasn1-tutorial.html file in the distribution.
-
-Also refer to example modules. Take a look at pyasn1-modules package -- maybe
-it already holds something useful to you.
-
-AVAILABILITY
-------------
-
-The pyasn1 package is distributed under terms and conditions of BSD-style
-license. See LICENSE file in the distribution. Source code is freely
-available from:
-
-http://pyasn1.sf.net
-
-
-FEEDBACK
---------
-
-Please, send your comments and fixes to mailing lists at project web site.
-
-=-=-=
-mailto: ilya@glas.net
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/README.md
@@ -0,0 +1,184 @@
+
+ASN.1 library for Python
+------------------------
+[![PyPI](https://img.shields.io/pypi/v/pyasn1.svg?maxAge=2592000)](https://pypi.python.org/pypi/pyasn1)
+[![Python Versions](https://img.shields.io/pypi/pyversions/pyasn1.svg)](https://pypi.python.org/pypi/pyasn1/)
+[![Build status](https://travis-ci.org/etingof/pyasn1.svg?branch=master)](https://secure.travis-ci.org/etingof/pyasn1)
+[![Coverage Status](https://img.shields.io/codecov/c/github/etingof/pyasn1.svg)](https://codecov.io/github/etingof/pyasn1)
+[![GitHub license](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/etingof/pyasn1/master/LICENSE.txt)
+
+This is a free and open source implementation of ASN.1 types and codecs
+as a Python package. It has been first written to support particular
+protocol (SNMP) but then generalized to be suitable for a wide range
+of protocols based on
+[ASN.1 specification](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items).
+
+Features
+--------
+
+* Generic implementation of ASN.1 types (X.208)
+* Standards compliant BER/CER/DER codecs
+* Dumps/loads ASN.1 structures from Python types
+* 100% Python, works with Python 2.4 up to Python 3.6
+* MT-safe
+* Contributed ASN.1 compiler [Asn1ate](https://github.com/kimgr/asn1ate)
+
+Why using pyasn1
+----------------
+
+ASN.1 solves the data serialization problem. This solution was
+designed long ago by the wise Ancients. Back then, they did not
+have the luxury of wasting bits. That is why ASN.1 is designed
+to serialize data structures of unbounded complexity into
+something compact and efficient when it comes to processing
+the data.
+
+That probably explains why many network protocols and file formats
+still rely on the 30+ years old technology. Including a number of
+high-profile Internet protocols and file formats.
+
+Quite a number of books cover the topic of ASN.1.
+[Communication between heterogeneous systems](http://www.oss.com/asn1/dubuisson.html)
+by Olivier Dubuisson is one of those high quality books freely
+available on the Internet.
+
+The pyasn1 package is designed to help Python programmers tackling
+network protocols and file formats at the comfort of their Python
+prompt. The tool struggles to capture all aspects of a rather
+complicated ASN.1 system and to represent it on the Python terms.
+
+How to use pyasn1
+-----------------
+
+With pyasn1 you can build Python objects from ASN.1 data structures.
+For example, the following ASN.1 data structure:
+
+```bash
+Record ::= SEQUENCE {
+ id INTEGER,
+ room [0] INTEGER OPTIONAL,
+ house [1] INTEGER DEFAULT 0
+}
+```
+
+Could be expressed in pyasn1 like this:
+
+```python
+class Record(Sequence):
+ componentType = NamedTypes(
+ NamedType('id', Integer()),
+ OptionalNamedType(
+ 'room', Integer().subtype(
+ implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
+ )
+ ),
+ DefaultedNamedType(
+ 'house', Integer(0).subtype(
+ implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
+ )
+ )
+ )
+```
+
+It is in the spirit of ASN.1 to take abstract data description
+and turn it into a programming language specific form.
+Once you have your ASN.1 data structure expressed in Python, you
+can use it along the lines of similar Python type (e.g. ASN.1
+`SET` is similar to Python `dict`, `SET OF` to `list`):
+
+```python
+>>> record = Record()
+>>> record['id'] = 123
+>>> record['room'] = 321
+>>> print(record.prettyPrint())
+Record:
+ id=123
+ room=321
+>>>
+```
+
+Part of the power of ASN.1 comes from its serialization features. You
+can serialize your data structure and send it over the network.
+
+```python
+>>> from pyasn1.codec.der.encoder import encode
+>>> substrate = encode(record)
+>>> hexdump(substrate)
+00000: 30 07 02 01 7B 80 02 01 41
+```
+
+Conversely, you can turn serialized ASN.1 content, as received from
+network or read from a file, into a Python object which you can
+introspect, modify, encode and send back.
+
+```python
+>>> from pyasn1.codec.der.decoder import decode
+>>> received_record, rest_of_substrate = decode(substrate, asn1Spec=Record())
+>>>
+>>> for field in received_record:
+>>> print('{} is {}'.format(field, received_record[field]))
+id is 123
+room is 321
+house is 0
+>>>
+>>> record == received_record
+True
+>>> received_record.update(room=123)
+>>> substrate = encode(received_record)
+>>> hexdump(substrate)
+00000: 30 06 02 01 7B 80 01 7B
+```
+
+The pyasn1 classes struggle to emulate their Python prototypes (e.g. int,
+list, dict etc.). But ASN.1 types exhibit more complicated behaviour.
+To make life easier for a Pythonista, they can turn their pyasn1
+classes into Python built-ins:
+
+```python
+>>> from pyasn1.codec.native.encoder import encode
+>>> encode(record)
+{'id': 123, 'room': 321, 'house': 0}
+```
+
+Or vice-versa -- you can initialize an ASN.1 structure from a tree of
+Python objects:
+
+```python
+>>> from pyasn1.codec.native.decoder import decode
+>>> record = decode({'id': 123, 'room': 321, 'house': 0}, asn1Spec=Record())
+>>> print(record.prettyPrint())
+Record:
+ id=123
+ room=321
+>>>
+```
+
+With ASN.1 design, serialization codecs are decoupled from data objects,
+so you could turn every single ASN.1 object into many different
+serialized forms. As of this moment, pyasn1 supports BER, DER, CER and
+Python built-ins codecs. The extremely compact PER encoding is expected
+to be introduced in the upcoming pyasn1 release.
+
+More information on pyasn1 APIs can be found in the
+[documentation](http://pyasn1.sourceforge.net),
+compiled ASN.1 modules for different protocols and file formats
+could be found in the pyasn1-modules
+[repo](https://github.com/etingof/pyasn1-modules).
+
+How to get pyasn1
+-----------------
+
+The pyasn1 package is distributed under terms and conditions of 2-clause
+BSD [license](http://pyasn1.sourceforge.net/license.html). Source code is freely
+available as a GitHub [repo](https://github.com/etingof/pyasn1).
+
+You could `pip install pyasn1` or download it from [PyPI](https://pypi.python.org/pypi/pyasn1).
+
+If something does not work as expected,
+[open an issue](https://github.com/etingof/pyasn1/issues) at GitHub or
+post your question [on Stack Overflow](http://stackoverflow.com/questions/ask)
+or try browsing pyasn1
+[mailing list archives](https://sourceforge.net/p/pyasn1/mailman/pyasn1-users/).
+
+Copyright (c) 2005-2017, [Ilya Etingof](mailto:etingof@gmail.com).
+All rights reserved.
deleted file mode 100644
--- a/third_party/python/pyasn1/THANKS
+++ /dev/null
@@ -1,4 +0,0 @@
-Denis S. Otkidach
-Gregory Golberg
-Bud P. Bruegger
-Jacek Konieczny
deleted file mode 100644
--- a/third_party/python/pyasn1/TODO
+++ /dev/null
@@ -1,36 +0,0 @@
-* Specialize ASN.1 character and useful types
-* Come up with simpler API for deeply nested constructed objects
- addressing
-
-ber.decoder:
-* suspend codec on underrun error ?
-* class-static components map (in simple type classes)
-* present subtypes ?
-* component presence check wont work at innertypeconst
-* add the rest of ASN1 types/codecs
-* type vs value, defaultValue
-
-ber.encoder:
-* Asn1Item.clone() / shallowcopy issue
-* large length encoder?
-* codec restart
-* preserve compatible API whenever stateful codec gets implemented
-* restartable vs incremental
-* plan: make a stateless univeral decoder, then convert it to restartable
- then to incremental
-
-type.useful:
-* may need to implement prettyIn/Out
-
-type.char:
-* may need to implement constraints
-
-type.univ:
-* simpler API to constructed objects: value init, recursive
-
-type.namedtypes
-* type vs tagset name convention
-
-general:
-
-* how untagged TagSet should be initialized?
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/TODO.rst
@@ -0,0 +1,92 @@
+
+Things to be done
+=================
+
+Big things to tackle, anyone interested is welcome to fork pyasn1, work on
+it and come up with a PR!
+
+New codecs
+----------
+
+* PER
+* OER
+* XER
+* LWER
+* JSON (alinged with existing experimental schemas)
+
+Lazy codecs
+-----------
+
+Implement a thin layer over base types to cache pieces
+of substrate being decoded till the very moment of ASN.1
+object access in the parse tree.
+
+Codecs generator interface
+--------------------------
+
+For indefinite length or chunked encoding mode, make codecs
+iterable producing/consuming substrate/objects.
+
+ASN.1 schema compiler
+---------------------
+
+Ideally, the compiler should parse modern schema files and be
+designed to emit code for arbitrary languages (including SQL).
+
+Base types
+----------
+
+Implement X.680 constructs, including information schema.
+
+Examples
+--------
+
+Add examples, including advanced/obscure use cases.
+
+Documentation
+-------------
+
+Document more API, add notes and example snippets.
+
+More fresh modules
+------------------
+
+Compile and ship more Pythonized ASN.1 modules for
+various ASN.1-based protocols (e.g. Kerberos etc).
+Refresh outdated modules in pyasn1-packages.
+
+Minor, housekeeping things
+--------------------------
+
+* more PEP8'ing at places
+* consider simplifying repr(), otherwise it tend to be too hard to grasp
+* Specialize ASN.1 character and useful types
+
+* ber.decoder:
+
+ * suspend codec on underrun error ?
+ * present subtypes ?
+ * component presence check wont work at innertypeconst
+ * type vs value, defaultValue
+
+* ber.encoder:
+
+ * Asn1Item.clone() / shallowcopy issue
+ * large length encoder?
+ * lookup type by tag first to allow custom codecs for non-base types
+
+* type.useful:
+
+ * may need to implement prettyIn/Out
+
+* type.char:
+
+ * may need to implement constraints
+
+* type.namedtypes
+
+ * type vs tagset name convention
+
+* how untagged TagSet should be initialized?
+
+* type and codecs for Real needs refactoring
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/Makefile
@@ -0,0 +1,192 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " applehelp to make an Apple Help Book"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+ @echo " coverage to run coverage check of the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyASN1.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyASN1.qhc"
+
+applehelp:
+ $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+ @echo
+ @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+ @echo "N.B. You won't be able to view it unless you put it in" \
+ "~/Library/Documentation/Help or install it in your application" \
+ "bundle."
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/PyASN1"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PyASN1"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+coverage:
+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+ @echo "Testing of coverage in the sources finished, look at the " \
+ "results in $(BUILDDIR)/coverage/python.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/codecs.html
+++ /dev/null
@@ -1,503 +0,0 @@
-<html>
-<title>
-PyASN1 codecs
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-<h3>
-2. PyASN1 Codecs
-</h3>
-
-<p>
-In ASN.1 context,
-<a href=http://en.wikipedia.org/wiki/Codec>codec</a>
-is a program that transforms between concrete data structures and a stream
-of octets, suitable for transmission over the wire. This serialized form of
-data is sometimes called <i>substrate</i> or <i>essence</i>.
-</p>
-
-<p>
-In pyasn1 implementation, substrate takes shape of Python 3 bytes or
-Python 2 string objects.
-</p>
-
-<p>
-One of the properties of a codec is its ability to cope with incomplete
-data and/or substrate what implies codec to be stateful. In other words,
-when decoder runs out of substrate and data item being recovered is still
-incomplete, stateful codec would suspend and complete data item recovery
-whenever the rest of substrate becomes available. Similarly, stateful encoder
-would encode data items in multiple steps waiting for source data to
-arrive. Codec restartability is especially important when application deals
-with large volumes of data and/or runs on low RAM. For an interesting
-discussion on codecs options and design choices, refer to
-<a href=http://directory.apache.org/subprojects/asn1/>Apache ASN.1 project</a>
-.
-</p>
-
-<p>
-As of this writing, codecs implemented in pyasn1 are all stateless, mostly
-to keep the code simple.
-</p>
-
-<p>
-The pyasn1 package currently supports
-<a href=http://en.wikipedia.org/wiki/Basic_encoding_rules>BER</a> codec and
-its variations --
-<a href=http://en.wikipedia.org/wiki/Canonical_encoding_rules>CER</a> and
-<a href=http://en.wikipedia.org/wiki/Distinguished_encoding_rules>DER</a>.
-More ASN.1 codecs are planned for implementation in the future.
-</p>
-
-<a name="2.1"></a>
-<h4>
-2.1 Encoders
-</h4>
-
-<p>
-Encoder is used for transforming pyasn1 value objects into substrate. Only
-pyasn1 value objects could be serialized, attempts to process pyasn1 type
-objects will cause encoder failure.
-</p>
-
-<p>
-The following code will create a pyasn1 Integer object and serialize it with
-BER encoder:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(univ.Integer(123456))
-b'\x02\x03\x01\xe2@'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-BER standard also defines a so-called <i>indefinite length</i> encoding form
-which makes large data items processing more memory efficient. It is mostly
-useful when encoder does not have the whole value all at once and the
-length of the value can not be determined at the beginning of encoding.
-</p>
-
-<p>
-<i>Constructed encoding</i> is another feature of BER closely related to the
-indefinite length form. In essence, a large scalar value (such as ASN.1
-character BitString type) could be chopped into smaller chunks by encoder
-and transmitted incrementally to limit memory consumption. Unlike indefinite
-length case, the length of the whole value must be known in advance when
-using constructed, definite length encoding form.
-</p>
-
-<p>
-Since pyasn1 codecs are not restartable, pyasn1 encoder may only encode data
-item all at once. However, even in this case, generating indefinite length
-encoding may help a low-memory receiver, running a restartable decoder,
-to process a large data item.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... defMode=False,
-... maxChunkSize=8
-... )
-b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog\x00\x00'
->>>
->>> encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... maxChunkSize=8
-... )
-b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog'
-</pre>
-</td></tr></table>
-
-<p>
-The <b>defMode</b> encoder parameter disables definite length encoding mode,
-while the optional <b>maxChunkSize</b> parameter specifies desired
-substrate chunk size that influences memory requirements at the decoder's end.
-</p>
-
-<p>
-To use CER or DER encoders one needs to explicitly import and call them - the
-APIs are all compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> from pyasn1.codec.cer import encoder as cer_encoder
->>> from pyasn1.codec.der import encoder as der_encoder
->>> ber_encoder.encode(univ.Boolean(True))
-b'\x01\x01\x01'
->>> cer_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>> der_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2"></a>
-<h4>
-2.2 Decoders
-</h4>
-
-<p>
-In the process of decoding, pyasn1 value objects are created and linked to
-each other, based on the information containted in the substrate. Thus,
-the original pyasn1 value object(s) are recovered.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(univ.Boolean(True))
->>> decoder.decode(substrate)
-(Boolean('True(1)'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Commenting on the code snippet above, pyasn1 decoder accepts substrate
-as an argument and returns a tuple of pyasn1 value object (possibly
-a top-level one in case of constructed object) and unprocessed part
-of input substrate.
-</p>
-
-<p>
-All pyasn1 decoders can handle both definite and indefinite length
-encoding modes automatically, explicit switching into one mode
-to another is not required.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... defMode=False,
-... maxChunkSize=8
-... )
->>> decoder.decode(substrate)
-(OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Speaking of BER/CER/DER encoding, in many situations substrate may not contain
-all necessary information needed for complete and accurate ASN.1 values
-recovery. The most obvious cases include implicitly tagged ASN.1 types
-and constrained types.
-</p>
-
-<p>
-As discussed earlier in this handbook, when an ASN.1 type is implicitly
-tagged, previous outermost tag is lost and never appears in substrate.
-If it is the base tag that gets lost, decoder is unable to pick type-specific
-value decoder at its table of built-in types, and therefore recover
-the value part, based only on the information contained in substrate. The
-approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
-a set of them) to <i>guide</i> the decoding process by matching [possibly
-incomplete] tags recovered from substrate with those found in prototype pyasn1
-type objects (also called pyasn1 specification object further in this paper).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import decoder
->>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
-Integer(12), b''
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Decoder would neither modify pyasn1 specification object nor use
-its current values (if it's a pyasn1 value object), but rather use it as
-a hint for choosing proper decoder and as a pattern for creating new objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> i = univ.Integer(12345).subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(i)
->>> substrate
-b'\x9f(\x0209'
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error:
- TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>> decoder.decode(substrate, asn1Spec=i)
-(Integer(12345), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Notice in the example above, that an attempt to run decoder without passing
-pyasn1 specification object fails because recovered tag does not belong
-to any of the built-in types.
-</p>
-
-<p>
-Another important feature of guided decoder operation is the use of
-values constraints possibly present in pyasn1 specification object.
-To explain this, we will decode a random integer object into generic Integer
-and the constrained one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> from pyasn1.codec.ber import encoder, decoder
->>> class DialDigit(univ.Integer):
-... subtypeSpec = constraint.ValueRangeConstraint(0,9)
->>> substrate = encoder.encode(univ.Integer(13))
->>> decoder.decode(substrate)
-(Integer(13), b'')
->>> decoder.decode(substrate, asn1Spec=DialDigit())
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueRangeConstraint(0, 9) failed at: 13
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Similarily to encoders, to use CER or DER decoders application has to
-explicitly import and call them - all APIs are compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
->>>
->>> from pyasn1.codec.ber import decoder as ber_decoder
->>> from pyasn1.codec.cer import decoder as cer_decoder
->>> from pyasn1.codec.der import decoder as der_decoder
->>>
->>> ber_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> cer_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> der_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2.1"></a>
-<h4>
-2.2.1 Decoding untagged types
-</h4>
-
-<p>
-It has already been mentioned, that ASN.1 has two "special case" types:
-CHOICE and ANY. They are different from other types in part of
-tagging - unless these two are additionally tagged, neither of them will
-have their own tag. Therefore these types become invisible in substrate
-and can not be recovered without passing pyasn1 specification object to
-decoder.
-</p>
-
-<p>
-To explain the issue, we will first prepare a Choice object to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('code', univ.Integer()),
-... namedtype.NamedType('message', univ.OctetString())
-... )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Let's now encode this Choice object and then decode its substrate
-with and without pyasn1 specification object:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(codeOrMessage)
->>> substrate
-b'\x04\x0fmy string value'
->>> encoder.encode(univ.OctetString('my string value'))
-b'\x04\x0fmy string value'
->>>
->>> decoder.decode(substrate)
-(OctetString(b'my string value'), b'')
->>> codeOrMessage, substrate = decoder.decode(substrate, asn1Spec=CodeOrMessage())
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-First thing to notice in the listing above is that the substrate produced
-for our Choice value object is equivalent to the substrate for an OctetString
-object initialized to the same value. In other words, any information about
-the Choice component is absent in encoding.
-</p>
-
-<p>
-Sure enough, that kind of substrate will decode into an OctetString object,
-unless original Choice type object is passed to decoder to guide the decoding
-process.
-</p>
-
-<p>
-Similarily untagged ANY type behaves differently on decoding phase - when
-decoder bumps into an Any object in pyasn1 specification, it stops decoding
-and puts all the substrate into a new Any value object in form of an octet
-string. Concerned application could then re-run decoder with an additional,
-more exact pyasn1 specification object to recover the contents of Any
-object.
-</p>
-
-<p>
-As it was mentioned elsewhere in this paper, Any type allows for incomplete
-or changing ASN.1 specification to be handled gracefully by decoder and
-applications.
-</p>
-
-<p>
-To illustrate the working of Any type, we'll have to make the stage
-by encoding a pyasn1 object and then putting its substrate into an any
-object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> innerSubstrate = encoder.encode(univ.Integer(1234))
->>> innerSubstrate
-b'\x02\x02\x04\xd2'
->>> any = univ.Any(innerSubstrate)
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> substrate = encoder.encode(any)
->>> substrate
-b'\x02\x02\x04\xd2'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As with Choice type encoding, there is no traces of Any type in substrate.
-Obviously, the substrate we are dealing with, will decode into the inner
-[Integer] component, unless pyasn1 specification is given to guide the
-decoder. Continuing previous code:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
-
->>> decoder.decode(substrate)
-(Integer(1234), b'')
->>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> decoder.decode(str(any))
-(Integer(1234), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Both CHOICE and ANY types are widely used in practice. Reader is welcome to
-take a look at
-<a href=http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>
-ASN.1 specifications of X.509 applications</a> for more information.
-</p>
-
-<a name="2.2.2"></a>
-<h4>
-2.2.2 Ignoring unknown types
-</h4>
-
-<p>
-When dealing with a loosely specified ASN.1 structure, the receiving
-end may not be aware of some types present in the substrate. It may be
-convenient then to turn decoder into a recovery mode. Whilst there, decoder
-will not bail out when hit an unknown tag but rather treat it as an Any
-type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> taggedInt = univ.Integer(12345).subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(taggedInt)
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>>
->>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
->>> decoder.decode(substrate)
-(Any(b'\x9f(\x0209'), '')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-It's also possible to configure a custom decoder, to handle unknown tags
-found in substrate. This can be done by means of <b>defaultRawDecoder</b>
-attribute holding a reference to type decoder object. Refer to the source
-for API details.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/constraints.html
+++ /dev/null
@@ -1,436 +0,0 @@
-<html>
-<title>
-PyASN1 subtype constraints
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h4>
-1.4 PyASN1 subtype constraints
-</h4>
-
-<p>
-Most ASN.1 types can correspond to an infinite set of values. To adapt to
-particular application's data model and needs, ASN.1 provides a mechanism
-for limiting the infinite set to values, that make sense in particular case.
-</p>
-
-<p>
-Imposing value constraints on an ASN.1 type can also be seen as creating
-a subtype from its base type.
-</p>
-
-<p>
-In pyasn1, constraints take shape of immutable objects capable
-of evaluating given value against constraint-specific requirements.
-Constraint object is a property of pyasn1 type. Like TagSet property,
-associated with every pyasn1 type, constraints can never be modified
-in place. The only way to modify pyasn1 type constraint is to associate
-new constraint object to a new pyasn1 type object.
-</p>
-
-<p>
-A handful of different flavors of <i>constraints</i> are defined in ASN.1.
-We will discuss them one by one in the following chapters and also explain
-how to combine and apply them to types.
-</p>
-
-<a name="1.4.1"></a>
-<h4>
-1.4.1 Single value constraint
-</h4>
-
-<p>
-This kind of constraint allows for limiting type to a finite, specified set
-of values.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-DialButton ::= OCTET STRING (
- "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-)
-</pre>
-</td></tr></table>
-
-<p>
-Its pyasn1 implementation would look like:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import constraint
->>> c = constraint.SingleValueConstraint(
- '0','1','2','3','4','5','6','7','8','9'
-)
->>> c
-SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
->>> c('0')
->>> c('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the snippet above, if a value violates the constraint, an
-exception will be thrown. A constrainted pyasn1 type object holds a
-reference to a constraint object (or their combination, as will be explained
-later) and calls it for value verification.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class DialButton(univ.OctetString):
-... subtypeSpec = constraint.SingleValueConstraint(
-... '0','1','2','3','4','5','6','7','8','9'
-... )
->>> DialButton('0')
-DialButton(b'0')
->>> DialButton('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Constrained pyasn1 value object can never hold a violating value.
-</p>
-
-<a name="1.4.2"></a>
-<h4>
-1.4.2 Value range constraint
-</h4>
-
-<p>
-A pair of values, compliant to a type to be constrained, denote low and upper
-bounds of allowed range of values of a type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Teenagers ::= INTEGER (13..19)
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1 terms:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class Teenagers(univ.Integer):
-... subtypeSpec = constraint.ValueRangeConstraint(13, 19)
->>> Teenagers(14)
-Teenagers(14)
->>> Teenagers(20)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueRangeConstraint(13, 19) failed at: 20
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Value range constraint usually applies numeric types.
-</p>
-
-<a name="1.4.3"></a>
-<h4>
-1.4.3 Size constraint
-</h4>
-
-<p>
-It is sometimes convenient to set or limit the allowed size of a data item
-to be sent from one application to another to manage bandwidth and memory
-consumption issues. Size constraint specifies the lower and upper bounds
-of the size of a valid value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-TwoBits ::= BIT STRING (SIZE (2))
-</pre>
-</td></tr></table>
-
-<p>
-Express the same grammar in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class TwoBits(univ.BitString):
-... subtypeSpec = constraint.ValueSizeConstraint(2, 2)
->>> TwoBits((1,1))
-TwoBits("'11'B")
->>> TwoBits((1,1,0))
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Size constraint can be applied to potentially massive values - bit or octet
-strings, SEQUENCE OF/SET OF values.
-</p>
-
-<a name="1.4.4"></a>
-<h4>
-1.4.4 Alphabet constraint
-</h4>
-
-<p>
-The permitted alphabet constraint is similar to Single value constraint
-but constraint applies to individual characters of a value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MorseCode ::= PrintableString (FROM ("."|"-"|" "))
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class MorseCode(char.PrintableString):
-... subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
->>> MorseCode("...---...")
-MorseCode('...---...')
->>> MorseCode("?")
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Current implementation does not handle ranges of characters in constraint
-(FROM "A".."Z" syntax), one has to list the whole set in a range.
-</p>
-
-<a name="1.4.5"></a>
-<h4>
-1.4.5 Constraint combinations
-</h4>
-
-<p>
-Up to this moment, we used a single constraint per ASN.1 type. The standard,
-however, allows for combining multiple individual constraints into
-intersections, unions and exclusions.
-</p>
-
-<p>
-In pyasn1 data model, all of these methods of constraint combinations are
-implemented as constraint-like objects holding individual constraint (or
-combination) objects. Like terminal constraint objects, combination objects
-are capable to perform value verification at its set of enclosed constraints
-according to the logic of particular combination.
-</p>
-
-<p>
-Constraints intersection verification succeeds only if a value is
-compliant to each constraint in a set. To begin with, the following
-specification will constitute a valid telephone number:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
-</pre>
-</td></tr></table>
-
-<p>
-Constraint intersection object serves the logic above:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class PhoneNumber(char.NumericString):
-... subtypeSpec = constraint.ConstraintsIntersection(
-... constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-... constraint.ValueSizeConstraint(11, 11)
-... )
->>> PhoneNumber('79039343212')
-PhoneNumber('79039343212')
->>> PhoneNumber('?9039343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsIntersection(
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
- ValueSizeConstraint(11, 11)) failed at:
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
->>> PhoneNumber('9343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsIntersection(
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
- ValueSizeConstraint(11, 11)) failed at:
- ValueSizeConstraint(10, 10) failed at: "9343212"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Union of constraints works by making sure that a value is compliant
-to any of the constraint in a set. For instance:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
-</pre>
-</td></tr></table>
-
-<p>
-It's important to note, that a value must fully comply to any single
-constraint in a set. In the specification above, a value of all small or
-all capital letters is compliant, but a mix of small&capitals is not.
-Here's its pyasn1 analogue:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class CapitalOrSmall(char.IA5String):
-... subtypeSpec = constraint.ConstraintsUnion(
-... constraint.PermittedAlphabetConstraint('A','B','C'),
-... constraint.PermittedAlphabetConstraint('a','b','c')
-... )
->>> CapitalOrSmall('ABBA')
-CapitalOrSmall('ABBA')
->>> CapitalOrSmall('abba')
-CapitalOrSmall('abba')
->>> CapitalOrSmall('Abba')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'),
- PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Finally, the exclusion constraint simply negates the logic of value
-verification at a constraint. In the following example, any integer value
-is allowed in a type but not zero.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-NoZero ::= INTEGER (ALL EXCEPT 0)
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 the above definition would read:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class NoZero(univ.Integer):
-... subtypeSpec = constraint.ConstraintsExclusion(
-... constraint.SingleValueConstraint(0)
-... )
->>> NoZero(1)
-NoZero(1)
->>> NoZero(0)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The depth of such a constraints tree, built with constraint combination objects
-at its nodes, has not explicit limit. Value verification is performed in a
-recursive manner till a definite solution is found.
-</p>
-
-<a name="1.5"></a>
-<h4>
-1.5 Types relationships
-</h4>
-
-<p>
-In the course of data processing in an application, it is sometimes
-convenient to figure out the type relationships between pyasn1 type or
-value objects. Formally, two things influence pyasn1 types relationship:
-<i>tag set</i> and <i>subtype constraints</i>. One pyasn1 type is considered
-to be a derivative of another if their TagSet and Constraint objects are
-a derivation of one another.
-</p>
-
-<p>
-The following example illustrates the concept (we use the same tagset but
-different constraints for simplicity):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
->>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
-... constraint.ValueRangeConstraint(3,8),
-... constraint.ValueRangeConstraint(4,7)
-... ) )
->>> i1.isSameTypeWith(i2)
-False
->>> i1.isSuperTypeOf(i2)
-True
->>> i1.isSuperTypeOf(i1)
-True
->>> i2.isSuperTypeOf(i1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the above code snippet, there are two methods of any pyasn1
-type/value object that test types for their relationship:
-<b>isSameTypeWith</b>() and <b>isSuperTypeOf</b>(). The former is
-self-descriptive while the latter yields true if the argument appears
-to be a pyasn1 object which has tagset and constraints derived from those
-of the object being called.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/constructed.html
+++ /dev/null
@@ -1,377 +0,0 @@
-<html>
-<title>
-PyASN1 Constructed types
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h4>
-1.3 PyASN1 Constructed types
-</h4>
-
-<p>
-Besides scalar types, ASN.1 specifies so-called constructed ones - these
-are capable of holding one or more values of other types, both scalar
-and constructed.
-</p>
-
-<p>
-In pyasn1 implementation, constructed ASN.1 types behave like
-Python sequences, and also support additional component addressing methods,
-specific to particular constructed type.
-</p>
-
-<a name="1.3.1"></a>
-<h4>
-1.3.1 Sequence and Set types
-</h4>
-
-<p>
-The Sequence and Set types have many similar properties:
-</p>
-<ul>
-<li>they can hold any number of inner components of different types
-<li>every component has a human-friendly identifier
-<li>any component can have a default value
-<li>some components can be absent.
-</ul>
-
-<p>
-However, Sequence type guarantees the ordering of Sequence value components
-to match their declaration order. By contrast, components of the
-Set type can be ordered to best suite application's needs.
-<p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Record ::= SEQUENCE {
- id INTEGER,
- room [0] INTEGER OPTIONAL,
- house [1] INTEGER DEFAULT 0
-}
-</pre>
-</td></tr></table>
-
-<p>
-Up to this moment, the only method we used for creating new pyasn1 types
-is Python sub-classing. With this method, a new, named Python class is created
-what mimics type derivation in ASN.1 grammar. However, ASN.1 also allows for
-defining anonymous subtypes (room and house components in the example above).
-To support anonymous subtyping in pyasn1, a cloning operation on an existing
-pyasn1 type object can be invoked what creates a new instance of original
-object with possibly modified properties.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Record(univ.Sequence):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('id', univ.Integer()),
-... namedtype.OptionalNamedType(
-... 'room',
-... univ.Integer().subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
-... )
-... ),
-... namedtype.DefaultedNamedType(
-... 'house',
-... univ.Integer(0).subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
-... )
-... )
-... )
->>>
-</pre>
-</td></tr></table>
-
-<p>
-All pyasn1 constructed type classes have a class attribute <b>componentType</b>
-that represent default type specification. Its value is a NamedTypes object.
-</p>
-
-<p>
-The NamedTypes class instance holds a sequence of NameType, OptionalNamedType
-or DefaultedNamedType objects which, in turn, refer to pyasn1 type objects that
-represent inner SEQUENCE components specification.
-</p>
-
-<p>
-Finally, invocation of a subtype() method of pyasn1 type objects in the code
-above returns an implicitly tagged copy of original object.
-</p>
-
-<p>
-Once a SEQUENCE or SET type is decleared with pyasn1, it can be instantiated
-and initialized (continuing the above code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record = Record()
->>> record.setComponentByName('id', 123)
->>> print(record.prettyPrint())
-Record:
- id=123
->>>
->>> record.setComponentByPosition(1, 321)
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
->>>
->>> record.setDefaultComponents()
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
- house=0
-</pre>
-</td></tr></table>
-
-<p>
-Inner components of pyasn1 Sequence/Set objects could be accessed using the
-following methods:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record.getComponentByName('id')
-Integer(123)
->>> record.getComponentByPosition(1)
-Integer(321)
->>> record[2]
-Integer(0)
->>> for idx in range(len(record)):
-... print(record.getNameByPosition(idx), record.getComponentByPosition(idx))
-id 123
-room 321
-house 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The Set type share all the properties of Sequence type, and additionally
-support by-tag component addressing (as all Set components have distinct
-types).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Gamer(univ.Set):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('score', univ.Integer()),
-... namedtype.NamedType('player', univ.OctetString()),
-... namedtype.NamedType('id', univ.ObjectIdentifier())
-... )
->>> gamer = Gamer()
->>> gamer.setComponentByType(univ.Integer().getTagSet(), 121343)
->>> gamer.setComponentByType(univ.OctetString().getTagSet(), 'Pascal')
->>> gamer.setComponentByType(univ.ObjectIdentifier().getTagSet(), (1,3,7,2))
->>> print(gamer.prettyPrint())
-Gamer:
- score=121343
- player=b'Pascal'
- id=1.3.7.2
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.2"></a>
-<h4>
-1.3.2 SequenceOf and SetOf types
-</h4>
-
-<p>
-Both, SequenceOf and SetOf types resemble an unlimited size list of components.
-All the components must be of the same type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Progression ::= SEQUENCE OF INTEGER
-
-arithmeticProgression Progression ::= { 1, 3, 5, 7 }
-</pre>
-</td></tr></table>
-
-<p>
-SequenceOf and SetOf types are expressed by the very similar pyasn1 type
-objects. Their components can only be addressed by position and they
-both have a property of automatic resize.
-</p>
-
-<p>
-To specify inner component type, the <b>componentType</b> class attribute
-should refer to another pyasn1 type object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class Progression(univ.SequenceOf):
-... componentType = univ.Integer()
->>> arithmeticProgression = Progression()
->>> arithmeticProgression.setComponentByPosition(1, 111)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
--empty- 111
->>> arithmeticProgression.setComponentByPosition(0, 100)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
-100 111
->>>
->>> for idx in range(len(arithmeticProgression)):
-... arithmeticProgression.getComponentByPosition(idx)
-Integer(100)
-Integer(111)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Any scalar or constructed pyasn1 type object can serve as an inner component.
-Missing components are prohibited in SequenceOf/SetOf value objects.
-</p>
-
-<a name="1.3.3"></a>
-<h4>
-1.3.3 Choice type
-</h4>
-
-<p>
-Values of ASN.1 CHOICE type can contain only a single value of a type from a
-list of possible alternatives. Alternatives must be ASN.1 types with
-distinct tags for the whole structure to remain unambiguous. Unlike most
-other types, CHOICE is an untagged one, e.g. it has no base tag of its own.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CodeOrMessage ::= CHOICE {
- code INTEGER,
- message OCTET STRING
-}
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 implementation, Choice object behaves like Set but accepts only
-a single inner component at a time. It also offers a few additional methods
-specific to its behaviour.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('code', univ.Integer()),
-... namedtype.NamedType('message', univ.OctetString())
-... )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
->>> codeOrMessage.setComponentByName('code', 123)
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- code=123
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Since there could be only a single inner component value in the pyasn1 Choice
-value object, either of the following methods could be used for fetching it
-(continuing previous code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> codeOrMessage.getName()
-'message'
->>> codeOrMessage.getComponent()
-OctetString(b'my string value')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.4"></a>
-<h4>
-1.3.4 Any type
-</h4>
-
-<p>
-The ASN.1 ANY type is a kind of wildcard or placeholder that matches
-any other type without knowing it in advance. Like CHOICE type, ANY
-has no base tag.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Error ::= SEQUENCE {
- code INTEGER,
- parameter ANY DEFINED BY code
-}
-</pre>
-</td></tr></table>
-
-<p>
-The ANY type is frequently used in specifications, where exact type is not
-yet agreed upon between communicating parties or the number of possible
-alternatives of a type is infinite.
-Sometimes an auxiliary selector is kept around to help parties indicate
-the kind of ANY payload in effect ("code" in the example above).
-</p>
-
-<p>
-Values of the ANY type contain serialized ASN.1 value(s) in form of
-an octet string. Therefore pyasn1 Any value object share the properties of
-pyasn1 OctetString object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> someValue = univ.Any(b'\x02\x01\x01')
->>> someValue
-Any(b'\x02\x01\x01')
->>> str(someValue)
-'\x02\x01\x01'
->>> bytes(someValue)
-b'\x02\x01\x01'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Receiving application is supposed to explicitly deserialize the content of Any
-value object, possibly using auxiliary selector for figuring out its ASN.1
-type to pick appropriate decoder.
-</p>
-
-<p>
-There will be some more talk and code snippets covering Any type in the codecs
-chapters that follow.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/intro.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<html>
-<title>
-PyASN1 reference manual
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-PyASN1 reference manual
-</h3>
-
-<p align=right>
-<i>written by <a href=mailto:ilya@glas.net>Ilya Etingof</a>, 2011-2012</i>
-</p>
-
-<p>
-Free and open-source pyasn1 library makes it easier for programmers and
-network engineers to develop, debug and experiment with ASN.1-based protocols
-using Python programming language as a tool.
-</p>
-
-<p>
-Abstract Syntax Notation One
-(<a href=http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>ASN.1</a>)
-is a set of
-<a href=http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>
-ITU standards</a> concered with provisioning instrumentation for developing
-data exchange protocols in a robust, clear and interoperabable way for
-various IT systems and applications. Most of the efforts are targeting the
-following areas:
-<ul>
-<li>Data structures: the standard introduces a collection of basic data types
-(similar to integers, bits, strings, arrays and records in a programming
-language) that can be used for defining complex, possibly nested data
-structures representing domain-specific data units.
-<li>Serialization protocols: domain-specific data units expressed in ASN.1
-types could be converted into a series of octets for storage or transmission
-over the wire and then recovered back into their structured form on the
-receiving end. This process is immune to various hardware and software
-related dependencies.
-<li>Data description language: could be used to describe particular set of
-domain-specific data structures and their relationships. Such a description
-could be passed to an ASN.1 compiler for automated generation of program
-code that represents ASN.1 data structures in language-native environment
-and handles data serialization issues.
-</ul>
-</p>
-
-<p>
-This tutorial and algorithms, implemented by pyasn1 library, are
-largely based on the information read in the book
-<a href="http://www.oss.com/asn1/dubuisson.html">
-ASN.1 - Communication between heterogeneous systems</a>
-by Olivier Dubuisson. Another relevant resource is
-<a href=ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>
-A Layman's Guide to a Subset of ASN.1, BER, and DER</a> by Burton S. Kaliski.
-It's advised to refer to these books for more in-depth knowledge on the
-subject of ASN.1.
-</p>
-
-<p>
-As of this writing, pyasn1 library implements most of standard ASN.1 data
-structures in a rather detailed and feature-rich manner. Another highly
-important capability of the library is its data serialization facilities.
-The last component of the standard - ASN.1 compiler is planned for
-implementation in the future.
-</p>
-
-</p>
-The pyasn1 library was designed to follow the pre-1995 ASN.1 specification
-(also known as X.208). Later, post 1995, revision (X.680) introduced
-significant changes most of which have not yet been supported by pyasn1.
-</p>
-
-<h3>
-Table of contents
-</h3>
-
-<p>
-<ul>
-<li><a href="scalar.html">1. Data model for ASN.1 types</a>
-<li><a href="scalar.html#1.1">1.1 Scalar types</a>
-<li><a href="scalar.html#1.1.1">1.1.1 Boolean type</a>
-<li><a href="scalar.html#1.1.2">1.1.2 Null type</a>
-<li><a href="scalar.html#1.1.3">1.1.3 Integer type</a>
-<li><a href="scalar.html#1.1.4">1.1.4 Enumerated type</a>
-<li><a href="scalar.html#1.1.5">1.1.5 Real type</a>
-<li><a href="scalar.html#1.1.6">1.1.6 Bit string type</a>
-<li><a href="scalar.html#1.1.7">1.1.7 OctetString type</a>
-<li><a href="scalar.html#1.1.8">1.1.8 ObjectIdentifier type</a>
-<li><a href="scalar.html#1.1.9">1.1.9 Character string types</a>
-<li><a href="scalar.html#1.1.10">1.1.10 Useful types</a>
-<li><a href="tagging.html">1.2 Tagging</a>
-<li><a href="constructed.html">1.3 Constructed types</a>
-<li><a href="constructed.html#1.3.1">1.3.1 Sequence and Set types</a>
-<li><a href="constructed.html#1.3.2">1.3.2 SequenceOf and SetOf types</a>
-<li><a href="constructed.html#1.3.3">1.3.3 Choice type</a>
-<li><a href="constructed.html#1.3.4">1.3.4 Any type</a>
-<li><a href="constraints.html">1.4 Subtype constraints</a>
-<li><a href="constraints.html#1.4.1">1.4.1 Single value constraint</a>
-<li><a href="constraints.html#1.4.2">1.4.2 Value range constraint</a>
-<li><a href="constraints.html#1.4.3">1.4.3 Size constraint</a>
-<li><a href="constraints.html#1.4.4">1.4.4 Alphabet constraint</a>
-<li><a href="constraints.html#1.4.5">1.4.5 Constraint combinations</a>
-<li><a href="constraints.html#1.5">1.5 Types relationships</a>
-<li><a href="codecs.html">2. Codecs</a>
-<li><a href="codecs.html#2.1">2.1 Encoders</a>
-<li><a href="codecs.html#2.2">2.2 Decoders</a>
-<li><a href="codecs.html#2.2.1">2.2.1 Decoding untagged types</a>
-<li><a href="codecs.html#2.2.2">2.2.2 Ignoring unknown types</a>
-</ul>
-
-<p>
-Although pyasn1 software is almost a decade old and used in many production
-environments, it still may have bugs and non-implemented pieces. Anyone
-who happens to run into such defect is welcome to complain to
-<a href=mailto:pyasn1-users@lists.sourceforge.net>pyasn1 mailing list</a>
-or better yet fix the issue and send
-<a href=mailto:ilya@glas.net>me</a> the patch.
-</p>
-
-<p>
-Typically, pyasn1 is used for building arbitrary protocol support into
-various applications. This involves manual translation of ASN.1 data
-structures into their pyasn1 implementations. To save time and effort,
-data structures for some of the popular protocols are pre-programmed
-and kept for further re-use in form of the
-<a href=http://sourceforge.net/projects/pyasn1/files/pyasn1-modules/>
-pyasn1-modules package</a>. For instance, many structures for PKI (X.509,
-PKCS#*, CRMF, OCSP), LDAP and SNMP are present.
-Applications authors are advised to import and use relevant modules
-from that package whenever needed protocol structures are already
-there. New protocol modules contributions are welcome.
-</p>
-
-<p>
-And finally, the latest pyasn1 package revision is available for free
-download from
-<a href=http://sourceforge.net/projects/pyasn1/>project home</a> and
-also from the
-<a href=http://pypi.python.org/pypi>Python package repository</a>.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/pyasn1-tutorial.html
+++ /dev/null
@@ -1,2405 +0,0 @@
-<html>
-<title>
-PyASN1 programmer's manual
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-PyASN1 programmer's manual
-</h3>
-
-<p align=right>
-<i>written by <a href=mailto:ilya@glas.net>Ilya Etingof</a>, 2011-2012</i>
-</p>
-
-<p>
-Free and open-source pyasn1 library makes it easier for programmers and
-network engineers to develop, debug and experiment with ASN.1-based protocols
-using Python programming language as a tool.
-</p>
-
-<p>
-Abstract Syntax Notation One
-(<a href=http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>ASN.1</a>)
-is a set of
-<a href=http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>
-ITU standards</a> concered with provisioning instrumentation for developing
-data exchange protocols in a robust, clear and interoperabable way for
-various IT systems and applications. Most of the efforts are targeting the
-following areas:
-<ul>
-<li>Data structures: the standard introduces a collection of basic data types
-(similar to integers, bits, strings, arrays and records in a programming
-language) that can be used for defining complex, possibly nested data
-structures representing domain-specific data units.
-<li>Serialization protocols: domain-specific data units expressed in ASN.1
-types could be converted into a series of octets for storage or transmission
-over the wire and then recovered back into their structured form on the
-receiving end. This process is immune to various hardware and software
-related dependencies.
-<li>Data description language: could be used to describe particular set of
-domain-specific data structures and their relationships. Such a description
-could be passed to an ASN.1 compiler for automated generation of program
-code that represents ASN.1 data structures in language-native environment
-and handles data serialization issues.
-</ul>
-</p>
-
-<p>
-This tutorial and algorithms, implemented by pyasn1 library, are
-largely based on the information read in the book
-<a href="http://www.oss.com/asn1/dubuisson.html">
-ASN.1 - Communication between heterogeneous systems</a>
-by Olivier Dubuisson. Another relevant resource is
-<a href=ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>
-A Layman's Guide to a Subset of ASN.1, BER, and DER</a> by Burton S. Kaliski.
-It's advised to refer to these books for more in-depth knowledge on the
-subject of ASN.1.
-</p>
-
-<p>
-As of this writing, pyasn1 library implements most of standard ASN.1 data
-structures in a rather detailed and feature-rich manner. Another highly
-important capability of the library is its data serialization facilities.
-The last component of the standard - ASN.1 compiler is planned for
-implementation in the future.
-</p>
-
-</p>
-The pyasn1 library was designed to follow the pre-1995 ASN.1 specification
-(also known as X.208). Later, post 1995, revision (X.680) introduced
-significant changes most of which have not yet been supported by pyasn1.
-</p>
-
-<h3>
-Table of contents
-</h3>
-
-<p>
-<ul>
-<li><a href="#1">1. Data model for ASN.1 types</a>
-<li><a href="#1.1">1.1 Scalar types</a>
-<li><a href="#1.1.1">1.1.1 Boolean type</a>
-<li><a href="#1.1.2">1.1.2 Null type</a>
-<li><a href="#1.1.3">1.1.3 Integer type</a>
-<li><a href="#1.1.4">1.1.4 Enumerated type</a>
-<li><a href="#1.1.5">1.1.5 Real type</a>
-<li><a href="#1.1.6">1.1.6 Bit string type</a>
-<li><a href="#1.1.7">1.1.7 OctetString type</a>
-<li><a href="#1.1.8">1.1.8 ObjectIdentifier type</a>
-<li><a href="#1.1.9">1.1.9 Character string types</a>
-<li><a href="#1.1.10">1.1.10 Useful types</a>
-<li><a href="#1.2">1.2 Tagging</a>
-<li><a href="#1.3">1.3 Constructed types</a>
-<li><a href="#1.3.1">1.3.1 Sequence and Set types</a>
-<li><a href="#1.3.2">1.3.2 SequenceOf and SetOf types</a>
-<li><a href="#1.3.3">1.3.3 Choice type</a>
-<li><a href="#1.3.4">1.3.4 Any type</a>
-<li><a href="#1.4">1.4 Subtype constraints</a>
-<li><a href="#1.4.1">1.4.1 Single value constraint</a>
-<li><a href="#1.4.2">1.4.2 Value range constraint</a>
-<li><a href="#1.4.3">1.4.3 Size constraint</a>
-<li><a href="#1.4.4">1.4.4 Alphabet constraint</a>
-<li><a href="#1.4.5">1.4.5 Constraint combinations</a>
-<li><a href="#1.5">1.5 Types relationships</a>
-<li><a href="#2">2. Codecs</a>
-<li><a href="#2.1">2.1 Encoders</a>
-<li><a href="#2.2">2.2 Decoders</a>
-<li><a href="#2.2.1">2.2.1 Decoding untagged types</a>
-<li><a href="#2.2.2">2.2.2 Ignoring unknown types</a>
-<li><a href="#3">3. Feedback and getting help</a>
-</ul>
-
-
-<a name="1"></a>
-<h3>
-1. Data model for ASN.1 types
-</h3>
-
-<p>
-All ASN.1 types could be categorized into two groups: scalar (also called
-simple or primitive) and constructed. The first group is populated by
-well-known types like Integer or String. Members of constructed group
-hold other types (simple or constructed) as their inner components, thus
-they are semantically close to a programming language records or lists.
-</p>
-
-<p>
-In pyasn1, all ASN.1 types and values are implemented as Python objects.
-The same pyasn1 object can represent either ASN.1 type and/or value
-depending of the presense of value initializer on object instantiation.
-We will further refer to these as <i>pyasn1 type object</i> versus <i>pyasn1
-value object</i>.
-</p>
-
-<p>
-Primitive ASN.1 types are implemented as immutable scalar objects. There values
-could be used just like corresponding native Python values (integers,
-strings/bytes etc) and freely mixed with them in expressions.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerValue = univ.Integer(12)
->>> asn1IntegerValue - 2
-10
->>> univ.OctetString('abc') == 'abc'
-True # Python 2
->>> univ.OctetString(b'abc') == b'abc'
-True # Python 3
-</pre>
-</td></tr></table>
-
-<p>
-It would be an error to perform an operation on a pyasn1 type object
-as it holds no value to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerType = univ.Integer()
->>> asn1IntegerType - 2
-...
-pyasn1.error.PyAsn1Error: No value for __coerce__()
-</pre>
-</td></tr></table>
-
-<a name="1.1"></a>
-<h4>
-1.1 Scalar types
-</h4>
-
-<p>
-In the sub-sections that follow we will explain pyasn1 mapping to those
-primitive ASN.1 types. Both, ASN.1 notation and corresponding pyasn1
-syntax will be given in each case.
-</p>
-
-<a name="1.1.1"></a>
-<h4>
-1.1.1 Boolean type
-</h4>
-
-<p>
-This is the simplest type those values could be either True or False.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-FunFactorPresent ::= BOOLEAN
-
-;; values declaration and assignment
-pythonFunFactor FunFactorPresent ::= TRUE
-cobolFunFactor FunFactorPresent :: FALSE
-</pre>
-</td></tr></table>
-
-<p>
-And here's pyasn1 version of it:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class FunFactorPresent(univ.Boolean): pass
-...
->>> pythonFunFactor = FunFactorPresent(True)
->>> cobolFunFactor = FunFactorPresent(False)
->>> pythonFunFactor
-FunFactorPresent('True(1)')
->>> cobolFunFactor
-FunFactorPresent('False(0)')
->>> pythonFunFactor == cobolFunFactor
-False
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.2"></a>
-<h4>
-1.1.2 Null type
-</h4>
-
-<p>
-The NULL type is sometimes used to express the absense of any information.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-Vote ::= CHOICE {
- agreed BOOLEAN,
- skip NULL
-}
-</td></tr></table>
-
-;; value declaration and assignment
-myVote Vote ::= skip:NULL
-</pre>
-
-<p>
-We will explain the CHOICE type later in this paper, meanwhile the NULL
-type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> skip = univ.Null()
->>> skip
-Null('')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.3"></a>
-<h4>
-1.1.3 Integer type
-</h4>
-
-<p>
-ASN.1 defines the values of Integer type as negative or positive of whatever
-length. This definition plays nicely with Python as the latter places no
-limit on Integers. However, some ASN.1 implementations may impose certain
-limits of integer value ranges. Keep that in mind when designing new
-data structures.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; values specification
-age-of-universe INTEGER ::= 13750000000
-mean-martian-surface-temperature INTEGER ::= -63
-</pre>
-</td></tr></table>
-
-<p>
-A rather strigntforward mapping into pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> ageOfUniverse = univ.Integer(13750000000)
->>> ageOfUniverse
-Integer(13750000000)
->>>
->>> meanMartianSurfaceTemperature = univ.Integer(-63)
->>> meanMartianSurfaceTemperature
-Integer(-63)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-ASN.1 allows to assign human-friendly names to particular values of
-an INTEGER type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Temperature ::= INTEGER {
- freezing(0),
- boiling(100)
-}
-</pre>
-</td></tr></table>
-
-<p>
-The Temperature type expressed in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class Temperature(univ.Integer):
-... namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
-...
->>> t = Temperature(0)
->>> t
-Temperature('freezing(0)')
->>> t + 1
-Temperature(1)
->>> t + 100
-Temperature('boiling(100)')
->>> t = Temperature('boiling')
->>> t
-Temperature('boiling(100)')
->>> Temperature('boiling') / 2
-Temperature(50)
->>> -1 < Temperature('freezing')
-True
->>> 47 > Temperature('boiling')
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-These values labels have no effect on Integer type operations, any value
-still could be assigned to a type (information on value constraints will
-follow further in this paper).
-</p>
-
-<a name="1.1.4"></a>
-<h4>
-1.1.4 Enumerated type
-</h4>
-
-<p>
-ASN.1 Enumerated type differs from an Integer type in a number of ways.
-Most important is that its instance can only hold a value that belongs
-to a set of values specified on type declaration.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-error-status ::= ENUMERATED {
- no-error(0),
- authentication-error(10),
- authorization-error(20),
- general-failure(51)
-}
-</pre>
-</td></tr></table>
-
-<p>
-When constructing Enumerated type we will use two pyasn1 features: values
-labels (as mentioned above) and value constraint (will be described in
-more details later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval, constraint
->>> class ErrorStatus(univ.Enumerated):
-... namedValues = namedval.NamedValues(
-... ('no-error', 0),
-... ('authentication-error', 10),
-... ('authorization-error', 20),
-... ('general-failure', 51)
-... )
-... subtypeSpec = univ.Enumerated.subtypeSpec + \
-... constraint.SingleValueConstraint(0, 10, 20, 51)
-...
->>> errorStatus = univ.ErrorStatus('no-error')
->>> errorStatus
-ErrorStatus('no-error(0)')
->>> errorStatus == univ.ErrorStatus('general-failure')
-False
->>> univ.ErrorStatus('non-existing-state')
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Particular integer values associated with Enumerated value states
-have no meaning. They should not be used as such or in any kind of
-math operation. Those integer values are only used by codecs to
-transfer state from one entity to another.
-</p>
-
-<a name="1.1.5"></a>
-<h4>
-1.1.5 Real type
-</h4>
-
-<p>
-Values of the Real type are a three-component tuple of mantissa, base and
-exponent. All three are integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-pi ::= REAL { mantissa 314159, base 10, exponent -5 }
-</pre>
-</td></tr></table>
-
-<p>
-Corresponding pyasn1 objects can be initialized with either a three-component
-tuple or a Python float. Infinite values could be expressed in a way,
-compatible with Python float type.
-
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> pi = univ.Real((314159, 10, -5))
->>> pi
-Real((314159, 10,-5))
->>> float(pi)
-3.14159
->>> pi == univ.Real(3.14159)
-True
->>> univ.Real('inf')
-Real('inf')
->>> univ.Real('-inf') == float('-inf')
-True
->>>
-</pre>
-</td></tr></table>
-
-<p>
-If a Real object is initialized from a Python float or yielded by a math
-operation, the base is set to decimal 10 (what affects encoding).
-</p>
-
-<a name="1.1.6"></a>
-<h4>
-1.1.6 Bit string type
-</h4>
-
-<p>
-ASN.1 BIT STRING type holds opaque binary data of an arbitrarily length.
-A BIT STRING value could be initialized by either a binary (base 2) or
-hex (base 16) value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-public-key BIT STRING ::= '1010111011110001010110101101101
- 1011000101010000010110101100010
- 0110101010000111101010111111110'B
-
-signature BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
-</pre>
-</td></tr></table>
-
-<p>
-The pyasn1 BitString objects can initialize from native ASN.1 notation
-(base 2 or base 16 strings) or from a Python tuple of binary components.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> publicKey = univ.BitString(
-... "'1010111011110001010110101101101"
-... "1011000101010000010110101100010"
-... "0110101010000111101010111111110'B"
-)
->>> publicKey
-BitString("'10101110111100010101101011011011011000101010000010110101100010\
-0110101010000111101010111111110'B")
->>> signature = univ.BitString(
-... "'AF01330CD932093392100B39FF00DE0'H"
-... )
->>> signature
-BitString("'101011110000000100110011000011001101100100110010000010010011001\
-1100100100001000000001011001110011111111100000000110111100000'B")
->>> fingerprint = univ.BitString(
-... (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
-... )
->>> fingerprint
-BitString("'101101110101'B")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Another BIT STRING initialization method supported by ASN.1 notation
-is to specify only 1-th bits along with their human-friendly label
-and bit offset relative to the beginning of the bit string. With this
-method, all not explicitly mentioned bits are doomed to be zeros.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-bit-mask BIT STRING ::= {
- read-flag(0),
- write-flag(2),
- run-flag(4)
-}
-</pre>
-</td></tr></table>
-
-<p>
-To express this in pyasn1, we will employ the named values feature (as with
-Enumeration type).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class BitMask(univ.BitString):
-... namedValues = namedval.NamedValues(
-... ('read-flag', 0),
-... ('write-flag', 2),
-... ('run-flag', 4)
-... )
->>> bitMask = BitMask('read-flag,run-flag')
->>> bitMask
-BitMask("'10001'B")
->>> tuple(bitMask)
-(1, 0, 0, 0, 1)
->>> bitMask[4]
-1
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The BitString objects mimic the properties of Python tuple type in part
-of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.7"></a>
-<h4>
-1.1.7 OctetString type
-</h4>
-
-<p>
-The OCTET STRING type is a confusing subject. According to ASN.1
-specification, this type is similar to BIT STRING, the major difference
-is that the former operates in 8-bit chunks of data. What is important
-to note, is that OCTET STRING was NOT designed to handle text strings - the
-standard provides many other types specialized for text content. For that
-reason, ASN.1 forbids to initialize OCTET STRING values with "quoted text
-strings", only binary or hex initializers, similar to BIT STRING ones,
-are allowed.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
-thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
-</pre>
-</td></tr></table>
-
-<p>
-However, ASN.1 users (e.g. protocols designers) seem to ignore the original
-purpose of the OCTET STRING type - they used it for handling all kinds of
-data, including text strings.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, we have taken a liberal approach and allowed both BIT STRING
-style and quoted text initializers for the OctetString objects. To avoid
-possible collisions, quoted text is the default initialization syntax.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> thumbnail = univ.OctetString(
-... binValue='1000010111101110101111000000111011'
-... )
->>> thumbnail
-OctetString(hexValue='85eebcec0')
->>> thumbnail = univ.OctetString(
-... hexValue='FA9823C43E43510DE3422'
-... )
->>> thumbnail
-OctetString(hexValue='fa9823c43e4351de34220')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Most frequent usage of the OctetString class is to instantiate it with
-a text string.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
->>> welcomeMessage
-OctetString(b'Welcome to ASN.1 wilderness!')
->>> print('%s' % welcomeMessage)
-Welcome to ASN.1 wilderness!
->>> welcomeMessage[11:16]
-OctetString(b'ASN.1')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-OctetString objects support the immutable sequence object protocol.
-In other words, they behave like Python 3 bytes (or Python 2 strings).
-</p>
-
-<p>
-When running pyasn1 on Python 3, it's better to use the bytes objects for
-OctetString instantiation, as it's more reliable and efficient.
-</p>
-
-<p>
-Additionally, OctetString's can also be instantiated with a sequence of
-8-bit integers (ASCII codes).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> univ.OctetString((77, 101, 101, 103, 111))
-OctetString(b'Meego')
-</pre>
-</td></tr></table>
-
-<p>
-It is sometimes convenient to express OctetString instances as 8-bit
-characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> octetString = univ.OctetString('ABCDEF')
->>> octetString.asNumbers()
-(65, 66, 67, 68, 69, 70)
->>> octetString.asOctets()
-b'ABCDEF'
-</pre>
-</td></tr></table>
-
-<a name="1.1.8"></a>
-<h4>
-1.1.8 ObjectIdentifier type
-</h4>
-
-<p>
-Values of the OBJECT IDENTIFIER type are sequences of integers that could
-be used to identify virtually anything in the world. Various ASN.1-based
-protocols employ OBJECT IDENTIFIERs for their own identification needs.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-internet-id OBJECT IDENTIFIER ::= {
- iso(1) identified-organization(3) dod(6) internet(1)
-}
-</pre>
-</td></tr></table>
-
-<p>
-One of the natural ways to map OBJECT IDENTIFIER type into a Python
-one is to use Python tuples of integers. So this approach is taken by
-pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
->>> internetId
-ObjectIdentifier('1.3.6.1')
->>> internetId[2]
-6
->>> internetId[1:3]
-ObjectIdentifier('3.6')
-</pre>
-</td></tr></table>
-
-<p>
-A more human-friendly "dotted" notation is also supported.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> univ.ObjectIdentifier('1.3.6.1')
-ObjectIdentifier('1.3.6.1')
-</pre>
-</td></tr></table>
-
-<p>
-Symbolic names of the arcs of object identifier, sometimes present in
-ASN.1 specifications, are not preserved and used in pyasn1 objects.
-</p>
-
-<p>
-The ObjectIdentifier objects mimic the properties of Python tuple type in
-part of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.9"></a>
-<h4>
-1.1.9 Character string types
-</h4>
-
-<p>
-ASN.1 standard introduces a diverse set of text-specific types. All of them
-were designed to handle various types of characters. Some of these types seem
-be obsolete nowdays, as their target technologies are gone. Another issue
-to be aware of is that raw OCTET STRING type is sometimes used in practice
-by ASN.1 users instead of specialized character string types, despite
-explicit prohibition imposed by ASN.1 specification.
-</p>
-
-<p>
-The two types are specific to ASN.1 are NumericString and PrintableString.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message ::= PrintableString {
- "Welcome to ASN.1 text types"
-}
-
-dial-pad-numbers ::= NumericString {
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
-}
-</pre>
-</td></tr></table>
-
-<p>
-Their pyasn1 implementations are:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
-'Welcome to ASN.1 text types'
->>> dialPadNumbers = char.NumericString(
- "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
-)
->>> dialPadNumbers
-NumericString(b'0123456789')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The following types came to ASN.1 from ISO standards on character sets.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.VisibleString("abc")
-VisibleString(b'abc')
->>> char.IA5String('abc')
-IA5String(b'abc')
->>> char.TeletexString('abc')
-TeletexString(b'abc')
->>> char.VideotexString('abc')
-VideotexString(b'abc')
->>> char.GraphicString('abc')
-GraphicString(b'abc')
->>> char.GeneralString('abc')
-GeneralString(b'abc')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The last three types are relatively recent addition to the family of
-character string types: UniversalString, BMPString, UTF8String.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.UniversalString("abc")
-UniversalString(b'abc')
->>> char.BMPString('abc')
-BMPString(b'abc')
->>> char.UTF8String('abc')
-UTF8String(b'abc')
->>> utf8String = char.UTF8String('У попа была собака')
->>> utf8String
-UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0 \
-\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
->>> print(utf8String)
-У попа была собака
->>>
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, all character type objects behave like Python strings. None of
-them is currently constrained in terms of valid alphabet so it's up to
-the data source to keep an eye on data validation for these types.
-</p>
-
-<a name="1.1.10"></a>
-<h4>
-1.1.10 Useful types
-</h4>
-
-<p>
-There are three so-called useful types defined in the standard:
-ObjectDescriptor, GeneralizedTime, UTCTime. They all are subtypes
-of GraphicString or VisibleString types therefore useful types are
-character string types.
-</p>
-
-<p>
-It's advised by the ASN.1 standard to have an instance of ObjectDescriptor
-type holding a human-readable description of corresponding instance of
-OBJECT IDENTIFIER type. There are no formal linkage between these instances
-and provision for ObjectDescriptor uniqueness in the standard.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> descrBER = useful.ObjectDescriptor(
- "Basic encoding of a single ASN.1 type"
-)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-GeneralizedTime and UTCTime types are designed to hold a human-readable
-timestamp in a universal and unambiguous form. The former provides
-more flexibility in notation while the latter is more strict but has
-Y2K issues.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; Mar 8 2010 12:00:00 MSK
-moscow-time GeneralizedTime ::= "20110308120000.0"
-;; Mar 8 2010 12:00:00 UTC
-utc-time GeneralizedTime ::= "201103081200Z"
-;; Mar 8 1999 12:00:00 UTC
-utc-time UTCTime ::= "9803081200Z"
-</pre>
-</td></tr></table>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> moscowTime = useful.GeneralizedTime("20110308120000.0")
->>> utcTime = useful.UTCTime("9803081200Z")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Despite their intended use, these types possess no special, time-related,
-handling in pyasn1. They are just printable strings.
-</p>
-
-<a name="1.2"></a>
-<h4>
-1.2 Tagging
-</h4>
-
-<p>
-In order to continue with the Constructed ASN.1 types, we will first have
-to introduce the concept of tagging (and its pyasn1 implementation), as
-some of the Constructed types rely upon the tagging feature.
-</p>
-
-<p>
-When a value is coming into an ASN.1-based system (received from a network
-or read from some storage), the receiving entity has to determine the
-type of the value to interpret and verify it accordingly.
-</p>
-
-<p>
-Historically, the first data serialization protocol introduced in
-ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
-value is packed into a triplet of (Type, Length, Value) where Type is a
-code that identifies the value (which is called <i>tag</i> in ASN.1),
-length is the number of bytes occupied by the value in its serialized form
-and value is ASN.1 value in a form suitable for serial transmission or storage.
-</p>
-
-<p>
-For that reason almost every ASN.1 type has a tag (which is actually a
-BER type) associated with it by default.
-</p>
-
-<p>
-An ASN.1 tag could be viewed as a tuple of three numbers:
-(Class, Format, Number). While Number identifies a tag, Class component
-is used to create scopes for Numbers. Four scopes are currently defined:
-UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
-is actually a one-bit flag - zero for tags associated with scalar types,
-and one for constructed types (will be discussed later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] INTEGER
-MyOctetString ::= [APPLICATION 0] OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, tags are implemented as immutable, tuple-like objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
->>> myTag
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tuple(myTag)
-(128, 0, 10)
->>> myTag[2]
-10
->>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Default tag, associated with any ASN.1 type, could be extended or replaced
-to make new type distinguishable from its ancestor. The standard provides
-two modes of tag mangling - IMPLICIT and EXPLICIT.
-</p>
-
-<p>
-EXPLICIT mode works by appending new tag to the existing ones thus creating
-an ordered set of tags. This set will be considered as a whole for type
-identification and encoding purposes. Important property of EXPLICIT tagging
-mode is that it preserves base type information in encoding what makes it
-possible to completely recover type information from encoding.
-</p>
-
-<p>
-When tagging in IMPLICIT mode, the outermost existing tag is dropped and
-replaced with a new one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] IMPLICIT INTEGER
-MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-To model both modes of tagging, a specialized container TagSet object (holding
-zero, one or more Tag objects) is used in pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet = tag.TagSet(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10), # base tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10) # effective tag
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10))
->>> tagSet.getBaseTag()
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tagSet = tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20))
->>> tagSet = tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20),
- Tag(tagClass=128, tagFormat=32, tagId=30))
->>> tagSet = tagSet.tagImplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20),
- Tag(tagClass=128, tagFormat=32, tagId=40))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As a side note: the "base tag" concept (accessible through the getBaseTag()
-method) is specific to pyasn1 -- the base tag is used to identify the original
-ASN.1 type of an object in question. Base tag is never occurs in encoding
-and is mostly used internally by pyasn1 for choosing type-specific data
-processing algorithms. The "effective tag" is the one that always appears in
-encoding and is used on tagSets comparation.
-</p>
-
-<p>
-Any two TagSet objects could be compared to see if one is a derivative
-of the other. Figuring this out is also useful in cases when a type-specific
-data processing algorithms are to be chosen.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet1 = tag.TagSet(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10) # base tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10) # effective tag
-... )
->>> tagSet2 = tagSet1.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet1.isSuperTagSetOf(tagSet2)
-True
->>> tagSet2.isSuperTagSetOf(tagSet1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-We will complete this discussion on tagging with a real-world example. The
-following ASN.1 tagged type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] EXPLICIT INTEGER
-</pre>
-</td></tr></table>
-
-<p>
-could be expressed in pyasn1 like this:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> class MyIntegerType(univ.Integer):
-... tagSet = univ.Integer.tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12)
-... )
->>> myInteger = MyIntegerType(12345)
->>> myInteger.getTagSet()
-TagSet(Tag(tagClass=0, tagFormat=0, tagId=2),
- Tag(tagClass=128, tagFormat=32, tagId=12))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Referring to the above code, the tagSet class attribute is a property of any
-pyasn1 type object that assigns default tagSet to a pyasn1 value object. This
-default tagSet specification can be ignored and effectively replaced by some
-other tagSet value passed on object instantiation.
-</p>
-
-<p>
-It's important to understand that the tag set property of pyasn1 type/value
-object can never be modifed in place. In other words, a pyasn1 type/value
-object can never change its tags. The only way is to create a new pyasn1
-type/value object and associate different tag set with it.
-</p>
-
-
-<a name="1.3"></a>
-<h4>
-1.3 Constructed types
-</h4>
-
-<p>
-Besides scalar types, ASN.1 specifies so-called constructed ones - these
-are capable of holding one or more values of other types, both scalar
-and constructed.
-</p>
-
-<p>
-In pyasn1 implementation, constructed ASN.1 types behave like
-Python sequences, and also support additional component addressing methods,
-specific to particular constructed type.
-</p>
-
-<a name="1.3.1"></a>
-<h4>
-1.3.1 Sequence and Set types
-</h4>
-
-<p>
-The Sequence and Set types have many similar properties:
-</p>
-<ul>
-<li>they can hold any number of inner components of different types
-<li>every component has a human-friendly identifier
-<li>any component can have a default value
-<li>some components can be absent.
-</ul>
-
-<p>
-However, Sequence type guarantees the ordering of Sequence value components
-to match their declaration order. By contrast, components of the
-Set type can be ordered to best suite application's needs.
-<p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Record ::= SEQUENCE {
- id INTEGER,
- room [0] INTEGER OPTIONAL,
- house [1] INTEGER DEFAULT 0
-}
-</pre>
-</td></tr></table>
-
-<p>
-Up to this moment, the only method we used for creating new pyasn1 types
-is Python sub-classing. With this method, a new, named Python class is created
-what mimics type derivation in ASN.1 grammar. However, ASN.1 also allows for
-defining anonymous subtypes (room and house components in the example above).
-To support anonymous subtyping in pyasn1, a cloning operation on an existing
-pyasn1 type object can be invoked what creates a new instance of original
-object with possibly modified properties.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Record(univ.Sequence):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('id', univ.Integer()),
-... namedtype.OptionalNamedType(
-... 'room',
-... univ.Integer().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
-... ),
-... namedtype.DefaultedNamedType(
-... 'house',
-... univ.Integer(0).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))
-... )
-... )
->>>
-</pre>
-</td></tr></table>
-
-<p>
-All pyasn1 constructed type classes have a class attribute <b>componentType</b>
-that represent default type specification. Its value is a NamedTypes object.
-</p>
-
-<p>
-The NamedTypes class instance holds a sequence of NameType, OptionalNamedType
-or DefaultedNamedType objects which, in turn, refer to pyasn1 type objects that
-represent inner SEQUENCE components specification.
-</p>
-
-<p>
-Finally, invocation of a subtype() method of pyasn1 type objects in the code
-above returns an implicitly tagged copy of original object.
-</p>
-
-<p>
-Once a SEQUENCE or SET type is decleared with pyasn1, it can be instantiated
-and initialized (continuing the above code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record = Record()
->>> record.setComponentByName('id', 123)
->>> print(record.prettyPrint())
-Record:
- id=123
->>>
->>> record.setComponentByPosition(1, 321)
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
->>>
->>> record.setDefaultComponents()
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
- house=0
-</pre>
-</td></tr></table>
-
-<p>
-Inner components of pyasn1 Sequence/Set objects could be accessed using the
-following methods:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record.getComponentByName('id')
-Integer(123)
->>> record.getComponentByPosition(1)
-Integer(321)
->>> record[2]
-Integer(0)
->>> for idx in range(len(record)):
-... print(record.getNameByPosition(idx), record.getComponentByPosition(idx))
-id 123
-room 321
-house 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The Set type share all the properties of Sequence type, and additionally
-support by-tag component addressing (as all Set components have distinct
-types).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Gamer(univ.Set):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('score', univ.Integer()),
-... namedtype.NamedType('player', univ.OctetString()),
-... namedtype.NamedType('id', univ.ObjectIdentifier())
-... )
->>> gamer = Gamer()
->>> gamer.setComponentByType(univ.Integer().getTagSet(), 121343)
->>> gamer.setComponentByType(univ.OctetString().getTagSet(), 'Pascal')
->>> gamer.setComponentByType(univ.ObjectIdentifier().getTagSet(), (1,3,7,2))
->>> print(gamer.prettyPrint())
-Gamer:
- score=121343
- player=b'Pascal'
- id=1.3.7.2
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.2"></a>
-<h4>
-1.3.2 SequenceOf and SetOf types
-</h4>
-
-<p>
-Both, SequenceOf and SetOf types resemble an unlimited size list of components.
-All the components must be of the same type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Progression ::= SEQUENCE OF INTEGER
-
-arithmeticProgression Progression ::= { 1, 3, 5, 7 }
-</pre>
-</td></tr></table>
-
-<p>
-SequenceOf and SetOf types are expressed by the very similar pyasn1 type
-objects. Their components can only be addressed by position and they
-both have a property of automatic resize.
-</p>
-
-<p>
-To specify inner component type, the <b>componentType</b> class attribute
-should refer to another pyasn1 type object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class Progression(univ.SequenceOf):
-... componentType = univ.Integer()
->>> arithmeticProgression = Progression()
->>> arithmeticProgression.setComponentByPosition(1, 111)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
--empty- 111
->>> arithmeticProgression.setComponentByPosition(0, 100)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
-100 111
->>>
->>> for idx in range(len(arithmeticProgression)):
-... arithmeticProgression.getComponentByPosition(idx)
-Integer(100)
-Integer(111)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Any scalar or constructed pyasn1 type object can serve as an inner component.
-Missing components are prohibited in SequenceOf/SetOf value objects.
-</p>
-
-<a name="1.3.3"></a>
-<h4>
-1.3.3 Choice type
-</h4>
-
-<p>
-Values of ASN.1 CHOICE type can contain only a single value of a type from a
-list of possible alternatives. Alternatives must be ASN.1 types with
-distinct tags for the whole structure to remain unambiguous. Unlike most
-other types, CHOICE is an untagged one, e.g. it has no base tag of its own.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CodeOrMessage ::= CHOICE {
- code INTEGER,
- message OCTET STRING
-}
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 implementation, Choice object behaves like Set but accepts only
-a single inner component at a time. It also offers a few additional methods
-specific to its behaviour.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('code', univ.Integer()),
-... namedtype.NamedType('message', univ.OctetString())
-... )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
->>> codeOrMessage.setComponentByName('code', 123)
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- code=123
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Since there could be only a single inner component value in the pyasn1 Choice
-value object, either of the following methods could be used for fetching it
-(continuing previous code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> codeOrMessage.getName()
-'message'
->>> codeOrMessage.getComponent()
-OctetString(b'my string value')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.4"></a>
-<h4>
-1.3.4 Any type
-</h4>
-
-<p>
-The ASN.1 ANY type is a kind of wildcard or placeholder that matches
-any other type without knowing it in advance. Like CHOICE type, ANY
-has no base tag.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Error ::= SEQUENCE {
- code INTEGER,
- parameter ANY DEFINED BY code
-}
-</pre>
-</td></tr></table>
-
-<p>
-The ANY type is frequently used in specifications, where exact type is not
-yet agreed upon between communicating parties or the number of possible
-alternatives of a type is infinite.
-Sometimes an auxiliary selector is kept around to help parties indicate
-the kind of ANY payload in effect ("code" in the example above).
-</p>
-
-<p>
-Values of the ANY type contain serialized ASN.1 value(s) in form of
-an octet string. Therefore pyasn1 Any value object share the properties of
-pyasn1 OctetString object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> someValue = univ.Any(b'\x02\x01\x01')
->>> someValue
-Any(b'\x02\x01\x01')
->>> str(someValue)
-'\x02\x01\x01'
->>> bytes(someValue)
-b'\x02\x01\x01'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Receiving application is supposed to explicitly deserialize the content of Any
-value object, possibly using auxiliary selector for figuring out its ASN.1
-type to pick appropriate decoder.
-</p>
-
-<p>
-There will be some more talk and code snippets covering Any type in the codecs
-chapters that follow.
-</p>
-
-<a name="1.4"></a>
-<h4>
-1.4 Subtype constraints
-</h4>
-
-<p>
-Most ASN.1 types can correspond to an infinite set of values. To adapt to
-particular application's data model and needs, ASN.1 provides a mechanism
-for limiting the infinite set to values, that make sense in particular case.
-</p>
-
-<p>
-Imposing value constraints on an ASN.1 type can also be seen as creating
-a subtype from its base type.
-</p>
-
-<p>
-In pyasn1, constraints take shape of immutable objects capable
-of evaluating given value against constraint-specific requirements.
-Constraint object is a property of pyasn1 type. Like TagSet property,
-associated with every pyasn1 type, constraints can never be modified
-in place. The only way to modify pyasn1 type constraint is to associate
-new constraint object to a new pyasn1 type object.
-</p>
-
-<p>
-A handful of different flavors of <i>constraints</i> are defined in ASN.1.
-We will discuss them one by one in the following chapters and also explain
-how to combine and apply them to types.
-</p>
-
-<a name="1.4.1"></a>
-<h4>
-1.4.1 Single value constraint
-</h4>
-
-<p>
-This kind of constraint allows for limiting type to a finite, specified set
-of values.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-DialButton ::= OCTET STRING (
- "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-)
-</pre>
-</td></tr></table>
-
-<p>
-Its pyasn1 implementation would look like:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import constraint
->>> c = constraint.SingleValueConstraint(
- '0','1','2','3','4','5','6','7','8','9'
-)
->>> c
-SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
->>> c('0')
->>> c('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the snippet above, if a value violates the constraint, an
-exception will be thrown. A constrainted pyasn1 type object holds a
-reference to a constraint object (or their combination, as will be explained
-later) and calls it for value verification.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class DialButton(univ.OctetString):
-... subtypeSpec = constraint.SingleValueConstraint(
-... '0','1','2','3','4','5','6','7','8','9'
-... )
->>> DialButton('0')
-DialButton(b'0')
->>> DialButton('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Constrained pyasn1 value object can never hold a violating value.
-</p>
-
-<a name="1.4.2"></a>
-<h4>
-1.4.2 Value range constraint
-</h4>
-
-<p>
-A pair of values, compliant to a type to be constrained, denote low and upper
-bounds of allowed range of values of a type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Teenagers ::= INTEGER (13..19)
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1 terms:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class Teenagers(univ.Integer):
-... subtypeSpec = constraint.ValueRangeConstraint(13, 19)
->>> Teenagers(14)
-Teenagers(14)
->>> Teenagers(20)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueRangeConstraint(13, 19) failed at: 20
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Value range constraint usually applies numeric types.
-</p>
-
-<a name="1.4.3"></a>
-<h4>
-1.4.3 Size constraint
-</h4>
-
-<p>
-It is sometimes convenient to set or limit the allowed size of a data item
-to be sent from one application to another to manage bandwidth and memory
-consumption issues. Size constraint specifies the lower and upper bounds
-of the size of a valid value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-TwoBits ::= BIT STRING (SIZE (2))
-</pre>
-</td></tr></table>
-
-<p>
-Express the same grammar in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class TwoBits(univ.BitString):
-... subtypeSpec = constraint.ValueSizeConstraint(2, 2)
->>> TwoBits((1,1))
-TwoBits("'11'B")
->>> TwoBits((1,1,0))
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Size constraint can be applied to potentially massive values - bit or octet
-strings, SEQUENCE OF/SET OF values.
-</p>
-
-<a name="1.4.4"></a>
-<h4>
-1.4.4 Alphabet constraint
-</h4>
-
-<p>
-The permitted alphabet constraint is similar to Single value constraint
-but constraint applies to individual characters of a value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MorseCode ::= PrintableString (FROM ("."|"-"|" "))
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class MorseCode(char.PrintableString):
-... subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
->>> MorseCode("...---...")
-MorseCode('...---...')
->>> MorseCode("?")
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Current implementation does not handle ranges of characters in constraint
-(FROM "A".."Z" syntax), one has to list the whole set in a range.
-</p>
-
-<a name="1.4.5"></a>
-<h4>
-1.4.5 Constraint combinations
-</h4>
-
-<p>
-Up to this moment, we used a single constraint per ASN.1 type. The standard,
-however, allows for combining multiple individual constraints into
-intersections, unions and exclusions.
-</p>
-
-<p>
-In pyasn1 data model, all of these methods of constraint combinations are
-implemented as constraint-like objects holding individual constraint (or
-combination) objects. Like terminal constraint objects, combination objects
-are capable to perform value verification at its set of enclosed constraints
-according to the logic of particular combination.
-</p>
-
-<p>
-Constraints intersection verification succeeds only if a value is
-compliant to each constraint in a set. To begin with, the following
-specification will constitute a valid telephone number:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
-</pre>
-</td></tr></table>
-
-<p>
-Constraint intersection object serves the logic above:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class PhoneNumber(char.NumericString):
-... subtypeSpec = constraint.ConstraintsIntersection(
-... constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-... constraint.ValueSizeConstraint(11, 11)
-... )
->>> PhoneNumber('79039343212')
-PhoneNumber('79039343212')
->>> PhoneNumber('?9039343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsIntersection(
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
- ValueSizeConstraint(11, 11)) failed at:
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
->>> PhoneNumber('9343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsIntersection(
- PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
- ValueSizeConstraint(11, 11)) failed at:
- ValueSizeConstraint(10, 10) failed at: "9343212"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Union of constraints works by making sure that a value is compliant
-to any of the constraint in a set. For instance:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
-</pre>
-</td></tr></table>
-
-<p>
-It's important to note, that a value must fully comply to any single
-constraint in a set. In the specification above, a value of all small or
-all capital letters is compliant, but a mix of small&capitals is not.
-Here's its pyasn1 analogue:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class CapitalOrSmall(char.IA5String):
-... subtypeSpec = constraint.ConstraintsUnion(
-... constraint.PermittedAlphabetConstraint('A','B','C'),
-... constraint.PermittedAlphabetConstraint('a','b','c')
-... )
->>> CapitalOrSmall('ABBA')
-CapitalOrSmall('ABBA')
->>> CapitalOrSmall('abba')
-CapitalOrSmall('abba')
->>> CapitalOrSmall('Abba')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'),
- PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Finally, the exclusion constraint simply negates the logic of value
-verification at a constraint. In the following example, any integer value
-is allowed in a type but not zero.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-NoZero ::= INTEGER (ALL EXCEPT 0)
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 the above definition would read:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class NoZero(univ.Integer):
-... subtypeSpec = constraint.ConstraintsExclusion(
-... constraint.SingleValueConstraint(0)
-... )
->>> NoZero(1)
-NoZero(1)
->>> NoZero(0)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The depth of such a constraints tree, built with constraint combination objects
-at its nodes, has not explicit limit. Value verification is performed in a
-recursive manner till a definite solution is found.
-</p>
-
-<a name="1.5"></a>
-<h4>
-1.5 Types relationships
-</h4>
-
-<p>
-In the course of data processing in an application, it is sometimes
-convenient to figure out the type relationships between pyasn1 type or
-value objects. Formally, two things influence pyasn1 types relationship:
-<i>tag set</i> and <i>subtype constraints</i>. One pyasn1 type is considered
-to be a derivative of another if their TagSet and Constraint objects are
-a derivation of one another.
-</p>
-
-<p>
-The following example illustrates the concept (we use the same tagset but
-different constraints for simplicity):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
->>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
-... constraint.ValueRangeConstraint(3,8),
-... constraint.ValueRangeConstraint(4,7)
-... ) )
->>> i1.isSameTypeWith(i2)
-False
->>> i1.isSuperTypeOf(i2)
-True
->>> i1.isSuperTypeOf(i1)
-True
->>> i2.isSuperTypeOf(i1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the above code snippet, there are two methods of any pyasn1
-type/value object that test types for their relationship:
-<b>isSameTypeWith</b>() and <b>isSuperTypeOf</b>(). The former is
-self-descriptive while the latter yields true if the argument appears
-to be a pyasn1 object which has tagset and constraints derived from those
-of the object being called.
-</p>
-
-<a name="2"></a>
-<h3>
-2. Codecs
-</h3>
-
-<p>
-In ASN.1 context,
-<a href=http://en.wikipedia.org/wiki/Codec>codec</a>
-is a program that transforms between concrete data structures and a stream
-of octets, suitable for transmission over the wire. This serialized form of
-data is sometimes called <i>substrate</i> or <i>essence</i>.
-</p>
-
-<p>
-In pyasn1 implementation, substrate takes shape of Python 3 bytes or
-Python 2 string objects.
-</p>
-
-<p>
-One of the properties of a codec is its ability to cope with incomplete
-data and/or substrate what implies codec to be stateful. In other words,
-when decoder runs out of substrate and data item being recovered is still
-incomplete, stateful codec would suspend and complete data item recovery
-whenever the rest of substrate becomes available. Similarly, stateful encoder
-would encode data items in multiple steps waiting for source data to
-arrive. Codec restartability is especially important when application deals
-with large volumes of data and/or runs on low RAM. For an interesting
-discussion on codecs options and design choices, refer to
-<a href=http://directory.apache.org/subprojects/asn1/>Apache ASN.1 project</a>
-.
-</p>
-
-<p>
-As of this writing, codecs implemented in pyasn1 are all stateless, mostly
-to keep the code simple.
-</p>
-
-<p>
-The pyasn1 package currently supports
-<a href=http://en.wikipedia.org/wiki/Basic_encoding_rules>BER</a> codec and
-its variations --
-<a href=http://en.wikipedia.org/wiki/Canonical_encoding_rules>CER</a> and
-<a href=http://en.wikipedia.org/wiki/Distinguished_encoding_rules>DER</a>.
-More ASN.1 codecs are planned for implementation in the future.
-</p>
-
-<a name="2.1"></a>
-<h4>
-2.1 Encoders
-</h4>
-
-<p>
-Encoder is used for transforming pyasn1 value objects into substrate. Only
-pyasn1 value objects could be serialized, attempts to process pyasn1 type
-objects will cause encoder failure.
-</p>
-
-<p>
-The following code will create a pyasn1 Integer object and serialize it with
-BER encoder:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(univ.Integer(123456))
-b'\x02\x03\x01\xe2@'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-BER standard also defines a so-called <i>indefinite length</i> encoding form
-which makes large data items processing more memory efficient. It is mostly
-useful when encoder does not have the whole value all at once and the
-length of the value can not be determined at the beginning of encoding.
-</p>
-
-<p>
-<i>Constructed encoding</i> is another feature of BER closely related to the
-indefinite length form. In essence, a large scalar value (such as ASN.1
-character BitString type) could be chopped into smaller chunks by encoder
-and transmitted incrementally to limit memory consumption. Unlike indefinite
-length case, the length of the whole value must be known in advance when
-using constructed, definite length encoding form.
-</p>
-
-<p>
-Since pyasn1 codecs are not restartable, pyasn1 encoder may only encode data
-item all at once. However, even in this case, generating indefinite length
-encoding may help a low-memory receiver, running a restartable decoder,
-to process a large data item.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... defMode=False,
-... maxChunkSize=8
-... )
-b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog\x00\x00'
->>>
->>> encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... maxChunkSize=8
-... )
-b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog'
-</pre>
-</td></tr></table>
-
-<p>
-The <b>defMode</b> encoder parameter disables definite length encoding mode,
-while the optional <b>maxChunkSize</b> parameter specifies desired
-substrate chunk size that influences memory requirements at the decoder's end.
-</p>
-
-<p>
-To use CER or DER encoders one needs to explicitly import and call them - the
-APIs are all compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> from pyasn1.codec.cer import encoder as cer_encoder
->>> from pyasn1.codec.der import encoder as der_encoder
->>> ber_encoder.encode(univ.Boolean(True))
-b'\x01\x01\x01'
->>> cer_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>> der_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2"></a>
-<h4>
-2.2 Decoders
-</h4>
-
-<p>
-In the process of decoding, pyasn1 value objects are created and linked to
-each other, based on the information containted in the substrate. Thus,
-the original pyasn1 value object(s) are recovered.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(univ.Boolean(True))
->>> decoder.decode(substrate)
-(Boolean('True(1)'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Commenting on the code snippet above, pyasn1 decoder accepts substrate
-as an argument and returns a tuple of pyasn1 value object (possibly
-a top-level one in case of constructed object) and unprocessed part
-of input substrate.
-</p>
-
-<p>
-All pyasn1 decoders can handle both definite and indefinite length
-encoding modes automatically, explicit switching into one mode
-to another is not required.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(
-... univ.OctetString('The quick brown fox jumps over the lazy dog'),
-... defMode=False,
-... maxChunkSize=8
-... )
->>> decoder.decode(substrate)
-(OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Speaking of BER/CER/DER encoding, in many situations substrate may not contain
-all necessary information needed for complete and accurate ASN.1 values
-recovery. The most obvious cases include implicitly tagged ASN.1 types
-and constrained types.
-</p>
-
-<p>
-As discussed earlier in this handbook, when an ASN.1 type is implicitly
-tagged, previous outermost tag is lost and never appears in substrate.
-If it is the base tag that gets lost, decoder is unable to pick type-specific
-value decoder at its table of built-in types, and therefore recover
-the value part, based only on the information contained in substrate. The
-approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
-a set of them) to <i>guide</i> the decoding process by matching [possibly
-incomplete] tags recovered from substrate with those found in prototype pyasn1
-type objects (also called pyasn1 specification object further in this paper).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import decoder
->>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
-Integer(12), b''
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Decoder would neither modify pyasn1 specification object nor use
-its current values (if it's a pyasn1 value object), but rather use it as
-a hint for choosing proper decoder and as a pattern for creating new objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> i = univ.Integer(12345).subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(i)
->>> substrate
-b'\x9f(\x0209'
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error:
- TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>> decoder.decode(substrate, asn1Spec=i)
-(Integer(12345), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Notice in the example above, that an attempt to run decoder without passing
-pyasn1 specification object fails because recovered tag does not belong
-to any of the built-in types.
-</p>
-
-<p>
-Another important feature of guided decoder operation is the use of
-values constraints possibly present in pyasn1 specification object.
-To explain this, we will decode a random integer object into generic Integer
-and the constrained one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> from pyasn1.codec.ber import encoder, decoder
->>> class DialDigit(univ.Integer):
-... subtypeSpec = constraint.ValueRangeConstraint(0,9)
->>> substrate = encoder.encode(univ.Integer(13))
->>> decoder.decode(substrate)
-(Integer(13), b'')
->>> decoder.decode(substrate, asn1Spec=DialDigit())
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
- ValueRangeConstraint(0, 9) failed at: 13
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Similarily to encoders, to use CER or DER decoders application has to
-explicitly import and call them - all APIs are compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
->>>
->>> from pyasn1.codec.ber import decoder as ber_decoder
->>> from pyasn1.codec.cer import decoder as cer_decoder
->>> from pyasn1.codec.der import decoder as der_decoder
->>>
->>> ber_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> cer_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> der_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2.1"></a>
-<h4>
-2.2.1 Decoding untagged types
-</h4>
-
-<p>
-It has already been mentioned, that ASN.1 has two "special case" types:
-CHOICE and ANY. They are different from other types in part of
-tagging - unless these two are additionally tagged, neither of them will
-have their own tag. Therefore these types become invisible in substrate
-and can not be recovered without passing pyasn1 specification object to
-decoder.
-</p>
-
-<p>
-To explain the issue, we will first prepare a Choice object to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-... componentType = namedtype.NamedTypes(
-... namedtype.NamedType('code', univ.Integer()),
-... namedtype.NamedType('message', univ.OctetString())
-... )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Let's now encode this Choice object and then decode its substrate
-with and without pyasn1 specification object:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(codeOrMessage)
->>> substrate
-b'\x04\x0fmy string value'
->>> encoder.encode(univ.OctetString('my string value'))
-b'\x04\x0fmy string value'
->>>
->>> decoder.decode(substrate)
-(OctetString(b'my string value'), b'')
->>> codeOrMessage, substrate = decoder.decode(substrate, asn1Spec=CodeOrMessage())
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-First thing to notice in the listing above is that the substrate produced
-for our Choice value object is equivalent to the substrate for an OctetString
-object initialized to the same value. In other words, any information about
-the Choice component is absent in encoding.
-</p>
-
-<p>
-Sure enough, that kind of substrate will decode into an OctetString object,
-unless original Choice type object is passed to decoder to guide the decoding
-process.
-</p>
-
-<p>
-Similarily untagged ANY type behaves differently on decoding phase - when
-decoder bumps into an Any object in pyasn1 specification, it stops decoding
-and puts all the substrate into a new Any value object in form of an octet
-string. Concerned application could then re-run decoder with an additional,
-more exact pyasn1 specification object to recover the contents of Any
-object.
-</p>
-
-<p>
-As it was mentioned elsewhere in this paper, Any type allows for incomplete
-or changing ASN.1 specification to be handled gracefully by decoder and
-applications.
-</p>
-
-<p>
-To illustrate the working of Any type, we'll have to make the stage
-by encoding a pyasn1 object and then putting its substrate into an any
-object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> innerSubstrate = encoder.encode(univ.Integer(1234))
->>> innerSubstrate
-b'\x02\x02\x04\xd2'
->>> any = univ.Any(innerSubstrate)
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> substrate = encoder.encode(any)
->>> substrate
-b'\x02\x02\x04\xd2'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As with Choice type encoding, there is no traces of Any type in substrate.
-Obviously, the substrate we are dealing with, will decode into the inner
-[Integer] component, unless pyasn1 specification is given to guide the
-decoder. Continuing previous code:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
-
->>> decoder.decode(substrate)
-(Integer(1234), b'')
->>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> decoder.decode(str(any))
-(Integer(1234), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Both CHOICE and ANY types are widely used in practice. Reader is welcome to
-take a look at
-<a href=http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>
-ASN.1 specifications of X.509 applications</a> for more information.
-</p>
-
-<a name="2.2.2"></a>
-<h4>
-2.2.2 Ignoring unknown types
-</h4>
-
-<p>
-When dealing with a loosely specified ASN.1 structure, the receiving
-end may not be aware of some types present in the substrate. It may be
-convenient then to turn decoder into a recovery mode. Whilst there, decoder
-will not bail out when hit an unknown tag but rather treat it as an Any
-type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> taggedInt = univ.Integer(12345).subtype(
-... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(taggedInt)
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>>
->>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
->>> decoder.decode(substrate)
-(Any(b'\x9f(\x0209'), '')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-It's also possible to configure a custom decoder, to handle unknown tags
-found in substrate. This can be done by means of <b>defaultRawDecoder</b>
-attribute holding a reference to type decoder object. Refer to the source
-for API details.
-</p>
-
-<a name="3"></a>
-<h3>
-3. Feedback and getting help
-</h3>
-
-<p>
-Although pyasn1 software is almost a decade old and used in many production
-environments, it still may have bugs and non-implemented pieces. Anyone
-who happens to run into such defect is welcome to complain to
-<a href=mailto:pyasn1-users@lists.sourceforge.net>pyasn1 mailing list</a>
-or better yet fix the issue and send
-<a href=mailto:ilya@glas.net>me</a> the patch.
-</p>
-
-<p>
-Typically, pyasn1 is used for building arbitrary protocol support into
-various applications. This involves manual translation of ASN.1 data
-structures into their pyasn1 implementations. To save time and effort,
-data structures for some of the popular protocols are pre-programmed
-and kept for further re-use in form of the
-<a href=http://sourceforge.net/projects/pyasn1/files/pyasn1-modules/>
-pyasn1-modules package</a>. For instance, many structures for PKI (X.509,
-PKCS#*, CRMF, OCSP), LDAP and SNMP are present.
-Applications authors are advised to import and use relevant modules
-from that package whenever needed protocol structures are already
-there. New protocol modules contributions are welcome.
-</p>
-
-<p>
-And finally, the latest pyasn1 package revision is available for free
-download from
-<a href=http://sourceforge.net/projects/pyasn1/>project home</a> and
-also from the
-<a href=http://pypi.python.org/pypi>Python package repository</a>.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/scalar.html
+++ /dev/null
@@ -1,794 +0,0 @@
-<html>
-<title>
-PyASN1 data model and scalar types
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-1. Data model for ASN.1 types
-</h3>
-
-<p>
-All ASN.1 types could be categorized into two groups: scalar (also called
-simple or primitive) and constructed. The first group is populated by
-well-known types like Integer or String. Members of constructed group
-hold other types (simple or constructed) as their inner components, thus
-they are semantically close to a programming language records or lists.
-</p>
-
-<p>
-In pyasn1, all ASN.1 types and values are implemented as Python objects.
-The same pyasn1 object can represent either ASN.1 type and/or value
-depending of the presense of value initializer on object instantiation.
-We will further refer to these as <i>pyasn1 type object</i> versus <i>pyasn1
-value object</i>.
-</p>
-
-<p>
-Primitive ASN.1 types are implemented as immutable scalar objects. There values
-could be used just like corresponding native Python values (integers,
-strings/bytes etc) and freely mixed with them in expressions.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerValue = univ.Integer(12)
->>> asn1IntegerValue - 2
-10
->>> univ.OctetString('abc') == 'abc'
-True # Python 2
->>> univ.OctetString(b'abc') == b'abc'
-True # Python 3
-</pre>
-</td></tr></table>
-
-<p>
-It would be an error to perform an operation on a pyasn1 type object
-as it holds no value to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerType = univ.Integer()
->>> asn1IntegerType - 2
-...
-pyasn1.error.PyAsn1Error: No value for __coerce__()
-</pre>
-</td></tr></table>
-
-<a name="1.1"></a>
-<h4>
-1.1 Scalar types
-</h4>
-
-<p>
-In the sub-sections that follow we will explain pyasn1 mapping to those
-primitive ASN.1 types. Both, ASN.1 notation and corresponding pyasn1
-syntax will be given in each case.
-</p>
-
-<a name="1.1.1"></a>
-<h4>
-1.1.1 Boolean type
-</h4>
-
-<p>
-This is the simplest type those values could be either True or False.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-FunFactorPresent ::= BOOLEAN
-
-;; values declaration and assignment
-pythonFunFactor FunFactorPresent ::= TRUE
-cobolFunFactor FunFactorPresent :: FALSE
-</pre>
-</td></tr></table>
-
-<p>
-And here's pyasn1 version of it:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class FunFactorPresent(univ.Boolean): pass
-...
->>> pythonFunFactor = FunFactorPresent(True)
->>> cobolFunFactor = FunFactorPresent(False)
->>> pythonFunFactor
-FunFactorPresent('True(1)')
->>> cobolFunFactor
-FunFactorPresent('False(0)')
->>> pythonFunFactor == cobolFunFactor
-False
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.2"></a>
-<h4>
-1.1.2 Null type
-</h4>
-
-<p>
-The NULL type is sometimes used to express the absense of any information.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-Vote ::= CHOICE {
- agreed BOOLEAN,
- skip NULL
-}
-</td></tr></table>
-
-;; value declaration and assignment
-myVote Vote ::= skip:NULL
-</pre>
-
-<p>
-We will explain the CHOICE type later in this paper, meanwhile the NULL
-type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> skip = univ.Null()
->>> skip
-Null('')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.3"></a>
-<h4>
-1.1.3 Integer type
-</h4>
-
-<p>
-ASN.1 defines the values of Integer type as negative or positive of whatever
-length. This definition plays nicely with Python as the latter places no
-limit on Integers. However, some ASN.1 implementations may impose certain
-limits of integer value ranges. Keep that in mind when designing new
-data structures.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; values specification
-age-of-universe INTEGER ::= 13750000000
-mean-martian-surface-temperature INTEGER ::= -63
-</pre>
-</td></tr></table>
-
-<p>
-A rather strigntforward mapping into pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> ageOfUniverse = univ.Integer(13750000000)
->>> ageOfUniverse
-Integer(13750000000)
->>>
->>> meanMartianSurfaceTemperature = univ.Integer(-63)
->>> meanMartianSurfaceTemperature
-Integer(-63)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-ASN.1 allows to assign human-friendly names to particular values of
-an INTEGER type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Temperature ::= INTEGER {
- freezing(0),
- boiling(100)
-}
-</pre>
-</td></tr></table>
-
-<p>
-The Temperature type expressed in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class Temperature(univ.Integer):
-... namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
-...
->>> t = Temperature(0)
->>> t
-Temperature('freezing(0)')
->>> t + 1
-Temperature(1)
->>> t + 100
-Temperature('boiling(100)')
->>> t = Temperature('boiling')
->>> t
-Temperature('boiling(100)')
->>> Temperature('boiling') / 2
-Temperature(50)
->>> -1 < Temperature('freezing')
-True
->>> 47 > Temperature('boiling')
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-These values labels have no effect on Integer type operations, any value
-still could be assigned to a type (information on value constraints will
-follow further in this paper).
-</p>
-
-<a name="1.1.4"></a>
-<h4>
-1.1.4 Enumerated type
-</h4>
-
-<p>
-ASN.1 Enumerated type differs from an Integer type in a number of ways.
-Most important is that its instance can only hold a value that belongs
-to a set of values specified on type declaration.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-error-status ::= ENUMERATED {
- no-error(0),
- authentication-error(10),
- authorization-error(20),
- general-failure(51)
-}
-</pre>
-</td></tr></table>
-
-<p>
-When constructing Enumerated type we will use two pyasn1 features: values
-labels (as mentioned above) and value constraint (will be described in
-more details later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval, constraint
->>> class ErrorStatus(univ.Enumerated):
-... namedValues = namedval.NamedValues(
-... ('no-error', 0),
-... ('authentication-error', 10),
-... ('authorization-error', 20),
-... ('general-failure', 51)
-... )
-... subtypeSpec = univ.Enumerated.subtypeSpec + \
-... constraint.SingleValueConstraint(0, 10, 20, 51)
-...
->>> errorStatus = univ.ErrorStatus('no-error')
->>> errorStatus
-ErrorStatus('no-error(0)')
->>> errorStatus == univ.ErrorStatus('general-failure')
-False
->>> univ.ErrorStatus('non-existing-state')
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Particular integer values associated with Enumerated value states
-have no meaning. They should not be used as such or in any kind of
-math operation. Those integer values are only used by codecs to
-transfer state from one entity to another.
-</p>
-
-<a name="1.1.5"></a>
-<h4>
-1.1.5 Real type
-</h4>
-
-<p>
-Values of the Real type are a three-component tuple of mantissa, base and
-exponent. All three are integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-pi ::= REAL { mantissa 314159, base 10, exponent -5 }
-</pre>
-</td></tr></table>
-
-<p>
-Corresponding pyasn1 objects can be initialized with either a three-component
-tuple or a Python float. Infinite values could be expressed in a way,
-compatible with Python float type.
-
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> pi = univ.Real((314159, 10, -5))
->>> pi
-Real((314159, 10,-5))
->>> float(pi)
-3.14159
->>> pi == univ.Real(3.14159)
-True
->>> univ.Real('inf')
-Real('inf')
->>> univ.Real('-inf') == float('-inf')
-True
->>>
-</pre>
-</td></tr></table>
-
-<p>
-If a Real object is initialized from a Python float or yielded by a math
-operation, the base is set to decimal 10 (what affects encoding).
-</p>
-
-<a name="1.1.6"></a>
-<h4>
-1.1.6 Bit string type
-</h4>
-
-<p>
-ASN.1 BIT STRING type holds opaque binary data of an arbitrarily length.
-A BIT STRING value could be initialized by either a binary (base 2) or
-hex (base 16) value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-public-key BIT STRING ::= '1010111011110001010110101101101
- 1011000101010000010110101100010
- 0110101010000111101010111111110'B
-
-signature BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
-</pre>
-</td></tr></table>
-
-<p>
-The pyasn1 BitString objects can initialize from native ASN.1 notation
-(base 2 or base 16 strings) or from a Python tuple of binary components.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> publicKey = univ.BitString(
-... "'1010111011110001010110101101101"
-... "1011000101010000010110101100010"
-... "0110101010000111101010111111110'B"
-)
->>> publicKey
-BitString("'10101110111100010101101011011011011000101010000010110101100010\
-0110101010000111101010111111110'B")
->>> signature = univ.BitString(
-... "'AF01330CD932093392100B39FF00DE0'H"
-... )
->>> signature
-BitString("'101011110000000100110011000011001101100100110010000010010011001\
-1100100100001000000001011001110011111111100000000110111100000'B")
->>> fingerprint = univ.BitString(
-... (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
-... )
->>> fingerprint
-BitString("'101101110101'B")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Another BIT STRING initialization method supported by ASN.1 notation
-is to specify only 1-th bits along with their human-friendly label
-and bit offset relative to the beginning of the bit string. With this
-method, all not explicitly mentioned bits are doomed to be zeros.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-bit-mask BIT STRING ::= {
- read-flag(0),
- write-flag(2),
- run-flag(4)
-}
-</pre>
-</td></tr></table>
-
-<p>
-To express this in pyasn1, we will employ the named values feature (as with
-Enumeration type).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class BitMask(univ.BitString):
-... namedValues = namedval.NamedValues(
-... ('read-flag', 0),
-... ('write-flag', 2),
-... ('run-flag', 4)
-... )
->>> bitMask = BitMask('read-flag,run-flag')
->>> bitMask
-BitMask("'10001'B")
->>> tuple(bitMask)
-(1, 0, 0, 0, 1)
->>> bitMask[4]
-1
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The BitString objects mimic the properties of Python tuple type in part
-of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.7"></a>
-<h4>
-1.1.7 OctetString type
-</h4>
-
-<p>
-The OCTET STRING type is a confusing subject. According to ASN.1
-specification, this type is similar to BIT STRING, the major difference
-is that the former operates in 8-bit chunks of data. What is important
-to note, is that OCTET STRING was NOT designed to handle text strings - the
-standard provides many other types specialized for text content. For that
-reason, ASN.1 forbids to initialize OCTET STRING values with "quoted text
-strings", only binary or hex initializers, similar to BIT STRING ones,
-are allowed.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
-thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
-</pre>
-</td></tr></table>
-
-<p>
-However, ASN.1 users (e.g. protocols designers) seem to ignore the original
-purpose of the OCTET STRING type - they used it for handling all kinds of
-data, including text strings.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, we have taken a liberal approach and allowed both BIT STRING
-style and quoted text initializers for the OctetString objects. To avoid
-possible collisions, quoted text is the default initialization syntax.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> thumbnail = univ.OctetString(
-... binValue='1000010111101110101111000000111011'
-... )
->>> thumbnail
-OctetString(hexValue='85eebcec0')
->>> thumbnail = univ.OctetString(
-... hexValue='FA9823C43E43510DE3422'
-... )
->>> thumbnail
-OctetString(hexValue='fa9823c43e4351de34220')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Most frequent usage of the OctetString class is to instantiate it with
-a text string.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
->>> welcomeMessage
-OctetString(b'Welcome to ASN.1 wilderness!')
->>> print('%s' % welcomeMessage)
-Welcome to ASN.1 wilderness!
->>> welcomeMessage[11:16]
-OctetString(b'ASN.1')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-OctetString objects support the immutable sequence object protocol.
-In other words, they behave like Python 3 bytes (or Python 2 strings).
-</p>
-
-<p>
-When running pyasn1 on Python 3, it's better to use the bytes objects for
-OctetString instantiation, as it's more reliable and efficient.
-</p>
-
-<p>
-Additionally, OctetString's can also be instantiated with a sequence of
-8-bit integers (ASCII codes).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> univ.OctetString((77, 101, 101, 103, 111))
-OctetString(b'Meego')
-</pre>
-</td></tr></table>
-
-<p>
-It is sometimes convenient to express OctetString instances as 8-bit
-characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> octetString = univ.OctetString('ABCDEF')
->>> octetString.asNumbers()
-(65, 66, 67, 68, 69, 70)
->>> octetString.asOctets()
-b'ABCDEF'
-</pre>
-</td></tr></table>
-
-<a name="1.1.8"></a>
-<h4>
-1.1.8 ObjectIdentifier type
-</h4>
-
-<p>
-Values of the OBJECT IDENTIFIER type are sequences of integers that could
-be used to identify virtually anything in the world. Various ASN.1-based
-protocols employ OBJECT IDENTIFIERs for their own identification needs.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-internet-id OBJECT IDENTIFIER ::= {
- iso(1) identified-organization(3) dod(6) internet(1)
-}
-</pre>
-</td></tr></table>
-
-<p>
-One of the natural ways to map OBJECT IDENTIFIER type into a Python
-one is to use Python tuples of integers. So this approach is taken by
-pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
->>> internetId
-ObjectIdentifier('1.3.6.1')
->>> internetId[2]
-6
->>> internetId[1:3]
-ObjectIdentifier('3.6')
-</pre>
-</td></tr></table>
-
-<p>
-A more human-friendly "dotted" notation is also supported.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> univ.ObjectIdentifier('1.3.6.1')
-ObjectIdentifier('1.3.6.1')
-</pre>
-</td></tr></table>
-
-<p>
-Symbolic names of the arcs of object identifier, sometimes present in
-ASN.1 specifications, are not preserved and used in pyasn1 objects.
-</p>
-
-<p>
-The ObjectIdentifier objects mimic the properties of Python tuple type in
-part of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.9"></a>
-<h4>
-1.1.9 Character string types
-</h4>
-
-<p>
-ASN.1 standard introduces a diverse set of text-specific types. All of them
-were designed to handle various types of characters. Some of these types seem
-be obsolete nowdays, as their target technologies are gone. Another issue
-to be aware of is that raw OCTET STRING type is sometimes used in practice
-by ASN.1 users instead of specialized character string types, despite
-explicit prohibition imposed by ASN.1 specification.
-</p>
-
-<p>
-The two types are specific to ASN.1 are NumericString and PrintableString.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message ::= PrintableString {
- "Welcome to ASN.1 text types"
-}
-
-dial-pad-numbers ::= NumericString {
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
-}
-</pre>
-</td></tr></table>
-
-<p>
-Their pyasn1 implementations are:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
-'Welcome to ASN.1 text types'
->>> dialPadNumbers = char.NumericString(
- "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
-)
->>> dialPadNumbers
-NumericString(b'0123456789')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The following types came to ASN.1 from ISO standards on character sets.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.VisibleString("abc")
-VisibleString(b'abc')
->>> char.IA5String('abc')
-IA5String(b'abc')
->>> char.TeletexString('abc')
-TeletexString(b'abc')
->>> char.VideotexString('abc')
-VideotexString(b'abc')
->>> char.GraphicString('abc')
-GraphicString(b'abc')
->>> char.GeneralString('abc')
-GeneralString(b'abc')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The last three types are relatively recent addition to the family of
-character string types: UniversalString, BMPString, UTF8String.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.UniversalString("abc")
-UniversalString(b'abc')
->>> char.BMPString('abc')
-BMPString(b'abc')
->>> char.UTF8String('abc')
-UTF8String(b'abc')
->>> utf8String = char.UTF8String('У попа была собака')
->>> utf8String
-UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0 \
-\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
->>> print(utf8String)
-У попа была собака
->>>
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, all character type objects behave like Python strings. None of
-them is currently constrained in terms of valid alphabet so it's up to
-the data source to keep an eye on data validation for these types.
-</p>
-
-<a name="1.1.10"></a>
-<h4>
-1.1.10 Useful types
-</h4>
-
-<p>
-There are three so-called useful types defined in the standard:
-ObjectDescriptor, GeneralizedTime, UTCTime. They all are subtypes
-of GraphicString or VisibleString types therefore useful types are
-character string types.
-</p>
-
-<p>
-It's advised by the ASN.1 standard to have an instance of ObjectDescriptor
-type holding a human-readable description of corresponding instance of
-OBJECT IDENTIFIER type. There are no formal linkage between these instances
-and provision for ObjectDescriptor uniqueness in the standard.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> descrBER = useful.ObjectDescriptor(
- "Basic encoding of a single ASN.1 type"
-)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-GeneralizedTime and UTCTime types are designed to hold a human-readable
-timestamp in a universal and unambiguous form. The former provides
-more flexibility in notation while the latter is more strict but has
-Y2K issues.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; Mar 8 2010 12:00:00 MSK
-moscow-time GeneralizedTime ::= "20110308120000.0"
-;; Mar 8 2010 12:00:00 UTC
-utc-time GeneralizedTime ::= "201103081200Z"
-;; Mar 8 1999 12:00:00 UTC
-utc-time UTCTime ::= "9803081200Z"
-</pre>
-</td></tr></table>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> moscowTime = useful.GeneralizedTime("20110308120000.0")
->>> utcTime = useful.UTCTime("9803081200Z")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Despite their intended use, these types possess no special, time-related,
-handling in pyasn1. They are just printable strings.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/changelog.rst
@@ -0,0 +1,6 @@
+
+Changelog
+=========
+
+.. include:: ../../CHANGES.rst
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/conf.py
@@ -0,0 +1,323 @@
+# -*- coding: utf-8 -*-
+#
+# PyASN1 documentation build configuration file, created by
+# sphinx-quickstart on Sat Jun 27 23:15:54 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+import shlex
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.napoleon',
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.todo'
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The encoding of source files.
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'contents'
+
+# General information about the project.
+project = u'PyASN1'
+# noinspection PyShadowingBuiltins
+copyright = u'2005-2017, Ilya Etingof <etingof@gmail.com>'
+author = u'Ilya Etingof <etingof@gmail.com>'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.3'
+# The full version, including alpha/beta/rc tags.
+release = '0.3.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+# html_theme = 'alabaster'
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+html_title = "PyASN1"
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = ""
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+if 'PYASN1DEV' in os.environ:
+ html_static_path = ['.static']
+
+# Custom CSS theme
+if 'PYASN1DEV' in os.environ:
+ html_style = 'css/rtdimproved.css'
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+# html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_domain_indices = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
+# html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+# html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+# html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'pyasn1doc'
+
+html_context = {
+ 'include_analytics': 'PYASN1DEV' in os.environ
+}
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'PyASN1.tex', u'PyASN1 Documentation',
+ u'Ilya Etingof \\textless{}etingof@gmail.com\\textgreater{}', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'pyasn1', u'PyASN1 Documentation',
+ [author], 1)
+]
+
+# If true, show URL addresses after external links.
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'PyASN1', u'PyASN1 Documentation',
+ author, 'PyASN1', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+# texinfo_no_detailmenu = False
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'python': ('https://docs.python.org/3.4/', None)}
+
+# this merges constructor docstring with class docstring
+autoclass_content = 'both'
+# Sort members by type
+autodoc_member_order = 'bysource'
+# autodoc_member_order = 'groupwise'
+
+# Napoleon settings
+napoleon_google_docstring = False
+napoleon_numpy_docstring = True
+napoleon_include_private_with_doc = False
+napoleon_include_special_with_doc = True
+napoleon_use_admonition_for_examples = False
+napoleon_use_admonition_for_notes = False
+napoleon_use_admonition_for_references = False
+napoleon_use_ivar = False
+napoleon_use_param = False
+napoleon_use_rtype = False
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/contents.rst
@@ -0,0 +1,194 @@
+
+ASN.1 library for Python
+========================
+
+.. toctree::
+ :maxdepth: 2
+
+Abstract Syntax Notation One (`ASN.1
+<http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>`_) is a
+technology for exchanging structured data in a universally understood,
+hardware agnostic way. Many industrial, security and telephony
+applications heavily rely on ASN.1.
+
+The `pyasn1 <https://pypi.python.org/pypi/pyasn1/>`_ library implements
+ASN.1 support in pure-Python.
+
+What is ASN.1
+-------------
+
+ASN.1 is a large, arguably over-engineered and extremely old data modelling and
+serialization tool. It is probably among the first serialization protocols in
+the history of computer science and technology.
+
+ASN.1 started its life over 30 years ago as a serialization mechanism for the first
+electronic mail (known as X.400). Later on if was split off the e-mail application
+and become a stand-alone tech still being actively supported by its designers
+and widely used in industry and technology.
+
+Since then ASN.1 is sort of haunted by its relations with the OSI model -- the
+first, unsuccessful, version of the Internet. You can read many interesting
+`discussions <https://news.ycombinator.com/item?id=8871453>`_ on that topic.
+
+In the following years, generations of software engineers tackled the serialization
+problem many times. We can see that in Google's `ProtoBuffers <https://developers.google.com/protocol-buffers/>`_
+or `FlatBuffers <https://google.github.io/flatbuffers/>`_, for example.
+Interestingly, many new takes on binary protocol design do not depart
+far from ASN.1 from technical perspective. It's more of a matter of striking
+a balance between processing overhead, wire format overhead and human
+readability.
+
+Looking at what ASN.1 has to offer, it has three loosely coupled parts:
+
+* Data types: the standard introduces a collection of basic data types
+ (integers, bits, strings, arrays and records) that can be used for describing
+ arbitrarily complex, nested data structures.
+
+* Serialization protocols: the above data structures could be converted into a
+ series of octets for storage or transmission over the wire as well as
+ recovered back into their structured form. The system is fully agnostic
+ to hardware architectures differences.
+
+* Schema language: ASN.1 data structures could be described in terms
+ of a schema language for ASN.1 compiler to turn it into platform-specific
+ implementation.
+
+ASN.1 applications
+------------------
+
+Being an old and generally successful standard, ASN.1 is widely
+adopted for many uses. To give you an example, these technologies
+use ASN.1 for their data exchange needs:
+
+* Signaling standards for the public switched telephone network (SS7 family)
+* Network management standards (SNMP, CMIP)
+* Directory standards (X.500 family, LDAP)
+* Public Key Infrastructure standards (X.509, etc.)
+* PBX control (CSTA)
+* IP-based Videoconferencing (H.323 family)
+* Biometrics (BIP, CBEFF, ACBio)
+* Intelligent transportation (SAE J2735)
+* Cellular telephony (GSM, GPRS/EDGE, UMTS, LTE)
+
+ASN.1 gotchas
+-------------
+
+Apparently, ASN.1 is hard to implement properly. Quality open-source
+ASN.1 tools are rare, but ad-hoc implementations are numerous. Judging from the
+`statistics <http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ASN.1>`_ on discovered
+security vulnerabilities, many people have implemented ASN.1 parsers
+and oftentimes fell victim to its edge cases.
+
+On the bright side, ASN.1 has been around for a long time, it is well understood
+and security reviewed.
+
+Library capabilities
+--------------------
+
+As of this moment, pyasn1 library implements all ASN.1 data
+types as Python objects in accordance with X.208 standard. Later,
+post-1995, revision (X.680) introduced some changes to the schema
+language which may not be fully supported by pyasn1. Aside from data
+types a collection of data transformation codecs comes with pyasn1 package.
+
+As for ASN.1 schema language, pyasn1 package does
+not ship any compiler for it. However, there's a tool called
+`asn1late <https://github.com/kimgr/asn1ate>`_ which is an ASN.1
+grammar parser paired to code generator capable of generating pyasn1
+code. So this is an alternative (or at least a good start) to manual
+implementation of pyasn1 classes from ASN.1 specification.
+
+Both `pyasn1 <https://github.com/etingof/pyasn1>`_ and
+`pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_ libraries
+can be used out-of-the-box with Python versions 2.4 through 3.6.
+No external dependencies required.
+
+Documentation
+-------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/tutorial
+ /docs/api-reference
+
+Use case
+--------
+
+ .. toctree::
+ :maxdepth: 2
+
+ /example-use-case
+
+Download & Install
+------------------
+
+The PyASN1 software is provided under terms and conditions of BSD-style
+:ref:`license`, and can be freely downloaded from `Github <https://github.com/etingof/pyasn1>`_
+or `PyPI <http://pypi.python.org/pypi/pyasn1/>`_.
+
+It is pure-Python and has no dependencies. Considering how much industrial or finance
+software can be stuck with an old platform (think RHEL 5), we struggle to maintain its
+compatibility back to the very pre-historic Python (which is 2.4!).
+
+The best way to obtain PyASN1 is by running `pip`:
+
+.. code-block:: bash
+
+ $ pip install pyasn1
+
+or
+
+.. code-block:: bash
+
+ $ easy_install pyasn1
+
+You may also want to use `pyasn1-modules`:
+
+.. code-block:: bash
+
+ $ pip install pyasn1-modules
+
+Changes
+-------
+
+All changes and release history is maintained in changelog. There you
+could also download the latest unreleased pyasn1 tarball containing
+the latest fixes and improvements.
+
+ .. toctree::
+ :maxdepth: 1
+
+ /changelog
+
+Getting help
+------------
+
+Please, file your `issues <https://github.com/etingof/pyasn1/issues>`_
+and `PRs <https://github.com/etingof/pyasn1/pulls>`_ at GitHub.
+Alternatively, you could ask for help at
+`Stack Overflow <http://stackoverflow.com/questions/tagged/pyasn1>`_
+or search
+`pyasn1-users <https://lists.sourceforge.net/lists/listinfo/pyasn1-users>`_
+mailing list archive.
+
+Books on ASN.1
+--------------
+
+The pyasn1 implementation is largely based on reading up the following awesome
+books:
+
+* `ASN.1 - Communication between heterogeneous systems <http://www.oss.com/asn1/dubuisson.html>`_ by Olivier Dubuisson
+* `ASN.1 Complete <http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf>`_ by Prof John Larmouth
+
+Here you can get the official standards which is hard to read:
+
+* `ITU standards <http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>`_
+
+On the other end of the readability spectrum, here is a quick and sweet write up:
+
+* `A Layman's Guide to a Subset of ASN.1, BER, and DER <ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>`_ by Burton S. Kaliski
+
+If you are working with ASN.1, we'd highly recommend reading a proper
+book on the subject.
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/api-reference.rst
@@ -0,0 +1,30 @@
+
+Library reference
+=================
+
+.. toctree::
+ :maxdepth: 2
+
+ASN.1 types
+-----------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/univ/contents
+ /docs/type/char/contents
+ /docs/type/useful/contents
+ /docs/type/tag/contents
+ /docs/type/namedtype/contents
+ /docs/type/namedval/contents
+
+Transformation codecs
+---------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/codec/ber/contents
+ /docs/codec/cer/contents
+ /docs/codec/der/contents
+ /docs/codec/native/contents
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/ber/contents.rst
@@ -0,0 +1,7 @@
+
+Basic Encoding Rules
+--------------------
+
+.. autofunction:: pyasn1.codec.ber.encoder.encode(value, defMode=True, maxChunkSize=0)
+
+.. autofunction:: pyasn1.codec.ber.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/cer/contents.rst
@@ -0,0 +1,7 @@
+
+Canonical Encoding Rules
+------------------------
+
+.. autofunction:: pyasn1.codec.cer.encoder.encode(value)
+
+.. autofunction:: pyasn1.codec.cer.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/der/contents.rst
@@ -0,0 +1,7 @@
+
+Distinguished Encoding Rules
+----------------------------
+
+.. autofunction:: pyasn1.codec.der.encoder.encode(value)
+
+.. autofunction:: pyasn1.codec.der.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/native/contents.rst
@@ -0,0 +1,7 @@
+
+Native Python types
+-------------------
+
+.. autofunction:: pyasn1.codec.native.encoder.encode(asn1Value)
+
+.. autofunction:: pyasn1.codec.native.decoder.decode(pyObject, asn1Spec)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/tutorial.rst
@@ -0,0 +1,1778 @@
+
+Documentation
+=============
+
+.. toctree::
+ :maxdepth: 2
+
+Data model for ASN.1 types
+--------------------------
+
+All ASN.1 types could be categorized into two groups: scalar (also
+called simple or primitive) and constructed. The first group is
+populated by well-known types like Integer or String. Members of
+constructed group hold other types (simple or constructed) as their
+inner components, thus they are semantically close to a programming
+language records or lists.
+
+In pyasn1, all ASN.1 types and values are implemented as Python
+objects. The same pyasn1 object can represent either ASN.1 type
+and/or value depending of the presense of value initializer on object
+instantiation. We will further refer to these as *pyasn1 type object*
+versus *pyasn1 value object*.
+
+Primitive ASN.1 types are implemented as immutable scalar objects.
+There values could be used just like corresponding native Python
+values (integers, strings/bytes etc) and freely mixed with them in
+expressions.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> asn1IntegerValue = univ.Integer(12)
+ >>> asn1IntegerValue - 2
+ 10
+ >>> univ.OctetString('abc') == 'abc'
+ True # Python 2
+ >>> univ.OctetString(b'abc') == b'abc'
+ True # Python 3
+
+It would be an error to perform an operation on a pyasn1 type object
+as it holds no value to deal with:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> asn1IntegerType = univ.Integer()
+ >>> asn1IntegerType - 2
+ ...
+ pyasn1.error.PyAsn1Error: No value for __coerce__()
+
+
+Scalar types
+------------
+
+In the sub-sections that follow we will explain pyasn1 mapping to
+those primitive ASN.1 types. Both, ASN.1 notation and corresponding
+pyasn1 syntax will be given in each case.
+
+Boolean type
+++++++++++++
+
+*BOOLEAN* is the simplest type those values could be either True or
+False.
+
+.. code-block:: bash
+
+ ;; type specification
+ FunFactorPresent ::= BOOLEAN
+
+ ;; values declaration and assignment
+ pythonFunFactor FunFactorPresent ::= TRUE
+ cobolFunFactor FunFactorPresent :: FALSE
+
+And here's pyasn1 version of :py:class:`~pyasn1.type.univ.Boolean`:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> class FunFactorPresent(univ.Boolean): pass
+ ...
+ >>> pythonFunFactor = FunFactorPresent(True)
+ >>> cobolFunFactor = FunFactorPresent(False)
+ >>> pythonFunFactor
+ FunFactorPresent('True(1)')
+ >>> cobolFunFactor
+ FunFactorPresent('False(0)')
+ >>> pythonFunFactor == cobolFunFactor
+ False
+ >>>
+
+Null type
++++++++++
+
+The *NULL* type is sometimes used to express the absense of
+information.
+
+.. code-block:: bash
+
+ ;; type specification
+ Vote ::= CHOICE {
+ agreed BOOLEAN,
+ skip NULL
+ }
+
+ ;; value declaration and assignment
+ myVote Vote ::= skip:NULL
+
+We will explain the CHOICE type later on, meanwhile the
+:py:class:`~pyasn1.type.univ.Null` type:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> skip = univ.Null()
+ >>> skip
+ Null('')
+ >>>
+
+Integer type
+++++++++++++
+
+ASN.1 defines the values of *INTEGER* type as negative or positive of
+whatever length. This definition plays nicely with Python as the
+latter places no limit on Integers. However, some ASN.1
+implementations may impose certain limits of integer value ranges.
+Keep that in mind when designing new data structures.
+
+.. code-block:: bash
+
+ ;; values specification
+ age-of-universe INTEGER ::= 13750000000
+ mean-martian-surface-temperature INTEGER ::= -63
+
+A rather strigntforward mapping into pyasn1 -
+:py:class:`~pyasn1.type.univ.Integer`:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> ageOfUniverse = univ.Integer(13750000000)
+ >>> ageOfUniverse
+ Integer(13750000000)
+ >>>
+ >>> meanMartianSurfaceTemperature = univ.Integer(-63)
+ >>> meanMartianSurfaceTemperature
+ Integer(-63)
+ >>>
+
+ASN.1 allows to assign human-friendly names to particular values of
+an INTEGER type.
+
+.. code-block:: bash
+
+ Temperature ::= INTEGER {
+ freezing(0),
+ boiling(100)
+ }
+
+The Temperature type expressed in pyasn1:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedval
+ >>> class Temperature(univ.Integer):
+ ... namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
+ ...
+ >>> t = Temperature(0)
+ >>> t
+ Temperature('freezing(0)')
+ >>> t + 1
+ Temperature(1)
+ >>> t + 100
+ Temperature('boiling(100)')
+ >>> t = Temperature('boiling')
+ >>> t
+ Temperature('boiling(100)')
+ >>> Temperature('boiling') / 2
+ Temperature(50)
+ >>> -1 < Temperature('freezing')
+ True
+ >>> 47 > Temperature('boiling')
+ False
+
+These values labels have no effect on Integer type operations, any value
+still could be assigned to a type (information on value constraints will
+follow further in the documentation).
+
+Enumerated type
++++++++++++++++
+
+ASN.1 *ENUMERATED* type differs from an Integer type in a number of
+ways. Most important is that its instance can only hold a value that
+belongs to a set of values specified on type declaration.
+
+.. code-block:: bash
+
+ error-status ::= ENUMERATED {
+ no-error(0),
+ authentication-error(10),
+ authorization-error(20),
+ general-failure(51)
+ }
+
+When constructing :py:class:`~pyasn1.type.univ.Enumerated` type we
+will use two pyasn1 features: values labels (as mentioned above) and
+value constraint (will be described in more details later on).
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedval, constraint
+ >>> class ErrorStatus(univ.Enumerated):
+ ... namedValues = namedval.NamedValues(
+ ... ('no-error', 0),
+ ... ('authentication-error', 10),
+ ... ('authorization-error', 20),
+ ... ('general-failure', 51)
+ ... )
+ ... subtypeSpec = univ.Enumerated.subtypeSpec + \
+ ... constraint.SingleValueConstraint(0, 10, 20, 51)
+ ...
+ >>> errorStatus = univ.ErrorStatus('no-error')
+ >>> errorStatus
+ ErrorStatus('no-error(0)')
+ >>> errorStatus == univ.ErrorStatus('general-failure')
+ False
+ >>> univ.ErrorStatus('non-existing-state')
+ Traceback (most recent call last):
+ ...
+ pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
+ >>>
+
+Particular integer values associated with Enumerated value states have
+no meaning. They should not be used as such or in any kind of math
+operation. Those integer values are only used by codecs to transfer
+state from one entity to another.
+
+Real type
++++++++++
+
+Values of the *REAL* type are a three-component tuple of mantissa,
+base and exponent. All three are integers.
+
+.. code-block:: bash
+
+ pi ::= REAL { mantissa 314159, base 10, exponent -5 }
+
+Corresponding pyasn1 :py:class:`~pyasn1.type.univ.Real` objects can be
+initialized with either a three-component tuple or a Python float.
+Infinite values could be expressed in a way, compatible with Python
+float type.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> pi = univ.Real((314159, 10, -5))
+ >>> pi
+ Real((314159, 10,-5))
+ >>> float(pi)
+ 3.14159
+ >>> pi == univ.Real(3.14159)
+ True
+ >>> univ.Real('inf')
+ Real('inf')
+ >>> univ.Real('-inf') == float('-inf')
+ True
+ >>>
+
+If a Real object is initialized from a Python float or yielded by a math
+operation, the base is set to decimal 10 (what affects encoding).
+
+Bit string type
++++++++++++++++
+
+ASN.1 *BIT STRING* type holds opaque binary data of an arbitrarily
+length. A BIT STRING value could be initialized by either a binary
+(base 2) or hex (base 16) value.
+
+.. code-block:: bash
+
+ public-key BIT STRING ::= '1010111011110001010110101101101
+ 1011000101010000010110101100010
+ 0110101010000111101010111111110'B
+
+ signature BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
+
+The pyasn1 :py:class:`~pyasn1.type.univ.BitString` objects can
+initialize from native ASN.1 notation (base 2 or base 16 strings) or
+from a Python tuple of binary components.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> publicKey = univ.BitString(
+ ... binValue='1010111011110001010110101101101'
+ ... '1011000101010000010110101100010'
+ ... '0110101010000111101010111111110'
+ )
+ >>> publicKey
+ BitString(binValue='101011101111000101011010110110110110001010100000101101011000100110101010000111101010111111110')
+ >>> signature = univ.BitString(
+ ... hexValue='AF01330CD932093392100B39FF00DE0'
+ ... )
+ >>> signature
+ BitString(binValue='1010111100000001001100110000110011011001001100100000100100110011100100100001000000001011001110011111111100000000110111100000')
+ >>> fingerprint = univ.BitString(
+ ... (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
+ ... )
+ >>> fingerprint
+ BitString(binValue='101101110101')
+ >>>
+
+Another BIT STRING initialization method supported by ASN.1 notation
+is to specify only 1-th bits along with their human-friendly label and
+bit offset relative to the beginning of the bit string. With this
+method, all not explicitly mentioned bits are doomed to be zeros.
+
+.. code-block:: bash
+
+ bit-mask BIT STRING ::= {
+ read-flag(0),
+ write-flag(2),
+ run-flag(4)
+ }
+
+To express this in pyasn1, we will employ the named values feature (as
+with Enumeration type).
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedval
+ >>> class BitMask(univ.BitString):
+ ... namedValues = namedval.NamedValues(
+ ... ('read-flag', 0),
+ ... ('write-flag', 2),
+ ... ('run-flag', 4)
+ ... )
+ >>> bitMask = BitMask('read-flag,run-flag')
+ >>> bitMask
+ BitMask(binValue='10001')
+ >>> tuple(bitMask)
+ (1, 0, 0, 0, 1)
+ >>> bitMask[4]
+ 1
+ >>>
+
+The BitString objects mimic the properties of Python tuple type in
+part of immutable sequence object protocol support.
+
+OctetString type
+++++++++++++++++
+
+The *OCTET STRING* type is a confusing subject. According to ASN.1
+specification, this type is similar to BIT STRING, the major
+difference is that the former operates in 8-bit chunks of data. What
+is important to note, is that OCTET STRING was NOT designed to handle
+text strings - the standard provides many other types specialized for
+text content. For that reason, ASN.1 forbids to initialize OCTET
+STRING values with "quoted text strings", only binary or hex
+initializers, similar to BIT STRING ones, are allowed.
+
+.. code-block:: bash
+
+ thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
+ thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
+
+However, ASN.1 users (e.g. protocols designers) seem to ignore the
+original purpose of the OCTET STRING type - they used it for handling
+all kinds of data, including text strings.
+
+.. code-block:: bash
+
+ welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
+
+In pyasn1, we have taken a liberal approach and allowed both BIT
+STRING style and quoted text initializers for the
+:py:class:`~pyasn1.type.univ.OctetString` objects. To avoid possible
+collisions, quoted text is the default initialization syntax.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> thumbnail = univ.OctetString(
+ ... binValue='1000010111101110101111000000111011'
+ ... )
+ >>> thumbnail
+ OctetString(hexValue='85eebcec0')
+ >>> thumbnail = univ.OctetString(
+ ... hexValue='FA9823C43E43510DE3422'
+ ... )
+ >>> thumbnail
+ OctetString(hexValue='fa9823c43e4351de34220')
+ >>>
+
+Most frequent usage of the OctetString class is to instantiate it with
+a text string.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
+ >>> welcomeMessage
+ OctetString(b'Welcome to ASN.1 wilderness!')
+ >>> print('%s' % welcomeMessage)
+ Welcome to ASN.1 wilderness!
+ >>> welcomeMessage[11:16]
+ OctetString(b'ASN.1')
+ >>>
+
+OctetString objects support the immutable sequence object protocol.
+In other words, they behave like Python 3 bytes (or Python 2 strings).
+When running pyasn1 on Python 3, it's better to use the bytes objects for
+OctetString instantiation, as it's more reliable and efficient.
+
+Additionally, OctetString's can also be instantiated with a sequence of
+8-bit integers (ASCII codes).
+
+.. code-block:: pycon
+
+ >>> univ.OctetString((77, 101, 101, 103, 111))
+ OctetString(b'Meego')
+
+It is sometimes convenient to express OctetString instances as 8-bit
+characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
+
+.. code-block:: pycon
+
+ >>> octetString = univ.OctetString('ABCDEF')
+ >>> octetString.asNumbers()
+ (65, 66, 67, 68, 69, 70)
+ >>> octetString.asOctets()
+ b'ABCDEF'
+
+ObjectIdentifier type
++++++++++++++++++++++
+
+Values of the *OBJECT IDENTIFIER* type are sequences of integers that
+could be used to identify virtually anything in the world. Various
+ASN.1-based protocols employ OBJECT IDENTIFIERs for their own
+identification needs.
+
+.. code-block:: bash
+
+ internet-id OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) dod(6) internet(1)
+ }
+
+One of the natural ways to map OBJECT IDENTIFIER type into a Python
+one is to use Python tuples of integers. So this approach is taken by
+pyasn1's :py:class:`~pyasn1.type.univ.ObjectIdentifier` class.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
+ >>> internetId
+ ObjectIdentifier('1.3.6.1')
+ >>> internetId[2]
+ 6
+ >>> internetId[1:3]
+ ObjectIdentifier('3.6')
+
+A more human-friendly "dotted" notation is also supported.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> univ.ObjectIdentifier('1.3.6.1')
+ ObjectIdentifier('1.3.6.1')
+
+Symbolic names of the arcs of object identifier, sometimes present in
+ASN.1 specifications, are not preserved and used in pyasn1 objects.
+
+The ObjectIdentifier objects mimic the properties of Python tuple type in
+part of immutable sequence object protocol support.
+
+Any type
+++++++++
+
+The ASN.1 ANY type is a kind of wildcard or placeholder that matches
+any other type without knowing it in advance. ANY has no base tag.
+
+.. code-block:: bash
+
+ Error ::= SEQUENCE {
+ code INTEGER,
+ parameter ANY DEFINED BY code
+ }
+
+The ANY type is frequently used in specifications, where exact type is
+not yet agreed upon between communicating parties or the number of
+possible alternatives of a type is infinite. Sometimes an auxiliary
+selector is kept around to help parties indicate the kind of ANY
+payload in effect ("code" in the example above).
+
+Values of the ANY type contain serialized ASN.1 value(s) in form of an
+octet string. Therefore pyasn1 :py:class:`~pyasn1.type.univ.Any` value
+object share the properties of pyasn1 OctetString object.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> someValue = univ.Any(b'\x02\x01\x01')
+ >>> someValue
+ Any(b'\x02\x01\x01')
+ >>> str(someValue)
+ '\x02\x01\x01'
+ >>> bytes(someValue)
+ b'\x02\x01\x01'
+ >>>
+
+Receiving application is supposed to explicitly deserialize the
+content of Any value object, possibly using auxiliary selector for
+figuring out its ASN.1 type to pick appropriate decoder.
+
+There will be some more talk and code snippets covering Any type in
+the codecs chapters that follow.
+
+Character string types
+++++++++++++++++++++++
+
+ASN.1 standard introduces a diverse set of text-specific types. All of
+them were designed to handle various types of characters. Some of
+these types seem be obsolete nowdays, as their target technologies are
+gone. Another issue to be aware of is that raw OCTET STRING type is
+sometimes used in practice by ASN.1 users instead of specialized
+character string types, despite explicit prohibition imposed by ASN.1
+specification.
+
+The two types are specific to ASN.1 are NumericString and PrintableString.
+
+.. code-block:: bash
+
+ welcome-message ::= PrintableString {
+ "Welcome to ASN.1 text types"
+ }
+
+ dial-pad-numbers ::= NumericString {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+ }
+
+Their pyasn1 implementations are
+:py:class:`~pyasn1.type.char.PrintableString` and
+:py:class:`~pyasn1.type.char.NumericString`:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char
+ >>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
+ 'Welcome to ASN.1 text types'
+ >>> dialPadNumbers = char.NumericString(
+ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
+ )
+ >>> dialPadNumbers
+ NumericString(b'0123456789')
+ >>>
+
+The :py:class:`~pyasn1.type.char.VisibleString`,
+:py:class:`~pyasn1.type.char.IA5String`,
+:py:class:`~pyasn1.type.char.TeletexString`,
+:py:class:`~pyasn1.type.char.VideotexString`,
+:py:class:`~pyasn1.type.char.GraphicString` and
+:py:class:`~pyasn1.type.char.GeneralString` types came to ASN.1 from
+ISO standards on character sets.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char
+ >>> char.VisibleString("abc")
+ VisibleString(b'abc')
+ >>> char.IA5String('abc')
+ IA5String(b'abc')
+ >>> char.TeletexString('abc')
+ TeletexString(b'abc')
+ >>> char.VideotexString('abc')
+ VideotexString(b'abc')
+ >>> char.GraphicString('abc')
+ GraphicString(b'abc')
+ >>> char.GeneralString('abc')
+ GeneralString(b'abc')
+ >>>
+
+The last three types are relatively recent addition to the family of
+character string types: :py:class:`~pyasn1.type.char.UniversalString`,
+:py:class:`~pyasn1.type.char.BMPString` and
+:py:class:`~pyasn1.type.char.UTF8String`.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char
+ >>> char.UniversalString("abc")
+ UniversalString(b'abc')
+ >>> char.BMPString('abc')
+ BMPString(b'abc')
+ >>> char.UTF8String('abc')
+ UTF8String(b'abc')
+ >>> utf8String = char.UTF8String('У попа была собака')
+ >>> utf8String
+ UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
+ >>> print(utf8String)
+ У попа была собака
+ >>>
+
+In pyasn1, all character type objects behave like Python strings. None
+of them is currently constrained in terms of valid alphabet so it's up
+to the data source to keep an eye on data validation for these types.
+
+Useful types
+++++++++++++
+
+There are three so-called useful types defined in the standard:
+:py:class:`~pyasn1.type.useful.ObjectDescriptor`,
+:py:class:`~pyasn1.type.useful.GeneralizedTime` and
+:py:class:`~pyasn1.type.useful.UTCTime`. They all are subtypes of
+GraphicString or VisibleString types therefore useful types are
+character string types.
+
+It's advised by the ASN.1 standard to have an instance of
+ObjectDescriptor type holding a human-readable description of
+corresponding instance of OBJECT IDENTIFIER type. There are no formal
+linkage between these instances and provision for ObjectDescriptor
+uniqueness in the standard.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import useful
+ >>> descrBER = useful.ObjectDescriptor(
+ "Basic encoding of a single ASN.1 type"
+ )
+ >>>
+
+GeneralizedTime and UTCTime types are designed to hold a
+human-readable timestamp in a universal and unambiguous form. The
+former provides more flexibility in notation while the latter is more
+strict but has Y2K issues.
+
+.. code-block:: bash
+
+ ;; Mar 8 2010 12:00:00 MSK
+ moscow-time GeneralizedTime ::= "20110308120000.0"
+ ;; Mar 8 2010 12:00:00 UTC
+ utc-time GeneralizedTime ::= "201103081200Z"
+ ;; Mar 8 1999 12:00:00 UTC
+ utc-time UTCTime ::= "9803081200Z"
+
+In pyasn1 parlance:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import useful
+ >>> moscowTime = useful.GeneralizedTime("20110308120000.0")
+ >>> utcTime = useful.UTCTime("9803081200Z")
+ >>>
+
+Despite their intended use, these types possess no special, time-related,
+handling in pyasn1. They are just printable strings.
+
+Tagging
+-------
+
+In order to proceed to the Constructed ASN.1 types, we will first have
+to introduce the concept of tagging (and its pyasn1 implementation), as
+some of the Constructed types rely upon the tagging feature.
+
+When a value is coming into an ASN.1-based system (received from a network
+or read from some storage), the receiving entity has to determine the
+type of the value to interpret and verify it accordingly.
+
+Historically, the first data serialization protocol introduced in
+ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
+value is packed into a triplet of (Type, Length, Value) where Type is a
+code that identifies the value (which is called *tag* in ASN.1),
+length is the number of bytes occupied by the value in its serialized form
+and value is ASN.1 value in a form suitable for serial transmission or storage.
+For that reason almost every ASN.1 type has a tag (which is actually a
+BER type) associated with it by default.
+
+An ASN.1 tag could be viewed as a tuple of three numbers:
+(Class, Format, Number). While Number identifies a tag, Class component
+is used to create scopes for Numbers. Four scopes are currently defined:
+UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
+is actually a one-bit flag - zero for tags associated with scalar types,
+and one for constructed types (will be discussed later on).
+
+.. code-block:: bash
+
+ MyIntegerType ::= [12] INTEGER
+ MyOctetString ::= [APPLICATION 0] OCTET STRING
+
+In pyasn1, tags are implemented as immutable, tuple-like objects:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import tag
+ >>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+ >>> myTag
+ Tag(tagClass=128, tagFormat=0, tagId=10)
+ >>> tuple(myTag)
+ (128, 0, 10)
+ >>> myTag[2]
+ 10
+ >>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
+ False
+ >>>
+
+Default tag, associated with any ASN.1 type, could be extended or
+replaced to make new type distinguishable from its ancestor. The
+standard provides two modes of tag mangling - IMPLICIT and EXPLICIT.
+
+EXPLICIT mode works by appending new tag to the existing ones thus
+creating an ordered set of tags. This set will be considered as a
+whole for type identification and encoding purposes. Important
+property of EXPLICIT tagging mode is that it preserves base type
+information in encoding what makes it possible to completely recover
+type information from encoding.
+
+When tagging in IMPLICIT mode, the outermost existing tag is dropped
+and replaced with a new one.
+
+.. code-block:: bash
+
+ MyIntegerType ::= [12] IMPLICIT INTEGER
+ MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
+
+To model both modes of tagging, a specialized container TagSet object
+(holding zero, one or more Tag objects) is used in pyasn1.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import tag
+ >>> tagSet = tag.TagSet(
+ ... # base tag (OBSOLETE AND NOT USED ANYMORE)
+ ... (),
+ ... # effective tag
+ ... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+ ... )
+ >>> tagSet
+ TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10))
+ >>> tagSet.getBaseTag()
+ Tag(tagClass=128, tagFormat=0, tagId=10)
+ >>> tagSet = tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20))
+ >>> tagSet
+ TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10),
+ Tag(tagClass=128, tagFormat=32, tagId=20))
+ >>> tagSet = tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30))
+ >>> tagSet
+ TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10),
+ Tag(tagClass=128, tagFormat=32, tagId=20),
+ Tag(tagClass=128, tagFormat=32, tagId=30))
+ >>> tagSet = tagSet.tagImplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40))
+ >>> tagSet
+ TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10),
+ Tag(tagClass=128, tagFormat=32, tagId=20),
+ Tag(tagClass=128, tagFormat=32, tagId=40))
+ >>>
+
+As a side note: the "base tag" concept is now obsolete and not used.
+The "effective tag" is the one that always appears in encoding and is
+used on tagSets comparation.
+
+Any two TagSet objects could be compared to see if one is a derivative
+of the other. Figuring this out is also useful in cases when a type-specific
+data processing algorithms are to be chosen.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import tag
+ >>> tagSet1 = tag.TagSet(
+ ... # base tag (OBSOLETE AND NOT USED ANYMORE)
+ ... (),
+ ... # effective tag
+ ... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+ ... )
+ >>> tagSet2 = tagSet1.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20))
+ >>> tagSet1.isSuperTagSetOf(tagSet2)
+ True
+ >>> tagSet2.isSuperTagSetOf(tagSet1)
+ False
+ >>>
+
+We will complete this discussion on tagging with a real-world example. The
+following ASN.1 tagged type:
+
+.. code-block:: bash
+
+ MyIntegerType ::= [12] EXPLICIT INTEGER
+
+could be expressed in pyasn1 like this:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, tag
+ >>> class MyIntegerType(univ.Integer):
+ ... tagSet = univ.Integer.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12))
+ >>> myInteger = MyIntegerType(12345)
+ >>> myInteger.tagSet
+ TagSet((), Tag(tagClass=0, tagFormat=0, tagId=2),
+ Tag(tagClass=128, tagFormat=32, tagId=12))
+ >>>
+
+Referring to the above code, the tagSet class attribute is a property
+of any pyasn1 type object that assigns default tagSet to a pyasn1
+value object. This default tagSet specification can be ignored and
+effectively replaced by some other tagSet value passed on object
+instantiation.
+
+It's important to understand that the tag set property of pyasn1 type/value
+object can never be modifed in place. In other words, a pyasn1 type/value
+object can never change its tags. The only way is to create a new pyasn1
+type/value object and associate different tag set with it.
+
+Constructed types
+-----------------
+
+Besides scalar types, ASN.1 specifies so-called constructed ones - these
+are capable of holding one or more values of other types, both scalar
+and constructed.
+
+In pyasn1 implementation, constructed ASN.1 types behave like
+Python sequences, and also support additional component addressing methods,
+specific to particular constructed type.
+
+Sequence and Set types
+++++++++++++++++++++++
+
+The *SEQUENCE* and *SET* types have many similar properties:
+
+* Both can hold any number of inner components of different types.
+* Every component has a human-friendly identifier.
+* Any component can have a default value.
+* Some components can be absent.
+
+However, :py:class:`~pyasn1.type.univ.Sequence` type guarantees the
+ordering of Sequence value components to match their declaration
+order. By contrast, components of the
+:py:class:`~pyasn1.type.univ.Set` type can be ordered to best suite
+application's needs.
+
+.. code-block:: bash
+
+ Record ::= SEQUENCE {
+ id INTEGER,
+ room [0] INTEGER OPTIONAL,
+ house [1] INTEGER DEFAULT 0
+ }
+
+Up to this moment, the only method we used for creating new pyasn1
+types is Python sub-classing. With this method, a new, named Python
+class is created what mimics type derivation in ASN.1 grammar.
+However, ASN.1 also allows for defining anonymous subtypes (room and
+house components in the example above). To support anonymous
+subtyping in pyasn1, a cloning operation on an existing pyasn1 type
+object can be invoked what creates a new instance of original object
+with possibly modified properties.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedtype, tag
+ >>> class Record(univ.Sequence):
+ ... componentType = namedtype.NamedTypes(
+ ... namedtype.NamedType('id', univ.Integer()),
+ ... namedtype.OptionalNamedType(
+ ... 'room',
+ ... univ.Integer().subtype(
+ ... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
+ ... )
+ ... ),
+ ... namedtype.DefaultedNamedType(
+ ... 'house',
+ ... univ.Integer(0).subtype(
+ ... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
+ ... )
+ ... )
+ ... )
+ >>>
+
+All pyasn1 constructed type classes have a class attribute
+**componentType** that represent default type specification. Its
+value is a NamedTypes object.
+
+The NamedTypes class instance holds a sequence of NameType,
+OptionalNamedType or DefaultedNamedType objects which, in turn, refer
+to pyasn1 type objects that represent inner SEQUENCE components
+specification.
+
+Finally, invocation of a subtype() method of pyasn1 type objects in
+the code above returns an implicitly tagged copy of original object.
+
+Once a SEQUENCE or SET type is decleared with pyasn1, it can be
+instantiated and initialized (continuing the above code):
+
+.. code-block:: pycon
+
+ >>> record = Record()
+ >>> record['id'] = 123
+ >>> print(record.prettyPrint())
+ Record:
+ id=123
+ >>>
+ >>> record[1] = 321
+ >>> print(record.prettyPrint())
+ Record:
+ id=123
+ room=321
+ >>>
+ >>> record.setDefaultComponents()
+ >>> print(record.prettyPrint())
+ Record:
+ id=123
+ room=321
+ house=0
+
+Inner components of pyasn1 Sequence/Set objects could be accessed
+using the following methods:
+
+.. code-block:: pycon
+
+ >>> record['id']
+ Integer(123)
+ >>> record[1]
+ Integer(321)
+ >>> record[2]
+ Integer(0)
+ >>> for idx, field in enumerate(record):
+ ... print(record.componentType[idx].name, field)
+ id 123
+ room 321
+ house 0
+ >>>
+
+The Set type share all the properties of Sequence type, and additionally
+support by-tag component addressing (as all Set components have distinct
+types).
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedtype, tag
+ >>> class Gamer(univ.Set):
+ ... componentType = namedtype.NamedTypes(
+ ... namedtype.NamedType('score', univ.Integer()),
+ ... namedtype.NamedType('player', univ.OctetString()),
+ ... namedtype.NamedType('id', univ.ObjectIdentifier())
+ ... )
+ >>> gamer = Gamer()
+ >>> gamer.setComponentByType(univ.Integer().tagSet, 121343)
+ >>> gamer.setComponentByType(univ.OctetString().tagSet, 'Pascal')
+ >>> gamer.setComponentByType(univ.ObjectIdentifier().tagSet, (1,3,7,2))
+ >>> print(gamer.prettyPrint())
+ Gamer:
+ score=121343
+ player=b'Pascal'
+ id=1.3.7.2
+
+SequenceOf and SetOf types
+++++++++++++++++++++++++++
+
+Both, *SEQUENCE OF* and *SET OF* types resemble an unlimited size list of
+components. All the components must be of the same type.
+
+.. code-block:: bash
+
+ Progression ::= SEQUENCE OF INTEGER
+
+ arithmeticProgression Progression ::= { 1, 3, 5, 7 }
+
+:py:class:`~pyasn1.type.univ.SequenceOf` and
+:py:class:`~pyasn1.type.univ.SetOf` types are expressed by the very
+similar pyasn1 `list` type objects. Their components can only be addressed by
+position and they both have a property of automatic resize.
+
+To specify inner component type, the **componentType** class
+attribute should refer to another pyasn1 type object.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> class Progression(univ.SequenceOf):
+ ... componentType = univ.Integer()
+ >>> arithmeticProgression = Progression()
+ >>> arithmeticProgression[1] = 111
+ >>> print(arithmeticProgression.prettyPrint())
+ Progression:
+ -empty- 111
+ >>> arithmeticProgression[0] = 100
+ >>> print(arithmeticProgression.prettyPrint())
+ Progression:
+ 100 111
+ >>>
+ >>> for element in arithmeticProgression:
+ ... element
+ Integer(100)
+ Integer(111)
+ >>>
+
+Any scalar or constructed pyasn1 type object can serve as an inner
+component. Missing components are prohibited in SequenceOf/SetOf
+value objects.
+
+Choice type
++++++++++++
+
+Values of ASN.1 *CHOICE* type can contain only a single value of a type
+from a list of possible alternatives. Alternatives must be ASN.1 types
+with distinct tags for the whole structure to remain unambiguous.
+Unlike most other types, CHOICE is an untagged one, e.g. it has no
+base tag of its own.
+
+.. code-block:: bash
+
+ CodeOrMessage ::= CHOICE {
+ code INTEGER,
+ message OCTET STRING
+ }
+
+In pyasn1 implementation,
+:py:class:`~pyasn1.type.univ.Choice` object behaves like Set but
+accepts only a single inner component at a time. It also offers a few
+additional methods specific to its behaviour.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedtype
+ >>> class CodeOrMessage(univ.Choice):
+ ... componentType = namedtype.NamedTypes(
+ ... namedtype.NamedType('code', univ.Integer()),
+ ... namedtype.NamedType('message', univ.OctetString())
+ ... )
+ >>>
+ >>> codeOrMessage = CodeOrMessage()
+ >>> print(codeOrMessage.prettyPrint())
+ CodeOrMessage:
+ >>> codeOrMessage['code'] = 123
+ >>> print(codeOrMessage.prettyPrint())
+ CodeOrMessage:
+ code=123
+ >>> codeOrMessage['message'] = 'my string value'
+ >>> print(codeOrMessage.prettyPrint())
+ CodeOrMessage:
+ message=b'my string value'
+ >>>
+
+Since there could be only a single inner component value in the pyasn1
+Choice value object, either of the following methods could be used for
+fetching it (continuing previous code):
+
+.. code-block:: pycon
+
+ >>> codeOrMessage.getName()
+ 'message'
+ >>> codeOrMessage.getComponent()
+ OctetString(b'my string value')
+ >>>
+
+Subtype constraints
+-------------------
+
+Most ASN.1 types can correspond to an infinite set of values. To adapt
+to particular application's data model and needs, ASN.1 provides a
+mechanism for limiting the infinite set to values, that make sense in
+particular case. Imposing value constraints on an ASN.1 type can also
+be seen as creating a subtype from its base type.
+
+In pyasn1, constraints take shape of immutable objects capable
+of evaluating given value against constraint-specific requirements.
+Constraint object is a property of pyasn1 type. Like TagSet property,
+associated with every pyasn1 type, constraints can never be modified
+in place. The only way to modify pyasn1 type constraint is to associate
+new constraint object to a new pyasn1 type object.
+
+A handful of different flavors of *constraints* are defined in
+ASN.1. We will discuss them one by one in the following chapters and
+also explain how to combine and apply them to types.
+
+Single value constraint
++++++++++++++++++++++++
+
+This kind of constraint allows for limiting type to a finite, specified set
+of values.
+
+.. code-block:: bash
+
+ DialButton ::= OCTET STRING (
+ "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+ )
+
+Its pyasn1 implementation would look like:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import constraint
+ >>> c = constraint.SingleValueConstraint('0','1','2','3','4','5','6','7','8','9')
+ >>> c
+ SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+ >>> c('0')
+ >>> c('A')
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+ >>>
+
+As can be seen in the snippet above, if a value violates the
+constraint, an exception will be thrown. A constrainted pyasn1 type
+object holds a reference to a constraint object (or their combination,
+as will be explained later) and calls it for value verification.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> class DialButton(univ.OctetString):
+ ... subtypeSpec = constraint.SingleValueConstraint(
+ ... '0','1','2','3','4','5','6','7','8','9'
+ ... )
+ >>> DialButton('0')
+ DialButton(b'0')
+ >>> DialButton('A')
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+ >>>
+
+Constrained pyasn1 value object can never hold a violating value.
+
+Value range constraint
+++++++++++++++++++++++
+
+A pair of values, compliant to a type to be constrained, denote low
+and upper bounds of allowed range of values of a type.
+
+.. code-block:: bash
+
+ Teenagers ::= INTEGER (13..19)
+
+And in pyasn1 terms:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> class Teenagers(univ.Integer):
+ ... subtypeSpec = constraint.ValueRangeConstraint(13, 19)
+ >>> Teenagers(14)
+ Teenagers(14)
+ >>> Teenagers(20)
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ ValueRangeConstraint(13, 19) failed at: 20
+ >>>
+
+ASN.1 MIN and MAX operands can be substituted with floating point
+infinity values.
+
+.. code-block:: bash
+
+ NegativeInt ::= INTEGER (MIN..-1)
+ PositiveInt ::= INTEGER (1..MAX)
+
+And in pyasn1 terms:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> class NegativeInt(univ.Integer):
+ ... subtypeSpec = constraint.ValueRangeConstraint(float('-inf'), -1)
+ >>> NegativeInt(-1)
+ NegativeInt(-1)
+ >>> NegativeInt(0)
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ ValueConstraintError: ValueRangeConstraint() failed at: "0" at NegativeInt
+ >>> class PositiveInt(univ.Integer):
+ ... subtypeSpec = constraint.ValueRangeConstraint(1, float('inf'))
+ >> PositiveInt(1)
+ PositiveInt(1)
+ >> PositiveInt(4)
+ PositiveInt(4)
+ >> PositiveInt(-1)
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ ValueConstraintError: ValueRangeConstraint() failed at: "-1" at PositiveInt
+
+Value range constraint usually applies to numeric types.
+
+Size constraint
++++++++++++++++
+
+It is sometimes convenient to set or limit the allowed size of a data
+item to be sent from one application to another to manage bandwidth
+and memory consumption issues. Size constraint specifies the lower and
+upper bounds of the size of a valid value.
+
+.. code-block:: bash
+
+ TwoBits ::= BIT STRING (SIZE (2))
+
+Express the same grammar in pyasn1:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> class TwoBits(univ.BitString):
+ ... subtypeSpec = constraint.ValueSizeConstraint(2, 2)
+ >>> TwoBits((1,1))
+ TwoBits("'11'B")
+ >>> TwoBits((1,1,0))
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError: ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
+ >>>
+
+Size constraint can be applied to potentially massive values - bit or
+octet strings, SEQUENCE OF/SET OF values.
+
+Alphabet constraint
++++++++++++++++++++
+
+The permitted alphabet constraint is similar to Single value
+constraint but constraint applies to individual characters of a value.
+
+.. code-block:: bash
+
+ MorseCode ::= PrintableString (FROM ("."|"-"|" "))
+
+And in pyasn1:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char, constraint
+ >>> class MorseCode(char.PrintableString):
+ ... subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
+ >>> MorseCode("...---...")
+ MorseCode('...---...')
+ >>> MorseCode("?")
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError: PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
+ >>>
+
+Current implementation does not handle ranges of characters in
+constraint (FROM "A".."Z" syntax), one has to list the whole set in a
+range.
+
+Constraint combinations
++++++++++++++++++++++++
+
+Up to this moment, we used a single constraint per ASN.1 type. The
+standard, however, allows for combining multiple individual
+constraints into intersections, unions and exclusions.
+
+In pyasn1 data model, all of these methods of constraint combinations
+are implemented as constraint-like objects holding individual
+constraint (or combination) objects. Like terminal constraint objects,
+combination objects are capable to perform value verification at its
+set of enclosed constraints according to the logic of particular
+combination.
+
+Constraints intersection verification succeeds only if a value is
+compliant to each constraint in a set. To begin with, the following
+specification will constitute a valid telephone number:
+
+.. code-block:: bash
+
+ PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
+
+Constraint intersection object serves the logic above:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char, constraint
+ >>> class PhoneNumber(char.NumericString):
+ ... subtypeSpec = constraint.ConstraintsIntersection(
+ ... constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6', '7','8','9'),
+ ... constraint.ValueSizeConstraint(11, 11)
+ ... )
+ >>> PhoneNumber('79039343212')
+ PhoneNumber('79039343212')
+ >>> PhoneNumber('?9039343212')
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError: ConstraintsIntersection(PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'), ValueSizeConstraint(11, 11)) failed at: PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
+ >>> PhoneNumber('9343212')
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ ConstraintsIntersection(PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'), ValueSizeConstraint(11, 11)) failed at: ValueSizeConstraint(10, 10) failed at: "9343212"
+ >>>
+
+Union of constraints works by making sure that a value is compliant
+to any of the constraint in a set. For instance:
+
+.. code-block:: bash
+
+ CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
+
+It's important to note, that a value must fully comply to any single
+constraint in a set. In the specification above, a value of all small
+or all capital letters is compliant, but a mix of small&capitals is
+not. Here's its pyasn1 analogue:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import char, constraint
+ >>> class CapitalOrSmall(char.IA5String):
+ ... subtypeSpec = constraint.ConstraintsUnion(
+ ... constraint.PermittedAlphabetConstraint('A','B','C'),
+ ... constraint.PermittedAlphabetConstraint('a','b','c')
+ ... )
+ >>> CapitalOrSmall('ABBA')
+ CapitalOrSmall('ABBA')
+ >>> CapitalOrSmall('abba')
+ CapitalOrSmall('abba')
+ >>> CapitalOrSmall('Abba')
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError: ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'), PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
+ >>>
+
+Finally, the exclusion constraint simply negates the logic of value
+verification at a constraint. In the following example, any integer
+value is allowed in a type but not zero.
+
+.. code-block:: bash
+
+ NoZero ::= INTEGER (ALL EXCEPT 0)
+
+In pyasn1 the above definition would read:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> class NoZero(univ.Integer):
+ ... subtypeSpec = constraint.ConstraintsExclusion(
+ ... constraint.SingleValueConstraint(0)
+ ... )
+ >>> NoZero(1)
+ NoZero(1)
+ >>> NoZero(0)
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError: ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
+ >>>
+
+The depth of such a constraints tree, built with constraint
+combination objects at its nodes, has not explicit limit. Value
+verification is performed in a recursive manner till a definite
+solution is found.
+
+Types relationships
++++++++++++++++++++
+
+In the course of data processing in an application, it is sometimes
+convenient to figure out the type relationships between pyasn1 type or
+value objects. Formally, two things influence pyasn1 types
+relationship: *tag set* and *subtype constraints*. One
+pyasn1 type is considered to be a derivative of another if their
+TagSet and Constraint objects are a derivation of one another.
+
+The following example illustrates the concept (we use the same tagset
+but different constraints for simplicity):
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
+ >>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
+ ... constraint.ValueRangeConstraint(3,8),
+ ... constraint.ValueRangeConstraint(4,7)
+ ... ) )
+ >>> i1.isSameTypeWith(i2)
+ False
+ >>> i1.isSuperTypeOf(i2)
+ True
+ >>> i1.isSuperTypeOf(i1)
+ True
+ >>> i2.isSuperTypeOf(i1)
+ False
+ >>>
+
+As can be seen in the above code snippet, there are two methods of any
+pyasn1 type/value object that test types for their relationship:
+*isSameTypeWith()* and *isSuperTypeOf()*. The former is
+self-descriptive while the latter yields true if the argument appears
+to be a pyasn1 object which has tagset and constraints derived from
+those of the object being called.
+
+Serialization codecs
+--------------------
+
+In ASN.1 context, `codec <http://en.wikipedia.org/wiki/Codec>`_
+is a program that transforms between concrete data structures and a stream
+of octets, suitable for transmission over the wire. This serialized form of
+data is sometimes called *substrate* or *essence*.
+
+In pyasn1 implementation, substrate takes shape of Python 3 bytes or
+Python 2 string objects.
+
+One of the properties of a codec is its ability to cope with
+incomplete data and/or substrate what implies codec to be stateful. In
+other words, when decoder runs out of substrate and data item being
+recovered is still incomplete, stateful codec would suspend and
+complete data item recovery whenever the rest of substrate becomes
+available. Similarly, stateful encoder would encode data items in
+multiple steps waiting for source data to arrive. Codec restartability
+is especially important when application deals with large volumes of
+data and/or runs on low RAM. For an interesting discussion on codecs
+options and design choices, refer to `Apache ASN.1 project
+<http://directory.apache.org/subprojects/asn1/>`_ .
+
+As of this writing, codecs implemented in pyasn1 are all stateless,
+mostly to keep the code simple.
+
+The pyasn1 package currently supports
+`BER <http://en.wikipedia.org/wiki/Basic_encoding_rules>`_ codec and
+its variations --
+`CER <http://en.wikipedia.org/wiki/Canonical_encoding_rules>`_ and
+`DER <http://en.wikipedia.org/wiki/Distinguished_encoding_rules>`_.
+More ASN.1 codecs are planned for implementation in the future.
+
+Encoders
+++++++++
+
+Encoder is used for transforming pyasn1 value objects into substrate.
+Only pyasn1 value objects could be serialized, attempts to process
+pyasn1 type objects will cause encoder failure.
+
+The following code will create a pyasn1 Integer object and serialize
+it with BER encoder:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder
+ >>> encoder.encode(univ.Integer(123456))
+ b'\x02\x03\x01\xe2@'
+ >>>
+
+BER standard also defines a so-called *indefinite length*
+encoding form which makes large data items processing more memory
+efficient. It is mostly useful when encoder does not have the whole
+value all at once and the length of the value can not be determined at
+the beginning of encoding.
+
+*Constructed encoding* is another feature of BER closely related to
+the indefinite length form. In essence, a large scalar value (such as
+ASN.1 character BitString type) could be chopped into smaller chunks
+by encoder and transmitted incrementally to limit memory consumption.
+Unlike indefinite length case, the length of the whole value must be
+known in advance when using constructed, definite length encoding
+form.
+
+Since pyasn1 codecs are not restartable, pyasn1 encoder may only
+encode data item all at once. However, even in this case, generating
+indefinite length encoding may help a low-memory receiver, running a
+restartable decoder, to process a large data item.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder
+ >>> encoder.encode(
+ ... univ.OctetString('The quick brown fox jumps over the lazy dog'),
+ ... defMode=False,
+ ... maxChunkSize=8
+ ... )
+ b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \t\x04\x08he lazy \x04\x03dog\x00\x00'
+ >>>
+ >>> encoder.encode(
+ ... univ.OctetString('The quick brown fox jumps over the lazy dog'),
+ ... maxChunkSize=8
+ ... )
+ b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \t\x04\x08he lazy \x04\x03dog'
+
+The *defMode* encoder parameter disables definite length encoding
+mode, while the optional *maxChunkSize* parameter specifies desired
+substrate chunk size that influences memory requirements at the
+decoder's end.
+
+To use CER or DER encoders one needs to explicitly import and call them - the
+APIs are all compatible.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder as ber_encoder
+ >>> from pyasn1.codec.cer import encoder as cer_encoder
+ >>> from pyasn1.codec.der import encoder as der_encoder
+ >>> ber_encoder.encode(univ.Boolean(True))
+ b'\x01\x01\x01'
+ >>> cer_encoder.encode(univ.Boolean(True))
+ b'\x01\x01\xff'
+ >>> der_encoder.encode(univ.Boolean(True))
+ b'\x01\x01\xff'
+ >>>
+
+Decoders
+++++++++
+
+In the process of decoding, pyasn1 value objects are created and
+linked to each other, based on the information containted in the
+substrate. Thus, the original pyasn1 value object(s) are recovered.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> substrate = encoder.encode(univ.Boolean(True))
+ >>> decoder.decode(substrate)
+ (Boolean('True(1)'), b'')
+ >>>
+
+Commenting on the code snippet above, pyasn1 decoder accepts substrate
+as an argument and returns a tuple of pyasn1 value object (possibly a
+top-level one in case of constructed object) and unprocessed part of
+input substrate.
+
+All pyasn1 decoders can handle both definite and indefinite length
+encoding modes automatically, explicit switching into one mode to
+another is not required.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> substrate = encoder.encode(
+ ... univ.OctetString('The quick brown fox jumps over the lazy dog'),
+ ... defMode=False,
+ ... maxChunkSize=8
+ ... )
+ >>> decoder.decode(substrate)
+ (OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
+ >>>
+
+Speaking of BER/CER/DER encoding, in many situations substrate may not
+contain all necessary information needed for complete and accurate
+ASN.1 values recovery. The most obvious cases include implicitly
+tagged ASN.1 types and constrained types.
+
+As discussed earlier in this tutorial, when an ASN.1 type is implicitly
+tagged, previous outermost tag is lost and never appears in substrate.
+If it is the base tag that gets lost, decoder is unable to pick type-specific
+value decoder at its table of built-in types, and therefore recover
+the value part, based only on the information contained in substrate. The
+approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
+a set of them) to *guide* the decoding process by matching [possibly
+incomplete] tags recovered from substrate with those found in prototype pyasn1
+type objects (also called pyasn1 specification object further in this
+document).
+
+.. code-block:: pycon
+
+ >>> from pyasn1.codec.ber import decoder
+ >>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
+ Integer(12), b''
+ >>>
+
+Decoder would neither modify pyasn1 specification object nor use its
+current values (if it's a pyasn1 value object), but rather use it as a
+hint for choosing proper decoder and as a pattern for creating new
+objects:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, tag
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> i = univ.Integer(12345).subtype(
+ ... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
+ ... )
+ >>> substrate = encoder.encode(i)
+ >>> substrate
+ b'\x9f(\x0209'
+ >>> decoder.decode(substrate)
+ Traceback (most recent call last):
+ ...
+ pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
+ >>> decoder.decode(substrate, asn1Spec=i)
+ (Integer(12345), b'')
+ >>>
+
+Notice in the example above, that an attempt to run decoder without
+passing pyasn1 specification object fails because recovered tag does
+not belong to any of the built-in types.
+
+Another important feature of guided decoder operation is the use of
+values constraints possibly present in pyasn1 specification object.
+To explain this, we will decode a random integer object into generic Integer
+and the constrained one.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, constraint
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> class DialDigit(univ.Integer):
+ ... subtypeSpec = constraint.ValueRangeConstraint(0,9)
+ >>> substrate = encoder.encode(univ.Integer(13))
+ >>> decoder.decode(substrate)
+ (Integer(13), b'')
+ >>> decoder.decode(substrate, asn1Spec=DialDigit())
+ Traceback (most recent call last):
+ ...
+ ValueConstraintError:
+ ValueRangeConstraint(0, 9) failed at: 13
+ >>>
+
+Similarily to encoders, to use CER or DER decoders application has to
+explicitly import and call them - all APIs are compatible.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder as ber_encoder
+ >>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
+ >>>
+ >>> from pyasn1.codec.ber import decoder as ber_decoder
+ >>> from pyasn1.codec.cer import decoder as cer_decoder
+ >>> from pyasn1.codec.der import decoder as der_decoder
+ >>>
+ >>> ber_decoder.decode(substrate)
+ (OctetString(b'http://pyasn1.sf.net'), b'')
+ >>> cer_decoder.decode(substrate)
+ (OctetString(b'http://pyasn1.sf.net'), b'')
+ >>> der_decoder.decode(substrate)
+ (OctetString(b'http://pyasn1.sf.net'), b'')
+ >>>
+
+Advanced topics
+---------------
+
+Certain, non-trivial, ASN.1 data structures may require special
+treatment, especially when running deserialization.
+
+Decoding untagged types
++++++++++++++++++++++++
+
+It has already been mentioned, that ASN.1 has two "special case"
+types: CHOICE and ANY. They are different from other types in part of
+tagging - unless these two are additionally tagged, neither of them
+will have their own tag. Therefore these types become invisible in
+substrate and can not be recovered without passing pyasn1
+specification object to decoder.
+
+To explain the issue, we will first prepare a Choice object to deal with:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, namedtype
+ >>> class CodeOrMessage(univ.Choice):
+ ... componentType = namedtype.NamedTypes(
+ ... namedtype.NamedType('code', univ.Integer()),
+ ... namedtype.NamedType('message', univ.OctetString())
+ ... )
+ >>>
+ >>> codeOrMessage = CodeOrMessage()
+ >>> codeOrMessage['message'] = 'my string value'
+ >>> print(codeOrMessage.prettyPrint())
+ CodeOrMessage:
+ message=b'my string value'
+ >>>
+
+Let's now encode this Choice object and then decode its substrate
+with and without pyasn1 specification object:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> substrate = encoder.encode(codeOrMessage)
+ >>> substrate
+ b'\x04\x0fmy string value'
+ >>> encoder.encode(univ.OctetString('my string value'))
+ b'\x04\x0fmy string value'
+ >>>
+ >>> decoder.decode(substrate)
+ (OctetString(b'my string value'), b'')
+ >>> codeOrMessage, substrate = decoder.decode(substrate,
+ asn1Spec=CodeOrMessage())
+ >>> print(codeOrMessage.prettyPrint())
+ CodeOrMessage:
+ message=b'my string value'
+ >>>
+
+First thing to notice in the listing above is that the substrate
+produced for our Choice value object is equivalent to the substrate
+for an OctetString object initialized to the same value. In other
+words, any information about the Choice component is absent in
+encoding.
+
+Sure enough, that kind of substrate will decode into an OctetString
+object, unless original Choice type object is passed to decoder to
+guide the decoding process.
+
+Similarily untagged ANY type behaves differently on decoding phase -
+when decoder bumps into an Any object in pyasn1 specification, it
+stops decoding and puts all the substrate into a new Any value object
+in form of an octet string. Concerned application could then re-run
+decoder with an additional, more exact pyasn1 specification object to
+recover the contents of Any object.
+
+As it was mentioned elsewhere in this documentation, Any type allows
+for incomplete or changing ASN.1 specification to be handled
+gracefully by decoder and applications.
+
+To illustrate the working of Any type, we'll have to make the stage by
+encoding a pyasn1 object and then putting its substrate into an any
+object.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> innerSubstrate = encoder.encode(univ.Integer(1234))
+ >>> innerSubstrate
+ b'\x02\x02\x04\xd2'
+ >>> any = univ.Any(innerSubstrate)
+ >>> any
+ Any(b'\x02\x02\x04\xd2')
+ >>> substrate = encoder.encode(any)
+ >>> substrate
+ b'\x02\x02\x04\xd2'
+ >>>
+
+As with Choice type encoding, there is no traces of Any type in
+substrate. Obviously, the substrate we are dealing with, will decode
+into the inner [Integer] component, unless pyasn1 specification is
+given to guide the decoder. Continuing previous code:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ
+ >>> from pyasn1.codec.ber import encoder, decoder
+
+ >>> decoder.decode(substrate)
+ (Integer(1234), b'')
+ >>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
+ >>> any
+ Any(b'\x02\x02\x04\xd2')
+ >>> decoder.decode(str(any))
+ (Integer(1234), b'')
+ >>>
+
+Both CHOICE and ANY types are widely used in practice. Reader is welcome to
+take a look at
+`ASN.1 specifications of X.509 applications
+<http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>`_
+for more information.
+
+Ignoring unknown types
+++++++++++++++++++++++
+
+When dealing with a loosely specified ASN.1 structure, the receiving
+end may not be aware of some types present in the substrate. It may be
+convenient then to turn decoder into a recovery mode. Whilst there,
+decoder will not bail out when hit an unknown tag but rather treat it
+as an Any type.
+
+.. code-block:: pycon
+
+ >>> from pyasn1.type import univ, tag
+ >>> from pyasn1.codec.ber import encoder, decoder
+ >>> taggedInt = univ.Integer(12345).subtype(
+ ... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
+ ... )
+ >>> substrate = encoder.encode(taggedInt)
+ >>> decoder.decode(substrate)
+ Traceback (most recent call last):
+ ...
+ pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40))
+ not in asn1Spec
+ >>>
+ >>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
+ >>> decoder.decode(substrate)
+ (Any(b'\x9f(\x0209'), '')
+ >>>
+
+It's also possible to configure a custom decoder, to handle unknown
+tags found in substrate. This can be done by means of
+*defaultRawDecoder* attribute holding a reference to type decoder
+object. Refer to the source for API details.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/bmpstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: BMPString
+
+.. |encoding| replace:: utf-16-be
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.BMPString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-16 big endian.
+
+ .. automethod:: pyasn1.type.char.BMPString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.BMPString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/contents.rst
@@ -0,0 +1,20 @@
+
+Character types
+---------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/char/numericstring
+ /docs/type/char/printablestring
+ /docs/type/char/teletexstring
+ /docs/type/char/t61string
+ /docs/type/char/videotexstring
+ /docs/type/char/ia5string
+ /docs/type/char/graphicstring
+ /docs/type/char/visiblestring
+ /docs/type/char/iso646string
+ /docs/type/char/generalstring
+ /docs/type/char/universalstring
+ /docs/type/char/bmpstring
+ /docs/type/char/utf8string
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/generalstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: GeneralString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.GeneralString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a character string similar to :py:class:`GraphicString` but additionally
+ including control characters.
+
+ .. automethod:: pyasn1.type.char.GeneralString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.GeneralString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/graphicstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: GraphicString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.GraphicString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a character string that can hold any "graphical" characters
+ mixed with control ones to select particular alphabet.
+
+ .. automethod:: pyasn1.type.char.GraphicString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.GraphicString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/ia5string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: IA5String
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.IA5String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a basic character string first published in 1963 as an ISO/ITU standard, then it turned into ASCII.
+
+ .. automethod:: pyasn1.type.char.IA5String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.IA5String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/iso646string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: ISO646String
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.ISO646String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type is an alias to the :py:class:`VisibleString` type
+
+ .. automethod:: pyasn1.type.char.ISO646String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.ISO646String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/numericstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: NumericString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.NumericString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| models character string that can be entered from a telephone handset.
+
+ .. automethod:: pyasn1.type.char.NumericString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.NumericString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/printablestring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: PrintableString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.PrintableString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| models character string that can be entered from a very rudimentary terminals featuring letters,
+ digits and punctuation marks.
+
+ .. automethod:: pyasn1.type.char.PrintableString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.PrintableString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/t61string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: T61String
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.T61String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type is an alias to :py:class:`TeletexString` type.
+
+ .. automethod:: pyasn1.type.char.T61String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.T61String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/teletexstring.rst
@@ -0,0 +1,19 @@
+
+.. |ASN.1| replace:: TeletexString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.TeletexString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models character string that can be entered from a sophisticated text processing machines
+ (by 20-th century standards) featuring letters from multiple alphabets (308 characters!), digits,
+ punctuation marks and escape sequences.
+
+ .. automethod:: pyasn1.type.char.TeletexString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.TeletexString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/universalstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: UniversalString
+
+.. |encoding| replace:: utf-32-be
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.UniversalString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-32 big endian.
+
+ .. automethod:: pyasn1.type.char.UniversalString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.UniversalString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/utf8string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: UTF8String
+
+.. |encoding| replace:: utf-8
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.UTF8String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-8.
+
+ .. automethod:: pyasn1.type.char.UTF8String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.UTF8String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/videotexstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: VideotexString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.VideotexString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models character string that can be consumed by sophisticated video
+ terminals (by 20-th century standards) to render ascii-art style pictures and animations.
+
+ .. automethod:: pyasn1.type.char.VideotexString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.VideotexString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/visiblestring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: VisibleString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.VisibleString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+ .. note::
+
+ The |ASN.1| type models a character string that can hold any "graphical" characters
+ mixed with control ones to select particular alphabet.
+
+ .. automethod:: pyasn1.type.char.VisibleString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.char.VisibleString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/contents.rst
@@ -0,0 +1,11 @@
+
+Fields of constructed types
+---------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/namedtype/namedtype
+ /docs/type/namedtype/optionalnamedtype
+ /docs/type/namedtype/defaultednamedtype
+ /docs/type/namedtype/namedtypes
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/defaultednamedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: DefaultedNamedType
+
+|NamedType|
+------------------
+
+.. autoclass:: pyasn1.type.namedtype.DefaultedNamedType
+ :members:
+
+ .. note::
+
+ The |NamedType| class models named field of a constructed ASN.1 type which has a default value.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: NamedType
+
+|NamedType|
+-----------
+
+.. autoclass:: pyasn1.type.namedtype.NamedType
+ :members:
+
+ .. note::
+
+ The |NamedType| class models a mandatory field of a constructed ASN.1 type.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtypes.rst
@@ -0,0 +1,6 @@
+
+NamedTypes
+----------
+
+.. autoclass:: pyasn1.type.namedtype.NamedTypes
+ :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/optionalnamedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: OptionalNamedType
+
+|NamedType|
+------------------
+
+.. autoclass:: pyasn1.type.namedtype.OptionalNamedType
+ :members:
+
+ .. note::
+
+ The |NamedType| class models an optional field of a constructed ASN.1 type.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedval/contents.rst
@@ -0,0 +1,13 @@
+
+Enumerating numbers
+-------------------
+
+Some ASN.1 types such as :py:class:`~pyasn1.type.univ.Integer`,
+:py:class:`~pyasn1.type.univ.Enumerated` and
+:py:class:`~pyasn1.type.univ.BitString` may enumerate their values
+with human-friendly labels.
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/namedval/namedval
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedval/namedval.rst
@@ -0,0 +1,11 @@
+
+.. |NamedValues| replace:: NamedValues
+
+|NamedValues|
+-------------
+
+The |NamedValues| class associates human-friendly names to a set of numbers
+or bits.
+
+.. autoclass:: pyasn1.type.namedval.NamedValues
+ :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/contents.rst
@@ -0,0 +1,10 @@
+
+Tagging types
+-------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/tag/tag
+ /docs/type/tag/tagset
+ /docs/type/tag/tagmap
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tag.rst
@@ -0,0 +1,8 @@
+
+Solitary tag
+------------
+
+.. automodule:: pyasn1.type.tag
+ :members: Tag, tagClassUniversal, tagClassApplication, tagClassContext,
+ tagClassPrivate, tagFormatSimple, tagFormatConstructed
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tagmap.rst
@@ -0,0 +1,6 @@
+
+Tag->type map
+-------------
+
+.. autoclass:: pyasn1.type.tagmap.TagMap
+ :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tagset.rst
@@ -0,0 +1,6 @@
+
+Composition of tags
+-------------------
+
+.. autoclass:: pyasn1.type.tag.TagSet
+ :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/any.rst
@@ -0,0 +1,20 @@
+
+.. |ASN.1| replace:: Any
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Any(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1', binValue=NoValue(),hexValue=NoValue())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+ .. note::
+
+ The |ASN.1| type models an arbitrary value of an arbitrary type. Sometimes
+ type is defined by accompanying object identifier or an integer identifier.
+ Frequently ANY value holds a serialized representation of some other ASN.1
+ object.
+
+ .. automethod:: pyasn1.type.univ.Any.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1')
+ .. automethod:: pyasn1.type.univ.Any.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(),encoding='iso-8859-1')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/bitstring.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: BitString
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.BitString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, asInteger, asNumbers, asOctets, asBinary, fromHexString, fromBinaryString, fromOctetString
+
+ .. note::
+
+ The |ASN.1| type models an arbitrary sequence of bits.
+
+ .. automethod:: pyasn1.type.univ.BitString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
+ .. automethod:: pyasn1.type.univ.BitString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), , namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/boolean.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Boolean
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Boolean(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+ .. note::
+
+ The |ASN.1| type models a BOOLEAN that can be either TRUE or FALSE.
+
+ .. automethod:: pyasn1.type.univ.Boolean.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.Boolean.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/choice.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Choice
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Choice(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+ getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
+ getComponentByType, setComponentByType, getName, getComponent
+
+ .. note::
+
+ The |ASN.1| type can only hold a single component at a time belonging to the list of allowed types.
+
+ .. automethod:: pyasn1.type.univ.Choice.clone(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.Choice.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/contents.rst
@@ -0,0 +1,23 @@
+
+Universal types
+---------------
+
+.. autoclass:: pyasn1.type.univ.NoValue()
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/univ/integer
+ /docs/type/univ/boolean
+ /docs/type/univ/bitstring
+ /docs/type/univ/octetstring
+ /docs/type/univ/null
+ /docs/type/univ/objectidentifier
+ /docs/type/univ/real
+ /docs/type/univ/enumerated
+ /docs/type/univ/any
+ /docs/type/univ/setof
+ /docs/type/univ/sequenceof
+ /docs/type/univ/set
+ /docs/type/univ/sequence
+ /docs/type/univ/choice
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/enumerated.rst
@@ -0,0 +1,16 @@
+
+.. |ASN.1| replace:: Enumerated
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Enumerated(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, namedValues
+
+ .. note::
+
+ The |ASN.1| type models bounded set of named integer values. Other than that, it is identical to
+ the *Integer* class.
+
+ .. automethod:: pyasn1.type.univ.Enumerated.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+ .. automethod:: pyasn1.type.univ.Enumerated.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/integer.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Integer
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Integer(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap,
+ subtypeSpec, namedValues
+
+ .. note::
+
+ The |ASN.1| type models an arbitrary integer. INTEGER values can be positive, negative,
+ or zero, and can have any magnitude.
+
+ .. automethod:: pyasn1.type.univ.Integer.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+ .. automethod:: pyasn1.type.univ.Integer.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/null.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Null
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Null(value=NoValue(), tagSet=TagSet())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+ .. note::
+
+ The |ASN.1| type models ASN.1 NULL.
+
+ .. automethod:: pyasn1.type.univ.Null.clone(value=NoValue(), tagSet=TagSet())
+ .. automethod:: pyasn1.type.univ.Null.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/objectidentifier.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: ObjectIdentifier
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.ObjectIdentifier(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, isPrefixOf
+
+ .. note::
+
+ The |ASN.1| type models ASN.1 OBJECT IDENTIFIER as a sequence of integer numbers.
+
+ .. automethod:: pyasn1.type.univ.ObjectIdentifier.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.ObjectIdentifier.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/octetstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: OctetString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.OctetString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1', binValue=NoValue(),hexValue=NoValue())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, fromHexString, fromBinaryString
+
+ .. note::
+
+ The |ASN.1| type models an arbitrary string of octets (eight-bit numbers), not printable text string.
+
+ .. automethod:: pyasn1.type.univ.OctetString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1')
+ .. automethod:: pyasn1.type.univ.OctetString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(),encoding='iso-8859-1')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/real.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Real
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Real(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, isInf, isPlusInf, isMinusInf
+
+ .. note::
+
+ The |ASN.1| type models a rational number of arbitrary precision.
+
+ .. automethod:: pyasn1.type.univ.Real.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.Real.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/sequence.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Sequence
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Sequence(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec, getComponentByPosition,
+ setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents
+
+ .. note::
+
+ The |ASN.1| type models a collection of named ASN.1 components.
+ Ordering of the components **is** preserved upon de/serialization.
+
+ .. automethod:: pyasn1.type.univ.Sequence.clone(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.Sequence.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/sequenceof.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: SequenceOf
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.SequenceOf(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+ getComponentByPosition, setComponentByPosition
+
+ .. note::
+
+ The |ASN.1| type models a collection of elements of a single ASN.1 type.
+ Ordering of the components **is** preserved upon de/serialization.
+
+ .. automethod:: pyasn1.type.univ.SequenceOf.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.SequenceOf.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/set.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: Set
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Set(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+ getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
+ getComponentByType, setComponentByType
+
+ .. note::
+
+ The |ASN.1| type models a collection of named ASN.1 components.
+ Ordering of the components **is not** preserved upon de/serialization.
+
+ .. automethod:: pyasn1.type.univ.Set.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.Set.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/setof.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: SetOf
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.SetOf(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+ getComponentByPosition, setComponentByPosition
+
+ .. note::
+
+ The |ASN.1| type models a collection of elements of a single ASN.1 type.
+ Ordering of the components **is not** preserved upon de/serialization.
+
+ .. automethod:: pyasn1.type.univ.SetOf.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+ .. automethod:: pyasn1.type.univ.SetOf.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/contents.rst
@@ -0,0 +1,10 @@
+
+Useful types
+------------
+
+.. toctree::
+ :maxdepth: 2
+
+ /docs/type/useful/objectdescriptor
+ /docs/type/useful/generalizedtime
+ /docs/type/useful/utctime
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/generalizedtime.rst
@@ -0,0 +1,35 @@
+
+.. |ASN.1| replace:: GeneralizedTime
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.GeneralizedTime(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, asDateTime, fromDateTime
+
+ .. note::
+
+
+ The |ASN.1| type models a character string representing date and time
+ in many different formats.
+
+ Formal syntax for the *GeneralizedTime* value is:
+
+ * **YYYYMMDDhh[mm[ss[(.|,)ffff]]]** standing for a local time, four
+ digits for the year, two for the month, two for the day and two
+ for the hour, followed by two digits for the minutes and two
+ for the seconds if required, then a dot (or a comma), and a
+ number for the fractions of second or
+
+ * a string as above followed by the letter “Z” (denoting a UTC
+ time) or
+
+ * a string as above followed by a string **(+|-)hh[mm]** denoting
+ time zone offset relative to UTC
+
+ For example, *20170126120000Z* stands for YYYYMMDDHHMMSSZ.
+
+ .. automethod:: pyasn1.type.useful.GeneralizedTime.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.useful.GeneralizedTime.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/objectdescriptor.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: ObjectDescriptor
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.ObjectDescriptor(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet
+
+ .. note::
+
+ The |ASN.1| type models a character string that can accompany the *ObjectIdentifier* type
+ to serve as a human-friendly annotation for an OBJECT IDENTIFIER.
+
+ .. automethod:: pyasn1.type.useful.ObjectDescriptor.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.useful.ObjectDescriptor.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/utctime.rst
@@ -0,0 +1,32 @@
+
+.. |ASN.1| replace:: UTCTime
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.UTCTime(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, asDateTime, fromDateTime
+
+ .. note::
+
+ The |ASN.1| type models a character string representing date and time.
+
+ Formal syntax for the *UTCTime* value is:
+
+ * **YYMMDDhhmm[ss]** standing for UTC time, two
+ digits for the year, two for the month, two for the day and two
+ for the hour, followed by two digits for the minutes and two
+ for the seconds if required or
+
+ * a string as above followed by the letter “Z” (denoting a UTC
+ time) or
+
+ * a string as above followed by a string **(+|-)hhmm** denoting
+ time zone offset relative to UTC
+
+ For example, *170126120000Z* which stands for YYMMDDHHMMSSZ.
+
+ .. automethod:: pyasn1.type.useful.UTCTime.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+ .. automethod:: pyasn1.type.useful.UTCTime.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/example-use-case.rst
@@ -0,0 +1,193 @@
+
+Example use case
+================
+
+.. toctree::
+ :maxdepth: 2
+
+To briefly explain how to approach pyasn1, consider a quick workflow example.
+
+Grab ASN.1 schema for SSH keys
+------------------------------
+
+ASN.1 is widely used in many Internet protocols. Frequently, whenever ASN.1 is employed,
+data structures are described in ASN.1 schema language right in the RFC.
+Take `RFC2437 <https://www.ietf.org/rfc/rfc2437.txt>`_ for example -- we can look into
+it and weed out data structures specification into a local file:
+
+.. code-block:: python
+
+ # pkcs-1.asn
+
+ PKCS-1 {iso(1) member(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) modules(0) pkcs-1(1)}
+
+ DEFINITIONS EXPLICIT TAGS ::= BEGIN
+ RSAPrivateKey ::= SEQUENCE {
+ version Version,
+ modulus INTEGER,
+ publicExponent INTEGER,
+ privateExponent INTEGER,
+ prime1 INTEGER,
+ prime2 INTEGER,
+ exponent1 INTEGER,
+ exponent2 INTEGER,
+ coefficient INTEGER
+ }
+ Version ::= INTEGER
+ END
+
+Compile ASN.1 schema into Python
+--------------------------------
+
+In the best case, you should be able to automatically compile ASN.1 spec into
+Python classes. For that purpose we have the `asn1ate <https://github.com/kimgr/asn1ate>`_
+tool:
+
+.. code-block:: bash
+
+ $ pyasn1gen.py pkcs-1.asn > rsakey.py
+
+Though it may not work out as, as it stands now, asn1ate does not support
+all ASN.1 language constructs.
+
+Alternatively, you could check out the `pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_
+package to see if it already has the ASN.1 spec you are looking for compiled and shipped
+there. Then just install the package, import the data structure you need and use it:
+
+.. code-block:: bash
+
+ $ pip install pyasn1-modules
+
+As a last resort, you could express ASN.1 in Python by hand. The end result
+should be a declarative Python code resembling original ASN.1 syntax like
+this:
+
+.. code-block:: python
+
+ # rsakey.py
+
+ class Version(Integer):
+ pass
+
+ class RSAPrivateKey(Sequence):
+ componentType = NamedTypes(
+ NamedType('version', Version()),
+ NamedType('modulus', Integer()),
+ NamedType('publicExponent', Integer()),
+ NamedType('privateExponent', Integer()),
+ NamedType('prime1', Integer()),
+ NamedType('prime2', Integer()),
+ NamedType('exponent1', Integer()),
+ NamedType('exponent2', Integer()),
+ NamedType('coefficient', Integer())
+ )
+
+Read your ~/.ssh/id_rsa
+-----------------------
+
+Given we've put our Python classes into the `rsakey.py` module, we could import
+the top-level object for SSH keys container and initialize it from our
+`~/.ssh/id_rsa` file (for sake of simplicity here we assume no passphrase is
+set on the key file):
+
+.. code-block:: python
+
+ from base64 import b64decode
+ from pyasn1.codec.der.decoder import decode as der_decoder
+ from rsakey import RSAPrivateKey
+
+ # Read SSH key from file (assuming no passphrase)
+ with open open('.ssh/id_rsa') as key_file:
+ b64_serialization = ''.join(key_file.readlines()[1:-1])
+
+ # Undo BASE64 serialization
+ der_serialization = b64decode(b64_serialization)
+
+ # Undo DER serialization, reconstruct SSH key structure
+ private_key, rest_of_input = der_decoder(der_serialization, asn1Spec=RSAPrivateKey())
+
+Once we have Python ASN.1 structures initialized, we could inspect them:
+
+.. code-block:: pycon
+
+ >>> print(private_key.prettyPrint())
+ RSAPrivateKey:
+ version=0
+ modulus=280789907761334970323210643584308373...
+ publicExponent=65537
+ privateExponent=1704567874679144879123080924...
+ prime1=1780178536719561265324798296279384073...
+ prime2=1577313184995269616049017780493740138...
+ exponent1=1193974819720845247396384239609024...
+ exponent2=9240965721817961178848297404494811...
+ coefficient=10207364473358910343346707141115...
+
+Play with the keys
+------------------
+
+As well as use them nearly as we do with native Python types:
+
+.. code-block:: pycon
+
+ >>> pk = private_key
+ >>>
+ >>> pk['prime1'] * pk['prime2'] == pk['modulus']
+ True
+ >>> pk['prime1'] == pk['modulus'] // pk['prime2']
+ True
+ >>> pk['exponent1'] == pk['privateExponent'] % (pk['prime1'] - 1)
+ True
+ >>> pk['exponent2'] == pk['privateExponent'] % (pk['prime2'] - 1)
+ True
+
+Technically, pyasn1 classes `emulate <https://docs.python.org/3/reference/datamodel.html#emulating-container-types>`_
+Python built-in types.
+
+Transform to built-ins
+----------------------
+
+ASN.1 data structures exhibit a way more complicated behaviour compared to
+Python types. You may wish to simplify things by turning the whole tree of
+pyasn1 objects into an analogous tree made of base Python types:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.codec.native.encoder import encode
+ >>> ...
+ >>> py_private_key = encode(private_key)
+ >>> py_private_key
+ {'version': 0, 'modulus': 280789907761334970323210643584308373, 'publicExponent': 65537,
+ 'privateExponent': 1704567874679144879123080924, 'prime1': 1780178536719561265324798296279384073,
+ 'prime2': 1577313184995269616049017780493740138, 'exponent1': 1193974819720845247396384239609024,
+ 'exponent2': 9240965721817961178848297404494811, 'coefficient': 10207364473358910343346707141115}
+
+You can do vice-versa: initialize ASN.1 structure from a dict:
+
+.. code-block:: pycon
+
+ >>> from pyasn1.codec.native.decoder import decode
+ >>> py_private_key = {'modulus': 280789907761334970323210643584308373}
+ >>> private_key = decode(py_private_key, asn1Spec=RSAPrivateKey())
+
+Write it back
+-------------
+
+Possibly not that applicable to the SSH key example, but you can of course modify
+any part of the ASN.1 data structure and serialize it back into the same or other
+wire representation:
+
+.. code-block:: python
+
+ from pyasn1.codec.der.encoder import encode as der_encoder
+
+ # Serialize SSH key data structure into DER stream
+ der_serialization = der_encoder(private_key)
+
+ # Serialize DER stream into BASE64 stream
+ b64_serialization = '-----BEGIN RSA PRIVATE KEY-----\n'
+ b64_serialization += b64encode(der_serialization)
+ b64_serialization += '-----END RSA PRIVATE KEY-----\n'
+
+ with open('.ssh/id_rsa.new', 'w') as key_file:
+ key_file.write(b64_serialization)
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/license.rst
@@ -0,0 +1,6 @@
+.. _license:
+
+License
+=======
+
+.. include:: ../../LICENSE.rst
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/tagging.html
+++ /dev/null
@@ -1,233 +0,0 @@
-<html>
-<title>
-Tagging in PyASN1
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-<a name="1.2"></a>
-<h4>
-1.2 Tagging in PyASN1
-</h4>
-
-<p>
-In order to continue with the Constructed ASN.1 types, we will first have
-to introduce the concept of tagging (and its pyasn1 implementation), as
-some of the Constructed types rely upon the tagging feature.
-</p>
-
-<p>
-When a value is coming into an ASN.1-based system (received from a network
-or read from some storage), the receiving entity has to determine the
-type of the value to interpret and verify it accordingly.
-</p>
-
-<p>
-Historically, the first data serialization protocol introduced in
-ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
-value is packed into a triplet of (Type, Length, Value) where Type is a
-code that identifies the value (which is called <i>tag</i> in ASN.1),
-length is the number of bytes occupied by the value in its serialized form
-and value is ASN.1 value in a form suitable for serial transmission or storage.
-</p>
-
-<p>
-For that reason almost every ASN.1 type has a tag (which is actually a
-BER type) associated with it by default.
-</p>
-
-<p>
-An ASN.1 tag could be viewed as a tuple of three numbers:
-(Class, Format, Number). While Number identifies a tag, Class component
-is used to create scopes for Numbers. Four scopes are currently defined:
-UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
-is actually a one-bit flag - zero for tags associated with scalar types,
-and one for constructed types (will be discussed later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] INTEGER
-MyOctetString ::= [APPLICATION 0] OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, tags are implemented as immutable, tuple-like objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
->>> myTag
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tuple(myTag)
-(128, 0, 10)
->>> myTag[2]
-10
->>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Default tag, associated with any ASN.1 type, could be extended or replaced
-to make new type distinguishable from its ancestor. The standard provides
-two modes of tag mangling - IMPLICIT and EXPLICIT.
-</p>
-
-<p>
-EXPLICIT mode works by appending new tag to the existing ones thus creating
-an ordered set of tags. This set will be considered as a whole for type
-identification and encoding purposes. Important property of EXPLICIT tagging
-mode is that it preserves base type information in encoding what makes it
-possible to completely recover type information from encoding.
-</p>
-
-<p>
-When tagging in IMPLICIT mode, the outermost existing tag is dropped and
-replaced with a new one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] IMPLICIT INTEGER
-MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-To model both modes of tagging, a specialized container TagSet object (holding
-zero, one or more Tag objects) is used in pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet = tag.TagSet(
-... # base tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10),
-... # effective tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10))
->>> tagSet.getBaseTag()
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tagSet = tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20))
->>> tagSet = tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20),
- Tag(tagClass=128, tagFormat=32, tagId=30))
->>> tagSet = tagSet.tagImplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
- Tag(tagClass=128, tagFormat=32, tagId=20),
- Tag(tagClass=128, tagFormat=32, tagId=40))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As a side note: the "base tag" concept (accessible through the getBaseTag()
-method) is specific to pyasn1 -- the base tag is used to identify the original
-ASN.1 type of an object in question. Base tag is never occurs in encoding
-and is mostly used internally by pyasn1 for choosing type-specific data
-processing algorithms. The "effective tag" is the one that always appears in
-encoding and is used on tagSets comparation.
-</p>
-
-<p>
-Any two TagSet objects could be compared to see if one is a derivative
-of the other. Figuring this out is also useful in cases when a type-specific
-data processing algorithms are to be chosen.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet1 = tag.TagSet(
-... # base tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-... # effective tag
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-... )
->>> tagSet2 = tagSet1.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet1.isSuperTagSetOf(tagSet2)
-True
->>> tagSet2.isSuperTagSetOf(tagSet1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-We will complete this discussion on tagging with a real-world example. The
-following ASN.1 tagged type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] EXPLICIT INTEGER
-</pre>
-</td></tr></table>
-
-<p>
-could be expressed in pyasn1 like this:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> class MyIntegerType(univ.Integer):
-... tagSet = univ.Integer.tagSet.tagExplicitly(
-... tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12)
-... )
->>> myInteger = MyIntegerType(12345)
->>> myInteger.getTagSet()
-TagSet(Tag(tagClass=0, tagFormat=0, tagId=2),
- Tag(tagClass=128, tagFormat=32, tagId=12))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Referring to the above code, the tagSet class attribute is a property of any
-pyasn1 type object that assigns default tagSet to a pyasn1 value object. This
-default tagSet specification can be ignored and effectively replaced by some
-other tagSet value passed on object instantiation.
-</p>
-
-<p>
-It's important to understand that the tag set property of pyasn1 type/value
-object can never be modifed in place. In other words, a pyasn1 type/value
-object can never change its tags. The only way is to create a new pyasn1
-type/value object and associate different tag set with it.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
--- a/third_party/python/pyasn1/pyasn1.egg-info/PKG-INFO
+++ b/third_party/python/pyasn1/pyasn1.egg-info/PKG-INFO
@@ -1,26 +1,33 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
Name: pyasn1
-Version: 0.1.7
+Version: 0.3.7
Summary: ASN.1 types and codecs
-Home-page: http://sourceforge.net/projects/pyasn1/
-Author: Ilya Etingof <ilya@glas.net>
-Author-email: ilya@glas.net
+Home-page: https://github.com/etingof/pyasn1
+Author: Ilya Etingof <etingof@gmail.com>
+Author-email: etingof@gmail.com
License: BSD
-Description: A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
+Description: Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Telecommunications Industry
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Communications
-Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
--- a/third_party/python/pyasn1/pyasn1.egg-info/SOURCES.txt
+++ b/third_party/python/pyasn1/pyasn1.egg-info/SOURCES.txt
@@ -1,22 +1,71 @@
-CHANGES
-LICENSE
+CHANGES.rst
+LICENSE.rst
MANIFEST.in
-README
-THANKS
-TODO
+README.md
+TODO.rst
+setup.cfg
setup.py
-doc/codecs.html
-doc/constraints.html
-doc/constructed.html
-doc/intro.html
-doc/pyasn1-tutorial.html
-doc/scalar.html
-doc/tagging.html
+doc/Makefile
+doc/source/changelog.rst
+doc/source/conf.py
+doc/source/contents.rst
+doc/source/example-use-case.rst
+doc/source/license.rst
+doc/source/docs/api-reference.rst
+doc/source/docs/tutorial.rst
+doc/source/docs/codec/ber/contents.rst
+doc/source/docs/codec/cer/contents.rst
+doc/source/docs/codec/der/contents.rst
+doc/source/docs/codec/native/contents.rst
+doc/source/docs/type/char/bmpstring.rst
+doc/source/docs/type/char/contents.rst
+doc/source/docs/type/char/generalstring.rst
+doc/source/docs/type/char/graphicstring.rst
+doc/source/docs/type/char/ia5string.rst
+doc/source/docs/type/char/iso646string.rst
+doc/source/docs/type/char/numericstring.rst
+doc/source/docs/type/char/printablestring.rst
+doc/source/docs/type/char/t61string.rst
+doc/source/docs/type/char/teletexstring.rst
+doc/source/docs/type/char/universalstring.rst
+doc/source/docs/type/char/utf8string.rst
+doc/source/docs/type/char/videotexstring.rst
+doc/source/docs/type/char/visiblestring.rst
+doc/source/docs/type/namedtype/contents.rst
+doc/source/docs/type/namedtype/defaultednamedtype.rst
+doc/source/docs/type/namedtype/namedtype.rst
+doc/source/docs/type/namedtype/namedtypes.rst
+doc/source/docs/type/namedtype/optionalnamedtype.rst
+doc/source/docs/type/namedval/contents.rst
+doc/source/docs/type/namedval/namedval.rst
+doc/source/docs/type/tag/contents.rst
+doc/source/docs/type/tag/tag.rst
+doc/source/docs/type/tag/tagmap.rst
+doc/source/docs/type/tag/tagset.rst
+doc/source/docs/type/univ/any.rst
+doc/source/docs/type/univ/bitstring.rst
+doc/source/docs/type/univ/boolean.rst
+doc/source/docs/type/univ/choice.rst
+doc/source/docs/type/univ/contents.rst
+doc/source/docs/type/univ/enumerated.rst
+doc/source/docs/type/univ/integer.rst
+doc/source/docs/type/univ/null.rst
+doc/source/docs/type/univ/objectidentifier.rst
+doc/source/docs/type/univ/octetstring.rst
+doc/source/docs/type/univ/real.rst
+doc/source/docs/type/univ/sequence.rst
+doc/source/docs/type/univ/sequenceof.rst
+doc/source/docs/type/univ/set.rst
+doc/source/docs/type/univ/setof.rst
+doc/source/docs/type/useful/contents.rst
+doc/source/docs/type/useful/generalizedtime.rst
+doc/source/docs/type/useful/objectdescriptor.rst
+doc/source/docs/type/useful/utctime.rst
pyasn1/__init__.py
pyasn1/debug.py
pyasn1/error.py
pyasn1.egg-info/PKG-INFO
pyasn1.egg-info/SOURCES.txt
pyasn1.egg-info/dependency_links.txt
pyasn1.egg-info/top_level.txt
pyasn1.egg-info/zip-safe
@@ -26,43 +75,65 @@ pyasn1/codec/ber/decoder.py
pyasn1/codec/ber/encoder.py
pyasn1/codec/ber/eoo.py
pyasn1/codec/cer/__init__.py
pyasn1/codec/cer/decoder.py
pyasn1/codec/cer/encoder.py
pyasn1/codec/der/__init__.py
pyasn1/codec/der/decoder.py
pyasn1/codec/der/encoder.py
+pyasn1/codec/native/__init__.py
+pyasn1/codec/native/decoder.py
+pyasn1/codec/native/encoder.py
pyasn1/compat/__init__.py
+pyasn1/compat/binary.py
+pyasn1/compat/calling.py
+pyasn1/compat/dateandtime.py
+pyasn1/compat/integer.py
pyasn1/compat/octets.py
+pyasn1/compat/string.py
pyasn1/type/__init__.py
pyasn1/type/base.py
pyasn1/type/char.py
pyasn1/type/constraint.py
pyasn1/type/error.py
pyasn1/type/namedtype.py
pyasn1/type/namedval.py
pyasn1/type/tag.py
pyasn1/type/tagmap.py
pyasn1/type/univ.py
pyasn1/type/useful.py
-test/__init__.py
-test/suite.py
-test/codec/__init__.py
-test/codec/suite.py
-test/codec/ber/__init__.py
-test/codec/ber/suite.py
-test/codec/ber/test_decoder.py
-test/codec/ber/test_encoder.py
-test/codec/cer/__init__.py
-test/codec/cer/suite.py
-test/codec/cer/test_decoder.py
-test/codec/cer/test_encoder.py
-test/codec/der/__init__.py
-test/codec/der/suite.py
-test/codec/der/test_decoder.py
-test/codec/der/test_encoder.py
-test/type/__init__.py
-test/type/suite.py
-test/type/test_constraint.py
-test/type/test_namedtype.py
-test/type/test_tag.py
-test/type/test_univ.py
\ No newline at end of file
+tests/__init__.py
+tests/__main__.py
+tests/base.py
+tests/test_debug.py
+tests/codec/__init__.py
+tests/codec/__main__.py
+tests/codec/ber/__init__.py
+tests/codec/ber/__main__.py
+tests/codec/ber/test_decoder.py
+tests/codec/ber/test_encoder.py
+tests/codec/cer/__init__.py
+tests/codec/cer/__main__.py
+tests/codec/cer/test_decoder.py
+tests/codec/cer/test_encoder.py
+tests/codec/der/__init__.py
+tests/codec/der/__main__.py
+tests/codec/der/test_decoder.py
+tests/codec/der/test_encoder.py
+tests/codec/native/__init__.py
+tests/codec/native/__main__.py
+tests/codec/native/test_decoder.py
+tests/codec/native/test_encoder.py
+tests/compat/__init__.py
+tests/compat/__main__.py
+tests/compat/test_binary.py
+tests/compat/test_integer.py
+tests/compat/test_octets.py
+tests/type/__init__.py
+tests/type/__main__.py
+tests/type/test_char.py
+tests/type/test_constraint.py
+tests/type/test_namedtype.py
+tests/type/test_namedval.py
+tests/type/test_tag.py
+tests/type/test_univ.py
+tests/type/test_useful.py
\ No newline at end of file
--- a/third_party/python/pyasn1/pyasn1/__init__.py
+++ b/third_party/python/pyasn1/pyasn1/__init__.py
@@ -1,8 +1,7 @@
import sys
# http://www.python.org/dev/peps/pep-0396/
-__version__ = '0.1.7'
+__version__ = '0.3.7'
if sys.version_info[:2] < (2, 4):
- raise RuntimeError('PyASN1 requires Python 2.4 or later')
-
+ raise RuntimeError('PyASN1 requires Python 2.4 or later')
--- a/third_party/python/pyasn1/pyasn1/codec/ber/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/decoder.py
@@ -1,683 +1,1061 @@
-# BER decoder
-from pyasn1.type import tag, base, univ, char, useful, tagmap
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import base, tag, univ, char, useful, tagmap
from pyasn1.codec.ber import eoo
-from pyasn1.compat.octets import oct2int, octs2ints, isOctetsType
+from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null
+from pyasn1.compat.integer import from_bytes
from pyasn1 import debug, error
-class AbstractDecoder:
+__all__ = ['decode']
+
+noValue = base.noValue
+
+
+class AbstractDecoder(object):
protoComponent = None
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
+
class AbstractSimpleDecoder(AbstractDecoder):
- tagFormats = (tag.tagFormatSimple,)
- def _createComponent(self, asn1Spec, tagSet, value=None):
- if tagSet[0][1] not in self.tagFormats:
- raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
+ @staticmethod
+ def substrateCollector(asn1Object, substrate, length):
+ return substrate[:length], substrate[length:]
+
+ def _createComponent(self, asn1Spec, tagSet, value=noValue):
if asn1Spec is None:
- return self.protoComponent.clone(value, tagSet)
- elif value is None:
+ return self.protoComponent.clone(value, tagSet=tagSet)
+ elif value is noValue:
return asn1Spec
else:
return asn1Spec.clone(value)
-
-class AbstractConstructedDecoder(AbstractDecoder):
- tagFormats = (tag.tagFormatConstructed,)
- def _createComponent(self, asn1Spec, tagSet, value=None):
- if tagSet[0][1] not in self.tagFormats:
- raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
- if asn1Spec is None:
- return self.protoComponent.clone(tagSet)
- else:
- return asn1Spec.clone()
-
-class EndOfOctetsDecoder(AbstractSimpleDecoder):
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- return eoo.endOfOctets, substrate[length:]
+
class ExplicitTagDecoder(AbstractSimpleDecoder):
protoComponent = univ.Any('')
- tagFormats = (tag.tagFormatConstructed,)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
if substrateFun:
return substrateFun(
- self._createComponent(asn1Spec, tagSet, ''),
- substrate, length
- )
+ self._createComponent(asn1Spec, tagSet, ''),
+ substrate, length
+ )
+
head, tail = substrate[:length], substrate[length:]
- value, _ = decodeFun(head, asn1Spec, tagSet, length)
+
+ value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)
+
return value, tail
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
if substrateFun:
return substrateFun(
- self._createComponent(asn1Spec, tagSet, ''),
- substrate, length
- )
- value, substrate = decodeFun(substrate, asn1Spec, tagSet, length)
- terminator, substrate = decodeFun(substrate)
- if eoo.endOfOctets.isSameTypeWith(terminator) and \
- terminator == eoo.endOfOctets:
+ self._createComponent(asn1Spec, tagSet, ''),
+ substrate, length
+ )
+
+ value, substrate = decodeFun(substrate, asn1Spec, tagSet, length, **options)
+
+ eooMarker, substrate = decodeFun(substrate, allowEoo=True, **options)
+
+ if eooMarker is eoo.endOfOctets:
return value, substrate
else:
raise error.PyAsn1Error('Missing end-of-octets terminator')
+
explicitTagDecoder = ExplicitTagDecoder()
+
class IntegerDecoder(AbstractSimpleDecoder):
protoComponent = univ.Integer(0)
- precomputedValues = {
- '\x00': 0,
- '\x01': 1,
- '\x02': 2,
- '\x03': 3,
- '\x04': 4,
- '\x05': 5,
- '\x06': 6,
- '\x07': 7,
- '\x08': 8,
- '\x09': 9,
- '\xff': -1,
- '\xfe': -2,
- '\xfd': -3,
- '\xfc': -4,
- '\xfb': -5
- }
-
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
- state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+
+ if tagSet[0].tagFormat != tag.tagFormatSimple:
+ raise error.PyAsn1Error('Simple tag format expected')
+
head, tail = substrate[:length], substrate[length:]
+
if not head:
return self._createComponent(asn1Spec, tagSet, 0), tail
- if head in self.precomputedValues:
- value = self.precomputedValues[head]
- else:
- firstOctet = oct2int(head[0])
- if firstOctet & 0x80:
- value = -1
- else:
- value = 0
- for octet in head:
- value = value << 8 | oct2int(octet)
+
+ value = from_bytes(head, signed=True)
+
return self._createComponent(asn1Spec, tagSet, value), tail
+
class BooleanDecoder(IntegerDecoder):
protoComponent = univ.Boolean(0)
- def _createComponent(self, asn1Spec, tagSet, value=None):
+
+ def _createComponent(self, asn1Spec, tagSet, value=noValue):
return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0)
+
class BitStringDecoder(AbstractSimpleDecoder):
protoComponent = univ.BitString(())
- tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
- state, decodeFun, substrateFun):
+ supportConstructedForm = True
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
head, tail = substrate[:length], substrate[length:]
- if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
+ if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
if not head:
raise error.PyAsn1Error('Empty substrate')
trailingBits = oct2int(head[0])
if trailingBits > 7:
raise error.PyAsn1Error(
'Trailing bits overflow %s' % trailingBits
- )
+ )
head = head[1:]
- lsb = p = 0; l = len(head)-1; b = ()
- while p <= l:
- if p == l:
- lsb = trailingBits
- j = 7
- o = oct2int(head[p])
- while j >= lsb:
- b = b + ((o>>j)&0x01,)
- j = j - 1
- p = p + 1
- return self._createComponent(asn1Spec, tagSet, b), tail
- r = self._createComponent(asn1Spec, tagSet, ())
+ value = self.protoComponent.fromOctetString(head, trailingBits)
+ return self._createComponent(asn1Spec, tagSet, value), tail
+
+ if not self.supportConstructedForm:
+ raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+
+ bitString = self._createComponent(asn1Spec, tagSet)
+
if substrateFun:
- return substrateFun(r, substrate, length)
+ return substrateFun(bitString, substrate, length)
+
while head:
- component, head = decodeFun(head)
- r = r + component
- return r, tail
+ component, head = decodeFun(head, self.protoComponent, **options)
+ bitString += component
+
+ return bitString, tail
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- r = self._createComponent(asn1Spec, tagSet, '')
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ bitString = self._createComponent(asn1Spec, tagSet)
+
if substrateFun:
- return substrateFun(r, substrate, length)
+ return substrateFun(bitString, substrate, length)
+
while substrate:
- component, substrate = decodeFun(substrate)
- if eoo.endOfOctets.isSameTypeWith(component) and \
- component == eoo.endOfOctets:
+ component, substrate = decodeFun(substrate, self.protoComponent,
+ allowEoo=True, **options)
+ if component is eoo.endOfOctets:
break
- r = r + component
+
+ bitString += component
+
else:
- raise error.SubstrateUnderrunError(
- 'No EOO seen before substrate ends'
- )
- return r, substrate
+ raise error.SubstrateUnderrunError('No EOO seen before substrate ends')
+
+ return bitString, substrate
+
class OctetStringDecoder(AbstractSimpleDecoder):
protoComponent = univ.OctetString('')
- tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
- state, decodeFun, substrateFun):
+ supportConstructedForm = True
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
head, tail = substrate[:length], substrate[length:]
- if tagSet[0][1] == tag.tagFormatSimple: # XXX what tag to check?
+
+ if substrateFun:
+ return substrateFun(self._createComponent(asn1Spec, tagSet),
+ substrate, length)
+
+ if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
return self._createComponent(asn1Spec, tagSet, head), tail
- r = self._createComponent(asn1Spec, tagSet, '')
- if substrateFun:
- return substrateFun(r, substrate, length)
+
+ if not self.supportConstructedForm:
+ raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+
+ # All inner fragments are of the same type, treat them as octet string
+ substrateFun = self.substrateCollector
+
+ header = null
+
while head:
- component, head = decodeFun(head)
- r = r + component
- return r, tail
+ component, head = decodeFun(head, self.protoComponent,
+ substrateFun=substrateFun,
+ **options)
+ header += component
+
+ return self._createComponent(asn1Spec, tagSet, header), tail
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- r = self._createComponent(asn1Spec, tagSet, '')
- if substrateFun:
- return substrateFun(r, substrate, length)
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if substrateFun and substrateFun is not self.substrateCollector:
+ asn1Object = self._createComponent(asn1Spec, tagSet)
+ return substrateFun(asn1Object, substrate, length)
+
+ # All inner fragments are of the same type, treat them as octet string
+ substrateFun = self.substrateCollector
+
+ header = null
+
while substrate:
- component, substrate = decodeFun(substrate)
- if eoo.endOfOctets.isSameTypeWith(component) and \
- component == eoo.endOfOctets:
+ component, substrate = decodeFun(substrate,
+ self.protoComponent,
+ substrateFun=substrateFun,
+ allowEoo=True, **options)
+ if component is eoo.endOfOctets:
break
- r = r + component
+ header += component
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
- )
- return r, substrate
+ )
+
+ return self._createComponent(asn1Spec, tagSet, header), substrate
+
class NullDecoder(AbstractSimpleDecoder):
protoComponent = univ.Null('')
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+
+ if tagSet[0].tagFormat != tag.tagFormatSimple:
+ raise error.PyAsn1Error('Simple tag format expected')
+
head, tail = substrate[:length], substrate[length:]
- r = self._createComponent(asn1Spec, tagSet)
+
+ component = self._createComponent(asn1Spec, tagSet)
+
if head:
raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
- return r, tail
+
+ return component, tail
+
class ObjectIdentifierDecoder(AbstractSimpleDecoder):
protoComponent = univ.ObjectIdentifier(())
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
- state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if tagSet[0].tagFormat != tag.tagFormatSimple:
+ raise error.PyAsn1Error('Simple tag format expected')
+
head, tail = substrate[:length], substrate[length:]
if not head:
raise error.PyAsn1Error('Empty substrate')
- # Get the first subid
- subId = oct2int(head[0])
- oid = divmod(subId, 40)
+ head = octs2ints(head)
- index = 1
+ oid = ()
+ index = 0
substrateLen = len(head)
while index < substrateLen:
- subId = oct2int(head[index])
- index = index + 1
- if subId == 128:
- # ASN.1 spec forbids leading zeros (0x80) in sub-ID OID
- # encoding, tolerating it opens a vulnerability.
- # See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf page 7
- raise error.PyAsn1Error('Invalid leading 0x80 in sub-OID')
+ subId = head[index]
+ index += 1
+ if subId < 128:
+ oid += (subId,)
elif subId > 128:
# Construct subid from a number of octets
nextSubId = subId
subId = 0
while nextSubId >= 128:
subId = (subId << 7) + (nextSubId & 0x7F)
if index >= substrateLen:
raise error.SubstrateUnderrunError(
'Short substrate for sub-OID past %s' % (oid,)
- )
- nextSubId = oct2int(head[index])
- index = index + 1
- subId = (subId << 7) + nextSubId
- oid = oid + (subId,)
+ )
+ nextSubId = head[index]
+ index += 1
+ oid += ((subId << 7) + nextSubId,)
+ elif subId == 128:
+ # ASN.1 spec forbids leading zeros (0x80) in OID
+ # encoding, tolerating it opens a vulnerability. See
+ # http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
+ # page 7
+ raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
+
+ # Decode two leading arcs
+ if 0 <= oid[0] <= 39:
+ oid = (0,) + oid
+ elif 40 <= oid[0] <= 79:
+ oid = (1, oid[0] - 40) + oid[1:]
+ elif oid[0] >= 80:
+ oid = (2, oid[0] - 80) + oid[1:]
+ else:
+ raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
+
return self._createComponent(asn1Spec, tagSet, oid), tail
+
class RealDecoder(AbstractSimpleDecoder):
protoComponent = univ.Real()
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if tagSet[0].tagFormat != tag.tagFormatSimple:
+ raise error.PyAsn1Error('Simple tag format expected')
+
head, tail = substrate[:length], substrate[length:]
+
if not head:
return self._createComponent(asn1Spec, tagSet, 0.0), tail
- fo = oct2int(head[0]); head = head[1:]
- if fo & 0x80: # binary enoding
+
+ fo = oct2int(head[0])
+ head = head[1:]
+ if fo & 0x80: # binary encoding
+ if not head:
+ raise error.PyAsn1Error("Incomplete floating-point value")
n = (fo & 0x03) + 1
if n == 4:
n = oct2int(head[0])
+ head = head[1:]
eo, head = head[:n], head[n:]
if not eo or not head:
raise error.PyAsn1Error('Real exponent screwed')
e = oct2int(eo[0]) & 0x80 and -1 or 0
- while eo: # exponent
+ while eo: # exponent
e <<= 8
e |= oct2int(eo[0])
eo = eo[1:]
+ b = fo >> 4 & 0x03 # base bits
+ if b > 2:
+ raise error.PyAsn1Error('Illegal Real base')
+ if b == 1: # encbase = 8
+ e *= 3
+ elif b == 2: # encbase = 16
+ e *= 4
p = 0
while head: # value
p <<= 8
p |= oct2int(head[0])
head = head[1:]
- if fo & 0x40: # sign bit
+ if fo & 0x40: # sign bit
p = -p
+ sf = fo >> 2 & 0x03 # scale bits
+ p *= 2 ** sf
value = (p, 2, e)
elif fo & 0x40: # infinite value
value = fo & 0x01 and '-inf' or 'inf'
elif fo & 0xc0 == 0: # character encoding
+ if not head:
+ raise error.PyAsn1Error("Incomplete floating-point value")
try:
if fo & 0x3 == 0x1: # NR1
value = (int(head), 10, 0)
elif fo & 0x3 == 0x2: # NR2
value = float(head)
elif fo & 0x3 == 0x3: # NR3
value = float(head)
else:
raise error.SubstrateUnderrunError(
'Unknown NR (tag %s)' % fo
- )
+ )
except ValueError:
raise error.SubstrateUnderrunError(
'Bad character Real syntax'
- )
+ )
else:
raise error.SubstrateUnderrunError(
'Unknown encoding (tag %s)' % fo
- )
+ )
return self._createComponent(asn1Spec, tagSet, value), tail
-
-class SequenceDecoder(AbstractConstructedDecoder):
- protoComponent = univ.Sequence()
- def _getComponentTagMap(self, r, idx):
- try:
- return r.getComponentTagMapNearPosition(idx)
- except error.PyAsn1Error:
- return
+
+
+class AbstractConstructedDecoder(AbstractDecoder):
+ protoComponent = None
+
+
+class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
+ protoRecordComponent = None
+ protoSequenceComponent = None
- def _getComponentPositionByType(self, r, t, idx):
- return r.getComponentPositionNearType(t, idx)
-
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- head, tail = substrate[:length], substrate[length:]
- r = self._createComponent(asn1Spec, tagSet)
- idx = 0
- if substrateFun:
- return substrateFun(r, substrate, length)
- while head:
- asn1Spec = self._getComponentTagMap(r, idx)
- component, head = decodeFun(head, asn1Spec)
- idx = self._getComponentPositionByType(
- r, component.getEffectiveTagSet(), idx
- )
- r.setComponentByPosition(idx, component, asn1Spec is None)
- idx = idx + 1
- r.setDefaultComponents()
- r.verifySizeSpec()
- return r, tail
+ def _getComponentTagMap(self, asn1Object, idx):
+ raise NotImplementedError()
+
+ def _getComponentPositionByType(self, asn1Object, tagSet, idx):
+ raise NotImplementedError()
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- r = self._createComponent(asn1Spec, tagSet)
- if substrateFun:
- return substrateFun(r, substrate, length)
- idx = 0
+ def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):
+ components = []
+ componentTypes = set()
while substrate:
- asn1Spec = self._getComponentTagMap(r, idx)
- component, substrate = decodeFun(substrate, asn1Spec)
- if eoo.endOfOctets.isSameTypeWith(component) and \
- component == eoo.endOfOctets:
+ component, substrate = decodeFun(substrate, **options)
+ if component is eoo.endOfOctets:
break
- idx = self._getComponentPositionByType(
- r, component.getEffectiveTagSet(), idx
- )
- r.setComponentByPosition(idx, component, asn1Spec is None)
- idx = idx + 1
+ components.append(component)
+ componentTypes.add(component.tagSet)
+
+ # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF
+ # The heuristics is:
+ # * 0-1 component -> likely SEQUENCE OF/SET OF
+ # * 1+ components of the same type -> likely SEQUENCE OF/SET OF
+ # * otherwise -> likely SEQUENCE/SET
+ if len(components) > 1 or len(componentTypes) > 1:
+ protoComponent = self.protoRecordComponent
else:
- raise error.SubstrateUnderrunError(
- 'No EOO seen before substrate ends'
+ protoComponent = self.protoSequenceComponent
+
+ asn1Object = protoComponent.clone(
+ # construct tagSet from base tag from prototype ASN.1 object
+ # and additional tags recovered from the substrate
+ tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
+ )
+
+ for idx, component in enumerate(components):
+ asn1Object.setComponentByPosition(
+ idx, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False
+ )
+
+ return asn1Object, substrate
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if tagSet[0].tagFormat != tag.tagFormatConstructed:
+ raise error.PyAsn1Error('Constructed tag format expected')
+
+ head, tail = substrate[:length], substrate[length:]
+
+ if substrateFun is not None:
+ if asn1Spec is not None:
+ asn1Object = asn1Spec.clone()
+ elif self.protoComponent is not None:
+ asn1Object = self.protoComponent.clone(tagSet=tagSet)
+ else:
+ asn1Object = self.protoRecordComponent, self.protoSequenceComponent
+
+ return substrateFun(asn1Object, substrate, length)
+
+ if asn1Spec is None:
+ asn1Object, trailing = self._decodeComponents(
+ head, tagSet=tagSet, decodeFun=decodeFun, **options
+ )
+ if trailing:
+ raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing))
+ return asn1Object, tail
+
+ asn1Object = asn1Spec.clone()
+
+ if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):
+
+ namedTypes = asn1Object.componentType
+
+ isSetType = asn1Object.typeId == univ.Set.typeId
+ isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+
+ seenIndices = set()
+ idx = 0
+ while head:
+ if not namedTypes:
+ asn1Spec = None
+ elif isSetType:
+ asn1Spec = namedTypes.tagMapUnique
+ else:
+ try:
+ if isDeterministic:
+ asn1Spec = namedTypes[idx].asn1Object
+ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+ asn1Spec = namedTypes.getTagMapNearPosition(idx)
+ else:
+ asn1Spec = namedTypes[idx].asn1Object
+ except IndexError:
+ raise error.PyAsn1Error(
+ 'Excessive components decoded at %r' % (asn1Object,)
+ )
+
+ component, head = decodeFun(head, asn1Spec, **options)
+
+ if not isDeterministic and namedTypes:
+ if isSetType:
+ idx = namedTypes.getPositionByType(component.effectiveTagSet)
+ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+ idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
+
+ asn1Object.setComponentByPosition(
+ idx, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False
+ )
+
+ seenIndices.add(idx)
+ idx += 1
+
+ if namedTypes:
+ if not namedTypes.requiredComponents.issubset(seenIndices):
+ raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
+ else:
+ asn1Object.verifySizeSpec()
+
+ else:
+ asn1Spec = asn1Object.componentType
+ idx = 0
+ while head:
+ component, head = decodeFun(head, asn1Spec, **options)
+ asn1Object.setComponentByPosition(
+ idx, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False
)
- r.setDefaultComponents()
- r.verifySizeSpec()
- return r, substrate
+ idx += 1
+
+ asn1Object.verifySizeSpec()
+
+ return asn1Object, tail
+
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if tagSet[0].tagFormat != tag.tagFormatConstructed:
+ raise error.PyAsn1Error('Constructed tag format expected')
+
+ if substrateFun is not None:
+ if asn1Spec is not None:
+ asn1Object = asn1Spec.clone()
+ elif self.protoComponent is not None:
+ asn1Object = self.protoComponent.clone(tagSet=tagSet)
+ else:
+ asn1Object = self.protoRecordComponent, self.protoSequenceComponent
+
+ return substrateFun(asn1Object, substrate, length)
+
+ if asn1Spec is None:
+ return self._decodeComponents(
+ substrate, tagSet=tagSet, decodeFun=decodeFun, allowEoo=True, **options
+ )
+
+ asn1Object = asn1Spec.clone()
+
+ if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):
+
+ namedTypes = asn1Object.componentType
+
+ isSetType = asn1Object.typeId == univ.Set.typeId
+ isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+
+ seenIndices = set()
+ idx = 0
+ while substrate:
+ if len(namedTypes) <= idx:
+ asn1Spec = None
+ elif isSetType:
+ asn1Spec = namedTypes.tagMapUnique
+ else:
+ try:
+ if isDeterministic:
+ asn1Spec = namedTypes[idx].asn1Object
+ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+ asn1Spec = namedTypes.getTagMapNearPosition(idx)
+ else:
+ asn1Spec = namedTypes[idx].asn1Object
+ except IndexError:
+ raise error.PyAsn1Error(
+ 'Excessive components decoded at %r' % (asn1Object,)
+ )
+
+ component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
+ if component is eoo.endOfOctets:
+ break
+
+ if not isDeterministic and namedTypes:
+ if isSetType:
+ idx = namedTypes.getPositionByType(component.effectiveTagSet)
+ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+ idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
+
+ asn1Object.setComponentByPosition(
+ idx, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False
+ )
-class SequenceOfDecoder(AbstractConstructedDecoder):
- protoComponent = univ.SequenceOf()
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
+ seenIndices.add(idx)
+ idx += 1
+
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+
+ if namedTypes:
+ if not namedTypes.requiredComponents.issubset(seenIndices):
+ raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
+ else:
+ asn1Object.verifySizeSpec()
+
+ else:
+ asn1Spec = asn1Object.componentType
+ idx = 0
+ while substrate:
+ component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
+ if component is eoo.endOfOctets:
+ break
+ asn1Object.setComponentByPosition(
+ idx, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False
+ )
+ idx += 1
+ else:
+ raise error.SubstrateUnderrunError(
+ 'No EOO seen before substrate ends'
+ )
+ asn1Object.verifySizeSpec()
+
+ return asn1Object, substrate
+
+
+class SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder):
+ protoRecordComponent = univ.Sequence()
+ protoSequenceComponent = univ.SequenceOf()
+
+
+class SequenceDecoder(SequenceOrSequenceOfDecoder):
+ protoComponent = univ.Sequence()
+
+
+class SequenceOfDecoder(SequenceOrSequenceOfDecoder):
+ protoComponent = univ.SequenceOf()
+
+
+class SetOrSetOfDecoder(UniversalConstructedTypeDecoder):
+ protoRecordComponent = univ.Set()
+ protoSequenceComponent = univ.SetOf()
+
+
+class SetDecoder(SetOrSetOfDecoder):
+ protoComponent = univ.Set()
+
+
+
+class SetOfDecoder(SetOrSetOfDecoder):
+ protoComponent = univ.SetOf()
+
+
+class ChoiceDecoder(AbstractConstructedDecoder):
+ protoComponent = univ.Choice()
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
head, tail = substrate[:length], substrate[length:]
- r = self._createComponent(asn1Spec, tagSet)
+ if asn1Spec is None:
+ asn1Object = self.protoComponent.clone(tagSet=tagSet)
+ else:
+ asn1Object = asn1Spec.clone()
if substrateFun:
- return substrateFun(r, substrate, length)
- asn1Spec = r.getComponentType()
- idx = 0
- while head:
- component, head = decodeFun(head, asn1Spec)
- r.setComponentByPosition(idx, component, asn1Spec is None)
- idx = idx + 1
- r.verifySizeSpec()
- return r, tail
+ return substrateFun(asn1Object, substrate, length)
+ if asn1Object.tagSet == tagSet: # explicitly tagged Choice
+ component, head = decodeFun(
+ head, asn1Object.componentTagMap, **options
+ )
+ else:
+ component, head = decodeFun(
+ head, asn1Object.componentTagMap,
+ tagSet, length, state, **options
+ )
+ effectiveTagSet = component.effectiveTagSet
+ asn1Object.setComponentByType(
+ effectiveTagSet, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False,
+ innerFlag=False
+ )
+ return asn1Object, tail
+
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if asn1Spec is None:
+ asn1Object = self.protoComponent.clone(tagSet=tagSet)
+ else:
+ asn1Object = asn1Spec.clone()
+ if substrateFun:
+ return substrateFun(asn1Object, substrate, length)
+ if asn1Object.tagSet == tagSet: # explicitly tagged Choice
+ component, substrate = decodeFun(
+ substrate, asn1Object.componentType.tagMapUnique, **options
+ )
+ # eat up EOO marker
+ eooMarker, substrate = decodeFun(
+ substrate, allowEoo=True, **options
+ )
+ if eooMarker is not eoo.endOfOctets:
+ raise error.PyAsn1Error('No EOO seen before substrate ends')
+ else:
+ component, substrate = decodeFun(
+ substrate, asn1Object.componentType.tagMapUnique,
+ tagSet, length, state, **options
+ )
+ effectiveTagSet = component.effectiveTagSet
+ asn1Object.setComponentByType(
+ effectiveTagSet, component,
+ verifyConstraints=False,
+ matchTags=False, matchConstraints=False,
+ innerFlag=False
+ )
+ return asn1Object, substrate
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- r = self._createComponent(asn1Spec, tagSet)
+
+class AnyDecoder(AbstractSimpleDecoder):
+ protoComponent = univ.Any()
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet:
+ fullSubstrate = options['fullSubstrate']
+
+ # untagged Any container, recover inner header substrate
+ length += len(fullSubstrate) - len(substrate)
+ substrate = fullSubstrate
+
if substrateFun:
- return substrateFun(r, substrate, length)
- asn1Spec = r.getComponentType()
- idx = 0
+ return substrateFun(self._createComponent(asn1Spec, tagSet),
+ substrate, length)
+
+ head, tail = substrate[:length], substrate[length:]
+
+ return self._createComponent(asn1Spec, tagSet, value=head), tail
+
+ def indefLenValueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
+ if asn1Spec is not None and tagSet == asn1Spec.tagSet:
+ # tagged Any type -- consume header substrate
+ header = null
+ else:
+ fullSubstrate = options['fullSubstrate']
+
+ # untagged Any, recover header substrate
+ header = fullSubstrate[:-len(substrate)]
+
+ # Any components do not inherit initial tag
+ asn1Spec = self.protoComponent
+
+ if substrateFun and substrateFun is not self.substrateCollector:
+ asn1Object = self._createComponent(asn1Spec, tagSet)
+ return substrateFun(asn1Object, header + substrate, length + len(header))
+
+ # All inner fragments are of the same type, treat them as octet string
+ substrateFun = self.substrateCollector
+
while substrate:
- component, substrate = decodeFun(substrate, asn1Spec)
- if eoo.endOfOctets.isSameTypeWith(component) and \
- component == eoo.endOfOctets:
+ component, substrate = decodeFun(substrate, asn1Spec,
+ substrateFun=substrateFun,
+ allowEoo=True, **options)
+ if component is eoo.endOfOctets:
break
- r.setComponentByPosition(idx, component, asn1Spec is None)
- idx = idx + 1
+ header += component
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
- )
- r.verifySizeSpec()
- return r, substrate
-
-class SetDecoder(SequenceDecoder):
- protoComponent = univ.Set()
- def _getComponentTagMap(self, r, idx):
- return r.getComponentTagMap()
-
- def _getComponentPositionByType(self, r, t, idx):
- nextIdx = r.getComponentPositionByType(t)
- if nextIdx is None:
- return idx
- else:
- return nextIdx
-
-class SetOfDecoder(SequenceOfDecoder):
- protoComponent = univ.SetOf()
-
-class ChoiceDecoder(AbstractConstructedDecoder):
- protoComponent = univ.Choice()
- tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- head, tail = substrate[:length], substrate[length:]
- r = self._createComponent(asn1Spec, tagSet)
- if substrateFun:
- return substrateFun(r, substrate, length)
- if r.getTagSet() == tagSet: # explicitly tagged Choice
- component, head = decodeFun(
- head, r.getComponentTagMap()
- )
- else:
- component, head = decodeFun(
- head, r.getComponentTagMap(), tagSet, length, state
- )
- if isinstance(component, univ.Choice):
- effectiveTagSet = component.getEffectiveTagSet()
- else:
- effectiveTagSet = component.getTagSet()
- r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None)
- return r, tail
-
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- r = self._createComponent(asn1Spec, tagSet)
+ )
if substrateFun:
- return substrateFun(r, substrate, length)
- if r.getTagSet() == tagSet: # explicitly tagged Choice
- component, substrate = decodeFun(substrate, r.getComponentTagMap())
- eooMarker, substrate = decodeFun(substrate) # eat up EOO marker
- if not eoo.endOfOctets.isSameTypeWith(eooMarker) or \
- eooMarker != eoo.endOfOctets:
- raise error.PyAsn1Error('No EOO seen before substrate ends')
+ return header, substrate
else:
- component, substrate= decodeFun(
- substrate, r.getComponentTagMap(), tagSet, length, state
- )
- if isinstance(component, univ.Choice):
- effectiveTagSet = component.getEffectiveTagSet()
- else:
- effectiveTagSet = component.getTagSet()
- r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None)
- return r, substrate
+ return self._createComponent(asn1Spec, tagSet, header), substrate
-class AnyDecoder(AbstractSimpleDecoder):
- protoComponent = univ.Any()
- tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- if asn1Spec is None or \
- asn1Spec is not None and tagSet != asn1Spec.getTagSet():
- # untagged Any container, recover inner header substrate
- length = length + len(fullSubstrate) - len(substrate)
- substrate = fullSubstrate
- if substrateFun:
- return substrateFun(self._createComponent(asn1Spec, tagSet),
- substrate, length)
- head, tail = substrate[:length], substrate[length:]
- return self._createComponent(asn1Spec, tagSet, value=head), tail
-
- def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
- length, state, decodeFun, substrateFun):
- if asn1Spec is not None and tagSet == asn1Spec.getTagSet():
- # tagged Any type -- consume header substrate
- header = ''
- else:
- # untagged Any, recover header substrate
- header = fullSubstrate[:-len(substrate)]
-
- r = self._createComponent(asn1Spec, tagSet, header)
-
- # Any components do not inherit initial tag
- asn1Spec = self.protoComponent
-
- if substrateFun:
- return substrateFun(r, substrate, length)
- while substrate:
- component, substrate = decodeFun(substrate, asn1Spec)
- if eoo.endOfOctets.isSameTypeWith(component) and \
- component == eoo.endOfOctets:
- break
- r = r + component
- else:
- raise error.SubstrateUnderrunError(
- 'No EOO seen before substrate ends'
- )
- return r, substrate
# character string types
class UTF8StringDecoder(OctetStringDecoder):
protoComponent = char.UTF8String()
+
+
class NumericStringDecoder(OctetStringDecoder):
protoComponent = char.NumericString()
+
+
class PrintableStringDecoder(OctetStringDecoder):
protoComponent = char.PrintableString()
+
+
class TeletexStringDecoder(OctetStringDecoder):
protoComponent = char.TeletexString()
+
+
class VideotexStringDecoder(OctetStringDecoder):
protoComponent = char.VideotexString()
+
+
class IA5StringDecoder(OctetStringDecoder):
protoComponent = char.IA5String()
+
+
class GraphicStringDecoder(OctetStringDecoder):
protoComponent = char.GraphicString()
+
+
class VisibleStringDecoder(OctetStringDecoder):
protoComponent = char.VisibleString()
+
+
class GeneralStringDecoder(OctetStringDecoder):
protoComponent = char.GeneralString()
+
+
class UniversalStringDecoder(OctetStringDecoder):
protoComponent = char.UniversalString()
+
+
class BMPStringDecoder(OctetStringDecoder):
protoComponent = char.BMPString()
+
# "useful" types
+class ObjectDescriptorDecoder(OctetStringDecoder):
+ protoComponent = useful.ObjectDescriptor()
+
+
class GeneralizedTimeDecoder(OctetStringDecoder):
protoComponent = useful.GeneralizedTime()
+
+
class UTCTimeDecoder(OctetStringDecoder):
protoComponent = useful.UTCTime()
+
tagMap = {
- eoo.endOfOctets.tagSet: EndOfOctetsDecoder(),
univ.Integer.tagSet: IntegerDecoder(),
univ.Boolean.tagSet: BooleanDecoder(),
univ.BitString.tagSet: BitStringDecoder(),
univ.OctetString.tagSet: OctetStringDecoder(),
univ.Null.tagSet: NullDecoder(),
univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
univ.Enumerated.tagSet: IntegerDecoder(),
univ.Real.tagSet: RealDecoder(),
- univ.Sequence.tagSet: SequenceDecoder(), # conflicts with SequenceOf
- univ.Set.tagSet: SetDecoder(), # conflicts with SetOf
- univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
+ univ.Sequence.tagSet: SequenceOrSequenceOfDecoder(), # conflicts with SequenceOf
+ univ.Set.tagSet: SetOrSetOfDecoder(), # conflicts with SetOf
+ univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
# character string types
char.UTF8String.tagSet: UTF8StringDecoder(),
char.NumericString.tagSet: NumericStringDecoder(),
char.PrintableString.tagSet: PrintableStringDecoder(),
char.TeletexString.tagSet: TeletexStringDecoder(),
char.VideotexString.tagSet: VideotexStringDecoder(),
char.IA5String.tagSet: IA5StringDecoder(),
char.GraphicString.tagSet: GraphicStringDecoder(),
char.VisibleString.tagSet: VisibleStringDecoder(),
char.GeneralString.tagSet: GeneralStringDecoder(),
char.UniversalString.tagSet: UniversalStringDecoder(),
char.BMPString.tagSet: BMPStringDecoder(),
# useful types
+ useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),
useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
useful.UTCTime.tagSet: UTCTimeDecoder()
- }
+}
# Type-to-codec map for ambiguous ASN.1 types
typeMap = {
univ.Set.typeId: SetDecoder(),
univ.SetOf.typeId: SetOfDecoder(),
univ.Sequence.typeId: SequenceDecoder(),
univ.SequenceOf.typeId: SequenceOfDecoder(),
univ.Choice.typeId: ChoiceDecoder(),
univ.Any.typeId: AnyDecoder()
- }
+}
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+ if typeDecoder.protoComponent is not None:
+ typeId = typeDecoder.protoComponent.__class__.typeId
+ if typeId is not None and typeId not in typeMap:
+ typeMap[typeId] = typeDecoder
+
-( stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
- stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
- stDumpRawValue, stErrorCondition, stStop ) = [x for x in range(10)]
+(stDecodeTag,
+ stDecodeLength,
+ stGetValueDecoder,
+ stGetValueDecoderByAsn1Spec,
+ stGetValueDecoderByTag,
+ stTryAsExplicitTag,
+ stDecodeValue,
+ stDumpRawValue,
+ stErrorCondition,
+ stStop) = [x for x in range(10)]
-class Decoder:
+
+class Decoder(object):
defaultErrorState = stErrorCondition
-# defaultErrorState = stDumpRawValue
+ # defaultErrorState = stDumpRawValue
defaultRawDecoder = AnyDecoder()
+ supportIndefLength = True
+
+ # noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap={}):
self.__tagMap = tagMap
self.__typeMap = typeMap
- self.__endOfOctetsTagSet = eoo.endOfOctets.getTagSet()
# Tag & TagSet objects caches
self.__tagCache = {}
self.__tagSetCache = {}
-
- def __call__(self, substrate, asn1Spec=None, tagSet=None,
- length=None, state=stDecodeTag, recursiveFlag=1,
- substrateFun=None):
+ self.__eooSentinel = ints2octs((0, 0))
+
+ def __call__(self, substrate, asn1Spec=None,
+ tagSet=None, length=None, state=stDecodeTag,
+ decodeFun=None, substrateFun=None,
+ **options):
+
if debug.logger & debug.flagDecoder:
- debug.logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
+ logger = debug.logger
+ else:
+ logger = None
+
+ if logger:
+ logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
+
+ allowEoo = options.pop('allowEoo', False)
+
+ # Look for end-of-octets sentinel
+ if allowEoo and self.supportIndefLength:
+ if substrate[:2] == self.__eooSentinel:
+ if logger:
+ logger('end-of-octets sentinel found')
+ return eoo.endOfOctets, substrate[2:]
+
+ value = noValue
+
+ tagMap = self.__tagMap
+ typeMap = self.__typeMap
+ tagCache = self.__tagCache
+ tagSetCache = self.__tagSetCache
+
fullSubstrate = substrate
- while state != stStop:
- if state == stDecodeTag:
- # Decode tag
+
+ while state is not stStop:
+ if state is stDecodeTag:
if not substrate:
raise error.SubstrateUnderrunError(
'Short octet stream on tag decoding'
- )
- if not isOctetsType(substrate) and \
- not isinstance(substrate, univ.OctetString):
- raise error.PyAsn1Error('Bad octet stream type')
-
+ )
+ # Decode tag
+ isShortTag = True
firstOctet = substrate[0]
substrate = substrate[1:]
- if firstOctet in self.__tagCache:
- lastTag = self.__tagCache[firstOctet]
- else:
- t = oct2int(firstOctet)
- tagClass = t&0xC0
- tagFormat = t&0x20
- tagId = t&0x1F
+ try:
+ lastTag = tagCache[firstOctet]
+ except KeyError:
+ integerTag = oct2int(firstOctet)
+ tagClass = integerTag & 0xC0
+ tagFormat = integerTag & 0x20
+ tagId = integerTag & 0x1F
if tagId == 0x1F:
+ isShortTag = False
+ lengthOctetIdx = 0
tagId = 0
- while 1:
- if not substrate:
- raise error.SubstrateUnderrunError(
- 'Short octet stream on long tag decoding'
- )
- t = oct2int(substrate[0])
- tagId = tagId << 7 | (t&0x7F)
- substrate = substrate[1:]
- if not t&0x80:
- break
+ try:
+ while True:
+ integerTag = oct2int(substrate[lengthOctetIdx])
+ lengthOctetIdx += 1
+ tagId <<= 7
+ tagId |= (integerTag & 0x7F)
+ if not integerTag & 0x80:
+ break
+ substrate = substrate[lengthOctetIdx:]
+ except IndexError:
+ raise error.SubstrateUnderrunError(
+ 'Short octet stream on long tag decoding'
+ )
lastTag = tag.Tag(
tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
- )
- if tagId < 31:
+ )
+ if isShortTag:
# cache short tags
- self.__tagCache[firstOctet] = lastTag
+ tagCache[firstOctet] = lastTag
if tagSet is None:
- if firstOctet in self.__tagSetCache:
- tagSet = self.__tagSetCache[firstOctet]
+ if isShortTag:
+ try:
+ tagSet = tagSetCache[firstOctet]
+ except KeyError:
+ # base tag not recovered
+ tagSet = tag.TagSet((), lastTag)
+ tagSetCache[firstOctet] = tagSet
else:
- # base tag not recovered
tagSet = tag.TagSet((), lastTag)
- if firstOctet in self.__tagCache:
- self.__tagSetCache[firstOctet] = tagSet
else:
tagSet = lastTag + tagSet
state = stDecodeLength
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('tag decoded into %r, decoding length' % tagSet)
- if state == stDecodeLength:
+ if logger:
+ logger('tag decoded into %s, decoding length' % tagSet)
+ if state is stDecodeLength:
# Decode length
if not substrate:
- raise error.SubstrateUnderrunError(
- 'Short octet stream on length decoding'
- )
- firstOctet = oct2int(substrate[0])
- if firstOctet == 128:
+ raise error.SubstrateUnderrunError(
+ 'Short octet stream on length decoding'
+ )
+ firstOctet = oct2int(substrate[0])
+ if firstOctet < 128:
size = 1
- length = -1
- elif firstOctet < 128:
- length, size = firstOctet, 1
- else:
+ length = firstOctet
+ elif firstOctet > 128:
size = firstOctet & 0x7F
# encoded in size bytes
- length = 0
- lengthString = substrate[1:size+1]
+ encodedLength = octs2ints(substrate[1:size + 1])
# missing check on maximum size, which shouldn't be a
# problem, we can handle more than is possible
- if len(lengthString) != size:
+ if len(encodedLength) != size:
raise error.SubstrateUnderrunError(
- '%s<%s at %s' %
- (size, len(lengthString), tagSet)
- )
- for char in lengthString:
- length = (length << 8) | oct2int(char)
- size = size + 1
+ '%s<%s at %s' % (size, len(encodedLength), tagSet)
+ )
+ length = 0
+ for lengthOctet in encodedLength:
+ length <<= 8
+ length |= lengthOctet
+ size += 1
+ else:
+ size = 1
+ length = -1
+
substrate = substrate[size:]
- if length != -1 and len(substrate) < length:
- raise error.SubstrateUnderrunError(
- '%d-octet short' % (length - len(substrate))
- )
+ if length == -1:
+ if not self.supportIndefLength:
+ raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
+ else:
+ if len(substrate) < length:
+ raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))
state = stGetValueDecoder
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
- if state == stGetValueDecoder:
+ if logger:
+ logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
+ if state is stGetValueDecoder:
if asn1Spec is None:
state = stGetValueDecoderByTag
else:
state = stGetValueDecoderByAsn1Spec
#
# There're two ways of creating subtypes in ASN.1 what influences
# decoder operation. These methods are:
# 1) Either base types used in or no IMPLICIT tagging has been
@@ -687,122 +1065,156 @@ class Decoder:
# The first case allows for complete tag recovery from substrate
# while the second one requires original ASN.1 type spec for
# decoding.
#
# In either case a set of tags (tagSet) is coming from substrate
# in an incremental, tag-by-tag fashion (this is the case of
# EXPLICIT tag which is most basic). Outermost tag comes first
# from the wire.
- #
- if state == stGetValueDecoderByTag:
- if tagSet in self.__tagMap:
- concreteDecoder = self.__tagMap[tagSet]
- else:
+ #
+ if state is stGetValueDecoderByTag:
+ try:
+ concreteDecoder = tagMap[tagSet]
+ except KeyError:
concreteDecoder = None
if concreteDecoder:
state = stDecodeValue
else:
- _k = tagSet[:1]
- if _k in self.__tagMap:
- concreteDecoder = self.__tagMap[_k]
- else:
+ try:
+ concreteDecoder = tagMap[tagSet[:1]]
+ except KeyError:
concreteDecoder = None
if concreteDecoder:
state = stDecodeValue
else:
state = stTryAsExplicitTag
- if debug.logger and debug.logger & debug.flagDecoder:
- debug.logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
+ if logger:
+ logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
- if state == stGetValueDecoderByAsn1Spec:
- if isinstance(asn1Spec, (dict, tagmap.TagMap)):
- if tagSet in asn1Spec:
- __chosenSpec = asn1Spec[tagSet]
- else:
- __chosenSpec = None
- if debug.logger and debug.logger & debug.flagDecoder:
- debug.logger('candidate ASN.1 spec is a map of:')
- for t, v in asn1Spec.getPosMap().items():
- debug.logger(' %r -> %s' % (t, v.__class__.__name__))
- if asn1Spec.getNegMap():
- debug.logger('but neither of: ')
- for i in asn1Spec.getNegMap().items():
- debug.logger(' %r -> %s' % (t, v.__class__.__name__))
- debug.logger('new candidate ASN.1 spec is %s, chosen by %r' % (__chosenSpec is None and '<none>' or __chosenSpec.__class__.__name__, tagSet))
+ if state is stGetValueDecoderByAsn1Spec:
+ if asn1Spec.__class__ is tagmap.TagMap:
+ try:
+ chosenSpec = asn1Spec[tagSet]
+ except KeyError:
+ chosenSpec = None
+ if logger:
+ logger('candidate ASN.1 spec is a map of:')
+ for firstOctet, v in asn1Spec.presentTypes.items():
+ logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
+ if asn1Spec.skipTypes:
+ logger('but neither of: ')
+ for firstOctet, v in asn1Spec.skipTypes.items():
+ logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
+ logger('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
+ elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
+ chosenSpec = asn1Spec
+ if logger:
+ logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
else:
- __chosenSpec = asn1Spec
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
- if __chosenSpec is not None and (
- tagSet == __chosenSpec.getTagSet() or \
- tagSet in __chosenSpec.getTagMap()
- ):
- # use base type for codec lookup to recover untagged types
- baseTagSet = __chosenSpec.baseTagSet
- if __chosenSpec.typeId is not None and \
- __chosenSpec.typeId in self.__typeMap:
- # ambiguous type
- concreteDecoder = self.__typeMap[__chosenSpec.typeId]
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen for an ambiguous type by type ID %s' % (__chosenSpec.typeId,))
- elif baseTagSet in self.__tagMap:
- # base type or tagged subtype
- concreteDecoder = self.__tagMap[baseTagSet]
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen by base %r' % (baseTagSet,))
- else:
- concreteDecoder = None
+ chosenSpec = None
+
+ if chosenSpec is not None:
+ try:
+ # ambiguous type or just faster codec lookup
+ concreteDecoder = typeMap[chosenSpec.typeId]
+ if logger:
+ logger('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
+ except KeyError:
+ # use base type for codec lookup to recover untagged types
+ baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag)
+ try:
+ # base type or tagged subtype
+ concreteDecoder = tagMap[baseTagSet]
+ if logger:
+ logger('value decoder chosen by base %s' % (baseTagSet,))
+ except KeyError:
+ concreteDecoder = None
if concreteDecoder:
- asn1Spec = __chosenSpec
+ asn1Spec = chosenSpec
state = stDecodeValue
else:
state = stTryAsExplicitTag
- elif tagSet == self.__endOfOctetsTagSet:
- concreteDecoder = self.__tagMap[tagSet]
- state = stDecodeValue
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('end-of-octets found')
else:
concreteDecoder = None
state = stTryAsExplicitTag
- if debug.logger and debug.logger & debug.flagDecoder:
- debug.logger('codec %s chosen by ASN.1 spec, decoding %s' % (state == stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
- debug.scope.push(__chosenSpec is None and '?' or __chosenSpec.__class__.__name__)
- if state == stTryAsExplicitTag:
- if tagSet and \
- tagSet[0][1] == tag.tagFormatConstructed and \
- tagSet[0][0] != tag.tagClassUniversal:
+ if logger:
+ logger('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
+ debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
+ if state is stDecodeValue:
+ if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this
+ substrateFun = lambda a, b, c: (a, b[:c])
+
+ options.update(fullSubstrate=fullSubstrate)
+
+ if length == -1: # indef length
+ value, substrate = concreteDecoder.indefLenValueDecoder(
+ substrate, asn1Spec,
+ tagSet, length, stGetValueDecoder,
+ self, substrateFun,
+ **options
+ )
+ else:
+ value, substrate = concreteDecoder.valueDecoder(
+ substrate, asn1Spec,
+ tagSet, length, stGetValueDecoder,
+ self, substrateFun,
+ **options
+ )
+ if logger:
+ logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
+ state = stStop
+ break
+ if state is stTryAsExplicitTag:
+ if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal:
# Assume explicit tagging
concreteDecoder = explicitTagDecoder
state = stDecodeValue
- else:
+ else:
concreteDecoder = None
state = self.defaultErrorState
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as failure'))
- if state == stDumpRawValue:
+ if logger:
+ logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
+ if state is stDumpRawValue:
concreteDecoder = self.defaultRawDecoder
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
+ if logger:
+ logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
state = stDecodeValue
- if state == stDecodeValue:
- if recursiveFlag == 0 and not substrateFun: # legacy
- substrateFun = lambda a,b,c: (a,b[:c])
- if length == -1: # indef length
- value, substrate = concreteDecoder.indefLenValueDecoder(
- fullSubstrate, substrate, asn1Spec, tagSet, length,
- stGetValueDecoder, self, substrateFun
- )
- else:
- value, substrate = concreteDecoder.valueDecoder(
- fullSubstrate, substrate, asn1Spec, tagSet, length,
- stGetValueDecoder, self, substrateFun
- )
- state = stStop
- debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or '<none>'))
- if state == stErrorCondition:
+ if state is stErrorCondition:
raise error.PyAsn1Error(
- '%r not in asn1Spec: %r' % (tagSet, asn1Spec)
- )
- if debug.logger and debug.logger & debug.flagDecoder:
+ '%s not in asn1Spec: %r' % (tagSet, asn1Spec)
+ )
+ if logger:
debug.scope.pop()
- debug.logger('decoder left scope %s, call completed' % debug.scope)
+ logger('decoder left scope %s, call completed' % debug.scope)
return value, substrate
-
+
+
+#: Turns BER octet stream into an ASN.1 object.
+#:
+#: Takes BER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: BER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#: being decoded, *asn1Spec* may or may not be required. Most common reason for
+#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On decoding errors
decode = Decoder(tagMap, typeMap)
# XXX
# non-recursive decoding; return position rather than substrate
--- a/third_party/python/pyasn1/pyasn1/codec/ber/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/encoder.py
@@ -1,290 +1,411 @@
-# BER encoder
-from pyasn1.type import base, tag, univ, char, useful
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import tag, univ, char, useful
from pyasn1.codec.ber import eoo
from pyasn1.compat.octets import int2oct, oct2int, ints2octs, null, str2octs
+from pyasn1.compat.integer import to_bytes
from pyasn1 import debug, error
-class Error(Exception): pass
+__all__ = ['encode']
-class AbstractItemEncoder:
+
+class AbstractItemEncoder(object):
supportIndefLenMode = 1
- def encodeTag(self, t, isConstructed):
- tagClass, tagFormat, tagId = t.asTuple() # this is a hotspot
- v = tagClass | tagFormat
+
+ # An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)`
+ eooIntegerSubstrate = (0, 0)
+ eooOctetsSubstrate = ints2octs(eooIntegerSubstrate)
+
+ # noinspection PyMethodMayBeStatic
+ def encodeTag(self, singleTag, isConstructed):
+ tagClass, tagFormat, tagId = singleTag
+ encodedTag = tagClass | tagFormat
if isConstructed:
- v = v|tag.tagFormatConstructed
+ encodedTag |= tag.tagFormatConstructed
if tagId < 31:
- return int2oct(v|tagId)
+ return encodedTag | tagId,
else:
- s = int2oct(tagId&0x7f)
- tagId = tagId >> 7
+ substrate = tagId & 0x7f,
+ tagId >>= 7
while tagId:
- s = int2oct(0x80|(tagId&0x7f)) + s
- tagId = tagId >> 7
- return int2oct(v|0x1F) + s
+ substrate = (0x80 | (tagId & 0x7f),) + substrate
+ tagId >>= 7
+ return (encodedTag | 0x1F,) + substrate
def encodeLength(self, length, defMode):
if not defMode and self.supportIndefLenMode:
- return int2oct(0x80)
+ return (0x80,)
if length < 0x80:
- return int2oct(length)
+ return length,
else:
- substrate = null
+ substrate = ()
while length:
- substrate = int2oct(length&0xff) + substrate
- length = length >> 8
+ substrate = (length & 0xff,) + substrate
+ length >>= 8
substrateLen = len(substrate)
if substrateLen > 126:
- raise Error('Length octets overflow (%d)' % substrateLen)
- return int2oct(0x80 | substrateLen) + substrate
+ raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen)
+ return (0x80 | substrateLen,) + substrate
+
+ def encodeValue(self, value, encodeFun, **options):
+ raise error.PyAsn1Error('Not implemented')
+
+ def encode(self, value, encodeFun, **options):
+
+ tagSet = value.tagSet
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- raise Error('Not implemented')
+ # untagged item?
+ if not tagSet:
+ substrate, isConstructed, isOctets = self.encodeValue(
+ value, encodeFun, **options
+ )
+ return substrate
+
+ defMode = options.get('defMode', True)
+
+ for idx, singleTag in enumerate(tagSet.superTags):
+
+ defModeOverride = defMode
- def _encodeEndOfOctets(self, encodeFun, defMode):
- if defMode or not self.supportIndefLenMode:
- return null
- else:
- return encodeFun(eoo.endOfOctets, defMode)
-
- def encode(self, encodeFun, value, defMode, maxChunkSize):
- substrate, isConstructed = self.encodeValue(
- encodeFun, value, defMode, maxChunkSize
- )
- tagSet = value.getTagSet()
- if tagSet:
- if not isConstructed: # primitive form implies definite mode
- defMode = 1
- return self.encodeTag(
- tagSet[-1], isConstructed
- ) + self.encodeLength(
- len(substrate), defMode
- ) + substrate + self._encodeEndOfOctets(encodeFun, defMode)
- else:
- return substrate # untagged value
+ # base tag?
+ if not idx:
+ substrate, isConstructed, isOctets = self.encodeValue(
+ value, encodeFun, **options
+ )
+
+ if options.get('ifNotEmpty', False) and not substrate:
+ return substrate
+
+ # primitive form implies definite mode
+ if not isConstructed:
+ defModeOverride = True
+
+ header = self.encodeTag(singleTag, isConstructed)
+ header += self.encodeLength(len(substrate), defModeOverride)
+
+ if isOctets:
+ substrate = ints2octs(header) + substrate
+
+ if not defModeOverride:
+ substrate += self.eooOctetsSubstrate
+
+ else:
+ substrate = header + substrate
+
+ if not defModeOverride:
+ substrate += self.eooIntegerSubstrate
+
+ if not isOctets:
+ substrate = ints2octs(substrate)
+
+ return substrate
+
class EndOfOctetsEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- return null, 0
+ def encodeValue(self, value, encodeFun, **options):
+ return null, False, True
-class ExplicitlyTaggedItemEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- if isinstance(value, base.AbstractConstructedAsn1Item):
- value = value.clone(tagSet=value.getTagSet()[:-1],
- cloneValueFlag=1)
- else:
- value = value.clone(tagSet=value.getTagSet()[:-1])
- return encodeFun(value, defMode, maxChunkSize), 1
-
-explicitlyTaggedItemEncoder = ExplicitlyTaggedItemEncoder()
class BooleanEncoder(AbstractItemEncoder):
- supportIndefLenMode = 0
- _true = ints2octs((1,))
- _false = ints2octs((0,))
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- return value and self._true or self._false, 0
+ supportIndefLenMode = False
+
+ def encodeValue(self, value, encodeFun, **options):
+ return value and (1,) or (0,), False, False
+
class IntegerEncoder(AbstractItemEncoder):
- supportIndefLenMode = 0
+ supportIndefLenMode = False
supportCompactZero = False
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- if value == 0: # shortcut for zero value
+
+ def encodeValue(self, value, encodeFun, **options):
+ if value == 0:
+ # de-facto way to encode zero
if self.supportCompactZero:
- # this seems to be a correct way for encoding zeros
- return null, 0
+ return (), False, False
else:
- # this seems to be a widespread way for encoding zeros
- return ints2octs((0,)), 0
- octets = []
- value = int(value) # to save on ops on asn1 type
- while 1:
- octets.insert(0, value & 0xff)
- if value == 0 or value == -1:
- break
- value = value >> 8
- if value == 0 and octets[0] & 0x80:
- octets.insert(0, 0)
- while len(octets) > 1 and \
- (octets[0] == 0 and octets[1] & 0x80 == 0 or \
- octets[0] == 0xff and octets[1] & 0x80 != 0):
- del octets[0]
- return ints2octs(octets), 0
+ return (0,), False, False
+
+ return to_bytes(int(value), signed=True), False, True
+
class BitStringEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- if not maxChunkSize or len(value) <= maxChunkSize*8:
- r = {}; l = len(value); p = 0; j = 7
- while p < l:
- i, j = divmod(p, 8)
- r[i] = r.get(i,0) | value[p]<<(7-j)
- p = p + 1
- keys = list(r); keys.sort()
- return int2oct(7-j) + ints2octs([r[k] for k in keys]), 0
+ def encodeValue(self, value, encodeFun, **options):
+ valueLength = len(value)
+ if valueLength % 8:
+ alignedValue = value << (8 - valueLength % 8)
else:
- pos = 0; substrate = null
- while 1:
- # count in octets
- v = value.clone(value[pos*8:pos*8+maxChunkSize*8])
- if not v:
- break
- substrate = substrate + encodeFun(v, defMode, maxChunkSize)
- pos = pos + maxChunkSize
- return substrate, 1
+ alignedValue = value
+
+ maxChunkSize = options.get('maxChunkSize', 0)
+ if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8:
+ substrate = alignedValue.asOctets()
+ return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True
+
+ # strip off explicit tags
+ alignedValue = alignedValue.clone(
+ tagSet=tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+ )
+
+ stop = 0
+ substrate = null
+ while stop < valueLength:
+ start = stop
+ stop = min(start + maxChunkSize * 8, valueLength)
+ substrate += encodeFun(alignedValue[start:stop], **options)
+
+ return substrate, True, True
+
class OctetStringEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ def encodeValue(self, value, encodeFun, **options):
+ maxChunkSize = options.get('maxChunkSize', 0)
if not maxChunkSize or len(value) <= maxChunkSize:
- return value.asOctets(), 0
+ return value.asOctets(), False, True
+
else:
- pos = 0; substrate = null
- while 1:
- v = value.clone(value[pos:pos+maxChunkSize])
- if not v:
+ # will strip off explicit tags
+ baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+ pos = 0
+ substrate = null
+ while True:
+ chunk = value.clone(value[pos:pos + maxChunkSize],
+ tagSet=baseTagSet)
+ if not chunk:
break
- substrate = substrate + encodeFun(v, defMode, maxChunkSize)
- pos = pos + maxChunkSize
- return substrate, 1
+ substrate += encodeFun(chunk, **options)
+ pos += maxChunkSize
+
+ return substrate, True, True
+
class NullEncoder(AbstractItemEncoder):
- supportIndefLenMode = 0
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- return null, 0
+ supportIndefLenMode = False
+
+ def encodeValue(self, value, encodeFun, **options):
+ return null, False, True
+
class ObjectIdentifierEncoder(AbstractItemEncoder):
- supportIndefLenMode = 0
- precomputedValues = {
- (1, 3, 6, 1, 2): (43, 6, 1, 2),
- (1, 3, 6, 1, 4): (43, 6, 1, 4)
- }
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ supportIndefLenMode = False
+
+ def encodeValue(self, value, encodeFun, **options):
oid = value.asTuple()
- if oid[:5] in self.precomputedValues:
- octets = self.precomputedValues[oid[:5]]
- index = 5
- else:
- if len(oid) < 2:
- raise error.PyAsn1Error('Short OID %s' % (value,))
+
+ # Build the first pair
+ try:
+ first = oid[0]
+ second = oid[1]
+
+ except IndexError:
+ raise error.PyAsn1Error('Short OID %s' % (value,))
- # Build the first twos
- if oid[0] > 6 or oid[1] > 39 or oid[0] == 6 and oid[1] > 15:
- raise error.PyAsn1Error(
- 'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)
- )
- octets = (oid[0] * 40 + oid[1],)
- index = 2
+ if 0 <= second <= 39:
+ if first == 1:
+ oid = (second + 40,) + oid[2:]
+ elif first == 0:
+ oid = (second,) + oid[2:]
+ elif first == 2:
+ oid = (second + 80,) + oid[2:]
+ else:
+ raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
+ elif first == 2:
+ oid = (second + 80,) + oid[2:]
+ else:
+ raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
- # Cycle through subids
- for subid in oid[index:]:
- if subid > -1 and subid < 128:
+ octets = ()
+
+ # Cycle through subIds
+ for subOid in oid:
+ if 0 <= subOid <= 127:
# Optimize for the common case
- octets = octets + (subid & 0x7f,)
- elif subid < 0 or subid > 0xFFFFFFFF:
- raise error.PyAsn1Error(
- 'SubId overflow %s in %s' % (subid, value)
- )
- else:
+ octets += (subOid,)
+ elif subOid > 127:
# Pack large Sub-Object IDs
- res = (subid & 0x7f,)
- subid = subid >> 7
- while subid > 0:
- res = (0x80 | (subid & 0x7f),) + res
- subid = subid >> 7
+ res = (subOid & 0x7f,)
+ subOid >>= 7
+ while subOid:
+ res = (0x80 | (subOid & 0x7f),) + res
+ subOid >>= 7
# Add packed Sub-Object ID to resulted Object ID
octets += res
-
- return ints2octs(octets), 0
+ else:
+ raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))
+
+ return octets, False, False
+
class RealEncoder(AbstractItemEncoder):
supportIndefLenMode = 0
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- if value.isPlusInfinity():
- return int2oct(0x40), 0
- if value.isMinusInfinity():
- return int2oct(0x41), 0
+ binEncBase = 2 # set to None to choose encoding base automatically
+
+ @staticmethod
+ def _dropFloatingPoint(m, encbase, e):
+ ms, es = 1, 1
+ if m < 0:
+ ms = -1 # mantissa sign
+ if e < 0:
+ es = -1 # exponenta sign
+ m *= ms
+ if encbase == 8:
+ m *= 2 ** (abs(e) % 3 * es)
+ e = abs(e) // 3 * es
+ elif encbase == 16:
+ m *= 2 ** (abs(e) % 4 * es)
+ e = abs(e) // 4 * es
+
+ while True:
+ if int(m) != m:
+ m *= encbase
+ e -= 1
+ continue
+ break
+ return ms, int(m), encbase, e
+
+ def _chooseEncBase(self, value):
+ m, b, e = value
+ encBase = [2, 8, 16]
+ if value.binEncBase in encBase:
+ return self._dropFloatingPoint(m, value.binEncBase, e)
+ elif self.binEncBase in encBase:
+ return self._dropFloatingPoint(m, self.binEncBase, e)
+ # auto choosing base 2/8/16
+ mantissa = [m, m, m]
+ exponenta = [e, e, e]
+ sign = 1
+ encbase = 2
+ e = float('inf')
+ for i in range(3):
+ (sign,
+ mantissa[i],
+ encBase[i],
+ exponenta[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponenta[i])
+ if abs(exponenta[i]) < abs(e) or (abs(exponenta[i]) == abs(e) and mantissa[i] < m):
+ e = exponenta[i]
+ m = int(mantissa[i])
+ encbase = encBase[i]
+ return sign, m, encbase, e
+
+ def encodeValue(self, value, encodeFun, **options):
+ if value.isPlusInf:
+ return (0x40,), False, False
+ if value.isMinusInf:
+ return (0x41,), False, False
m, b, e = value
if not m:
- return null, 0
+ return null, False, True
if b == 10:
- return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), 0
+ return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True
elif b == 2:
- fo = 0x80 # binary enoding
- if m < 0:
- fo = fo | 0x40 # sign bit
- m = -m
- while int(m) != m: # drop floating point
- m *= 2
- e -= 1
- while m & 0x1 == 0: # mantissa normalization
+ fo = 0x80 # binary encoding
+ ms, m, encbase, e = self._chooseEncBase(value)
+ if ms < 0: # mantissa sign
+ fo |= 0x40 # sign bit
+ # exponenta & mantissa normalization
+ if encbase == 2:
+ while m & 0x1 == 0:
+ m >>= 1
+ e += 1
+ elif encbase == 8:
+ while m & 0x7 == 0:
+ m >>= 3
+ e += 1
+ fo |= 0x10
+ else: # encbase = 16
+ while m & 0xf == 0:
+ m >>= 4
+ e += 1
+ fo |= 0x20
+ sf = 0 # scale factor
+ while m & 0x1 == 0:
m >>= 1
- e += 1
+ sf += 1
+ if sf > 3:
+ raise error.PyAsn1Error('Scale factor overflow') # bug if raised
+ fo |= sf << 2
eo = null
- while e not in (0, -1):
- eo = int2oct(e&0xff) + eo
- e >>= 8
- if e == 0 and eo and oct2int(eo[0]) & 0x80:
- eo = int2oct(0) + eo
+ if e == 0 or e == -1:
+ eo = int2oct(e & 0xff)
+ else:
+ while e not in (0, -1):
+ eo = int2oct(e & 0xff) + eo
+ e >>= 8
+ if e == 0 and eo and oct2int(eo[0]) & 0x80:
+ eo = int2oct(0) + eo
+ if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
+ eo = int2oct(0xff) + eo
n = len(eo)
if n > 0xff:
raise error.PyAsn1Error('Real exponent overflow')
if n == 1:
pass
elif n == 2:
fo |= 1
elif n == 3:
fo |= 2
else:
fo |= 3
- eo = int2oct(n//0xff+1) + eo
+ eo = int2oct(n & 0xff) + eo
po = null
while m:
- po = int2oct(m&0xff) + po
+ po = int2oct(m & 0xff) + po
m >>= 8
substrate = int2oct(fo) + eo + po
- return substrate, 0
+ return substrate, False, True
else:
raise error.PyAsn1Error('Prohibited Real base %s' % b)
+
class SequenceEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- value.setDefaultComponents()
+ def encodeValue(self, value, encodeFun, **options):
value.verifySizeSpec()
- substrate = null; idx = len(value)
+
+ namedTypes = value.componentType
+ substrate = null
+
+ idx = len(value)
while idx > 0:
- idx = idx - 1
- if value[idx] is None: # Optional component
- continue
- component = value.getDefaultComponentByPosition(idx)
- if component is not None and component == value[idx]:
- continue
- substrate = encodeFun(
- value[idx], defMode, maxChunkSize
- ) + substrate
- return substrate, 1
+ idx -= 1
+ if namedTypes:
+ if namedTypes[idx].isOptional and not value[idx].isValue:
+ continue
+ if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+ continue
+ substrate = encodeFun(value[idx], **options) + substrate
+
+ return substrate, True, True
+
class SequenceOfEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+ def encodeValue(self, value, encodeFun, **options):
value.verifySizeSpec()
- substrate = null; idx = len(value)
+ substrate = null
+ idx = len(value)
while idx > 0:
- idx = idx - 1
- substrate = encodeFun(
- value[idx], defMode, maxChunkSize
- ) + substrate
- return substrate, 1
+ idx -= 1
+ substrate = encodeFun(value[idx], **options) + substrate
+ return substrate, True, True
+
class ChoiceEncoder(AbstractItemEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- return encodeFun(value.getComponent(), defMode, maxChunkSize), 1
+ def encodeValue(self, value, encodeFun, **options):
+ return encodeFun(value.getComponent(), **options), True, True
+
class AnyEncoder(OctetStringEncoder):
- def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
- return value.asOctets(), defMode == 0
+ def encodeValue(self, value, encodeFun, **options):
+ return value.asOctets(), not options.get('defMode', True), True
+
tagMap = {
eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),
univ.Boolean.tagSet: BooleanEncoder(),
univ.Integer.tagSet: IntegerEncoder(),
univ.BitString.tagSet: BitStringEncoder(),
univ.OctetString.tagSet: OctetStringEncoder(),
univ.Null.tagSet: NullEncoder(),
@@ -303,51 +424,125 @@ tagMap = {
char.VideotexString.tagSet: OctetStringEncoder(),
char.IA5String.tagSet: OctetStringEncoder(),
char.GraphicString.tagSet: OctetStringEncoder(),
char.VisibleString.tagSet: OctetStringEncoder(),
char.GeneralString.tagSet: OctetStringEncoder(),
char.UniversalString.tagSet: OctetStringEncoder(),
char.BMPString.tagSet: OctetStringEncoder(),
# useful types
+ useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
useful.GeneralizedTime.tagSet: OctetStringEncoder(),
- useful.UTCTime.tagSet: OctetStringEncoder()
- }
+ useful.UTCTime.tagSet: OctetStringEncoder()
+}
-# Type-to-codec map for ambiguous ASN.1 types
+# Put in ambiguous & non-ambiguous types for faster codec lookup
typeMap = {
+ univ.Boolean.typeId: BooleanEncoder(),
+ univ.Integer.typeId: IntegerEncoder(),
+ univ.BitString.typeId: BitStringEncoder(),
+ univ.OctetString.typeId: OctetStringEncoder(),
+ univ.Null.typeId: NullEncoder(),
+ univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(),
+ univ.Enumerated.typeId: IntegerEncoder(),
+ univ.Real.typeId: RealEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
univ.Set.typeId: SequenceEncoder(),
univ.SetOf.typeId: SequenceOfEncoder(),
univ.Sequence.typeId: SequenceEncoder(),
univ.SequenceOf.typeId: SequenceOfEncoder(),
univ.Choice.typeId: ChoiceEncoder(),
- univ.Any.typeId: AnyEncoder()
- }
+ univ.Any.typeId: AnyEncoder(),
+ # character string types
+ char.UTF8String.typeId: OctetStringEncoder(),
+ char.NumericString.typeId: OctetStringEncoder(),
+ char.PrintableString.typeId: OctetStringEncoder(),
+ char.TeletexString.typeId: OctetStringEncoder(),
+ char.VideotexString.typeId: OctetStringEncoder(),
+ char.IA5String.typeId: OctetStringEncoder(),
+ char.GraphicString.typeId: OctetStringEncoder(),
+ char.VisibleString.typeId: OctetStringEncoder(),
+ char.GeneralString.typeId: OctetStringEncoder(),
+ char.UniversalString.typeId: OctetStringEncoder(),
+ char.BMPString.typeId: OctetStringEncoder(),
+ # useful types
+ useful.ObjectDescriptor.typeId: OctetStringEncoder(),
+ useful.GeneralizedTime.typeId: OctetStringEncoder(),
+ useful.UTCTime.typeId: OctetStringEncoder()
+}
-class Encoder:
+
+class Encoder(object):
+ fixedDefLengthMode = None
+ fixedChunkSize = None
+
+ # noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap={}):
self.__tagMap = tagMap
self.__typeMap = typeMap
- def __call__(self, value, defMode=1, maxChunkSize=0):
- debug.logger & debug.flagEncoder and debug.logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.__class__.__name__, value.prettyPrint()))
- tagSet = value.getTagSet()
- if len(tagSet) > 1:
- concreteEncoder = explicitlyTaggedItemEncoder
+ def __call__(self, value, **options):
+
+ if debug.logger & debug.flagEncoder:
+ logger = debug.logger
else:
- if value.typeId is not None and value.typeId in self.__typeMap:
- concreteEncoder = self.__typeMap[value.typeId]
- elif tagSet in self.__tagMap:
- concreteEncoder = self.__tagMap[tagSet]
- else:
- tagSet = value.baseTagSet
- if tagSet in self.__tagMap:
- concreteEncoder = self.__tagMap[tagSet]
- else:
- raise Error('No encoder for %s' % (value,))
- debug.logger & debug.flagEncoder and debug.logger('using value codec %s chosen by %r' % (concreteEncoder.__class__.__name__, tagSet))
- substrate = concreteEncoder.encode(
- self, value, defMode, maxChunkSize
- )
- debug.logger & debug.flagEncoder and debug.logger('built %s octets of substrate: %s\nencoder completed' % (len(substrate), debug.hexdump(substrate)))
+ logger = None
+
+ if logger:
+ logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), value.prettyPrintType(), value.prettyPrint()))
+
+ if self.fixedDefLengthMode is not None:
+ options.update(defMode=self.fixedDefLengthMode)
+
+ if self.fixedChunkSize is not None:
+ options.update(maxChunkSize=self.fixedChunkSize)
+
+ tagSet = value.tagSet
+
+ try:
+ concreteEncoder = self.__typeMap[value.typeId]
+
+ except KeyError:
+ # use base type for codec lookup to recover untagged types
+ baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+ try:
+ concreteEncoder = self.__tagMap[baseTagSet]
+
+ except KeyError:
+ raise error.PyAsn1Error('No encoder for %s' % (value,))
+
+ if logger:
+ logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
+
+ substrate = concreteEncoder.encode(value, self, **options)
+
+ if logger:
+ logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
+
return substrate
+#: Turns ASN.1 object into BER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a BER octet stream.
+#:
+#: Parameters
+#: ----------
+# value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#: If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#: Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On encoding errors
encode = Encoder(tagMap, typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/ber/eoo.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/eoo.py
@@ -1,8 +1,25 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.type import base, tag
+
class EndOfOctets(base.AbstractSimpleAsn1Item):
defaultValue = 0
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)
- )
+ )
+
+ _instance = None
+
+ def __new__(cls, *args, **kwargs):
+ if cls._instance is None:
+ cls._instance = object.__new__(cls, *args, **kwargs)
+
+ return cls._instance
+
+
endOfOctets = EndOfOctets()
--- a/third_party/python/pyasn1/pyasn1/codec/cer/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/cer/decoder.py
@@ -1,35 +1,90 @@
-# CER decoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.type import univ
from pyasn1.codec.ber import decoder
from pyasn1.compat.octets import oct2int
from pyasn1 import error
+__all__ = ['decode']
+
+
class BooleanDecoder(decoder.AbstractSimpleDecoder):
protoComponent = univ.Boolean(0)
- def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
- state, decodeFun, substrateFun):
+
+ def valueDecoder(self, substrate, asn1Spec,
+ tagSet=None, length=None, state=None,
+ decodeFun=None, substrateFun=None,
+ **options):
head, tail = substrate[:length], substrate[length:]
- if not head:
- raise error.PyAsn1Error('Empty substrate')
+ if not head or length != 1:
+ raise error.PyAsn1Error('Not single-octet Boolean payload')
byte = oct2int(head[0])
# CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
# BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1
# in http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
if byte == 0xff:
value = 1
elif byte == 0x00:
value = 0
else:
- raise error.PyAsn1Error('Boolean CER violation: %s' % byte)
+ raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte)
return self._createComponent(asn1Spec, tagSet, value), tail
+# TODO: prohibit non-canonical encoding
+BitStringDecoder = decoder.BitStringDecoder
+OctetStringDecoder = decoder.OctetStringDecoder
+RealDecoder = decoder.RealDecoder
+
tagMap = decoder.tagMap.copy()
-tagMap.update({
- univ.Boolean.tagSet: BooleanDecoder()
- })
+tagMap.update(
+ {univ.Boolean.tagSet: BooleanDecoder(),
+ univ.BitString.tagSet: BitStringDecoder(),
+ univ.OctetString.tagSet: OctetStringDecoder(),
+ univ.Real.tagSet: RealDecoder()}
+)
+
+typeMap = decoder.typeMap.copy()
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+ if typeDecoder.protoComponent is not None:
+ typeId = typeDecoder.protoComponent.__class__.typeId
+ if typeId is not None and typeId not in typeMap:
+ typeMap[typeId] = typeDecoder
+
+
+class Decoder(decoder.Decoder):
+ pass
+
-typeMap = decoder.typeMap
-
-class Decoder(decoder.Decoder): pass
-
+#: Turns CER octet stream into an ASN.1 object.
+#:
+#: Takes CER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: CER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#: being decoded, *asn1Spec* may or may not be required. Most common reason for
+#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#: A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On decoding errors
decode = Decoder(tagMap, decoder.typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/cer/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/cer/encoder.py
@@ -1,87 +1,221 @@
-# CER encoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.type import univ
+from pyasn1.type import useful
from pyasn1.codec.ber import encoder
-from pyasn1.compat.octets import int2oct, null
+from pyasn1.compat.octets import str2octs, null
+from pyasn1 import error
+
+__all__ = ['encode']
+
class BooleanEncoder(encoder.IntegerEncoder):
- def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
- if client == 0:
- substrate = int2oct(0)
+ def encodeValue(self, value, encodeFun, **options):
+ if value == 0:
+ substrate = (0,)
else:
- substrate = int2oct(255)
- return substrate, 0
+ substrate = (255,)
+ return substrate, False, False
+
+
+class RealEncoder(encoder.RealEncoder):
+ def _chooseEncBase(self, value):
+ m, b, e = value
+ return self._dropFloatingPoint(m, b, e)
+
+
+# specialized GeneralStringEncoder here
+
+class TimeEncoderMixIn(object):
+ zchar, = str2octs('Z')
+ pluschar, = str2octs('+')
+ minuschar, = str2octs('-')
+ commachar, = str2octs(',')
+ minLength = 12
+ maxLength = 19
-class BitStringEncoder(encoder.BitStringEncoder):
- def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
- return encoder.BitStringEncoder.encodeValue(
- self, encodeFun, client, defMode, 1000
- )
+ def encodeValue(self, value, encodeFun, **options):
+ # Encoding constraints:
+ # - minutes are mandatory, seconds are optional
+ # - subseconds must NOT be zero
+ # - no hanging fraction dot
+ # - time in UTC (Z)
+ # - only dot is allowed for fractions
+
+ octets = value.asOctets()
+
+ if not self.minLength < len(octets) < self.maxLength:
+ raise error.PyAsn1Error('Length constraint violated: %r' % value)
+
+ if self.pluschar in octets or self.minuschar in octets:
+ raise error.PyAsn1Error('Must be UTC time: %r' % octets)
+
+ if octets[-1] != self.zchar:
+ raise error.PyAsn1Error('Missing "Z" time zone specifier: %r' % octets)
-class OctetStringEncoder(encoder.OctetStringEncoder):
- def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ if self.commachar in octets:
+ raise error.PyAsn1Error('Comma in fractions disallowed: %r' % value)
+
+ options.update(maxChunkSize=1000)
+
return encoder.OctetStringEncoder.encodeValue(
- self, encodeFun, client, defMode, 1000
- )
+ self, value, encodeFun, **options
+ )
+
-# specialized RealEncoder here
-# specialized GeneralStringEncoder here
-# specialized GeneralizedTimeEncoder here
-# specialized UTCTimeEncoder here
+class GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
+ minLength = 12
+ maxLength = 19
+
+
+class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
+ minLength = 10
+ maxLength = 14
+
class SetOfEncoder(encoder.SequenceOfEncoder):
- def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
- if isinstance(client, univ.SequenceAndSetBase):
- client.setDefaultComponents()
- client.verifySizeSpec()
- substrate = null; idx = len(client)
- # This is certainly a hack but how else do I distinguish SetOf
- # from Set if they have the same tags&constraints?
- if isinstance(client, univ.SequenceAndSetBase):
- # Set
+ @staticmethod
+ def _sortComponents(components):
+ # sort by tags regardless of the Choice value (static sort)
+ return sorted(components, key=lambda x: isinstance(x, univ.Choice) and x.minTagSet or x.tagSet)
+
+ def encodeValue(self, value, encodeFun, **options):
+ value.verifySizeSpec()
+ substrate = null
+ idx = len(value)
+ if value.typeId == univ.Set.typeId:
+ namedTypes = value.componentType
comps = []
+ compsMap = {}
while idx > 0:
- idx = idx - 1
- if client[idx] is None: # Optional component
- continue
- if client.getDefaultComponentByPosition(idx) == client[idx]:
+ idx -= 1
+ if namedTypes:
+ if namedTypes[idx].isOptional and not value[idx].isValue:
+ continue
+ if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+ continue
+
+ comps.append(value[idx])
+ compsMap[id(value[idx])] = namedTypes and namedTypes[idx].isOptional
+
+ for comp in self._sortComponents(comps):
+ options.update(ifNotEmpty=compsMap[id(comp)])
+ substrate += encodeFun(comp, **options)
+ else:
+ components = [encodeFun(x, **options) for x in value]
+
+ # sort by serialized and padded components
+ if len(components) > 1:
+ zero = str2octs('\x00')
+ maxLen = max(map(len, components))
+ paddedComponents = [
+ (x.ljust(maxLen, zero), x) for x in components
+ ]
+ paddedComponents.sort(key=lambda x: x[0])
+
+ components = [x[1] for x in paddedComponents]
+
+ substrate = null.join(components)
+
+ return substrate, True, True
+
+
+class SequenceEncoder(encoder.SequenceEncoder):
+ def encodeValue(self, value, encodeFun, **options):
+ value.verifySizeSpec()
+
+ namedTypes = value.componentType
+ substrate = null
+
+ idx = len(value)
+ while idx > 0:
+ idx -= 1
+ if namedTypes:
+ if namedTypes[idx].isOptional and not value[idx].isValue:
continue
- comps.append(client[idx])
- comps.sort(key=lambda x: isinstance(x, univ.Choice) and \
- x.getMinTagSet() or x.getTagSet())
- for c in comps:
- substrate += encodeFun(c, defMode, maxChunkSize)
- else:
- # SetOf
- compSubs = []
- while idx > 0:
- idx = idx - 1
- compSubs.append(
- encodeFun(client[idx], defMode, maxChunkSize)
- )
- compSubs.sort() # perhaps padding's not needed
- substrate = null
- for compSub in compSubs:
- substrate += compSub
- return substrate, 1
+ if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+ continue
+
+ options.update(ifNotEmpty=namedTypes and namedTypes[idx].isOptional)
+
+ substrate = encodeFun(value[idx], **options) + substrate
+
+ return substrate, True, True
+
+
+class SequenceOfEncoder(encoder.SequenceOfEncoder):
+ def encodeValue(self, value, encodeFun, **options):
+ substrate = null
+ idx = len(value)
+
+ if options.get('ifNotEmpty', False) and not idx:
+ return substrate, True, True
+
+ value.verifySizeSpec()
+ while idx > 0:
+ idx -= 1
+ substrate = encodeFun(value[idx], **options) + substrate
+ return substrate, True, True
+
tagMap = encoder.tagMap.copy()
tagMap.update({
univ.Boolean.tagSet: BooleanEncoder(),
- univ.BitString.tagSet: BitStringEncoder(),
- univ.OctetString.tagSet: OctetStringEncoder(),
- univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set
- })
+ univ.Real.tagSet: RealEncoder(),
+ useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(),
+ useful.UTCTime.tagSet: UTCTimeEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
+ univ.SetOf.tagSet: SetOfEncoder(),
+ univ.Sequence.typeId: SequenceEncoder()
+})
typeMap = encoder.typeMap.copy()
typeMap.update({
+ univ.Boolean.typeId: BooleanEncoder(),
+ univ.Real.typeId: RealEncoder(),
+ useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(),
+ useful.UTCTime.typeId: UTCTimeEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
univ.Set.typeId: SetOfEncoder(),
- univ.SetOf.typeId: SetOfEncoder()
- })
+ univ.SetOf.typeId: SetOfEncoder(),
+ univ.Sequence.typeId: SequenceEncoder(),
+ univ.SequenceOf.typeId: SequenceOfEncoder()
+})
+
class Encoder(encoder.Encoder):
- def __call__(self, client, defMode=0, maxChunkSize=0):
- return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
+ fixedDefLengthMode = False
+ fixedChunkSize = 1000
+#: Turns ASN.1 object into CER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a CER octet stream.
+#:
+#: Parameters
+#: ----------
+# value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#: If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#: Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On encoding errors
encode = Encoder(tagMap, typeMap)
# EncoderFactory queries class instance and builds a map of tags -> encoders
--- a/third_party/python/pyasn1/pyasn1/codec/der/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/der/decoder.py
@@ -1,9 +1,70 @@
-# DER decoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.type import univ
from pyasn1.codec.cer import decoder
-tagMap = decoder.tagMap
-typeMap = decoder.typeMap
-Decoder = decoder.Decoder
+__all__ = ['decode']
+
+
+class BitStringDecoder(decoder.BitStringDecoder):
+ supportConstructedForm = False
+
+
+class OctetStringDecoder(decoder.OctetStringDecoder):
+ supportConstructedForm = False
+
+# TODO: prohibit non-canonical encoding
+RealDecoder = decoder.RealDecoder
+
+tagMap = decoder.tagMap.copy()
+tagMap.update(
+ {univ.BitString.tagSet: BitStringDecoder(),
+ univ.OctetString.tagSet: OctetStringDecoder(),
+ univ.Real.tagSet: RealDecoder()}
+)
+
+typeMap = decoder.typeMap.copy()
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+ if typeDecoder.protoComponent is not None:
+ typeId = typeDecoder.protoComponent.__class__.typeId
+ if typeId is not None and typeId not in typeMap:
+ typeMap[typeId] = typeDecoder
+
+class Decoder(decoder.Decoder):
+ supportIndefLength = False
+
+
+#: Turns DER octet stream into an ASN.1 object.
+#:
+#: Takes DER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: DER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#: being decoded, *asn1Spec* may or may not be required. Most common reason for
+#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#: A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On decoding errors
decode = Decoder(tagMap, typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/der/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/der/encoder.py
@@ -1,28 +1,62 @@
-# DER encoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.type import univ
from pyasn1.codec.cer import encoder
+__all__ = ['encode']
+
+
class SetOfEncoder(encoder.SetOfEncoder):
- def _cmpSetComponents(self, c1, c2):
- tagSet1 = isinstance(c1, univ.Choice) and \
- c1.getEffectiveTagSet() or c1.getTagSet()
- tagSet2 = isinstance(c2, univ.Choice) and \
- c2.getEffectiveTagSet() or c2.getTagSet()
- return cmp(tagSet1, tagSet2)
+ @staticmethod
+ def _sortComponents(components):
+ # sort by tags depending on the actual Choice value (dynamic sort)
+ return sorted(components, key=lambda x: isinstance(x, univ.Choice) and x.getComponent().tagSet or x.tagSet)
tagMap = encoder.tagMap.copy()
tagMap.update({
- # Overload CER encodrs with BER ones (a bit hackerish XXX)
- univ.BitString.tagSet: encoder.encoder.BitStringEncoder(),
- univ.OctetString.tagSet: encoder.encoder.OctetStringEncoder(),
# Set & SetOf have same tags
- univ.SetOf().tagSet: SetOfEncoder()
- })
+ univ.SetOf.tagSet: SetOfEncoder()
+})
-typeMap = encoder.typeMap
+typeMap = encoder.typeMap.copy()
+typeMap.update({
+ # Set & SetOf have same tags
+ univ.Set.typeId: SetOfEncoder(),
+ univ.SetOf.typeId: SetOfEncoder()
+})
+
class Encoder(encoder.Encoder):
- def __call__(self, client, defMode=1, maxChunkSize=0):
- return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
-
+ fixedDefLengthMode = True
+ fixedChunkSize = 0
+
+#: Turns ASN.1 object into DER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a DER octet stream.
+#:
+#: Parameters
+#: ----------
+# value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#: If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#: Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#: Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On encoding errors
encode = Encoder(tagMap, typeMap)
rename from third_party/python/pyasn1/test/__init__.py
rename to third_party/python/pyasn1/pyasn1/codec/native/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/codec/native/decoder.py
@@ -0,0 +1,194 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import base, univ, char, useful, tag
+from pyasn1 import debug, error
+
+__all__ = ['decode']
+
+
+class AbstractScalarDecoder(object):
+ def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+ return asn1Spec.clone(pyObject)
+
+
+class BitStringDecoder(AbstractScalarDecoder):
+ def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+ return asn1Spec.clone(univ.BitString.fromBinaryString(pyObject))
+
+
+class SequenceOrSetDecoder(object):
+ def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+ asn1Value = asn1Spec.clone()
+
+ componentsTypes = asn1Spec.componentType
+
+ for field in asn1Value:
+ if field in pyObject:
+ asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
+
+ return asn1Value
+
+
+class SequenceOfOrSetOfDecoder(object):
+ def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+ asn1Value = asn1Spec.clone()
+
+ for pyValue in pyObject:
+ asn1Value.append(decodeFun(pyValue, asn1Spec.componentType), **options)
+
+ return asn1Value
+
+
+class ChoiceDecoder(object):
+ def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+ asn1Value = asn1Spec.clone()
+
+ componentsTypes = asn1Spec.componentType
+
+ for field in pyObject:
+ if field in componentsTypes:
+ asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
+ break
+
+ return asn1Value
+
+
+tagMap = {
+ univ.Integer.tagSet: AbstractScalarDecoder(),
+ univ.Boolean.tagSet: AbstractScalarDecoder(),
+ univ.BitString.tagSet: BitStringDecoder(),
+ univ.OctetString.tagSet: AbstractScalarDecoder(),
+ univ.Null.tagSet: AbstractScalarDecoder(),
+ univ.ObjectIdentifier.tagSet: AbstractScalarDecoder(),
+ univ.Enumerated.tagSet: AbstractScalarDecoder(),
+ univ.Real.tagSet: AbstractScalarDecoder(),
+ univ.Sequence.tagSet: SequenceOrSetDecoder(), # conflicts with SequenceOf
+ univ.Set.tagSet: SequenceOrSetDecoder(), # conflicts with SetOf
+ univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
+ # character string types
+ char.UTF8String.tagSet: AbstractScalarDecoder(),
+ char.NumericString.tagSet: AbstractScalarDecoder(),
+ char.PrintableString.tagSet: AbstractScalarDecoder(),
+ char.TeletexString.tagSet: AbstractScalarDecoder(),
+ char.VideotexString.tagSet: AbstractScalarDecoder(),
+ char.IA5String.tagSet: AbstractScalarDecoder(),
+ char.GraphicString.tagSet: AbstractScalarDecoder(),
+ char.VisibleString.tagSet: AbstractScalarDecoder(),
+ char.GeneralString.tagSet: AbstractScalarDecoder(),
+ char.UniversalString.tagSet: AbstractScalarDecoder(),
+ char.BMPString.tagSet: AbstractScalarDecoder(),
+ # useful types
+ useful.ObjectDescriptor.tagSet: AbstractScalarDecoder(),
+ useful.GeneralizedTime.tagSet: AbstractScalarDecoder(),
+ useful.UTCTime.tagSet: AbstractScalarDecoder()
+}
+
+# Put in ambiguous & non-ambiguous types for faster codec lookup
+typeMap = {
+ univ.Integer.typeId: AbstractScalarDecoder(),
+ univ.Boolean.typeId: AbstractScalarDecoder(),
+ univ.BitString.typeId: BitStringDecoder(),
+ univ.OctetString.typeId: AbstractScalarDecoder(),
+ univ.Null.typeId: AbstractScalarDecoder(),
+ univ.ObjectIdentifier.typeId: AbstractScalarDecoder(),
+ univ.Enumerated.typeId: AbstractScalarDecoder(),
+ univ.Real.typeId: AbstractScalarDecoder(),
+ # ambiguous base types
+ univ.Set.typeId: SequenceOrSetDecoder(),
+ univ.SetOf.typeId: SequenceOfOrSetOfDecoder(),
+ univ.Sequence.typeId: SequenceOrSetDecoder(),
+ univ.SequenceOf.typeId: SequenceOfOrSetOfDecoder(),
+ univ.Choice.typeId: ChoiceDecoder(),
+ univ.Any.typeId: AbstractScalarDecoder(),
+ # character string types
+ char.UTF8String.typeId: AbstractScalarDecoder(),
+ char.NumericString.typeId: AbstractScalarDecoder(),
+ char.PrintableString.typeId: AbstractScalarDecoder(),
+ char.TeletexString.typeId: AbstractScalarDecoder(),
+ char.VideotexString.typeId: AbstractScalarDecoder(),
+ char.IA5String.typeId: AbstractScalarDecoder(),
+ char.GraphicString.typeId: AbstractScalarDecoder(),
+ char.VisibleString.typeId: AbstractScalarDecoder(),
+ char.GeneralString.typeId: AbstractScalarDecoder(),
+ char.UniversalString.typeId: AbstractScalarDecoder(),
+ char.BMPString.typeId: AbstractScalarDecoder(),
+ # useful types
+ useful.ObjectDescriptor.typeId: AbstractScalarDecoder(),
+ useful.GeneralizedTime.typeId: AbstractScalarDecoder(),
+ useful.UTCTime.typeId: AbstractScalarDecoder()
+}
+
+
+class Decoder(object):
+
+ # noinspection PyDefaultArgument
+ def __init__(self, tagMap, typeMap):
+ self.__tagMap = tagMap
+ self.__typeMap = typeMap
+
+ def __call__(self, pyObject, asn1Spec, **options):
+ if debug.logger & debug.flagDecoder:
+ logger = debug.logger
+ else:
+ logger = None
+ if logger:
+ debug.scope.push(type(pyObject).__name__)
+ logger('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))
+
+ if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item):
+ raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)
+
+ try:
+ valueDecoder = self.__typeMap[asn1Spec.typeId]
+
+ except KeyError:
+ # use base type for codec lookup to recover untagged types
+ baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag)
+
+ try:
+ valueDecoder = self.__tagMap[baseTagSet]
+ except KeyError:
+ raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet)
+
+ if logger:
+ logger('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))
+
+ value = valueDecoder(pyObject, asn1Spec, self, **options)
+
+ if logger:
+ logger('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))
+ debug.scope.pop()
+
+ return value
+
+
+#: Turns Python objects of built-in types into ASN.1 objects.
+#:
+#: Takes Python objects of built-in types and turns them into a tree of
+#: ASN.1 objects (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: pyObject: :py:class:`object`
+#: A scalar or nested Python objects
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#: A pyasn1 type object to act as a template guiding the decoder. It is required
+#: for successful interpretation of Python objects mapping into their ASN.1
+#: representations.
+#:
+#: Returns
+#: -------
+#: : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#: A scalar or constructed pyasn1 object
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On decoding errors
+decode = Decoder(tagMap, typeMap)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/codec/native/encoder.py
@@ -0,0 +1,212 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ from collections import OrderedDict
+
+except ImportError:
+ OrderedDict = dict
+
+from pyasn1.type import base, univ, tag, char, useful
+from pyasn1 import debug, error
+
+__all__ = ['encode']
+
+
+class AbstractItemEncoder(object):
+ def encode(self, value, encodeFun, **options):
+ raise error.PyAsn1Error('Not implemented')
+
+
+class BooleanEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return bool(value)
+
+
+class IntegerEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return int(value)
+
+
+class BitStringEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return str(value)
+
+
+class OctetStringEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return value.asOctets()
+
+
+class TextStringEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return value.prettyPrint()
+
+
+class NullEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return None
+
+
+class ObjectIdentifierEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return str(value)
+
+
+class RealEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return float(value)
+
+
+class SetEncoder(AbstractItemEncoder):
+ protoDict = dict
+
+ def encode(self, value, encodeFun, **options):
+ value.verifySizeSpec()
+
+ namedTypes = value.componentType
+ substrate = self.protoDict()
+
+ for idx, (key, subValue) in enumerate(value.items()):
+ if namedTypes and namedTypes[idx].isOptional and not value[idx].isValue:
+ continue
+ substrate[key] = encodeFun(subValue, **options)
+ return substrate
+
+
+class SequenceEncoder(SetEncoder):
+ protoDict = OrderedDict
+
+
+class SequenceOfEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ value.verifySizeSpec()
+ return [encodeFun(x, **options) for x in value]
+
+
+class ChoiceEncoder(SequenceEncoder):
+ pass
+
+
+class AnyEncoder(AbstractItemEncoder):
+ def encode(self, value, encodeFun, **options):
+ return value.asOctets()
+
+
+tagMap = {
+ univ.Boolean.tagSet: BooleanEncoder(),
+ univ.Integer.tagSet: IntegerEncoder(),
+ univ.BitString.tagSet: BitStringEncoder(),
+ univ.OctetString.tagSet: OctetStringEncoder(),
+ univ.Null.tagSet: NullEncoder(),
+ univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),
+ univ.Enumerated.tagSet: IntegerEncoder(),
+ univ.Real.tagSet: RealEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
+ univ.SequenceOf.tagSet: SequenceOfEncoder(),
+ univ.SetOf.tagSet: SequenceOfEncoder(),
+ univ.Choice.tagSet: ChoiceEncoder(),
+ # character string types
+ char.UTF8String.tagSet: TextStringEncoder(),
+ char.NumericString.tagSet: TextStringEncoder(),
+ char.PrintableString.tagSet: TextStringEncoder(),
+ char.TeletexString.tagSet: TextStringEncoder(),
+ char.VideotexString.tagSet: TextStringEncoder(),
+ char.IA5String.tagSet: TextStringEncoder(),
+ char.GraphicString.tagSet: TextStringEncoder(),
+ char.VisibleString.tagSet: TextStringEncoder(),
+ char.GeneralString.tagSet: TextStringEncoder(),
+ char.UniversalString.tagSet: TextStringEncoder(),
+ char.BMPString.tagSet: TextStringEncoder(),
+ # useful types
+ useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
+ useful.GeneralizedTime.tagSet: OctetStringEncoder(),
+ useful.UTCTime.tagSet: OctetStringEncoder()
+}
+
+# Type-to-codec map for ambiguous ASN.1 types
+typeMap = {
+ univ.Set.typeId: SetEncoder(),
+ univ.SetOf.typeId: SequenceOfEncoder(),
+ univ.Sequence.typeId: SequenceEncoder(),
+ univ.SequenceOf.typeId: SequenceOfEncoder(),
+ univ.Choice.typeId: ChoiceEncoder(),
+ univ.Any.typeId: AnyEncoder()
+}
+
+
+class Encoder(object):
+
+ # noinspection PyDefaultArgument
+ def __init__(self, tagMap, typeMap={}):
+ self.__tagMap = tagMap
+ self.__typeMap = typeMap
+
+ def __call__(self, value, **options):
+ if not isinstance(value, base.Asn1Item):
+ raise error.PyAsn1Error('value is not valid (should be an instance of an ASN.1 Item)')
+
+ if debug.logger & debug.flagEncoder:
+ logger = debug.logger
+ else:
+ logger = None
+
+ if logger:
+ debug.scope.push(type(value).__name__)
+ logger('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))
+
+ tagSet = value.tagSet
+
+ try:
+ concreteEncoder = self.__typeMap[value.typeId]
+
+ except KeyError:
+ # use base type for codec lookup to recover untagged types
+ baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+ try:
+ concreteEncoder = self.__tagMap[baseTagSet]
+
+ except KeyError:
+ raise error.PyAsn1Error('No encoder for %s' % (value,))
+
+ if logger:
+ logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
+
+ pyObject = concreteEncoder.encode(value, self, **options)
+
+ if logger:
+ logger('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))
+ debug.scope.pop()
+
+ return pyObject
+
+
+#: Turns ASN.1 object into a Python built-in type object(s).
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a Python built-in type or a tree
+#: of those.
+#:
+#: One exception is that instead of :py:class:`dict`, the :py:class:`OrderedDict`
+#: can be produced (whenever available) to preserve ordering of the components
+#: in ASN.1 SEQUENCE.
+#:
+#: Parameters
+#: ----------
+# asn1Value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: pyasn1 object to encode (or a tree of them)
+#:
+#: Returns
+#: -------
+#: : :py:class:`object`
+#: Python built-in type instance (or a tree of them)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#: On encoding errors
+encode = Encoder(tagMap, typeMap)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/binary.py
@@ -0,0 +1,33 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+if version_info[0:2] < (2, 6):
+ def bin(value):
+ bitstring = []
+
+ if value > 0:
+ prefix = '0b'
+ elif value < 0:
+ prefix = '-0b'
+ value = abs(value)
+ else:
+ prefix = '0b0'
+
+ while value:
+ if value & 1 == 1:
+ bitstring.append('1')
+ else:
+ bitstring.append('0')
+
+ value >>= 1
+
+ bitstring.reverse()
+
+ return prefix + ''.join(bitstring)
+else:
+ bin = bin
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/calling.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+__all__ = ['callable']
+
+
+if (2, 7) < version_info[:2] < (3, 2):
+ import collections
+
+ def callable(x):
+ return isinstance(x, collections.Callable)
+
+else:
+
+ callable = callable
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/dateandtime.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+from datetime import datetime
+import time
+
+__all__ = ['strptime']
+
+
+if version_info[:2] <= (2, 4):
+
+ def strptime(text, dateFormat):
+ return datetime(*(time.strptime(text, dateFormat)[0:6]))
+
+else:
+
+ def strptime(text, dateFormat):
+ return datetime.strptime(text, dateFormat)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/integer.py
@@ -0,0 +1,108 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+ import platform
+ implementation = platform.python_implementation()
+
+except (ImportError, AttributeError):
+ implementation = 'CPython'
+
+from pyasn1.compat.octets import oct2int, null, ensureString
+
+if sys.version_info[0:2] < (3, 2) or implementation != 'CPython':
+ from binascii import a2b_hex, b2a_hex
+
+ if sys.version_info[0] > 2:
+ long = int
+
+ def from_bytes(octets, signed=False):
+ if not octets:
+ return 0
+
+ value = long(b2a_hex(ensureString(octets)), 16)
+
+ if signed and oct2int(octets[0]) & 0x80:
+ return value - (1 << len(octets) * 8)
+
+ return value
+
+ def to_bytes(value, signed=False, length=0):
+ if value < 0:
+ if signed:
+ bits = bitLength(value)
+
+ # two's complement form
+ maxValue = 1 << bits
+ valueToEncode = (value + maxValue) % maxValue
+
+ else:
+ raise OverflowError('can\'t convert negative int to unsigned')
+ elif value == 0 and length == 0:
+ return null
+ else:
+ bits = 0
+ valueToEncode = value
+
+ hexValue = hex(valueToEncode)[2:]
+ if hexValue.endswith('L'):
+ hexValue = hexValue[:-1]
+
+ if len(hexValue) & 1:
+ hexValue = '0' + hexValue
+
+ # padding may be needed for two's complement encoding
+ if value != valueToEncode or length:
+ hexLength = len(hexValue) * 4
+
+ padLength = max(length, bits)
+
+ if padLength > hexLength:
+ hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue
+ elif length and hexLength - length > 7:
+ raise OverflowError('int too big to convert')
+
+ firstOctet = int(hexValue[:2], 16)
+
+ if signed:
+ if firstOctet & 0x80:
+ if value >= 0:
+ hexValue = '00' + hexValue
+ elif value < 0:
+ hexValue = 'ff' + hexValue
+
+ octets_value = a2b_hex(hexValue)
+
+ return octets_value
+
+ def bitLength(number):
+ # bits in unsigned number
+ hexValue = hex(abs(number))
+ bits = len(hexValue) - 2
+ if hexValue.endswith('L'):
+ bits -= 1
+ if bits & 1:
+ bits += 1
+ bits *= 4
+ # TODO: strip lhs zeros
+ return bits
+
+else:
+
+ def from_bytes(octets, signed=False):
+ return int.from_bytes(bytes(octets), 'big', signed=signed)
+
+ def to_bytes(value, signed=False, length=0):
+ length = max(value.bit_length(), length)
+
+ if signed and length % 8 == 0:
+ length += 1
+
+ return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed)
+
+ def bitLength(number):
+ return int(number).bit_length()
--- a/third_party/python/pyasn1/pyasn1/compat/octets.py
+++ b/third_party/python/pyasn1/pyasn1/compat/octets.py
@@ -1,20 +1,46 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from sys import version_info
if version_info[0] <= 2:
int2oct = chr
- ints2octs = lambda s: ''.join([ int2oct(x) for x in s ])
+ # noinspection PyPep8
+ ints2octs = lambda s: ''.join([int2oct(x) for x in s])
null = ''
oct2int = ord
- octs2ints = lambda s: [ oct2int(x) for x in s ]
+ # TODO: refactor to return a sequence of ints
+ # noinspection PyPep8
+ octs2ints = lambda s: [oct2int(x) for x in s]
+ # noinspection PyPep8
str2octs = lambda x: x
+ # noinspection PyPep8
octs2str = lambda x: x
+ # noinspection PyPep8
isOctetsType = lambda s: isinstance(s, str)
+ # noinspection PyPep8
+ isStringType = lambda s: isinstance(s, (str, unicode))
+ # noinspection PyPep8
+ ensureString = str
else:
ints2octs = bytes
+ # noinspection PyPep8
int2oct = lambda x: ints2octs((x,))
null = ints2octs()
+ # noinspection PyPep8
oct2int = lambda x: x
- octs2ints = lambda s: [ x for x in s ]
- str2octs = lambda x: x.encode()
- octs2str = lambda x: x.decode()
+ # noinspection PyPep8
+ octs2ints = lambda x: x
+ # noinspection PyPep8
+ str2octs = lambda x: x.encode('iso-8859-1')
+ # noinspection PyPep8
+ octs2str = lambda x: x.decode('iso-8859-1')
+ # noinspection PyPep8
isOctetsType = lambda s: isinstance(s, bytes)
+ # noinspection PyPep8
+ isStringType = lambda s: isinstance(s, str)
+ # noinspection PyPep8
+ ensureString = bytes
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/string.py
@@ -0,0 +1,26 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+if version_info[:2] <= (2, 5):
+
+ def partition(string, sep):
+ try:
+ a, c = string.split(sep, 1)
+
+ except ValueError:
+ a, b, c = string, '', ''
+
+ else:
+ b = sep
+
+ return a, b, c
+
+else:
+
+ def partition(string, sep):
+ return string.partition(sep)
--- a/third_party/python/pyasn1/pyasn1/debug.py
+++ b/third_party/python/pyasn1/pyasn1/debug.py
@@ -1,65 +1,143 @@
-import sys
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import logging
from pyasn1.compat.octets import octs2ints
from pyasn1 import error
from pyasn1 import __version__
-flagNone = 0x0000
-flagEncoder = 0x0001
-flagDecoder = 0x0002
-flagAll = 0xffff
+__all__ = ['Debug', 'setLogger', 'hexdump']
+
+flagNone = 0x0000
+flagEncoder = 0x0001
+flagDecoder = 0x0002
+flagAll = 0xffff
flagMap = {
'encoder': flagEncoder,
'decoder': flagDecoder,
'all': flagAll
- }
+}
+
+
+class Printer(object):
+ # noinspection PyShadowingNames
+ def __init__(self, logger=None, handler=None, formatter=None):
+ if logger is None:
+ logger = logging.getLogger('pyasn1')
+
+ logger.setLevel(logging.DEBUG)
+
+ if handler is None:
+ handler = logging.StreamHandler()
+
+ if formatter is None:
+ formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s')
+
+ handler.setFormatter(formatter)
+ handler.setLevel(logging.DEBUG)
+ logger.addHandler(handler)
-class Debug:
- defaultPrinter = sys.stderr.write
- def __init__(self, *flags):
+ self.__logger = logger
+
+ def __call__(self, msg):
+ self.__logger.debug(msg)
+
+ def __str__(self):
+ return '<python logging>'
+
+
+if hasattr(logging, 'NullHandler'):
+ NullHandler = logging.NullHandler
+
+else:
+ # Python 2.6 and older
+ class NullHandler(logging.Handler):
+ def emit(self, record):
+ pass
+
+
+class Debug(object):
+ defaultPrinter = Printer()
+
+ def __init__(self, *flags, **options):
self._flags = flagNone
- self._printer = self.defaultPrinter
- self('running pyasn1 version %s' % __version__)
- for f in flags:
- if f not in flagMap:
- raise error.PyAsn1Error('bad debug flag %s' % (f,))
- self._flags = self._flags | flagMap[f]
- self('debug category \'%s\' enabled' % f)
-
+
+ if 'loggerName' in options:
+ # route our logs to parent logger
+ self._printer = Printer(
+ logger=logging.getLogger(options['loggerName']),
+ handler=NullHandler()
+ )
+
+ elif 'printer' in options:
+ self._printer = options.get('printer')
+
+ else:
+ self._printer = self.defaultPrinter
+
+ self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags)))
+
+ for flag in flags:
+ inverse = flag and flag[0] in ('!', '~')
+ if inverse:
+ flag = flag[1:]
+ try:
+ if inverse:
+ self._flags &= ~flagMap[flag]
+ else:
+ self._flags |= flagMap[flag]
+ except KeyError:
+ raise error.PyAsn1Error('bad debug flag %s' % flag)
+
+ self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled'))
+
def __str__(self):
return 'logger %s, flags %x' % (self._printer, self._flags)
-
+
def __call__(self, msg):
- self._printer('DBG: %s\n' % msg)
+ self._printer(msg)
def __and__(self, flag):
return self._flags & flag
def __rand__(self, flag):
return flag & self._flags
+
logger = 0
-def setLogger(l):
+
+def setLogger(userLogger):
global logger
- logger = l
+
+ if userLogger:
+ logger = userLogger
+ else:
+ logger = 0
+
def hexdump(octets):
return ' '.join(
- [ '%s%.2X' % (n%16 == 0 and ('\n%.5d: ' % n) or '', x)
- for n,x in zip(range(len(octets)), octs2ints(octets)) ]
- )
+ ['%s%.2X' % (n % 16 == 0 and ('\n%.5d: ' % n) or '', x)
+ for n, x in zip(range(len(octets)), octs2ints(octets))]
+ )
-class Scope:
+
+class Scope(object):
def __init__(self):
self._list = []
def __str__(self): return '.'.join(self._list)
def push(self, token):
self._list.append(token)
def pop(self):
return self._list.pop()
+
scope = Scope()
--- a/third_party/python/pyasn1/pyasn1/error.py
+++ b/third_party/python/pyasn1/pyasn1/error.py
@@ -1,3 +1,18 @@
-class PyAsn1Error(Exception): pass
-class ValueConstraintError(PyAsn1Error): pass
-class SubstrateUnderrunError(PyAsn1Error): pass
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+
+
+class PyAsn1Error(Exception):
+ pass
+
+
+class ValueConstraintError(PyAsn1Error):
+ pass
+
+
+class SubstrateUnderrunError(PyAsn1Error):
+ pass
--- a/third_party/python/pyasn1/pyasn1/type/base.py
+++ b/third_party/python/pyasn1/pyasn1/type/base.py
@@ -1,139 +1,399 @@
-# Base classes for ASN.1 types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
import sys
-from pyasn1.type import constraint, tagmap
+from pyasn1.type import constraint, tagmap, tag
+from pyasn1.compat import calling
from pyasn1 import error
-class Asn1Item: pass
+__all__ = ['Asn1Item', 'Asn1ItemBase', 'AbstractSimpleAsn1Item', 'AbstractConstructedAsn1Item']
+
+
+class Asn1Item(object):
+ @classmethod
+ def getTypeId(cls, increment=1):
+ try:
+ Asn1Item._typeCounter += increment
+ except AttributeError:
+ Asn1Item._typeCounter = increment
+ return Asn1Item._typeCounter
+
class Asn1ItemBase(Asn1Item):
- # Set of tags for this ASN.1 type
- tagSet = ()
-
- # A list of constraint.Constraint instances for checking values
+ #: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing
+ #: ASN.1 tag(s) associated with |ASN.1| type.
+ tagSet = tag.TagSet()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing constraints on initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
- # Used for ambiguous ASN.1 types identification
+ # Disambiguation ASN.1 types identification
typeId = None
-
- def __init__(self, tagSet=None, subtypeSpec=None):
- if tagSet is None:
- self._tagSet = self.tagSet
- else:
- self._tagSet = tagSet
- if subtypeSpec is None:
- self._subtypeSpec = self.subtypeSpec
- else:
- self._subtypeSpec = subtypeSpec
+
+ def __init__(self, **kwargs):
+ readOnly = {
+ 'tagSet': self.tagSet,
+ 'subtypeSpec': self.subtypeSpec
+ }
+
+ readOnly.update(kwargs)
+
+ self.__dict__.update(readOnly)
+
+ self._readOnly = readOnly
+
+ def __setattr__(self, name, value):
+ if name[0] != '_' and name in self._readOnly:
+ raise error.PyAsn1Error('read-only instance attribute "%s"' % name)
+
+ self.__dict__[name] = value
+
+ @property
+ def readOnly(self):
+ return self._readOnly
+
+ @property
+ def effectiveTagSet(self):
+ """For |ASN.1| type is equivalent to *tagSet*
+ """
+ return self.tagSet # used by untagged types
- def _verifySubtypeSpec(self, value, idx=None):
- try:
- self._subtypeSpec(value, idx)
- except error.PyAsn1Error:
- c, i, t = sys.exc_info()
- raise c('%s at %s' % (i, self.__class__.__name__))
+ @property
+ def tagMap(self):
+ """Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object.
+ """
+ return tagmap.TagMap({self.tagSet: self})
+
+ def isSameTypeWith(self, other, matchTags=True, matchConstraints=True):
+ """Examine |ASN.1| type for equality with other ASN.1 type.
+
+ ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
+ (:py:mod:`~pyasn1.type.constraint`) are examined when carrying
+ out ASN.1 types comparison.
+
+ No Python inheritance relationship between PyASN1 objects is considered.
+
+ Parameters
+ ----------
+ other: a pyasn1 type object
+ Class instance representing ASN.1 type.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if *other* is |ASN.1| type,
+ :class:`False` otherwise.
+ """
+ return (self is other or
+ (not matchTags or self.tagSet == other.tagSet) and
+ (not matchConstraints or self.subtypeSpec == other.subtypeSpec))
+
+ def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True):
+ """Examine |ASN.1| type for subtype relationship with other ASN.1 type.
- def getSubtypeSpec(self): return self._subtypeSpec
-
- def getTagSet(self): return self._tagSet
- def getEffectiveTagSet(self): return self._tagSet # used by untagged types
- def getTagMap(self): return tagmap.TagMap({self._tagSet: self})
-
- def isSameTypeWith(self, other):
- return self is other or \
- self._tagSet == other.getTagSet() and \
- self._subtypeSpec == other.getSubtypeSpec()
- def isSuperTypeOf(self, other):
- """Returns true if argument is a ASN1 subtype of ourselves"""
- return self._tagSet.isSuperTagSetOf(other.getTagSet()) and \
- self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec())
+ ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
+ (:py:mod:`~pyasn1.type.constraint`) are examined when carrying
+ out ASN.1 types comparison.
+
+ No Python inheritance relationship between PyASN1 objects is considered.
+
+
+ Parameters
+ ----------
+ other: a pyasn1 type object
+ Class instance representing ASN.1 type.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if *other* is a subtype of |ASN.1| type,
+ :class:`False` otherwise.
+ """
+ return (not matchTags or
+ (self.tagSet.isSuperTagSetOf(other.tagSet)) and
+ (not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec)))
+
+ @staticmethod
+ def isNoValue(*values):
+ for value in values:
+ if value is not None and value is not noValue:
+ return False
+ return True
+
+ # backward compatibility
+
+ def getTagSet(self):
+ return self.tagSet
+
+ def getEffectiveTagSet(self):
+ return self.effectiveTagSet
+
+ def getTagMap(self):
+ return self.tagMap
+
+ def getSubtypeSpec(self):
+ return self.subtypeSpec
+
+ def hasValue(self):
+ return self.isValue
+
-class __NoValue:
+class NoValue(object):
+ """Create a singleton instance of NoValue class.
+
+ NoValue object can be used as an initializer on PyASN1 type class
+ instantiation to represent ASN.1 type rather than ASN.1 data value.
+
+ No operations other than type comparison can be performed on
+ a PyASN1 type object.
+ """
+ skipMethods = ('__getattribute__', '__getattr__', '__setattr__', '__delattr__',
+ '__class__', '__init__', '__del__', '__new__', '__repr__',
+ '__qualname__', '__objclass__', 'im_class', '__sizeof__')
+
+ _instance = None
+
+ def __new__(cls):
+ if cls._instance is None:
+ def getPlug(name):
+ def plug(self, *args, **kw):
+ raise error.PyAsn1Error('Uninitialized ASN.1 value ("%s" attribute looked up)' % name)
+ return plug
+
+ op_names = [name
+ for typ in (str, int, list, dict)
+ for name in dir(typ)
+ if (name not in cls.skipMethods and
+ name.startswith('__') and
+ name.endswith('__') and
+ calling.callable(getattr(typ, name)))]
+
+ for name in set(op_names):
+ setattr(cls, name, getPlug(name))
+
+ cls._instance = object.__new__(cls)
+
+ return cls._instance
+
def __getattr__(self, attr):
- raise error.PyAsn1Error('No value for %s()' % attr)
- def __getitem__(self, i):
- raise error.PyAsn1Error('No value')
-
-noValue = __NoValue()
+ if attr in self.skipMethods:
+ raise AttributeError('attribute %s not present' % attr)
+ raise error.PyAsn1Error('No value for "%s"' % attr)
+
+ def __repr__(self):
+ return '%s()' % self.__class__.__name__
+
+noValue = NoValue()
+
# Base class for "simple" ASN.1 objects. These are immutable.
-class AbstractSimpleAsn1Item(Asn1ItemBase):
+class AbstractSimpleAsn1Item(Asn1ItemBase):
+ #: Default payload value
defaultValue = noValue
- def __init__(self, value=None, tagSet=None, subtypeSpec=None):
- Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
- if value is None or value is noValue:
+
+ def __init__(self, value=noValue, **kwargs):
+ Asn1ItemBase.__init__(self, **kwargs)
+ if value is noValue or value is None:
value = self.defaultValue
- if value is None or value is noValue:
- self.__hashedValue = value = noValue
else:
value = self.prettyIn(value)
- self._verifySubtypeSpec(value)
- self.__hashedValue = hash(value)
+ try:
+ self.subtypeSpec(value)
+
+ except error.PyAsn1Error:
+ exType, exValue, exTb = sys.exc_info()
+ raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
self._value = value
- self._len = None
-
+
def __repr__(self):
- if self._value is noValue:
- return self.__class__.__name__ + '()'
- else:
- return self.__class__.__name__ + '(%s)' % (self.prettyOut(self._value),)
- def __str__(self): return str(self._value)
+ representation = []
+ if self._value is not self.defaultValue:
+ representation.append(self.prettyOut(self._value))
+ if self.tagSet is not self.__class__.tagSet:
+ representation.append('tagSet=%r' % (self.tagSet,))
+ if self.subtypeSpec is not self.__class__.subtypeSpec:
+ representation.append('subtypeSpec=%r' % (self.subtypeSpec,))
+ return '%s(%s)' % (self.__class__.__name__, ', '.join(representation))
+
+ def __str__(self):
+ return str(self._value)
+
def __eq__(self, other):
return self is other and True or self._value == other
- def __ne__(self, other): return self._value != other
- def __lt__(self, other): return self._value < other
- def __le__(self, other): return self._value <= other
- def __gt__(self, other): return self._value > other
- def __ge__(self, other): return self._value >= other
+
+ def __ne__(self, other):
+ return self._value != other
+
+ def __lt__(self, other):
+ return self._value < other
+
+ def __le__(self, other):
+ return self._value <= other
+
+ def __gt__(self, other):
+ return self._value > other
+
+ def __ge__(self, other):
+ return self._value >= other
+
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(self._value)
+ def __nonzero__(self):
+ return self._value and True or False
else:
- def __bool__(self): return bool(self._value)
- def __hash__(self): return self.__hashedValue
+ def __bool__(self):
+ return self._value and True or False
+
+ def __hash__(self):
+ return hash(self._value)
+
+ @property
+ def isValue(self):
+ """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+ In other words, if *isValue* is `True`, then the ASN.1 object is
+ initialized.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if object represents ASN.1 value and type,
+ :class:`False` if object represents just ASN.1 type.
+
+ Note
+ ----
+ There is an important distinction between PyASN1 type and value objects.
+ The PyASN1 type objects can only participate in ASN.1 type
+ operations (subtyping, comparison etc) and serve as a
+ blueprint for serialization codecs to resolve ambiguous types.
- def clone(self, value=None, tagSet=None, subtypeSpec=None):
- if value is None and tagSet is None and subtypeSpec is None:
- return self
- if value is None:
+ The PyASN1 value objects can additionally participate in most
+ of built-in Python operations.
+ """
+ return self._value is not noValue
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ if value is noValue or value is None:
+ if not kwargs:
+ return self
+
value = self._value
- if tagSet is None:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- return self.__class__(value, tagSet, subtypeSpec)
+
+ initilaizers = self.readOnly.copy()
+ initilaizers.update(kwargs)
+
+ return self.__class__(value, **initilaizers)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
- def subtype(self, value=None, implicitTag=None, explicitTag=None,
- subtypeSpec=None):
- if value is None:
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Add ASN.1 constraints object to one of the caller, then
+ use the result as new object's ASN.1 constraints.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ if value is noValue or value is None:
+ if not kwargs:
+ return self
+
value = self._value
+
+ initializers = self.readOnly.copy()
+
+ implicitTag = kwargs.pop('implicitTag', None)
if implicitTag is not None:
- tagSet = self._tagSet.tagImplicitly(implicitTag)
- elif explicitTag is not None:
- tagSet = self._tagSet.tagExplicitly(explicitTag)
- else:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- else:
- subtypeSpec = subtypeSpec + self._subtypeSpec
- return self.__class__(value, tagSet, subtypeSpec)
+ initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
+
+ explicitTag = kwargs.pop('explicitTag', None)
+ if explicitTag is not None:
+ initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
- def prettyIn(self, value): return value
- def prettyOut(self, value): return str(value)
+ for arg, option in kwargs.items():
+ initializers[arg] += option
+
+ return self.__class__(value, **initializers)
+
+ def prettyIn(self, value):
+ return value
+
+ def prettyOut(self, value):
+ return str(value)
def prettyPrint(self, scope=0):
- if self._value is noValue:
+ """Provide human-friendly printable object representation.
+
+ Returns
+ -------
+ : :class:`str`
+ human-friendly type and/or value representation.
+ """
+ if self.isValue:
+ return self.prettyOut(self._value)
+ else:
return '<no value>'
- else:
- return self.prettyOut(self._value)
# XXX Compatibility stub
- def prettyPrinter(self, scope=0): return self.prettyPrint(scope)
-
+ def prettyPrinter(self, scope=0):
+ return self.prettyPrint(scope)
+
+ # noinspection PyUnusedLocal
+ def prettyPrintType(self, scope=0):
+ return '%s -> %s' % (self.tagSet, self.__class__.__name__)
+
#
# Constructed types:
# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
# * ASN1 types and values are represened by Python class instances
# * Value initialization is made for defaulted components only
# * Primary method of component addressing is by-position. Data model for base
# type is Python sequence. Additional type-specific addressing methods
# may be implemented for particular types.
@@ -143,107 +403,199 @@ class AbstractSimpleAsn1Item(Asn1ItemBas
# * Sequence and Set types may include optional and defaulted
# components
# * Constructed types hold a reference to component types used for value
# verification and ordering.
# * Component type is a scalar type for SequenceOf/SetOf types and a list
# of types for Sequence/Set/Choice.
#
+def setupComponent():
+ """Returns a sentinel value.
+
+ Indicates to a constructed type to set up its inner component so that it
+ can be referred to. This is useful in situation when you want to populate
+ descendants of a constructed type what requires being able to refer to
+ their parent types along the way.
+
+ Example
+ -------
+
+ >>> constructed['record'] = setupComponent()
+ >>> constructed['record']['scalar'] = 42
+ """
+ return noValue
+
+
class AbstractConstructedAsn1Item(Asn1ItemBase):
+
+ #: If `True`, requires exact component type matching,
+ #: otherwise subtype relation is only enforced
+ strictConstraints = False
+
componentType = None
- sizeSpec = constraint.ConstraintsIntersection()
- def __init__(self, componentType=None, tagSet=None,
- subtypeSpec=None, sizeSpec=None):
- Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
- if componentType is None:
- self._componentType = self.componentType
- else:
- self._componentType = componentType
- if sizeSpec is None:
- self._sizeSpec = self.sizeSpec
- else:
- self._sizeSpec = sizeSpec
+ sizeSpec = None
+
+ def __init__(self, **kwargs):
+ readOnly = {
+ 'componentType': self.componentType,
+ 'sizeSpec': self.sizeSpec
+ }
+ readOnly.update(kwargs)
+
+ Asn1ItemBase.__init__(self, **readOnly)
+
self._componentValues = []
- self._componentValuesSet = 0
def __repr__(self):
- r = self.__class__.__name__ + '()'
- for idx in range(len(self._componentValues)):
- if self._componentValues[idx] is None:
- continue
- r = r + '.setComponentByPosition(%s, %r)' % (
- idx, self._componentValues[idx]
- )
- return r
+ representation = []
+ if self.componentType is not self.__class__.componentType:
+ representation.append('componentType=%r' % (self.componentType,))
+ if self.tagSet is not self.__class__.tagSet:
+ representation.append('tagSet=%r' % (self.tagSet,))
+ if self.subtypeSpec is not self.__class__.subtypeSpec:
+ representation.append('subtypeSpec=%r' % (self.subtypeSpec,))
+ representation = '%s(%s)' % (self.__class__.__name__, ', '.join(representation))
+ if self._componentValues:
+ for idx, component in enumerate(self._componentValues):
+ if component is None or component is noValue:
+ continue
+ representation += '.setComponentByPosition(%d, %s)' % (idx, repr(component))
+ return representation
def __eq__(self, other):
return self is other and True or self._componentValues == other
- def __ne__(self, other): return self._componentValues != other
- def __lt__(self, other): return self._componentValues < other
- def __le__(self, other): return self._componentValues <= other
- def __gt__(self, other): return self._componentValues > other
- def __ge__(self, other): return self._componentValues >= other
+
+ def __ne__(self, other):
+ return self._componentValues != other
+
+ def __lt__(self, other):
+ return self._componentValues < other
+
+ def __le__(self, other):
+ return self._componentValues <= other
+
+ def __gt__(self, other):
+ return self._componentValues > other
+
+ def __ge__(self, other):
+ return self._componentValues >= other
+
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(self._componentValues)
+ def __nonzero__(self):
+ return self._componentValues and True or False
else:
- def __bool__(self): return bool(self._componentValues)
+ def __bool__(self):
+ return self._componentValues and True or False
+
+ def _cloneComponentValues(self, myClone, cloneValueFlag):
+ pass
- def getComponentTagMap(self):
- raise error.PyAsn1Error('Method not implemented')
+ def clone(self, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
- def _cloneComponentValues(self, myClone, cloneValueFlag): pass
+ Parameters
+ ----------
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
- def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None,
- cloneValueFlag=None):
- if tagSet is None:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- if sizeSpec is None:
- sizeSpec = self._sizeSpec
- r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
+ sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 size constraint(s)
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+
+ """
+ cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+ initilaizers = self.readOnly.copy()
+ initilaizers.update(kwargs)
+
+ clone = self.__class__(**initilaizers)
+
if cloneValueFlag:
- self._cloneComponentValues(r, cloneValueFlag)
- return r
+ self._cloneComponentValues(clone, cloneValueFlag)
+
+ return clone
+
+ def subtype(self, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
- def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None,
- sizeSpec=None, cloneValueFlag=None):
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 size constraint(s)
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+
+ """
+
+ initializers = self.readOnly.copy()
+
+ cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+ implicitTag = kwargs.pop('implicitTag', None)
if implicitTag is not None:
- tagSet = self._tagSet.tagImplicitly(implicitTag)
- elif explicitTag is not None:
- tagSet = self._tagSet.tagExplicitly(explicitTag)
- else:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- else:
- subtypeSpec = subtypeSpec + self._subtypeSpec
- if sizeSpec is None:
- sizeSpec = self._sizeSpec
- else:
- sizeSpec = sizeSpec + self._sizeSpec
- r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
+ initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
+
+ explicitTag = kwargs.pop('explicitTag', None)
+ if explicitTag is not None:
+ initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
+
+ for arg, option in kwargs.items():
+ initializers[arg] += option
+
+ clone = self.__class__(**initializers)
+
if cloneValueFlag:
- self._cloneComponentValues(r, cloneValueFlag)
- return r
+ self._cloneComponentValues(clone, cloneValueFlag)
- def _verifyComponent(self, idx, value): pass
+ return clone
- def verifySizeSpec(self): self._sizeSpec(self)
+ def verifySizeSpec(self):
+ self.sizeSpec(self)
def getComponentByPosition(self, idx):
raise error.PyAsn1Error('Method not implemented')
+
def setComponentByPosition(self, idx, value, verifyConstraints=True):
raise error.PyAsn1Error('Method not implemented')
- def getComponentType(self): return self._componentType
+ def setComponents(self, *args, **kwargs):
+ for idx, value in enumerate(args):
+ self[idx] = value
+ for k in kwargs:
+ self[k] = kwargs[k]
+ return self
- def __getitem__(self, idx): return self.getComponentByPosition(idx)
- def __setitem__(self, idx, value): self.setComponentByPosition(idx, value)
+ def __len__(self):
+ return len(self._componentValues)
- def __len__(self): return len(self._componentValues)
-
def clear(self):
self._componentValues = []
- self._componentValuesSet = 0
+
+ # backward compatibility
- def setDefaultComponents(self): pass
+ def setDefaultComponents(self):
+ pass
+
+ def getComponentType(self):
+ return self.componentType
--- a/third_party/python/pyasn1/pyasn1/type/char.py
+++ b/third_party/python/pyasn1/pyasn1/type/char.py
@@ -1,61 +1,374 @@
-# ASN.1 "character string" types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
from pyasn1.type import univ, tag
+from pyasn1 import error
+
+
+__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString',
+ 'IA5String', 'GraphicString', 'VisibleString', 'ISO646String',
+ 'GeneralString', 'UniversalString', 'BMPString', 'UTF8String']
+
+NoValue = univ.NoValue
+noValue = univ.noValue
+
+
+class AbstractCharacterString(univ.OctetString):
+ """Creates |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python 2 :class:`unicode` or Python 3 :class:`str`.
+ When used in octet-stream context, |ASN.1| type assumes "|encoding|" encoding.
+
+ Parameters
+ ----------
+ value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+ unicode object (Python 2) or string (Python 3), alternatively string
+ (Python 2) or bytes (Python 3) representing octet-stream of serialized
+ unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
+ :class:`str` (Python 3) the payload when |ASN.1| object is used
+ in octet-stream context.
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
+
+ if sys.version_info[0] <= 2:
+ def __str__(self):
+ try:
+ return self._value.encode(self.encoding)
+ except UnicodeEncodeError:
+ raise error.PyAsn1Error(
+ "Can't encode string '%s' with codec %s" % (self._value, self.encoding)
+ )
+
+ def __unicode__(self):
+ return unicode(self._value)
+
+ def prettyIn(self, value):
+ try:
+ if isinstance(value, unicode):
+ return value
+ elif isinstance(value, str):
+ return value.decode(self.encoding)
+ elif isinstance(value, (tuple, list)):
+ return self.prettyIn(''.join([chr(x) for x in value]))
+ elif isinstance(value, univ.OctetString):
+ return value.asOctets().decode(self.encoding)
+ else:
+ return unicode(value)
+
+ except (UnicodeDecodeError, LookupError):
+ raise error.PyAsn1Error(
+ "Can't decode string '%s' with codec %s" % (value, self.encoding)
+ )
+
+ def asOctets(self, padding=True):
+ return str(self)
+
+ def asNumbers(self, padding=True):
+ return tuple([ord(x) for x in str(self)])
+
+ else:
+ def __str__(self):
+ return str(self._value)
+
+ def __bytes__(self):
+ try:
+ return self._value.encode(self.encoding)
+ except UnicodeEncodeError:
+ raise error.PyAsn1Error(
+ "Can't encode string '%s' with codec %s" % (self._value, self.encoding)
+ )
+
+ def prettyIn(self, value):
+ try:
+ if isinstance(value, str):
+ return value
+ elif isinstance(value, bytes):
+ return value.decode(self.encoding)
+ elif isinstance(value, (tuple, list)):
+ return self.prettyIn(bytes(value))
+ elif isinstance(value, univ.OctetString):
+ return value.asOctets().decode(self.encoding)
+ else:
+ return str(value)
+
+ except (UnicodeDecodeError, LookupError):
+ raise error.PyAsn1Error(
+ "Can't decode string '%s' with codec %s" % (value, self.encoding)
+ )
+
+ def asOctets(self, padding=True):
+ return bytes(self)
+
+ def asNumbers(self, padding=True):
+ return tuple(bytes(self))
+
+ def prettyOut(self, value):
+ return value
+
+ def __reversed__(self):
+ return reversed(self._value)
+
+ def clone(self, value=noValue, **kwargs):
+ """Creates a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+ unicode object (Python 2) or string (Python 3), alternatively string
+ (Python 2) or bytes (Python 3) representing octet-stream of serialized
+ unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :py:class:`unicode` (Python 2) or
+ :py:class:`str` (Python 3) the payload when |ASN.1| object is used
+ in octet-stream context.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+
+ """
+ return univ.OctetString.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Creates a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+ unicode object (Python 2) or string (Python 3), alternatively string
+ (Python 2) or bytes (Python 3) representing octet-stream of serialized
+ unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
-class UTF8String(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :py:class:`unicode` (Python 2) or
+ :py:class:`str` (Python 3) the payload when |ASN.1| object is used
+ in octet-stream context.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+
+ """
+ return univ.OctetString.subtype(self, value, **kwargs)
+
+class NumericString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
+ )
+ encoding = 'us-ascii'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class PrintableString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
+ )
+ encoding = 'us-ascii'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class TeletexString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
+ )
+ encoding = 'iso-8859-1'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class T61String(TeletexString):
+ __doc__ = TeletexString.__doc__
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class VideotexString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
+ )
+ encoding = 'iso-8859-1'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class IA5String(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
+ )
+ encoding = 'us-ascii'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class GraphicString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
+ )
+ encoding = 'iso-8859-1'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class VisibleString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
+ )
+ encoding = 'us-ascii'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class ISO646String(VisibleString):
+ __doc__ = VisibleString.__doc__
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+class GeneralString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
+ )
+ encoding = 'iso-8859-1'
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class UniversalString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
+ )
+ encoding = "utf-32-be"
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class BMPString(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
+ )
+ encoding = "utf-16-be"
+
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
+
+
+class UTF8String(AbstractCharacterString):
+ __doc__ = AbstractCharacterString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
- )
+ )
encoding = "utf-8"
-class NumericString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
- )
-
-class PrintableString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
- )
-
-class TeletexString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
- )
-
-
-class VideotexString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
- )
-
-class IA5String(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
- )
-
-class GraphicString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
- )
-
-class VisibleString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
- )
-
-class GeneralString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
- )
-
-class UniversalString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
- )
- encoding = "utf-32-be"
-
-class BMPString(univ.OctetString):
- tagSet = univ.OctetString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
- )
- encoding = "utf-16-be"
+ # Optimization for faster codec lookup
+ typeId = AbstractCharacterString.getTypeId()
--- a/third_party/python/pyasn1/pyasn1/type/constraint.py
+++ b/third_party/python/pyasn1/pyasn1/type/constraint.py
@@ -1,200 +1,258 @@
#
-# ASN.1 subtype constraints classes.
+# This file is part of pyasn1 software.
#
-# Constraints are relatively rare, but every ASN1 object
-# is doing checks all the time for whether they have any
-# constraints and whether they are applicable to the object.
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
#
-# What we're going to do is define objects/functions that
-# can be called unconditionally if they are present, and that
-# are simply not present if there are no constraints.
-#
-# Original concept and code by Mike C. Fletcher.
+# Original concept and code by Mike C. Fletcher.
#
import sys
from pyasn1.type import error
-class AbstractConstraint:
+__all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint', 'ValueRangeConstraint',
+ 'ValueSizeConstraint', 'PermittedAlphabetConstraint', 'InnerTypeConstraint',
+ 'ConstraintsExclusion', 'ConstraintsIntersection', 'ConstraintsUnion']
+
+
+class AbstractConstraint(object):
"""Abstract base-class for constraint objects
Constraints should be stored in a simple sequence in the
- namespace of their client Asn1Item sub-classes.
+ namespace of their client Asn1Item sub-classes in cases
+ when ASN.1 constraint is define.
"""
+
def __init__(self, *values):
- self._valueMap = {}
+ self._valueMap = set()
self._setValues(values)
- self.__hashedValues = None
+ self.__hash = hash((self.__class__.__name__, self._values))
+
def __call__(self, value, idx=None):
+ if not self._values:
+ return
+
try:
self._testValue(value, idx)
+
except error.ValueConstraintError:
raise error.ValueConstraintError(
- '%s failed at: \"%s\"' % (self, sys.exc_info()[1])
+ '%s failed at: %r' % (self, sys.exc_info()[1])
)
+
def __repr__(self):
return '%s(%s)' % (
self.__class__.__name__,
', '.join([repr(x) for x in self._values])
)
+
def __eq__(self, other):
return self is other and True or self._values == other
- def __ne__(self, other): return self._values != other
- def __lt__(self, other): return self._values < other
- def __le__(self, other): return self._values <= other
- def __gt__(self, other): return self._values > other
- def __ge__(self, other): return self._values >= other
+
+ def __ne__(self, other):
+ return self._values != other
+
+ def __lt__(self, other):
+ return self._values < other
+
+ def __le__(self, other):
+ return self._values <= other
+
+ def __gt__(self, other):
+ return self._values > other
+
+ def __ge__(self, other):
+ return self._values >= other
+
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(self._values)
+ def __nonzero__(self):
+ return self._values and True or False
else:
- def __bool__(self): return bool(self._values)
+ def __bool__(self):
+ return self._values and True or False
def __hash__(self):
- if self.__hashedValues is None:
- self.__hashedValues = hash((self.__class__.__name__, self._values))
- return self.__hashedValues
+ return self.__hash
- def _setValues(self, values): self._values = values
+ def _setValues(self, values):
+ self._values = values
+
def _testValue(self, value, idx):
raise error.ValueConstraintError(value)
# Constraints derivation logic
- def getValueMap(self): return self._valueMap
+ def getValueMap(self):
+ return self._valueMap
+
def isSuperTypeOf(self, otherConstraint):
- return self in otherConstraint.getValueMap() or \
- otherConstraint is self or otherConstraint == self
+ # TODO: fix possible comparison of set vs scalars here
+ return (otherConstraint is self or
+ not self._values or
+ otherConstraint == self or
+ self in otherConstraint.getValueMap())
+
def isSubTypeOf(self, otherConstraint):
- return otherConstraint in self._valueMap or \
- otherConstraint is self or otherConstraint == self
+ return (otherConstraint is self or
+ not self or
+ otherConstraint == self or
+ otherConstraint in self._valueMap)
class SingleValueConstraint(AbstractConstraint):
"""Value must be part of defined values constraint"""
+
+ def _setValues(self, values):
+ self._values = values
+ self._set = set(values)
+
def _testValue(self, value, idx):
- # XXX index vals for performance?
- if value not in self._values:
+ if value not in self._set:
raise error.ValueConstraintError(value)
+
class ContainedSubtypeConstraint(AbstractConstraint):
"""Value must satisfy all of defined set of constraints"""
+
def _testValue(self, value, idx):
for c in self._values:
c(value, idx)
+
class ValueRangeConstraint(AbstractConstraint):
"""Value must be within start and stop values (inclusive)"""
+
def _testValue(self, value, idx):
if value < self.start or value > self.stop:
raise error.ValueConstraintError(value)
def _setValues(self, values):
if len(values) != 2:
raise error.PyAsn1Error(
'%s: bad constraint values' % (self.__class__.__name__,)
- )
+ )
self.start, self.stop = values
if self.start > self.stop:
raise error.PyAsn1Error(
'%s: screwed constraint values (start > stop): %s > %s' % (
self.__class__.__name__,
self.start, self.stop
)
)
AbstractConstraint._setValues(self, values)
-
+
+
class ValueSizeConstraint(ValueRangeConstraint):
"""len(value) must be within start and stop values (inclusive)"""
+
def _testValue(self, value, idx):
- l = len(value)
- if l < self.start or l > self.stop:
+ valueSize = len(value)
+ if valueSize < self.start or valueSize > self.stop:
raise error.ValueConstraintError(value)
+
class PermittedAlphabetConstraint(SingleValueConstraint):
def _setValues(self, values):
- self._values = ()
- for v in values:
- self._values = self._values + tuple(v)
+ self._values = values
+ self._set = set(values)
def _testValue(self, value, idx):
- for v in value:
- if v not in self._values:
- raise error.ValueConstraintError(value)
+ if not self._set.issuperset(value):
+ raise error.ValueConstraintError(value)
-# This is a bit kludgy, meaning two op modes within a single constraing
+
+# This is a bit kludgy, meaning two op modes within a single constraint
class InnerTypeConstraint(AbstractConstraint):
"""Value must satisfy type and presense constraints"""
+
def _testValue(self, value, idx):
if self.__singleTypeConstraint:
self.__singleTypeConstraint(value)
elif self.__multipleTypeConstraint:
if idx not in self.__multipleTypeConstraint:
raise error.ValueConstraintError(value)
constraint, status = self.__multipleTypeConstraint[idx]
- if status == 'ABSENT': # XXX presense is not checked!
+ if status == 'ABSENT': # XXX presense is not checked!
raise error.ValueConstraintError(value)
constraint(value)
def _setValues(self, values):
self.__multipleTypeConstraint = {}
self.__singleTypeConstraint = None
for v in values:
if isinstance(v, tuple):
self.__multipleTypeConstraint[v[0]] = v[1], v[2]
else:
self.__singleTypeConstraint = v
AbstractConstraint._setValues(self, values)
-# Boolean ops on constraints
+
+# Boolean ops on constraints
class ConstraintsExclusion(AbstractConstraint):
"""Value must not fit the single constraint"""
+
def _testValue(self, value, idx):
try:
self._values[0](value, idx)
except error.ValueConstraintError:
return
else:
raise error.ValueConstraintError(value)
def _setValues(self, values):
if len(values) != 1:
raise error.PyAsn1Error('Single constraint expected')
AbstractConstraint._setValues(self, values)
+
class AbstractConstraintSet(AbstractConstraint):
"""Value must not satisfy the single constraint"""
- def __getitem__(self, idx): return self._values[idx]
+
+ def __getitem__(self, idx):
+ return self._values[idx]
+
+ def __iter__(self):
+ return iter(self._values)
- def __add__(self, value): return self.__class__(self, value)
- def __radd__(self, value): return self.__class__(self, value)
+ def __add__(self, value):
+ return self.__class__(*(self._values + (value,)))
- def __len__(self): return len(self._values)
+ def __radd__(self, value):
+ return self.__class__(*((value,) + self._values))
+
+ def __len__(self):
+ return len(self._values)
# Constraints inclusion in sets
-
+
def _setValues(self, values):
self._values = values
- for v in values:
- self._valueMap[v] = 1
- self._valueMap.update(v.getValueMap())
+ for constraint in values:
+ if constraint:
+ self._valueMap.add(constraint)
+ self._valueMap.update(constraint.getValueMap())
+
class ConstraintsIntersection(AbstractConstraintSet):
"""Value must satisfy all constraints"""
+
def _testValue(self, value, idx):
- for v in self._values:
- v(value, idx)
+ for constraint in self._values:
+ constraint(value, idx)
+
class ConstraintsUnion(AbstractConstraintSet):
"""Value must satisfy at least one constraint"""
+
def _testValue(self, value, idx):
- for v in self._values:
+ for constraint in self._values:
try:
- v(value, idx)
+ constraint(value, idx)
except error.ValueConstraintError:
pass
else:
return
raise error.ValueConstraintError(
'all of %s failed for \"%s\"' % (self._values, value)
- )
+ )
# XXX
# add tests for type check
--- a/third_party/python/pyasn1/pyasn1/type/error.py
+++ b/third_party/python/pyasn1/pyasn1/type/error.py
@@ -1,3 +1,11 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1.error import PyAsn1Error
-class ValueConstraintError(PyAsn1Error): pass
+
+class ValueConstraintError(PyAsn1Error):
+ pass
--- a/third_party/python/pyasn1/pyasn1/type/namedtype.py
+++ b/third_party/python/pyasn1/pyasn1/type/namedtype.py
@@ -1,132 +1,511 @@
-# NamedType specification for constructed types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
import sys
-from pyasn1.type import tagmap
+from pyasn1.type import tag, tagmap
from pyasn1 import error
-class NamedType:
- isOptional = 0
- isDefaulted = 0
- def __init__(self, name, t):
- self.__name = name; self.__type = t
- def __repr__(self): return '%s(%s, %s)' % (
- self.__class__.__name__, self.__name, self.__type
- )
- def getType(self): return self.__type
- def getName(self): return self.__name
+__all__ = ['NamedType', 'OptionalNamedType', 'DefaultedNamedType', 'NamedTypes']
+
+
+class NamedType(object):
+ """Create named field object for a constructed ASN.1 type.
+
+ The |NamedType| object represents a single name and ASN.1 type of a constructed ASN.1 type.
+
+ |NamedType| objects are immutable and duck-type Python :class:`tuple` objects
+ holding *name* and *asn1Object* components.
+
+ Parameters
+ ----------
+ name: :py:class:`str`
+ Field name
+
+ asn1Object:
+ ASN.1 type object
+ """
+ isOptional = False
+ isDefaulted = False
+
+ def __init__(self, name, asn1Object):
+ self.__name = name
+ self.__type = asn1Object
+ self.__nameAndType = name, asn1Object
+
+ def __repr__(self):
+ return '%s(%r, %r)' % (self.__class__.__name__, self.__name, self.__type)
+
+ def __eq__(self, other):
+ return self.__nameAndType == other
+
+ def __ne__(self, other):
+ return self.__nameAndType != other
+
+ def __lt__(self, other):
+ return self.__nameAndType < other
+
+ def __le__(self, other):
+ return self.__nameAndType <= other
+
+ def __gt__(self, other):
+ return self.__nameAndType > other
+
+ def __ge__(self, other):
+ return self.__nameAndType >= other
+
+ def __hash__(self):
+ return hash(self.__nameAndType)
+
def __getitem__(self, idx):
- if idx == 0: return self.__name
- if idx == 1: return self.__type
- raise IndexError()
+ return self.__nameAndType[idx]
+
+ def __iter__(self):
+ return iter(self.__nameAndType)
+
+ @property
+ def name(self):
+ return self.__name
+ @property
+ def asn1Object(self):
+ return self.__type
+
+ # Backward compatibility
+
+ def getName(self):
+ return self.name
+
+ def getType(self):
+ return self.asn1Object
+
+
class OptionalNamedType(NamedType):
- isOptional = 1
+ __doc__ = NamedType.__doc__
+
+ isOptional = True
+
+
class DefaultedNamedType(NamedType):
- isDefaulted = 1
-
-class NamedTypes:
- def __init__(self, *namedTypes):
+ __doc__ = NamedType.__doc__
+
+ isDefaulted = True
+
+
+class NamedTypes(object):
+ """Create a collection of named fields for a constructed ASN.1 type.
+
+ The NamedTypes object represents a collection of named fields of a constructed ASN.1 type.
+
+ *NamedTypes* objects are immutable and duck-type Python :class:`dict` objects
+ holding *name* as keys and ASN.1 type object as values.
+
+ Parameters
+ ----------
+ *namedTypes: :class:`~pyasn1.type.namedtype.NamedType`
+ """
+ def __init__(self, *namedTypes, **kwargs):
self.__namedTypes = namedTypes
self.__namedTypesLen = len(self.__namedTypes)
- self.__minTagSet = None
- self.__tagToPosIdx = {}; self.__nameToPosIdx = {}
- self.__tagMap = { False: None, True: None }
- self.__ambigiousTypes = {}
+ self.__minTagSet = self.__computeMinTagSet()
+ self.__nameToPosMap = self.__computeNameToPosMap()
+ self.__tagToPosMap = self.__computeTagToPosMap()
+ self.__ambiguousTypes = 'terminal' not in kwargs and self.__computeAmbiguousTypes() or {}
+ self.__uniqueTagMap = self.__computeTagMaps(unique=True)
+ self.__nonUniqueTagMap = self.__computeTagMaps(unique=False)
+ self.__hasOptionalOrDefault = bool([True for namedType in self.__namedTypes
+ if namedType.isDefaulted or namedType.isOptional])
+ self.__requiredComponents = frozenset(
+ [idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted]
+ )
+ self.__keys = frozenset([namedType.name for namedType in self.__namedTypes])
+ self.__values = tuple([namedType.asn1Object for namedType in self.__namedTypes])
+ self.__items = tuple([(namedType.name, namedType.asn1Object) for namedType in self.__namedTypes])
def __repr__(self):
- r = '%s(' % self.__class__.__name__
- for n in self.__namedTypes:
- r = r + '%r, ' % (n,)
- return r + ')'
-
- def __getitem__(self, idx): return self.__namedTypes[idx]
+ return '%s(%s)' % (
+ self.__class__.__name__, ', '.join([repr(x) for x in self.__namedTypes])
+ )
+
+ def __eq__(self, other):
+ return self.__namedTypes == other
+
+ def __ne__(self, other):
+ return self.__namedTypes != other
+
+ def __lt__(self, other):
+ return self.__namedTypes < other
+
+ def __le__(self, other):
+ return self.__namedTypes <= other
+
+ def __gt__(self, other):
+ return self.__namedTypes > other
+
+ def __ge__(self, other):
+ return self.__namedTypes >= other
+
+ def __hash__(self):
+ return hash(self.__namedTypes)
+
+ def __getitem__(self, idx):
+ try:
+ return self.__namedTypes[idx]
+
+ except TypeError:
+ return self.__namedTypes[self.__nameToPosMap[idx]]
+
+ def __contains__(self, key):
+ return key in self.__nameToPosMap
+
+ def __iter__(self):
+ return (x[0] for x in self.__namedTypes)
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(self.__namedTypesLen)
+ def __nonzero__(self):
+ return self.__namedTypesLen > 0
else:
- def __bool__(self): return bool(self.__namedTypesLen)
- def __len__(self): return self.__namedTypesLen
-
+ def __bool__(self):
+ return self.__namedTypesLen > 0
+
+ def __len__(self):
+ return self.__namedTypesLen
+
+ # Python dict protocol
+
+ def values(self):
+ return self.__values
+
+ def keys(self):
+ return self.__keys
+
+ def items(self):
+ return self.__items
+
+ def clone(self):
+ return self.__class__(*self.__namedTypes)
+
+ class PostponedError(object):
+ def __init__(self, errorMsg):
+ self.__errorMsg = errorMsg
+
+ def __getitem__(self, item):
+ raise error.PyAsn1Error(self.__errorMsg)
+
+ def __computeTagToPosMap(self):
+ tagToPosMap = {}
+ for idx, namedType in enumerate(self.__namedTypes):
+ tagMap = namedType.asn1Object.tagMap
+ if isinstance(tagMap, NamedTypes.PostponedError):
+ return tagMap
+ if not tagMap:
+ continue
+ for _tagSet in tagMap.presentTypes:
+ if _tagSet in tagToPosMap:
+ return NamedTypes.PostponedError('Duplicate component tag %s at %s' % (_tagSet, namedType))
+ tagToPosMap[_tagSet] = idx
+
+ return tagToPosMap
+
+ def __computeNameToPosMap(self):
+ nameToPosMap = {}
+ for idx, namedType in enumerate(self.__namedTypes):
+ if namedType.name in nameToPosMap:
+ return NamedTypes.PostponedError('Duplicate component name %s at %s' % (namedType.name, namedType))
+ nameToPosMap[namedType.name] = idx
+
+ return nameToPosMap
+
+ def __computeAmbiguousTypes(self):
+ ambigiousTypes = {}
+ partialAmbigiousTypes = ()
+ for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))):
+ if namedType.isOptional or namedType.isDefaulted:
+ partialAmbigiousTypes = (namedType,) + partialAmbigiousTypes
+ else:
+ partialAmbigiousTypes = (namedType,)
+ if len(partialAmbigiousTypes) == len(self.__namedTypes):
+ ambigiousTypes[idx] = self
+ else:
+ ambigiousTypes[idx] = NamedTypes(*partialAmbigiousTypes, **dict(terminal=True))
+ return ambigiousTypes
+
def getTypeByPosition(self, idx):
- if idx < 0 or idx >= self.__namedTypesLen:
+ """Return ASN.1 type object by its position in fields set.
+
+ Parameters
+ ----------
+ idx: :py:class:`int`
+ Field index
+
+ Returns
+ -------
+ :
+ ASN.1 type
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If given position is out of fields range
+ """
+ try:
+ return self.__namedTypes[idx].asn1Object
+
+ except IndexError:
raise error.PyAsn1Error('Type position out of range')
- else:
- return self.__namedTypes[idx].getType()
def getPositionByType(self, tagSet):
- if not self.__tagToPosIdx:
- idx = self.__namedTypesLen
- while idx > 0:
- idx = idx - 1
- tagMap = self.__namedTypes[idx].getType().getTagMap()
- for t in tagMap.getPosMap():
- if t in self.__tagToPosIdx:
- raise error.PyAsn1Error('Duplicate type %s' % (t,))
- self.__tagToPosIdx[t] = idx
+ """Return field position by its ASN.1 type.
+
+ Parameters
+ ----------
+ tagSet: :class:`~pysnmp.type.tag.TagSet`
+ ASN.1 tag set distinguishing one ASN.1 type from others.
+
+ Returns
+ -------
+ : :py:class:`int`
+ ASN.1 type position in fields set
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If *tagSet* is not present or ASN.1 types are not unique within callee *NamedTypes*
+ """
try:
- return self.__tagToPosIdx[tagSet]
+ return self.__tagToPosMap[tagSet]
+
except KeyError:
raise error.PyAsn1Error('Type %s not found' % (tagSet,))
-
+
def getNameByPosition(self, idx):
+ """Return field name by its position in fields set.
+
+ Parameters
+ ----------
+ idx: :py:class:`idx`
+ Field index
+
+ Returns
+ -------
+ : :py:class:`str`
+ Field name
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If given field name is not present in callee *NamedTypes*
+ """
try:
- return self.__namedTypes[idx].getName()
+ return self.__namedTypes[idx].name
+
except IndexError:
raise error.PyAsn1Error('Type position out of range')
+
def getPositionByName(self, name):
- if not self.__nameToPosIdx:
- idx = self.__namedTypesLen
- while idx > 0:
- idx = idx - 1
- n = self.__namedTypes[idx].getName()
- if n in self.__nameToPosIdx:
- raise error.PyAsn1Error('Duplicate name %s' % (n,))
- self.__nameToPosIdx[n] = idx
+ """Return field position by filed name.
+
+ Parameters
+ ----------
+ name: :py:class:`str`
+ Field name
+
+ Returns
+ -------
+ : :py:class:`int`
+ Field position in fields set
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If *name* is not present or not unique within callee *NamedTypes*
+ """
try:
- return self.__nameToPosIdx[name]
+ return self.__nameToPosMap[name]
+
except KeyError:
raise error.PyAsn1Error('Name %s not found' % (name,))
- def __buildAmbigiousTagMap(self):
- ambigiousTypes = ()
- idx = self.__namedTypesLen
- while idx > 0:
- idx = idx - 1
- t = self.__namedTypes[idx]
- if t.isOptional or t.isDefaulted:
- ambigiousTypes = (t, ) + ambigiousTypes
- else:
- ambigiousTypes = (t, )
- self.__ambigiousTypes[idx] = NamedTypes(*ambigiousTypes)
-
def getTagMapNearPosition(self, idx):
- if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
+ """Return ASN.1 types that are allowed at or past given field position.
+
+ Some ASN.1 serialization allow for skipping optional and defaulted fields.
+ Some constructed ASN.1 types allow reordering of the fields. When recovering
+ such objects it may be important to know which types can possibly be
+ present at any given position in the field sets.
+
+ Parameters
+ ----------
+ idx: :py:class:`int`
+ Field index
+
+ Returns
+ -------
+ : :class:`~pyasn1.type.tagmap.TagMap`
+ Map if ASN.1 types allowed at given field position
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If given position is out of fields range
+ """
try:
- return self.__ambigiousTypes[idx].getTagMap()
+ return self.__ambiguousTypes[idx].tagMap
+
except KeyError:
raise error.PyAsn1Error('Type position out of range')
def getPositionNearType(self, tagSet, idx):
- if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
+ """Return the closest field position where given ASN.1 type is allowed.
+
+ Some ASN.1 serialization allow for skipping optional and defaulted fields.
+ Some constructed ASN.1 types allow reordering of the fields. When recovering
+ such objects it may be important to know at which field position, in field set,
+ given *tagSet* is allowed at or past *idx* position.
+
+ Parameters
+ ----------
+ tagSet: :class:`~pyasn1.type.tag.TagSet`
+ ASN.1 type which field position to look up
+
+ idx: :py:class:`int`
+ Field position at or past which to perform ASN.1 type look up
+
+ Returns
+ -------
+ : :py:class:`int`
+ Field position in fields set
+
+ Raises
+ ------
+ : :class:`~pyasn1.error.PyAsn1Error`
+ If *tagSet* is not present or not unique within callee *NamedTypes*
+ or *idx* is out of fields range
+ """
try:
- return idx+self.__ambigiousTypes[idx].getPositionByType(tagSet)
+ return idx + self.__ambiguousTypes[idx].getPositionByType(tagSet)
+
except KeyError:
raise error.PyAsn1Error('Type position out of range')
- def genMinTagSet(self):
- if self.__minTagSet is None:
- for t in self.__namedTypes:
- __type = t.getType()
- tagSet = getattr(__type,'getMinTagSet',__type.getTagSet)()
- if self.__minTagSet is None or tagSet < self.__minTagSet:
- self.__minTagSet = tagSet
+ def __computeMinTagSet(self):
+ minTagSet = None
+ for namedType in self.__namedTypes:
+ asn1Object = namedType.asn1Object
+
+ try:
+ tagSet = asn1Object.minTagSet
+
+ except AttributeError:
+ tagSet = asn1Object.tagSet
+
+ if minTagSet is None or tagSet < minTagSet:
+ minTagSet = tagSet
+
+ return minTagSet or tag.TagSet()
+
+ @property
+ def minTagSet(self):
+ """Return the minimal TagSet among ASN.1 type in callee *NamedTypes*.
+
+ Some ASN.1 types/serialization protocols require ASN.1 types to be
+ arranged based on their numerical tag value. The *minTagSet* property
+ returns that.
+
+ Returns
+ -------
+ : :class:`~pyasn1.type.tagset.TagSet`
+ Minimal TagSet among ASN.1 types in callee *NamedTypes*
+ """
return self.__minTagSet
-
- def getTagMap(self, uniq=False):
- if self.__tagMap[uniq] is None:
- tagMap = tagmap.TagMap()
- for nt in self.__namedTypes:
- tagMap = tagMap.clone(
- nt.getType(), nt.getType().getTagMap(), uniq
- )
- self.__tagMap[uniq] = tagMap
- return self.__tagMap[uniq]
+
+ def __computeTagMaps(self, unique):
+ presentTypes = {}
+ skipTypes = {}
+ defaultType = None
+ for namedType in self.__namedTypes:
+ tagMap = namedType.asn1Object.tagMap
+ if isinstance(tagMap, NamedTypes.PostponedError):
+ return tagMap
+ for tagSet in tagMap:
+ if unique and tagSet in presentTypes:
+ return NamedTypes.PostponedError('Non-unique tagSet %s of %s at %s' % (tagSet, namedType, self))
+ presentTypes[tagSet] = namedType.asn1Object
+ skipTypes.update(tagMap.skipTypes)
+
+ if defaultType is None:
+ defaultType = tagMap.defaultType
+ elif tagMap.defaultType is not None:
+ return NamedTypes.PostponedError('Duplicate default ASN.1 type at %s' % (self,))
+
+ return tagmap.TagMap(presentTypes, skipTypes, defaultType)
+
+ @property
+ def tagMap(self):
+ """Return a *TagMap* object from tags and types recursively.
+
+ Return a :class:`~pyasn1.type.tagmap.TagMap` object by
+ combining tags from *TagMap* objects of children types and
+ associating them with their immediate child type.
+
+ Example
+ -------
+
+ .. code-block:: python
+
+ OuterType ::= CHOICE {
+ innerType INTEGER
+ }
+
+ Calling *.tagMap* on *OuterType* will yield a map like this:
+
+ .. code-block:: python
+
+ Integer.tagSet -> Choice
+ """
+ return self.__nonUniqueTagMap
+
+ @property
+ def tagMapUnique(self):
+ """Return a *TagMap* object from unique tags and types recursively.
+
+ Return a :class:`~pyasn1.type.tagmap.TagMap` object by
+ combining tags from *TagMap* objects of children types and
+ associating them with their immediate child type.
+
+ Example
+ -------
+
+ .. code-block:: python
+
+ OuterType ::= CHOICE {
+ innerType INTEGER
+ }
+
+ Calling *.tagMapUnique* on *OuterType* will yield a map like this:
+
+ .. code-block:: python
+
+ Integer.tagSet -> Choice
+
+ Note
+ ----
+
+ Duplicate *TagSet* objects found in the tree of children
+ types would cause error.
+ """
+ return self.__uniqueTagMap
+
+ @property
+ def hasOptionalOrDefault(self):
+ return self.__hasOptionalOrDefault
+
+ @property
+ def namedTypes(self):
+ return iter(self.__namedTypes)
+
+ @property
+ def requiredComponents(self):
+ return self.__requiredComponents
--- a/third_party/python/pyasn1/pyasn1/type/namedval.py
+++ b/third_party/python/pyasn1/pyasn1/type/namedval.py
@@ -1,46 +1,181 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
# ASN.1 named integers
+#
from pyasn1 import error
-__all__ = [ 'NamedValues' ]
+__all__ = ['NamedValues']
+
+
+class NamedValues(object):
+ """Create named values object.
+
+ The |NamedValues| object represents a collection of string names
+ associated with numeric IDs. These objects are used for giving
+ names to otherwise numerical values.
+
+ |NamedValues| objects are immutable and duck-type Python
+ :class:`dict` object mapping ID to name and vice-versa.
+
+ Parameters
+ ----------
+
+ \*args: variable number of two-element :py:class:`tuple`
+ \*\*kwargs: keyword parameters of:
+
+ name: :py:class:`str`
+ Value name
+
+ value: :py:class:`int`
+ A numerical value
-class NamedValues:
- def __init__(self, *namedValues):
- self.nameToValIdx = {}; self.valToNameIdx = {}
- self.namedValues = ()
- automaticVal = 1
- for namedValue in namedValues:
- if isinstance(namedValue, tuple):
- name, val = namedValue
+ Examples
+ --------
+
+ >>> nv = namedval.NamedValues('a', 'b', ('c', 0), d=1)
+ >>> nv
+ >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}
+ >>> nv[0]
+ 'c'
+ >>> nv['a']
+ 2
+ """
+ def __init__(self, *args, **kwargs):
+ self.__names = {}
+ self.__numbers = {}
+
+ anonymousNames = []
+
+ for namedValue in args:
+ if isinstance(namedValue, (tuple, list)):
+ try:
+ name, number = namedValue
+
+ except ValueError:
+ raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
+
else:
- name = namedValue
- val = automaticVal
- if name in self.nameToValIdx:
+ anonymousNames.append(namedValue)
+ continue
+
+ if name in self.__names:
+ raise error.PyAsn1Error('Duplicate name %s' % (name,))
+
+ if number in self.__numbers:
+ raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
+
+ self.__names[name] = number
+ self.__numbers[number] = name
+
+ for name, number in kwargs.items():
+ if name in self.__names:
raise error.PyAsn1Error('Duplicate name %s' % (name,))
- self.nameToValIdx[name] = val
- if val in self.valToNameIdx:
- raise error.PyAsn1Error('Duplicate value %s=%s' % (name, val))
- self.valToNameIdx[val] = name
- self.namedValues = self.namedValues + ((name, val),)
- automaticVal = automaticVal + 1
- def __str__(self): return str(self.namedValues)
-
+
+ if number in self.__numbers:
+ raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
+
+ self.__names[name] = number
+ self.__numbers[number] = name
+
+ if anonymousNames:
+
+ number = self.__numbers and max(self.__numbers) + 1 or 0
+
+ for name in anonymousNames:
+
+ if name in self.__names:
+ raise error.PyAsn1Error('Duplicate name %s' % (name,))
+
+ self.__names[name] = number
+ self.__numbers[number] = name
+
+ number += 1
+
+ def __repr__(self):
+ return '%s(%r)' % (self.__class__.__name__, tuple(self.items()))
+
+ def __str__(self):
+ return str(self.items())
+
+ def __eq__(self, other):
+ return dict(self) == other
+
+ def __ne__(self, other):
+ return dict(self) != other
+
+ def __lt__(self, other):
+ return dict(self) < other
+
+ def __le__(self, other):
+ return dict(self) <= other
+
+ def __gt__(self, other):
+ return dict(self) > other
+
+ def __ge__(self, other):
+ return dict(self) >= other
+
+ def __hash__(self):
+ return hash(self.items())
+
+ # Python dict protocol (read-only)
+
+ def __getitem__(self, key):
+ try:
+ return self.__numbers[key]
+
+ except KeyError:
+ return self.__names[key]
+
+ def __len__(self):
+ return len(self.__names)
+
+ def __contains__(self, key):
+ return key in self.__names or key in self.__numbers
+
+ def __iter__(self):
+ return iter(self.__names)
+
+ def values(self):
+ return iter(self.__numbers)
+
+ def keys(self):
+ return iter(self.__names)
+
+ def items(self):
+ for name in self.__names:
+ yield name, self.__names[name]
+
+ # support merging
+
+ def __add__(self, namedValues):
+ return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
+
+ # XXX clone/subtype?
+
+ def clone(self, *args, **kwargs):
+ new = self.__class__(*args, **kwargs)
+ return self + new
+
+ # legacy protocol
+
def getName(self, value):
- if value in self.valToNameIdx:
- return self.valToNameIdx[value]
+ if value in self.__numbers:
+ return self.__numbers[value]
def getValue(self, name):
- if name in self.nameToValIdx:
- return self.nameToValIdx[name]
-
- def __getitem__(self, i): return self.namedValues[i]
- def __len__(self): return len(self.namedValues)
+ if name in self.__names:
+ return self.__names[name]
- def __add__(self, namedValues):
- return self.__class__(*self.namedValues + namedValues)
- def __radd__(self, namedValues):
- return self.__class__(*namedValues + tuple(self))
-
- def clone(self, *namedValues):
- return self.__class__(*tuple(self) + namedValues)
+ def getValues(self, *names):
+ try:
+ return [self.__names[name] for name in names]
-# XXX clone/subtype?
+ except KeyError:
+ raise error.PyAsn1Error(
+ 'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
+ )
--- a/third_party/python/pyasn1/pyasn1/type/tag.py
+++ b/third_party/python/pyasn1/pyasn1/type/tag.py
@@ -1,122 +1,318 @@
-# ASN.1 types tags
-from operator import getitem
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1 import error
+__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext',
+ 'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed',
+ 'tagCategoryImplicit', 'tagCategoryExplicit', 'tagCategoryUntagged',
+ 'Tag', 'TagSet']
+
+#: Identifier for ASN.1 class UNIVERSAL
tagClassUniversal = 0x00
+
+#: Identifier for ASN.1 class APPLICATION
tagClassApplication = 0x40
+
+#: Identifier for ASN.1 class context-specific
tagClassContext = 0x80
+
+#: Identifier for ASN.1 class private
tagClassPrivate = 0xC0
+#: Identifier for "simple" ASN.1 structure (e.g. scalar)
tagFormatSimple = 0x00
+
+#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components)
tagFormatConstructed = 0x20
tagCategoryImplicit = 0x01
tagCategoryExplicit = 0x02
tagCategoryUntagged = 0x04
-class Tag:
+
+class Tag(object):
+ """Create ASN.1 tag
+
+ Represents ASN.1 tag that can be attached to a ASN.1 type to make
+ types distinguishable from each other.
+
+ *Tag* objects are immutable and duck-type Python :class:`tuple` objects
+ holding three integer components of a tag.
+
+ Parameters
+ ----------
+ tagClass: :py:class:`int`
+ Tag *class* value
+
+ tagFormat: :py:class:`int`
+ Tag *format* value
+
+ tagId: :py:class:`int`
+ Tag ID value
+ """
def __init__(self, tagClass, tagFormat, tagId):
if tagId < 0:
- raise error.PyAsn1Error(
- 'Negative tag ID (%s) not allowed' % (tagId,)
- )
- self.__tag = (tagClass, tagFormat, tagId)
- self.uniq = (tagClass, tagId)
- self.__hashedUniqTag = hash(self.uniq)
+ raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % tagId)
+ self.__tagClass = tagClass
+ self.__tagFormat = tagFormat
+ self.__tagId = tagId
+ self.__tagClassId = tagClass, tagId
+ self.__hash = hash(self.__tagClassId)
+
+ def __str__(self):
+ return '[%s:%s:%s]' % (self.__tagClass, self.__tagFormat, self.__tagId)
def __repr__(self):
return '%s(tagClass=%s, tagFormat=%s, tagId=%s)' % (
- (self.__class__.__name__,) + self.__tag
- )
- # These is really a hotspot -- expose public "uniq" attribute to save on
- # function calls
- def __eq__(self, other): return self.uniq == other.uniq
- def __ne__(self, other): return self.uniq != other.uniq
- def __lt__(self, other): return self.uniq < other.uniq
- def __le__(self, other): return self.uniq <= other.uniq
- def __gt__(self, other): return self.uniq > other.uniq
- def __ge__(self, other): return self.uniq >= other.uniq
- def __hash__(self): return self.__hashedUniqTag
- def __getitem__(self, idx): return self.__tag[idx]
+ (self.__class__.__name__, self.__tagClass, self.__tagFormat, self.__tagId)
+ )
+
+ def __eq__(self, other):
+ return self.__tagClassId == other
+
+ def __ne__(self, other):
+ return self.__tagClassId != other
+
+ def __lt__(self, other):
+ return self.__tagClassId < other
+
+ def __le__(self, other):
+ return self.__tagClassId <= other
+
+ def __gt__(self, other):
+ return self.__tagClassId > other
+
+ def __ge__(self, other):
+ return self.__tagClassId >= other
+
+ def __hash__(self):
+ return self.__hash
+
+ def __getitem__(self, idx):
+ if idx == 0:
+ return self.__tagClass
+ elif idx == 1:
+ return self.__tagFormat
+ elif idx == 2:
+ return self.__tagId
+ else:
+ raise IndexError()
+
+ def __iter__(self):
+ yield self.__tagClass
+ yield self.__tagFormat
+ yield self.__tagId
+
def __and__(self, otherTag):
- (tagClass, tagFormat, tagId) = otherTag
- return self.__class__(
- self.__tag&tagClass, self.__tag&tagFormat, self.__tag&tagId
- )
+ return self.__class__(self.__tagClass & otherTag.tagClass,
+ self.__tagFormat & otherTag.tagFormat,
+ self.__tagId & otherTag.tagId)
+
def __or__(self, otherTag):
- (tagClass, tagFormat, tagId) = otherTag
- return self.__class__(
- self.__tag[0]|tagClass,
- self.__tag[1]|tagFormat,
- self.__tag[2]|tagId
- )
- def asTuple(self): return self.__tag # __getitem__() is slow
-
-class TagSet:
+ return self.__class__(self.__tagClass | otherTag.tagClass,
+ self.__tagFormat | otherTag.tagFormat,
+ self.__tagId | otherTag.tagId)
+
+ @property
+ def tagClass(self):
+ """ASN.1 tag class
+
+ Returns
+ -------
+ : :py:class:`int`
+ Tag class
+ """
+ return self.__tagClass
+
+ @property
+ def tagFormat(self):
+ """ASN.1 tag format
+
+ Returns
+ -------
+ : :py:class:`int`
+ Tag format
+ """
+ return self.__tagFormat
+
+ @property
+ def tagId(self):
+ """ASN.1 tag ID
+
+ Returns
+ -------
+ : :py:class:`int`
+ Tag ID
+ """
+ return self.__tagId
+
+
+class TagSet(object):
+ """Create a collection of ASN.1 tags
+
+ Represents a combination of :class:`~pyasn1.type.tag.Tag` objects
+ that can be attached to a ASN.1 type to make types distinguishable
+ from each other.
+
+ *TagSet* objects are immutable and duck-type Python :class:`tuple` objects
+ holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects.
+
+ Parameters
+ ----------
+ baseTag: :class:`~pyasn1.type.tag.Tag`
+ Base *Tag* object. This tag survives IMPLICIT tagging.
+
+ *superTags: :class:`~pyasn1.type.tag.Tag`
+ Additional *Tag* objects taking part in subtyping.
+ """
def __init__(self, baseTag=(), *superTags):
self.__baseTag = baseTag
self.__superTags = superTags
- self.__hashedSuperTags = hash(superTags)
- _uniq = ()
- for t in superTags:
- _uniq = _uniq + t.uniq
- self.uniq = _uniq
+ self.__superTagsClassId = tuple(
+ [(superTag.tagClass, superTag.tagId) for superTag in superTags]
+ )
self.__lenOfSuperTags = len(superTags)
-
+ self.__hash = hash(self.__superTagsClassId)
+
+ def __str__(self):
+ return self.__superTags and '+'.join([str(x) for x in self.__superTags]) or '[untagged]'
+
def __repr__(self):
return '%s(%s)' % (
- self.__class__.__name__,
- ', '.join([repr(x) for x in self.__superTags])
- )
+ self.__class__.__name__, '(), ' + ', '.join([repr(x) for x in self.__superTags])
+ )
def __add__(self, superTag):
- return self.__class__(
- self.__baseTag, *self.__superTags + (superTag,)
- )
+ return self.__class__(self.__baseTag, *self.__superTags + (superTag,))
+
def __radd__(self, superTag):
- return self.__class__(
- self.__baseTag, *(superTag,) + self.__superTags
- )
+ return self.__class__(self.__baseTag, *(superTag,) + self.__superTags)
+
+ def __getitem__(self, i):
+ if i.__class__ is slice:
+ return self.__class__(self.__baseTag, *self.__superTags[i])
+ else:
+ return self.__superTags[i]
+
+ def __eq__(self, other):
+ return self.__superTagsClassId == other
+
+ def __ne__(self, other):
+ return self.__superTagsClassId != other
+
+ def __lt__(self, other):
+ return self.__superTagsClassId < other
+
+ def __le__(self, other):
+ return self.__superTagsClassId <= other
+
+ def __gt__(self, other):
+ return self.__superTagsClassId > other
+
+ def __ge__(self, other):
+ return self.__superTagsClassId >= other
+
+ def __hash__(self):
+ return self.__hash
+
+ def __len__(self):
+ return self.__lenOfSuperTags
+
+ @property
+ def baseTag(self):
+ """Return base ASN.1 tag
+
+ Returns
+ -------
+ : :class:`~pyasn1.type.tag.Tag`
+ Base tag of this *TagSet*
+ """
+ return self.__baseTag
+
+ @property
+ def superTags(self):
+ """Return ASN.1 tags
+
+ Returns
+ -------
+ : :py:class:`tuple`
+ Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains
+ """
+ return self.__superTags
def tagExplicitly(self, superTag):
- tagClass, tagFormat, tagId = superTag
- if tagClass == tagClassUniversal:
- raise error.PyAsn1Error(
- 'Can\'t tag with UNIVERSAL-class tag'
- )
- if tagFormat != tagFormatConstructed:
- superTag = Tag(tagClass, tagFormatConstructed, tagId)
+ """Return explicitly tagged *TagSet*
+
+ Create a new *TagSet* representing callee *TagSet* explicitly tagged
+ with passed tag(s). With explicit tagging mode, new tags are appended
+ to existing tag(s).
+
+ Parameters
+ ----------
+ superTag: :class:`~pyasn1.type.tag.Tag`
+ *Tag* object to tag this *TagSet*
+
+ Returns
+ -------
+ : :class:`~pyasn1.type.tag.TagSet`
+ New *TagSet* object
+ """
+ if superTag.tagClass == tagClassUniversal:
+ raise error.PyAsn1Error("Can't tag with UNIVERSAL class tag")
+ if superTag.tagFormat != tagFormatConstructed:
+ superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId)
return self + superTag
def tagImplicitly(self, superTag):
- tagClass, tagFormat, tagId = superTag
+ """Return implicitly tagged *TagSet*
+
+ Create a new *TagSet* representing callee *TagSet* implicitly tagged
+ with passed tag(s). With implicit tagging mode, new tag(s) replace the
+ last existing tag.
+
+ Parameters
+ ----------
+ superTag: :class:`~pyasn1.type.tag.Tag`
+ *Tag* object to tag this *TagSet*
+
+ Returns
+ -------
+ : :class:`~pyasn1.type.tag.TagSet`
+ New *TagSet* object
+ """
if self.__superTags:
- superTag = Tag(tagClass, self.__superTags[-1][1], tagId)
+ superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId)
return self[:-1] + superTag
- def getBaseTag(self): return self.__baseTag
- def __getitem__(self, idx):
- if isinstance(idx, slice):
- return self.__class__(
- self.__baseTag, *getitem(self.__superTags, idx)
- )
- return self.__superTags[idx]
- def __eq__(self, other): return self.uniq == other.uniq
- def __ne__(self, other): return self.uniq != other.uniq
- def __lt__(self, other): return self.uniq < other.uniq
- def __le__(self, other): return self.uniq <= other.uniq
- def __gt__(self, other): return self.uniq > other.uniq
- def __ge__(self, other): return self.uniq >= other.uniq
- def __hash__(self): return self.__hashedSuperTags
- def __len__(self): return self.__lenOfSuperTags
def isSuperTagSetOf(self, tagSet):
+ """Test type relationship against given *TagSet*
+
+ The callee is considered to be a supertype of given *TagSet*
+ tag-wise if all tags in *TagSet* are present in the callee and
+ they are in the same order.
+
+ Parameters
+ ----------
+ tagSet: :class:`~pyasn1.type.tag.TagSet`
+ *TagSet* object to evaluate against the callee
+
+ Returns
+ -------
+ : :py:class:`bool`
+ `True` if callee is a supertype of *tagSet*
+ """
if len(tagSet) < self.__lenOfSuperTags:
- return
- idx = self.__lenOfSuperTags - 1
- while idx >= 0:
- if self.__superTags[idx] != tagSet[idx]:
- return
- idx = idx - 1
- return 1
-
-def initTagSet(tag): return TagSet(tag, tag)
+ return False
+ return self.__superTags == tagSet[:self.__lenOfSuperTags]
+
+ # Backward compatibility
+
+ def getBaseTag(self):
+ return self.__baseTag
+
+def initTagSet(tag):
+ return TagSet(tag, tag)
--- a/third_party/python/pyasn1/pyasn1/type/tagmap.py
+++ b/third_party/python/pyasn1/pyasn1/type/tagmap.py
@@ -1,52 +1,102 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
from pyasn1 import error
-class TagMap:
- def __init__(self, posMap={}, negMap={}, defType=None):
- self.__posMap = posMap.copy()
- self.__negMap = negMap.copy()
- self.__defType = defType
-
+__all__ = ['TagMap']
+
+
+class TagMap(object):
+ """Map *TagSet* objects to ASN.1 types
+
+ Create an object mapping *TagSet* object to ASN.1 type.
+
+ *TagMap* objects are immutable and duck-type read-only Python
+ :class:`dict` objects holding *TagSet* objects as keys and ASN.1
+ type objects as values.
+
+ Parameters
+ ----------
+ presentTypes: :py:class:`dict`
+ Map of :class:`~pyasn1.type.tag.TagSet` to ASN.1 objects considered
+ as being unconditionally present in the *TagMap*.
+
+ skipTypes: :py:class:`dict`
+ A collection of :class:`~pyasn1.type.tag.TagSet` objects considered
+ as absent in the *TagMap* even when *defaultType* is present.
+
+ defaultType: ASN.1 type object
+ An ASN.1 type object callee *TagMap* returns for any *TagSet* key not present
+ in *presentTypes* (unless given key is present in *skipTypes*).
+ """
+ def __init__(self, presentTypes=None, skipTypes=None, defaultType=None):
+ self.__presentTypes = presentTypes or {}
+ self.__skipTypes = skipTypes or {}
+ self.__defaultType = defaultType
+
def __contains__(self, tagSet):
- return tagSet in self.__posMap or \
- self.__defType is not None and tagSet not in self.__negMap
+ return (tagSet in self.__presentTypes or
+ self.__defaultType is not None and tagSet not in self.__skipTypes)
def __getitem__(self, tagSet):
- if tagSet in self.__posMap:
- return self.__posMap[tagSet]
- elif tagSet in self.__negMap:
- raise error.PyAsn1Error('Key in negative map')
- elif self.__defType is not None:
- return self.__defType
- else:
- raise KeyError()
+ try:
+ return self.__presentTypes[tagSet]
+ except KeyError:
+ if self.__defaultType is None:
+ raise KeyError()
+ elif tagSet in self.__skipTypes:
+ raise error.PyAsn1Error('Key in negative map')
+ else:
+ return self.__defaultType
+
+ def __iter__(self):
+ return iter(self.__presentTypes)
def __repr__(self):
- s = '%r/%r' % (self.__posMap, self.__negMap)
- if self.__defType is not None:
- s = s + '/%r' % (self.__defType,)
+ s = self.__class__.__name__ + '('
+ if self.__presentTypes:
+ s += 'presentTypes=%r, ' % (self.__presentTypes,)
+ if self.__skipTypes:
+ s += 'skipTypes=%r, ' % (self.__skipTypes,)
+ if self.__defaultType is not None:
+ s += 'defaultType=%r' % (self.__defaultType,)
+ return s + ')'
+
+ def __str__(self):
+ s = self.__class__.__name__ + ': '
+ if self.__presentTypes:
+ s += 'presentTypes: %s, ' % ', '.join([x.prettyPrintType() for x in self.__presentTypes.values()])
+ if self.__skipTypes:
+ s += 'skipTypes: %s, ' % ', '.join([x.prettyPrintType() for x in self.__skipTypes.values()])
+ if self.__defaultType is not None:
+ s += 'defaultType: %s, ' % self.__defaultType.prettyPrintType()
return s
- def clone(self, parentType, tagMap, uniq=False):
- if self.__defType is not None and tagMap.getDef() is not None:
- raise error.PyAsn1Error('Duplicate default value at %s' % (self,))
- if tagMap.getDef() is not None:
- defType = tagMap.getDef()
- else:
- defType = self.__defType
-
- posMap = self.__posMap.copy()
- for k in tagMap.getPosMap():
- if uniq and k in posMap:
- raise error.PyAsn1Error('Duplicate positive key %s' % (k,))
- posMap[k] = parentType
+ @property
+ def presentTypes(self):
+ """Return *TagSet* to ASN.1 type map present in callee *TagMap*"""
+ return self.__presentTypes
+
+ @property
+ def skipTypes(self):
+ """Return *TagSet* collection unconditionally absent in callee *TagMap*"""
+ return self.__skipTypes
- negMap = self.__negMap.copy()
- negMap.update(tagMap.getNegMap())
-
- return self.__class__(
- posMap, negMap, defType,
- )
+ @property
+ def defaultType(self):
+ """Return default ASN.1 type being returned for any missing *TagSet*"""
+ return self.__defaultType
+
+ # Backward compatibility
- def getPosMap(self): return self.__posMap.copy()
- def getNegMap(self): return self.__negMap.copy()
- def getDef(self): return self.__defType
+ def getPosMap(self):
+ return self.presentTypes
+
+ def getNegMap(self):
+ return self.skipTypes
+
+ def getDef(self):
+ return self.defaultType
--- a/third_party/python/pyasn1/pyasn1/type/univ.py
+++ b/third_party/python/pyasn1/pyasn1/type/univ.py
@@ -1,1042 +1,2875 @@
-# ASN.1 "universal" data types
-import operator, sys
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import math
from pyasn1.type import base, tag, constraint, namedtype, namedval, tagmap
from pyasn1.codec.ber import eoo
-from pyasn1.compat import octets
+from pyasn1.compat import octets, integer, binary
from pyasn1 import error
+NoValue = base.NoValue
+noValue = NoValue()
+
+__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
+ 'ObjectIdentifier', 'Real', 'Enumerated', 'SequenceOfAndSetOfBase', 'SequenceOf',
+ 'SetOf', 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
+ 'NoValue', 'noValue']
+
# "Simple" ASN.1 types (yet incomplete)
+
class Integer(base.AbstractSimpleAsn1Item):
- tagSet = baseTagSet = tag.initTagSet(
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
+
+ Parameters
+ ----------
+ value : :class:`int`, :class:`str` or |ASN.1| object
+ Python integer or string literal or |ASN.1| class instance.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Object representing non-default symbolic aliases for numbers
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
- )
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+ #: representing symbolic aliases for numbers
namedValues = namedval.NamedValues()
- def __init__(self, value=None, tagSet=None, subtypeSpec=None,
- namedValues=None):
- if namedValues is None:
- self.__namedValues = self.namedValues
+
+ # Optimization for faster codec lookup
+ typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+ def __init__(self, value=noValue, **kwargs):
+ if 'namedValues' not in kwargs:
+ kwargs['namedValues'] = self.namedValues
+
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+ def __repr__(self):
+ if self.namedValues is not self.__class__.namedValues:
+ return '%s, %r)' % (base.AbstractSimpleAsn1Item.__repr__(self)[:-1], self.namedValues)
else:
- self.__namedValues = namedValues
- base.AbstractSimpleAsn1Item.__init__(
- self, value, tagSet, subtypeSpec
- )
-
- def __and__(self, value): return self.clone(self._value & value)
- def __rand__(self, value): return self.clone(value & self._value)
- def __or__(self, value): return self.clone(self._value | value)
- def __ror__(self, value): return self.clone(value | self._value)
- def __xor__(self, value): return self.clone(self._value ^ value)
- def __rxor__(self, value): return self.clone(value ^ self._value)
- def __lshift__(self, value): return self.clone(self._value << value)
- def __rshift__(self, value): return self.clone(self._value >> value)
-
- def __add__(self, value): return self.clone(self._value + value)
- def __radd__(self, value): return self.clone(value + self._value)
- def __sub__(self, value): return self.clone(self._value - value)
- def __rsub__(self, value): return self.clone(value - self._value)
- def __mul__(self, value): return self.clone(self._value * value)
- def __rmul__(self, value): return self.clone(value * self._value)
- def __mod__(self, value): return self.clone(self._value % value)
- def __rmod__(self, value): return self.clone(value % self._value)
- def __pow__(self, value, modulo=None): return self.clone(pow(self._value, value, modulo))
- def __rpow__(self, value): return self.clone(pow(value, self._value))
+ return base.AbstractSimpleAsn1Item.__repr__(self)
+
+ def __and__(self, value):
+ return self.clone(self._value & value)
+
+ def __rand__(self, value):
+ return self.clone(value & self._value)
+
+ def __or__(self, value):
+ return self.clone(self._value | value)
+
+ def __ror__(self, value):
+ return self.clone(value | self._value)
+
+ def __xor__(self, value):
+ return self.clone(self._value ^ value)
+
+ def __rxor__(self, value):
+ return self.clone(value ^ self._value)
+
+ def __lshift__(self, value):
+ return self.clone(self._value << value)
+
+ def __rshift__(self, value):
+ return self.clone(self._value >> value)
+
+ def __add__(self, value):
+ return self.clone(self._value + value)
+
+ def __radd__(self, value):
+ return self.clone(value + self._value)
+
+ def __sub__(self, value):
+ return self.clone(self._value - value)
+
+ def __rsub__(self, value):
+ return self.clone(value - self._value)
+
+ def __mul__(self, value):
+ return self.clone(self._value * value)
+
+ def __rmul__(self, value):
+ return self.clone(value * self._value)
+
+ def __mod__(self, value):
+ return self.clone(self._value % value)
+
+ def __rmod__(self, value):
+ return self.clone(value % self._value)
+
+ def __pow__(self, value, modulo=None):
+ return self.clone(pow(self._value, value, modulo))
+
+ def __rpow__(self, value):
+ return self.clone(pow(value, self._value))
+
+ def __floordiv__(self, value):
+ return self.clone(self._value // value)
+
+ def __rfloordiv__(self, value):
+ return self.clone(value // self._value)
if sys.version_info[0] <= 2:
- def __div__(self, value): return self.clone(self._value // value)
- def __rdiv__(self, value): return self.clone(value // self._value)
+ def __div__(self, value):
+ if isinstance(value, float):
+ return Real(self._value / value)
+ else:
+ return self.clone(self._value / value)
+
+ def __rdiv__(self, value):
+ if isinstance(value, float):
+ return Real(value / self._value)
+ else:
+ return self.clone(value / self._value)
else:
- def __truediv__(self, value): return self.clone(self._value / value)
- def __rtruediv__(self, value): return self.clone(value / self._value)
- def __divmod__(self, value): return self.clone(self._value // value)
- def __rdivmod__(self, value): return self.clone(value // self._value)
+ def __truediv__(self, value):
+ return Real(self._value / value)
+
+ def __rtruediv__(self, value):
+ return Real(value / self._value)
+
+ def __divmod__(self, value):
+ return self.clone(divmod(self._value, value))
+
+ def __rdivmod__(self, value):
+ return self.clone(divmod(value, self._value))
__hash__ = base.AbstractSimpleAsn1Item.__hash__
- def __int__(self): return int(self._value)
+ def __int__(self):
+ return int(self._value)
+
if sys.version_info[0] <= 2:
- def __long__(self): return long(self._value)
- def __float__(self): return float(self._value)
- def __abs__(self): return abs(self._value)
- def __index__(self): return int(self._value)
-
- def __lt__(self, value): return self._value < value
- def __le__(self, value): return self._value <= value
- def __eq__(self, value): return self._value == value
- def __ne__(self, value): return self._value != value
- def __gt__(self, value): return self._value > value
- def __ge__(self, value): return self._value >= value
+ def __long__(self):
+ return long(self._value)
+
+ def __float__(self):
+ return float(self._value)
+
+ def __abs__(self):
+ return self.clone(abs(self._value))
+
+ def __index__(self):
+ return int(self._value)
+
+ def __pos__(self):
+ return self.clone(+self._value)
+
+ def __neg__(self):
+ return self.clone(-self._value)
+
+ def __invert__(self):
+ return self.clone(~self._value)
+
+ def __round__(self, n=0):
+ r = round(self._value, n)
+ if n:
+ return self.clone(r)
+ else:
+ return r
+
+ def __floor__(self):
+ return math.floor(self._value)
+
+ def __ceil__(self):
+ return math.ceil(self._value)
+
+ if sys.version_info[0:2] > (2, 5):
+ def __trunc__(self):
+ return self.clone(math.trunc(self._value))
+
+ def __lt__(self, value):
+ return self._value < value
+
+ def __le__(self, value):
+ return self._value <= value
+
+ def __eq__(self, value):
+ return self._value == value
+
+ def __ne__(self, value):
+ return self._value != value
+
+ def __gt__(self, value):
+ return self._value > value
+
+ def __ge__(self, value):
+ return self._value >= value
def prettyIn(self, value):
- if not isinstance(value, str):
- try:
- return int(value)
- except:
- raise error.PyAsn1Error(
- 'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
- )
- r = self.__namedValues.getValue(value)
- if r is not None:
- return r
try:
return int(value)
- except:
- raise error.PyAsn1Error(
- 'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
+
+ except ValueError:
+ try:
+ return self.namedValues[value]
+
+ except KeyError:
+ raise error.PyAsn1Error(
+ 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
)
def prettyOut(self, value):
- r = self.__namedValues.getName(value)
- return r is None and str(value) or repr(r)
-
- def getNamedValues(self): return self.__namedValues
-
- def clone(self, value=None, tagSet=None, subtypeSpec=None,
- namedValues=None):
- if value is None and tagSet is None and subtypeSpec is None \
- and namedValues is None:
- return self
- if value is None:
- value = self._value
- if tagSet is None:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- if namedValues is None:
- namedValues = self.__namedValues
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
- def subtype(self, value=None, implicitTag=None, explicitTag=None,
- subtypeSpec=None, namedValues=None):
- if value is None:
- value = self._value
- if implicitTag is not None:
- tagSet = self._tagSet.tagImplicitly(implicitTag)
- elif explicitTag is not None:
- tagSet = self._tagSet.tagExplicitly(explicitTag)
- else:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- else:
- subtypeSpec = subtypeSpec + self._subtypeSpec
- if namedValues is None:
- namedValues = self.__namedValues
- else:
- namedValues = namedValues + self.__namedValues
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
+ try:
+ return repr(self.namedValues[value])
+
+ except KeyError:
+ return str(value)
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`int`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Object representing symbolic aliases for numbers to use instead of inheriting from caller
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`int`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Add ASN.1 constraints object to one of the caller, then
+ use the result as new object's ASN.1 constraints.
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Add given object representing symbolic aliases for numbers
+ to one of the caller, then use the result as new object's
+ named numbers.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+ # backward compatibility
+
+ def getNamedValues(self):
+ return self.namedValues
+
class Boolean(Integer):
- tagSet = baseTagSet = tag.initTagSet(
+ __doc__ = Integer.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
- )
- subtypeSpec = Integer.subtypeSpec+constraint.SingleValueConstraint(0,1)
- namedValues = Integer.namedValues.clone(('False', 0), ('True', 1))
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
+
+ #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+ #: representing symbolic aliases for numbers
+ namedValues = namedval.NamedValues(('False', 0), ('True', 1))
+
+ # Optimization for faster codec lookup
+ typeId = Integer.getTypeId()
+
class BitString(base.AbstractSimpleAsn1Item):
- tagSet = baseTagSet = tag.initTagSet(
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple
+ of bits) and :class:`int` objects.
+
+ Parameters
+ ----------
+ value : :class:`int`, :class:`str` or |ASN.1| object
+ Python integer or string literal representing binary or hexadecimal
+ number or sequence of integer bits or |ASN.1| object.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Object representing non-default symbolic aliases for numbers
+
+ binValue: :py:class:`str`
+ Binary string initializer to use instead of the *value*.
+ Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer to use instead of the *value*.
+ Example: 'DEADBEEF'.
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
- )
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+ #: representing symbolic aliases for numbers
namedValues = namedval.NamedValues()
- def __init__(self, value=None, tagSet=None, subtypeSpec=None,
- namedValues=None):
- if namedValues is None:
- self.__namedValues = self.namedValues
- else:
- self.__namedValues = namedValues
- base.AbstractSimpleAsn1Item.__init__(
- self, value, tagSet, subtypeSpec
- )
-
- def clone(self, value=None, tagSet=None, subtypeSpec=None,
- namedValues=None):
- if value is None and tagSet is None and subtypeSpec is None \
- and namedValues is None:
+
+ # Optimization for faster codec lookup
+ typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+ defaultBinValue = defaultHexValue = noValue
+
+ if sys.version_info[0] < 3:
+ SizedIntegerBase = long
+ else:
+ SizedIntegerBase = int
+
+ class SizedInteger(SizedIntegerBase):
+ bitLength = leadingZeroBits = None
+
+ def setBitLength(self, bitLength):
+ self.bitLength = bitLength
+ self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
return self
- if value is None:
- value = self._value
- if tagSet is None:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- if namedValues is None:
- namedValues = self.__namedValues
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
- def subtype(self, value=None, implicitTag=None, explicitTag=None,
- subtypeSpec=None, namedValues=None):
- if value is None:
- value = self._value
- if implicitTag is not None:
- tagSet = self._tagSet.tagImplicitly(implicitTag)
- elif explicitTag is not None:
- tagSet = self._tagSet.tagExplicitly(explicitTag)
- else:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- else:
- subtypeSpec = subtypeSpec + self._subtypeSpec
- if namedValues is None:
- namedValues = self.__namedValues
- else:
- namedValues = namedValues + self.__namedValues
- return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
- def __str__(self): return str(tuple(self))
+
+ def __len__(self):
+ if self.bitLength is None:
+ self.setBitLength(integer.bitLength(self))
+
+ return self.bitLength
+
+ def __init__(self, value=noValue, **kwargs):
+ if value is noValue or value is None:
+ if kwargs:
+ try:
+ value = self.fromBinaryString(kwargs.pop('binValue'))
+
+ except KeyError:
+ pass
+
+ try:
+ value = self.fromHexString(kwargs.pop('hexValue'))
+
+ except KeyError:
+ pass
+
+ if value is noValue or value is None:
+ if self.defaultBinValue is not noValue:
+ value = self.fromBinaryString(self.defaultBinValue)
+
+ elif self.defaultHexValue is not noValue:
+ value = self.fromHexString(self.defaultHexValue)
+
+ if 'namedValues' not in kwargs:
+ kwargs['namedValues'] = self.namedValues
+
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value : :class:`int`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Class instance representing BitString type enumerations
+
+ binValue: :py:class:`str`
+ Binary string initializer to use instead of the *value*.
+ Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer to use instead of the *value*.
+ Example: 'DEADBEEF'.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`int`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Add ASN.1 constraints object to one of the caller, then
+ use the result as new object's ASN.1 constraints.
+
+ namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+ Add given object representing symbolic aliases for numbers
+ to one of the caller, then use the result as new object's
+ named numbers.
+
+ binValue: :py:class:`str`
+ Binary string initializer to use instead of the *value*.
+ Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer to use instead of the *value*.
+ Example: 'DEADBEEF'.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+ def __str__(self):
+ return self.asBinary()
+
+ def __eq__(self, other):
+ other = self.prettyIn(other)
+ return self is other or self._value == other and len(self._value) == len(other)
+
+ def __ne__(self, other):
+ other = self.prettyIn(other)
+ return self._value != other or len(self._value) != len(other)
+
+ def __lt__(self, other):
+ other = self.prettyIn(other)
+ return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
+
+ def __le__(self, other):
+ other = self.prettyIn(other)
+ return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
+
+ def __gt__(self, other):
+ other = self.prettyIn(other)
+ return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
+
+ def __ge__(self, other):
+ other = self.prettyIn(other)
+ return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
# Immutable sequence object protocol
def __len__(self):
- if self._len is None:
- self._len = len(self._value)
- return self._len
+ return len(self._value)
+
def __getitem__(self, i):
- if isinstance(i, slice):
- return self.clone(operator.getitem(self._value, i))
+ if i.__class__ is slice:
+ return self.clone([self[x] for x in range(*i.indices(len(self)))])
else:
- return self._value[i]
-
- def __add__(self, value): return self.clone(self._value + value)
- def __radd__(self, value): return self.clone(value + self._value)
- def __mul__(self, value): return self.clone(self._value * value)
- def __rmul__(self, value): return self * value
+ length = len(self._value) - 1
+ if i > length or i < 0:
+ raise IndexError('bit index out of range')
+ return (self._value >> (length - i)) & 1
+
+ def __iter__(self):
+ length = len(self._value)
+ while length:
+ length -= 1
+ yield (self._value >> length) & 1
+
+ def __reversed__(self):
+ return reversed(tuple(self))
+
+ # arithmetic operators
+
+ def __add__(self, value):
+ value = self.prettyIn(value)
+ return self.clone(self.SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
+
+ def __radd__(self, value):
+ value = self.prettyIn(value)
+ return self.clone(self.SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
+
+ def __mul__(self, value):
+ bitString = self._value
+ while value > 1:
+ bitString <<= len(self._value)
+ bitString |= self._value
+ value -= 1
+ return self.clone(bitString)
+
+ def __rmul__(self, value):
+ return self * value
+
+ def __lshift__(self, count):
+ return self.clone(self.SizedInteger(self._value << count).setBitLength(len(self._value) + count))
+
+ def __rshift__(self, count):
+ return self.clone(self.SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
+
+ def __int__(self):
+ return self._value
+
+ def __float__(self):
+ return float(self._value)
+
+ if sys.version_info[0] < 3:
+ def __long__(self):
+ return self._value
+
+ def asNumbers(self):
+ """Get |ASN.1| value as a sequence of 8-bit integers.
+
+ If |ASN.1| object length is not a multiple of 8, result
+ will be left-padded with zeros.
+ """
+ return tuple(octets.octs2ints(self.asOctets()))
+
+ def asOctets(self):
+ """Get |ASN.1| value as a sequence of octets.
+
+ If |ASN.1| object length is not a multiple of 8, result
+ will be left-padded with zeros.
+ """
+ return integer.to_bytes(self._value, length=len(self))
+
+ def asInteger(self):
+ """Get |ASN.1| value as a single integer value.
+ """
+ return self._value
+
+ def asBinary(self):
+ """Get |ASN.1| value as a text string of bits.
+ """
+ binString = binary.bin(self._value)[2:]
+ return '0' * (len(self._value) - len(binString)) + binString
+
+ @classmethod
+ def fromHexString(cls, value):
+ """Create a |ASN.1| object initialized from the hex string.
+
+ Parameters
+ ----------
+ value: :class:`str`
+ Text string like 'DEADBEEF'
+ """
+ try:
+ return cls.SizedInteger(value, 16).setBitLength(len(value) * 4)
+
+ except ValueError:
+ raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
+
+ @classmethod
+ def fromBinaryString(cls, value):
+ """Create a |ASN.1| object initialized from a string of '0' and '1'.
+
+ Parameters
+ ----------
+ value: :class:`str`
+ Text string like '1010111'
+ """
+ try:
+ return cls.SizedInteger(value or '0', 2).setBitLength(len(value))
+
+ except ValueError:
+ raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
+
+ @classmethod
+ def fromOctetString(cls, value, padding=0):
+ """Create a |ASN.1| object initialized from a string.
+
+ Parameters
+ ----------
+ value: :class:`str` (Py2) or :class:`bytes` (Py3)
+ Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
+ """
+ return cls(cls.SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding))
def prettyIn(self, value):
- r = []
- if not value:
- return ()
- elif isinstance(value, str):
- if value[0] == '\'':
+ if octets.isStringType(value):
+ if not value:
+ return self.SizedInteger(0).setBitLength(0)
+
+ elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated)
if value[-2:] == '\'B':
- for v in value[1:-2]:
- if v == '0':
- r.append(0)
- elif v == '1':
- r.append(1)
- else:
- raise error.PyAsn1Error(
- 'Non-binary BIT STRING initializer %s' % (v,)
- )
- return tuple(r)
+ return self.fromBinaryString(value[1:-2])
elif value[-2:] == '\'H':
- for v in value[1:-2]:
- i = 4
- v = int(v, 16)
- while i:
- i = i - 1
- r.append((v>>i)&0x01)
- return tuple(r)
+ return self.fromHexString(value[1:-2])
else:
raise error.PyAsn1Error(
'Bad BIT STRING value notation %s' % (value,)
- )
- else:
- for i in value.split(','):
- j = self.__namedValues.getValue(i)
- if j is None:
- raise error.PyAsn1Error(
- 'Unknown bit identifier \'%s\'' % (i,)
- )
- if j >= len(r):
- r.extend([0]*(j-len(r)+1))
- r[j] = 1
- return tuple(r)
+ )
+
+ elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active'
+ names = [x.strip() for x in value.split(',')]
+
+ try:
+
+ bitPositions = [self.namedValues[name] for name in names]
+
+ except KeyError:
+ raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
+
+ rightmostPosition = max(bitPositions)
+
+ number = 0
+ for bitPosition in bitPositions:
+ number |= 1 << (rightmostPosition - bitPosition)
+
+ return self.SizedInteger(number).setBitLength(rightmostPosition + 1)
+
+ elif value.startswith('0x'):
+ return self.fromHexString(value[2:])
+
+ elif value.startswith('0b'):
+ return self.fromBinaryString(value[2:])
+
+ else: # assume plain binary string like '1011'
+ return self.fromBinaryString(value)
+
elif isinstance(value, (tuple, list)):
- r = tuple(value)
- for b in r:
- if b and b != 1:
- raise error.PyAsn1Error(
- 'Non-binary BitString initializer \'%s\'' % (r,)
- )
- return r
- elif isinstance(value, BitString):
- return tuple(value)
+ return self.fromBinaryString(''.join([b and '1' or '0' for b in value]))
+
+ elif isinstance(value, (self.SizedInteger, BitString)):
+ return self.SizedInteger(value).setBitLength(len(value))
+
+ elif isinstance(value, intTypes):
+ return self.SizedInteger(value)
+
else:
raise error.PyAsn1Error(
'Bad BitString initializer type \'%s\'' % (value,)
- )
+ )
def prettyOut(self, value):
- return '\"\'%s\'B\"' % ''.join([str(x) for x in value])
+ return '\'%s\'' % str(self)
+
+
+try:
+ # noinspection PyStatementEffect
+ all
+
+except NameError: # Python 2.4
+ # noinspection PyShadowingBuiltins
+ def all(iterable):
+ for element in iterable:
+ if not element:
+ return False
+ return True
+
class OctetString(base.AbstractSimpleAsn1Item):
- tagSet = baseTagSet = tag.initTagSet(
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.
+ When used in Unicode context, |ASN.1| type assumes "|encoding|" serialization.
+
+ Parameters
+ ----------
+ value : :class:`str`, :class:`bytes` or |ASN.1| object
+ string (Python 2) or bytes (Python 3), alternatively unicode object
+ (Python 2) or string (Python 3) representing character string to be
+ serialized into octets (note `encoding` parameter) or |ASN.1| object.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
+ :class:`str` (Python 3) the payload when |ASN.1| object is used
+ in text string context.
+
+ binValue: :py:class:`str`
+ Binary string initializer to use instead of the *value*.
+ Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer to use instead of the *value*.
+ Example: 'DEADBEEF'.
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
- )
- defaultBinValue = defaultHexValue = base.noValue
- encoding = 'us-ascii'
- def __init__(self, value=None, tagSet=None, subtypeSpec=None,
- encoding=None, binValue=None, hexValue=None):
- if encoding is None:
- self._encoding = self.encoding
- else:
- self._encoding = encoding
- if binValue is not None:
- value = self.fromBinaryString(binValue)
- if hexValue is not None:
- value = self.fromHexString(hexValue)
- if value is None or value is base.noValue:
- value = self.defaultHexValue
- if value is None or value is base.noValue:
- value = self.defaultBinValue
- self.__intValue = None
- base.AbstractSimpleAsn1Item.__init__(self, value, tagSet, subtypeSpec)
-
- def clone(self, value=None, tagSet=None, subtypeSpec=None,
- encoding=None, binValue=None, hexValue=None):
- if value is None and tagSet is None and subtypeSpec is None and \
- encoding is None and binValue is None and hexValue is None:
- return self
- if value is None and binValue is None and hexValue is None:
- value = self._value
- if tagSet is None:
- tagSet = self._tagSet
- if subtypeSpec is None:
- subtypeSpec = self._subtypeSpec
- if encoding is None:
- encoding = self._encoding
- return self.__class__(
- value, tagSet, subtypeSpec, encoding, binValue, hexValue
- )
-
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ # Optimization for faster codec lookup
+ typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+ defaultBinValue = defaultHexValue = noValue
+ encoding = 'iso-8859-1'
+
+ def __init__(self, value=noValue, **kwargs):
+ if kwargs:
+ if value is noValue or value is None:
+ try:
+ value = self.fromBinaryString(kwargs.pop('binValue'))
+
+ except KeyError:
+ pass
+
+ try:
+ value = self.fromHexString(kwargs.pop('hexValue'))
+
+ except KeyError:
+ pass
+
+ if value is noValue or value is None:
+ if self.defaultBinValue is not noValue:
+ value = self.fromBinaryString(self.defaultBinValue)
+
+ elif self.defaultHexValue is not noValue:
+ value = self.fromHexString(self.defaultHexValue)
+
+ if 'encoding' not in kwargs:
+ kwargs['encoding'] = self.encoding
+
+ base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value : :class:`str`, :class:`bytes` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :class:`unicode` (Python 2)
+ or :class:`str` (Python 3) the payload when |ASN.1|
+ object is used in string context.
+
+ binValue: :py:class:`str`
+ Binary string initializer. Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer. Example: 'DEADBEEF'.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value : :class:`str`, :class:`bytes` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to |ASN.1| object tag set
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to |ASN.1| object tag set
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Add ASN.1 constraints object to one of the caller, then
+ use the result as new object's ASN.1 constraints.
+
+ encoding: :py:class:`str`
+ Unicode codec ID to encode/decode :class:`unicode` (Python 2)
+ or :class:`str` (Python 3) the payload when *OctetString*
+ object is used in string context.
+
+ binValue: :py:class:`str`
+ Binary string initializer. Example: '10110011'.
+
+ hexValue: :py:class:`str`
+ Hexadecimal string initializer. Example: 'DEADBEEF'.
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
if sys.version_info[0] <= 2:
def prettyIn(self, value):
if isinstance(value, str):
return value
+ elif isinstance(value, unicode):
+ try:
+ return value.encode(self.encoding)
+ except (LookupError, UnicodeEncodeError):
+ raise error.PyAsn1Error(
+ "Can't encode string '%s' with codec %s" % (value, self.encoding)
+ )
elif isinstance(value, (tuple, list)):
try:
- return ''.join([ chr(x) for x in value ])
+ return ''.join([chr(x) for x in value])
except ValueError:
raise error.PyAsn1Error(
- 'Bad OctetString initializer \'%s\'' % (value,)
- )
+ 'Bad %s initializer \'%s\'' % (self.__class__.__name__, value)
+ )
else:
return str(value)
+
+ def __str__(self):
+ return str(self._value)
+
+ def __unicode__(self):
+ try:
+ return self._value.decode(self.encoding)
+
+ except UnicodeDecodeError:
+ raise error.PyAsn1Error(
+ "Can't decode string '%s' with codec %s" % (self._value, self.encoding)
+ )
+
+ def asOctets(self):
+ return str(self._value)
+
+ def asNumbers(self):
+ return tuple([ord(x) for x in self._value])
+
else:
def prettyIn(self, value):
if isinstance(value, bytes):
return value
- elif isinstance(value, OctetString):
- return value.asOctets()
- elif isinstance(value, (tuple, list, map)):
+ elif isinstance(value, str):
try:
- return bytes(value)
- except ValueError:
- raise error.PyAsn1Error(
- 'Bad OctetString initializer \'%s\'' % (value,)
- )
- else:
- try:
- return str(value).encode(self._encoding)
+ return value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
- 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
- )
-
-
- def fromBinaryString(self, value):
- bitNo = 8; byte = 0; r = ()
- for v in value:
- if bitNo:
- bitNo = bitNo - 1
- else:
- bitNo = 7
- r = r + (byte,)
- byte = 0
- if v == '0':
- v = 0
- elif v == '1':
- v = 1
+ 'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self.encoding)
+ )
+ elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
+ return value.asOctets()
+ elif isinstance(value, base.AbstractSimpleAsn1Item): # this mostly targets Integer objects
+ return self.prettyIn(str(value))
+ elif isinstance(value, (tuple, list)):
+ return self.prettyIn(bytes(value))
else:
+ return bytes(value)
+
+ def __str__(self):
+ try:
+ return self._value.decode(self.encoding)
+
+ except UnicodeDecodeError:
raise error.PyAsn1Error(
- 'Non-binary OCTET STRING initializer %s' % (v,)
- )
- byte = byte | (v << bitNo)
- return octets.ints2octs(r + (byte,))
-
- def fromHexString(self, value):
- r = p = ()
- for v in value:
- if p:
- r = r + (int(p+v, 16),)
- p = ()
- else:
- p = v
- if p:
- r = r + (int(p+'0', 16),)
- return octets.ints2octs(r)
+ 'Can\'t decode string \'%s\' with \'%s\' codec at \'%s\'' % (self._value, self.encoding, self.__class__.__name__)
+ )
+
+ def __bytes__(self):
+ return bytes(self._value)
+
+ def asOctets(self):
+ return bytes(self._value)
+
+ def asNumbers(self):
+ return tuple(self._value)
def prettyOut(self, value):
if sys.version_info[0] <= 2:
- numbers = tuple([ ord(x) for x in value ])
+ numbers = tuple((ord(x) for x in value))
else:
numbers = tuple(value)
- if [ x for x in numbers if x < 32 or x > 126 ]:
- return '0x' + ''.join([ '%.2x' % x for x in numbers ])
+ for x in numbers:
+ if x < 32 or x > 126:
+ return '0x' + ''.join(('%.2x' % x for x in numbers))
else:
- return str(value)
+ try:
+ return value.decode(self.encoding)
+
+ except UnicodeDecodeError:
+ raise error.PyAsn1Error(
+ "Can't decode string '%s' with '%s' codec at '%s'" % (value, self.encoding, self.__class__.__name__)
+ )
+
+ @staticmethod
+ def fromBinaryString(value):
+ """Create a |ASN.1| object initialized from a string of '0' and '1'.
+
+ Parameters
+ ----------
+ value: :class:`str`
+ Text string like '1010111'
+ """
+ bitNo = 8
+ byte = 0
+ r = []
+ for v in value:
+ if bitNo:
+ bitNo -= 1
+ else:
+ bitNo = 7
+ r.append(byte)
+ byte = 0
+ if v in ('0', '1'):
+ v = int(v)
+ else:
+ raise error.PyAsn1Error(
+ 'Non-binary OCTET STRING initializer %s' % (v,)
+ )
+ byte |= v << bitNo
+
+ r.append(byte)
+
+ return octets.ints2octs(r)
+
+ @staticmethod
+ def fromHexString(value):
+ """Create a |ASN.1| object initialized from the hex string.
+
+ Parameters
+ ----------
+ value: :class:`str`
+ Text string like 'DEADBEEF'
+ """
+ r = []
+ p = []
+ for v in value:
+ if p:
+ r.append(int(p + v, 16))
+ p = None
+ else:
+ p = v
+ if p:
+ r.append(int(p + '0', 16))
+
+ return octets.ints2octs(r)
def __repr__(self):
- if self._value is base.noValue:
- return self.__class__.__name__ + '()'
- if [ x for x in self.asNumbers() if x < 32 or x > 126 ]:
- return self.__class__.__name__ + '(hexValue=\'' + ''.join([ '%.2x' % x for x in self.asNumbers() ])+'\')'
- else:
- return self.__class__.__name__ + '(\'' + self.prettyOut(self._value) + '\')'
-
- if sys.version_info[0] <= 2:
- def __str__(self): return str(self._value)
- def __unicode__(self):
- return self._value.decode(self._encoding, 'ignore')
- def asOctets(self): return self._value
- def asNumbers(self):
- if self.__intValue is None:
- self.__intValue = tuple([ ord(x) for x in self._value ])
- return self.__intValue
- else:
- def __str__(self): return self._value.decode(self._encoding, 'ignore')
- def __bytes__(self): return self._value
- def asOctets(self): return self._value
- def asNumbers(self):
- if self.__intValue is None:
- self.__intValue = tuple(self._value)
- return self.__intValue
-
+ r = []
+ doHex = False
+ if self._value is not self.defaultValue:
+ for x in self.asNumbers():
+ if x < 32 or x > 126:
+ doHex = True
+ break
+ if not doHex:
+ r.append('%r' % (self._value,))
+ if self.tagSet is not self.__class__.tagSet:
+ r.append('tagSet=%r' % (self.tagSet,))
+ if self.subtypeSpec is not self.__class__.subtypeSpec:
+ r.append('subtypeSpec=%r' % (self.subtypeSpec,))
+ if self.encoding is not self.__class__.encoding:
+ r.append('encoding=%r' % (self.encoding,))
+ if doHex:
+ r.append('hexValue=%r' % ''.join(['%.2x' % x for x in self.asNumbers()]))
+ return '%s(%s)' % (self.__class__.__name__, ', '.join(r))
+
# Immutable sequence object protocol
-
+
def __len__(self):
- if self._len is None:
- self._len = len(self._value)
- return self._len
+ return len(self._value)
+
def __getitem__(self, i):
- if isinstance(i, slice):
- return self.clone(operator.getitem(self._value, i))
+ if i.__class__ is slice:
+ return self.clone(self._value[i])
else:
return self._value[i]
- def __add__(self, value): return self.clone(self._value + self.prettyIn(value))
- def __radd__(self, value): return self.clone(self.prettyIn(value) + self._value)
- def __mul__(self, value): return self.clone(self._value * value)
- def __rmul__(self, value): return self * value
+ def __iter__(self):
+ return iter(self._value)
+
+ def __contains__(self, value):
+ return value in self._value
+
+ def __add__(self, value):
+ return self.clone(self._value + self.prettyIn(value))
+
+ def __radd__(self, value):
+ return self.clone(self.prettyIn(value) + self._value)
+
+ def __mul__(self, value):
+ return self.clone(self._value * value)
+
+ def __rmul__(self, value):
+ return self * value
+
+ def __int__(self):
+ return int(self._value)
+
+ def __float__(self):
+ return float(self._value)
+
+ def __reversed__(self):
+ return reversed(self._value)
+
class Null(OctetString):
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).
+
+ Parameters
+ ----------
+ value : :class:`str` or :py:class:`~pyasn1.type.univ.Null` object
+ Python empty string literal or *Null* class instance.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
defaultValue = ''.encode() # This is tightly constrained
- tagSet = baseTagSet = tag.initTagSet(
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
- )
- subtypeSpec = OctetString.subtypeSpec+constraint.SingleValueConstraint(''.encode())
-
+ )
+ subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
+
+ # Optimization for faster codec lookup
+ typeId = OctetString.getTypeId()
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.univ.Null`
+ new instance of NULL type/value
+ """
+ return OctetString.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`int`, :class:`str` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.univ.Null`
+ new instance of NULL type/value
+ """
+ return OctetString.subtype(self, value, **kwargs)
+
+
if sys.version_info[0] <= 2:
intTypes = (int, long)
else:
- intTypes = int
+ intTypes = (int,)
+
+numericTypes = intTypes + (float,)
+
class ObjectIdentifier(base.AbstractSimpleAsn1Item):
- tagSet = baseTagSet = tag.initTagSet(
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`str` or |ASN.1| object
+ Python sequence of :class:`int` or string literal or |ASN.1| object.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+ """
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
- )
- def __add__(self, other): return self.clone(self._value + other)
- def __radd__(self, other): return self.clone(other + self._value)
-
- def asTuple(self): return self._value
-
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ # Optimization for faster codec lookup
+ typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+ def __add__(self, other):
+ return self.clone(self._value + other)
+
+ def __radd__(self, other):
+ return self.clone(other + self._value)
+
+ def asTuple(self):
+ return self._value
+
# Sequence object protocol
-
+
def __len__(self):
- if self._len is None:
- self._len = len(self._value)
- return self._len
+ return len(self._value)
+
def __getitem__(self, i):
- if isinstance(i, slice):
- return self.clone(
- operator.getitem(self._value, i)
- )
+ if i.__class__ is slice:
+ return self.clone(self._value[i])
else:
return self._value[i]
- def __str__(self): return self.prettyPrint()
-
- def index(self, suboid): return self._value.index(suboid)
-
- def isPrefixOf(self, value):
- """Returns true if argument OID resides deeper in the OID tree"""
+ def __iter__(self):
+ return iter(self._value)
+
+ def __contains__(self, value):
+ return value in self._value
+
+ def __str__(self):
+ return self.prettyPrint()
+
+ def __repr__(self):
+ return '%s(%r)' % (self.__class__.__name__, self.prettyPrint())
+
+ def index(self, suboid):
+ return self._value.index(suboid)
+
+ def isPrefixOf(self, other):
+ """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
+
+ Parameters
+ ----------
+ other: |ASN.1| object
+ |ASN.1| object
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
+ or :class:`False` otherwise.
+ """
l = len(self)
- if l <= len(value):
- if self._value[:l] == value[:l]:
- return 1
- return 0
+ if l <= len(other):
+ if self._value[:l] == other[:l]:
+ return True
+ return False
def prettyIn(self, value):
- """Dotted -> tuple of numerics OID converter"""
- if isinstance(value, tuple):
- pass
- elif isinstance(value, ObjectIdentifier):
- return tuple(value)
- elif isinstance(value, str):
- r = []
- for element in [ x for x in value.split('.') if x != '' ]:
- try:
- r.append(int(element, 0))
- except ValueError:
- raise error.PyAsn1Error(
- 'Malformed Object ID %s at %s: %s' %
- (str(value), self.__class__.__name__, sys.exc_info()[1])
- )
- value = tuple(r)
- else:
+ if isinstance(value, ObjectIdentifier):
+ return tuple(value)
+ elif octets.isStringType(value):
+ if '-' in value:
+ raise error.PyAsn1Error(
+ 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+ )
try:
- value = tuple(value)
- except TypeError:
+ return tuple([int(subOid) for subOid in value.split('.') if subOid])
+ except ValueError:
raise error.PyAsn1Error(
- 'Malformed Object ID %s at %s: %s' %
- (str(value), self.__class__.__name__,sys.exc_info()[1])
- )
-
- for x in value:
- if not isinstance(x, intTypes) or x < 0:
- raise error.PyAsn1Error(
- 'Invalid sub-ID in %s at %s' % (value, self.__class__.__name__)
- )
-
- return value
-
- def prettyOut(self, value): return '.'.join([ str(x) for x in value ])
-
+ 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+ )
+
+ try:
+ tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
+
+ except (ValueError, TypeError):
+ raise error.PyAsn1Error(
+ 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+ )
+
+ if len(tupleOfInts) == len(value):
+ return tupleOfInts
+
+ raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
+
+ def prettyOut(self, value):
+ return '.'.join([str(x) for x in value])
+
+
class Real(base.AbstractSimpleAsn1Item):
+ """Create |ASN.1| type or object.
+
+ |ASN.1| objects are immutable and duck-type Python :class:`float` objects.
+ Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
+ elements are mantissa, base and exponent.
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`float` or |ASN.1| object
+ Python sequence of :class:`int` (representing mantissa, base and
+ exponent) or float instance or *Real* class instance.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ Raises
+ ------
+ : :py:class:`pyasn1.error.PyAsn1Error`
+ On constraint violation or bad initializer.
+
+ """
+ binEncBase = None # binEncBase = 16 is recommended for large numbers
+
try:
_plusInf = float('inf')
_minusInf = float('-inf')
_inf = (_plusInf, _minusInf)
except ValueError:
# Infinity support is platform and Python dependent
_plusInf = _minusInf = None
_inf = ()
- tagSet = baseTagSet = tag.initTagSet(
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
- )
-
- def __normalizeBase10(self, value):
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ # Optimization for faster codec lookup
+ typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+ def clone(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *clone()* method will replace corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`float` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+ def subtype(self, value=noValue, **kwargs):
+ """Create a copy of a |ASN.1| type or object.
+
+ Any parameters to the *subtype()* method will be added to the corresponding
+ properties of the |ASN.1| object.
+
+ Parameters
+ ----------
+ value: :class:`tuple`, :class:`float` or |ASN.1| object
+ Initialization value to pass to new ASN.1 object instead of
+ inheriting one from the caller.
+
+ implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Implicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+ Explicitly apply given ASN.1 tag object to caller's
+ :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+ new object's ASN.1 tag(s).
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| type/value
+ """
+ return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+ @staticmethod
+ def __normalizeBase10(value):
m, b, e = value
while m and m % 10 == 0:
- m = m / 10
- e = e + 1
+ m /= 10
+ e += 1
return m, b, e
def prettyIn(self, value):
if isinstance(value, tuple) and len(value) == 3:
- for d in value:
- if not isinstance(d, intTypes):
- raise error.PyAsn1Error(
- 'Lame Real value syntax: %s' % (value,)
- )
+ if not isinstance(value[0], numericTypes) or \
+ not isinstance(value[1], intTypes) or \
+ not isinstance(value[2], intTypes):
+ raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
+ if isinstance(value[0], float) and \
+ self._inf and value[0] in self._inf:
+ return value[0]
if value[1] not in (2, 10):
raise error.PyAsn1Error(
'Prohibited base for Real value: %s' % (value[1],)
- )
+ )
if value[1] == 10:
value = self.__normalizeBase10(value)
return value
elif isinstance(value, intTypes):
return self.__normalizeBase10((value, 10, 0))
- elif isinstance(value, float):
+ elif isinstance(value, float) or octets.isStringType(value):
+ if octets.isStringType(value):
+ try:
+ value = float(value)
+ except ValueError:
+ raise error.PyAsn1Error(
+ 'Bad real value syntax: %s' % (value,)
+ )
if self._inf and value in self._inf:
return value
else:
e = 0
while int(value) != value:
- value = value * 10
- e = e - 1
+ value *= 10
+ e -= 1
return self.__normalizeBase10((int(value), 10, e))
elif isinstance(value, Real):
return tuple(value)
- elif isinstance(value, str): # handle infinite literal
- try:
- return float(value)
- except ValueError:
- pass
raise error.PyAsn1Error(
'Bad real value syntax: %s' % (value,)
- )
-
+ )
+
def prettyOut(self, value):
if value in self._inf:
return '\'%s\'' % value
else:
return str(value)
- def isPlusInfinity(self): return self._value == self._plusInf
- def isMinusInfinity(self): return self._value == self._minusInf
- def isInfinity(self): return self._value in self._inf
-
- def __str__(self): return str(float(self))
-
- def __add__(self, value): return self.clone(float(self) + value)
- def __radd__(self, value): return self + value
- def __mul__(self, value): return self.clone(float(self) * value)
- def __rmul__(self, value): return self * value
- def __sub__(self, value): return self.clone(float(self) - value)
- def __rsub__(self, value): return self.clone(value - float(self))
- def __mod__(self, value): return self.clone(float(self) % value)
- def __rmod__(self, value): return self.clone(value % float(self))
- def __pow__(self, value, modulo=None): return self.clone(pow(float(self), value, modulo))
- def __rpow__(self, value): return self.clone(pow(value, float(self)))
+ def prettyPrint(self, scope=0):
+ if self.isInf:
+ return self.prettyOut(self._value)
+ else:
+ try:
+ return str(float(self))
+
+ except OverflowError:
+ return '<overflow>'
+
+ @property
+ def isPlusInf(self):
+ """Indicate PLUS-INFINITY object value
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if calling object represents plus infinity
+ or :class:`False` otherwise.
+
+ """
+ return self._value == self._plusInf
+
+ @property
+ def isMinusInf(self):
+ """Indicate MINUS-INFINITY object value
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if calling object represents minus infinity
+ or :class:`False` otherwise.
+ """
+ return self._value == self._minusInf
+
+ @property
+ def isInf(self):
+ return self._value in self._inf
+
+ def __str__(self):
+ return str(float(self))
+
+ def __add__(self, value):
+ return self.clone(float(self) + value)
+
+ def __radd__(self, value):
+ return self + value
+
+ def __mul__(self, value):
+ return self.clone(float(self) * value)
+
+ def __rmul__(self, value):
+ return self * value
+
+ def __sub__(self, value):
+ return self.clone(float(self) - value)
+
+ def __rsub__(self, value):
+ return self.clone(value - float(self))
+
+ def __mod__(self, value):
+ return self.clone(float(self) % value)
+
+ def __rmod__(self, value):
+ return self.clone(value % float(self))
+
+ def __pow__(self, value, modulo=None):
+ return self.clone(pow(float(self), value, modulo))
+
+ def __rpow__(self, value):
+ return self.clone(pow(value, float(self)))
if sys.version_info[0] <= 2:
- def __div__(self, value): return self.clone(float(self) / value)
- def __rdiv__(self, value): return self.clone(value / float(self))
+ def __div__(self, value):
+ return self.clone(float(self) / value)
+
+ def __rdiv__(self, value):
+ return self.clone(value / float(self))
else:
- def __truediv__(self, value): return self.clone(float(self) / value)
- def __rtruediv__(self, value): return self.clone(value / float(self))
- def __divmod__(self, value): return self.clone(float(self) // value)
- def __rdivmod__(self, value): return self.clone(value // float(self))
-
- def __int__(self): return int(float(self))
+ def __truediv__(self, value):
+ return self.clone(float(self) / value)
+
+ def __rtruediv__(self, value):
+ return self.clone(value / float(self))
+
+ def __divmod__(self, value):
+ return self.clone(float(self) // value)
+
+ def __rdivmod__(self, value):
+ return self.clone(value // float(self))
+
+ def __int__(self):
+ return int(float(self))
+
if sys.version_info[0] <= 2:
- def __long__(self): return long(float(self))
+ def __long__(self):
+ return long(float(self))
+
def __float__(self):
if self._value in self._inf:
return self._value
else:
return float(
self._value[0] * pow(self._value[1], self._value[2])
- )
- def __abs__(self): return abs(float(self))
-
- def __lt__(self, value): return float(self) < value
- def __le__(self, value): return float(self) <= value
- def __eq__(self, value): return float(self) == value
- def __ne__(self, value): return float(self) != value
- def __gt__(self, value): return float(self) > value
- def __ge__(self, value): return float(self) >= value
+ )
+
+ def __abs__(self):
+ return self.clone(abs(float(self)))
+
+ def __pos__(self):
+ return self.clone(+float(self))
+
+ def __neg__(self):
+ return self.clone(-float(self))
+
+ def __round__(self, n=0):
+ r = round(float(self), n)
+ if n:
+ return self.clone(r)
+ else:
+ return r
+
+ def __floor__(self):
+ return self.clone(math.floor(float(self)))
+
+ def __ceil__(self):
+ return self.clone(math.ceil(float(self)))
+
+ if sys.version_info[0:2] > (2, 5):
+ def __trunc__(self):
+ return self.clone(math.trunc(float(self)))
+
+ def __lt__(self, value):
+ return float(self) < value
+
+ def __le__(self, value):
+ return float(self) <= value
+
+ def __eq__(self, value):
+ return float(self) == value
+
+ def __ne__(self, value):
+ return float(self) != value
+
+ def __gt__(self, value):
+ return float(self) > value
+
+ def __ge__(self, value):
+ return float(self) >= value
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(float(self))
+ def __nonzero__(self):
+ return bool(float(self))
else:
- def __bool__(self): return bool(float(self))
+ def __bool__(self):
+ return bool(float(self))
+
__hash__ = base.AbstractSimpleAsn1Item.__hash__
def __getitem__(self, idx):
if self._value in self._inf:
raise error.PyAsn1Error('Invalid infinite value operation')
else:
return self._value[idx]
-
+
+ # compatibility stubs
+
+ def isPlusInfinity(self):
+ return self.isPlusInf
+
+ def isMinusInfinity(self):
+ return self.isMinusInf
+
+ def isInfinity(self):
+ return self.isInf
+
+
class Enumerated(Integer):
- tagSet = baseTagSet = tag.initTagSet(
+ __doc__ = Integer.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
- )
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ # Optimization for faster codec lookup
+ typeId = Integer.getTypeId()
+
+ #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+ #: representing symbolic aliases for numbers
+ namedValues = namedval.NamedValues()
+
# "Structured" ASN.1 types
-class SetOf(base.AbstractConstructedAsn1Item):
- componentType = None
- tagSet = baseTagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
- )
- typeId = 1
+class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
+ """Create |ASN.1| type.
+
+ |ASN.1| objects are mutable and duck-type Python :class:`list` objects.
+
+ Parameters
+ ----------
+ componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing collection size constraint
+ """
+
+ def __init__(self, *args, **kwargs):
+ # support positional params for backward compatibility
+ if args:
+ for key, value in zip(('componentType', 'tagSet',
+ 'subtypeSpec', 'sizeSpec'), args):
+ if key in kwargs:
+ raise error.PyAsn1Error('Conflicting positional and keyword params!')
+ kwargs['componentType'] = value
+
+ base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
+
+ # Python list protocol
+
+ def __getitem__(self, idx):
+ try:
+ return self.getComponentByPosition(idx)
+
+ except error.PyAsn1Error:
+ raise IndexError(sys.exc_info()[1])
+
+ def __setitem__(self, idx, value):
+ try:
+ self.setComponentByPosition(idx, value)
+
+ except error.PyAsn1Error:
+ raise IndexError(sys.exc_info()[1])
+
+ def clear(self):
+ self._componentValues = []
+
+ def append(self, value):
+ self[len(self)] = value
+
+ def count(self, value):
+ return self._componentValues.count(value)
+
+ def extend(self, values):
+ for value in values:
+ self.append(value)
+
+ def index(self, value, start=0, stop=None):
+ if stop is None:
+ stop = len(self)
+ try:
+ return self._componentValues.index(value, start, stop)
+
+ except error.PyAsn1Error:
+ raise ValueError(sys.exc_info()[1])
+
+ def reverse(self):
+ self._componentValues.reverse()
+
+ def sort(self, key=None, reverse=False):
+ self._componentValues.sort(key=key, reverse=reverse)
+
+ def __iter__(self):
+ return iter(self._componentValues)
def _cloneComponentValues(self, myClone, cloneValueFlag):
- idx = 0; l = len(self._componentValues)
- while idx < l:
- c = self._componentValues[idx]
- if c is not None:
- if isinstance(c, base.AbstractConstructedAsn1Item):
+ for idx, componentValue in enumerate(self._componentValues):
+ if componentValue is not noValue:
+ if isinstance(componentValue, base.AbstractConstructedAsn1Item):
myClone.setComponentByPosition(
- idx, c.clone(cloneValueFlag=cloneValueFlag)
- )
+ idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
+ )
else:
- myClone.setComponentByPosition(idx, c.clone())
- idx = idx + 1
-
- def _verifyComponent(self, idx, value):
- if self._componentType is not None and \
- not self._componentType.isSuperTypeOf(value):
- raise error.PyAsn1Error('Component type error %s' % (value,))
-
- def getComponentByPosition(self, idx): return self._componentValues[idx]
- def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
- l = len(self._componentValues)
- if idx >= l:
- self._componentValues = self._componentValues + (idx-l+1)*[None]
- if value is None:
- if self._componentValues[idx] is None:
- if self._componentType is None:
- raise error.PyAsn1Error('Component type not defined')
- self._componentValues[idx] = self._componentType.clone()
- self._componentValuesSet = self._componentValuesSet + 1
- return self
- elif not isinstance(value, base.Asn1Item):
- if self._componentType is None:
- raise error.PyAsn1Error('Component type not defined')
- if isinstance(self._componentType, base.AbstractSimpleAsn1Item):
- value = self._componentType.clone(value=value)
- else:
- raise error.PyAsn1Error('Instance value required')
- if verifyConstraints:
- if self._componentType is not None:
- self._verifyComponent(idx, value)
- self._verifySubtypeSpec(value, idx)
- if self._componentValues[idx] is None:
- self._componentValuesSet = self._componentValuesSet + 1
- self._componentValues[idx] = value
- return self
-
- def getComponentTagMap(self):
- if self._componentType is not None:
- return self._componentType.getTagMap()
-
- def prettyPrint(self, scope=0):
- scope = scope + 1
- r = self.__class__.__name__ + ':\n'
- for idx in range(len(self._componentValues)):
- r = r + ' '*scope
- if self._componentValues[idx] is None:
- r = r + '<empty>'
- else:
- r = r + self._componentValues[idx].prettyPrint(scope)
- return r
-
-class SequenceOf(SetOf):
- tagSet = baseTagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- )
- typeId = 2
-
-class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
- componentType = namedtype.NamedTypes()
- def __init__(self, componentType=None, tagSet=None,
- subtypeSpec=None, sizeSpec=None):
- base.AbstractConstructedAsn1Item.__init__(
- self, componentType, tagSet, subtypeSpec, sizeSpec
- )
- if self._componentType is None:
- self._componentTypeLen = 0
- else:
- self._componentTypeLen = len(self._componentType)
-
- def __getitem__(self, idx):
- if isinstance(idx, str):
- return self.getComponentByName(idx)
- else:
- return base.AbstractConstructedAsn1Item.__getitem__(self, idx)
-
- def __setitem__(self, idx, value):
- if isinstance(idx, str):
- self.setComponentByName(idx, value)
- else:
- base.AbstractConstructedAsn1Item.__setitem__(self, idx, value)
-
- def _cloneComponentValues(self, myClone, cloneValueFlag):
- idx = 0; l = len(self._componentValues)
- while idx < l:
- c = self._componentValues[idx]
- if c is not None:
- if isinstance(c, base.AbstractConstructedAsn1Item):
- myClone.setComponentByPosition(
- idx, c.clone(cloneValueFlag=cloneValueFlag)
- )
- else:
- myClone.setComponentByPosition(idx, c.clone())
- idx = idx + 1
-
- def _verifyComponent(self, idx, value):
- if idx >= self._componentTypeLen:
- raise error.PyAsn1Error(
- 'Component type error out of range'
- )
- t = self._componentType[idx].getType()
- if not t.isSuperTypeOf(value):
- raise error.PyAsn1Error('Component type error %r vs %r' % (t, value))
-
- def getComponentByName(self, name):
- return self.getComponentByPosition(
- self._componentType.getPositionByName(name)
- )
- def setComponentByName(self, name, value=None, verifyConstraints=True):
- return self.setComponentByPosition(
- self._componentType.getPositionByName(name), value,
- verifyConstraints
- )
+ myClone.setComponentByPosition(idx, componentValue.clone())
def getComponentByPosition(self, idx):
+ """Return |ASN.1| type component value by position.
+
+ Equivalent to Python sequence subscription operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ idx : :class:`int`
+ Component index (zero-based). Must either refer to an existing
+ component or to N+1 component (if *componentType* is set). In the latter
+ case a new component type gets instantiated and appended to the |ASN.1|
+ sequence.
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.base.PyAsn1Item`
+ a pyasn1 object
+ """
try:
return self._componentValues[idx]
except IndexError:
- if idx < self._componentTypeLen:
- return
- raise
- def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
- l = len(self._componentValues)
- if idx >= l:
- self._componentValues = self._componentValues + (idx-l+1)*[None]
- if value is None:
- if self._componentValues[idx] is None:
- self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
- self._componentValuesSet = self._componentValuesSet + 1
- return self
+ self.setComponentByPosition(idx)
+ return self._componentValues[idx]
+
+ def setComponentByPosition(self, idx, value=noValue,
+ verifyConstraints=True,
+ matchTags=True,
+ matchConstraints=True):
+ """Assign |ASN.1| type component by position.
+
+ Equivalent to Python sequence item assignment operation (e.g. `[]`)
+ or list.append() (when idx == len(self)).
+
+ Parameters
+ ----------
+ idx: :class:`int`
+ Component index (zero-based). Must either refer to existing
+ component or to N+1 component. In the latter case a new component
+ type gets instantiated (if *componentType* is set, or given ASN.1
+ object is taken otherwise) and appended to the |ASN.1| sequence.
+
+ value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A Python value to initialize |ASN.1| component with (if *componentType* is set)
+ or ASN.1 value object to assign to |ASN.1| component.
+
+ verifyConstraints: :class:`bool`
+ If `False`, skip constraints validation
+
+ matchTags: :class:`bool`
+ If `False`, skip component tags matching
+
+ matchConstraints: :class:`bool`
+ If `False`, skip component constraints matching
+
+ Returns
+ -------
+ self
+
+ Raises
+ ------
+ IndexError:
+ When idx > len(self)
+ """
+ if value is None: # backward compatibility
+ value = noValue
+
+ componentType = self.componentType
+
+ try:
+ currentValue = self._componentValues[idx]
+ except IndexError:
+ currentValue = noValue
+
+ if len(self._componentValues) < idx:
+ raise error.PyAsn1Error('Component index out of range')
+
+ if value is noValue:
+ if componentType is not None:
+ value = componentType.clone()
+ elif currentValue is noValue:
+ raise error.PyAsn1Error('Component type not defined')
elif not isinstance(value, base.Asn1Item):
- t = self._componentType.getTypeByPosition(idx)
- if isinstance(t, base.AbstractSimpleAsn1Item):
- value = t.clone(value=value)
+ if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):
+ value = componentType.clone(value=value)
+ elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
+ value = currentValue.clone(value=value)
+ else:
+ raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))
+ elif componentType is not None:
+ if self.strictConstraints:
+ if not componentType.isSameTypeWith(value, matchTags, matchConstraints):
+ raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+ else:
+ if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):
+ raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+
+ if verifyConstraints and value.isValue:
+ try:
+ self.subtypeSpec(value, idx)
+
+ except error.PyAsn1Error:
+ exType, exValue, exTb = sys.exc_info()
+ raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
+ if currentValue is noValue:
+ self._componentValues.append(value)
+ else:
+ self._componentValues[idx] = value
+
+ return self
+
+ @property
+ def componentTagMap(self):
+ if self.componentType is not None:
+ return self.componentType.tagMap
+
+ def prettyPrint(self, scope=0):
+ scope += 1
+ representation = self.__class__.__name__ + ':\n'
+ for idx, componentValue in enumerate(self._componentValues):
+ representation += ' ' * scope
+ if (componentValue is noValue and
+ self.componentType is not None):
+ representation += '<empty>'
else:
- raise error.PyAsn1Error('Instance value required')
- if verifyConstraints:
+ representation += componentValue.prettyPrint(scope)
+ return representation
+
+ def prettyPrintType(self, scope=0):
+ scope += 1
+ representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
+ if self.componentType is not None:
+ representation += ' ' * scope
+ representation += self.componentType.prettyPrintType(scope)
+ return representation + '\n' + ' ' * (scope - 1) + '}'
+
+
+ @property
+ def isValue(self):
+ """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+ In other words, if *isValue* is `True`, then the ASN.1 object is
+ initialized.
+
+ For the purpose of this check, empty |ASN.1| object is considered
+ as initialized.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if object represents ASN.1 value and type,
+ :class:`False` if object represents just ASN.1 type.
+
+ Note
+ ----
+ There is an important distinction between PyASN1 type and value objects.
+ The PyASN1 type objects can only participate in ASN.1 type
+ operations (subtyping, comparison etc) and serve as a
+ blueprint for serialization codecs to resolve ambiguous types.
+
+ The PyASN1 value objects can additionally participate in most
+ of built-in Python operations.
+ """
+ for componentValue in self._componentValues:
+ if not componentValue.isValue:
+ return False
+
+ return True
+
+
+class SequenceOf(SequenceOfAndSetOfBase):
+ __doc__ = SequenceOfAndSetOfBase.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+ )
+
+ #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ #: object representing ASN.1 type allowed within |ASN.1| type
+ componentType = None
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing size constraint on |ASN.1| objects
+ sizeSpec = constraint.ConstraintsIntersection()
+
+ # Disambiguation ASN.1 types identification
+ typeId = SequenceOfAndSetOfBase.getTypeId()
+
+
+class SetOf(SequenceOfAndSetOfBase):
+ __doc__ = SequenceOfAndSetOfBase.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+ )
+
+ #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ #: object representing ASN.1 type allowed within |ASN.1| type
+ componentType = None
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing size constraint on |ASN.1| objects
+ sizeSpec = constraint.ConstraintsIntersection()
+
+ # Disambiguation ASN.1 types identification
+ typeId = SequenceOfAndSetOfBase.getTypeId()
+
+
+class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
+ """Create |ASN.1| type.
+
+ |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
+
+ Parameters
+ ----------
+ componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
+ Object holding named ASN.1 types allowed within this collection
+
+ tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing non-default ASN.1 tag(s)
+
+ subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing non-default ASN.1 subtype constraint(s)
+
+ sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ Object representing collection size constraint
+ """
+ #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
+ #: object representing named ASN.1 types allowed within |ASN.1| type
+ componentType = namedtype.NamedTypes()
+
+
+ class DynamicNames(object):
+ """Fields names/positions mapping for component-less objects"""
+ def __init__(self):
+ self._keyToIdxMap = {}
+ self._idxToKeyMap = {}
+
+ def __len__(self):
+ return len(self._keyToIdxMap)
+
+ def __contains__(self, item):
+ return item in self._keyToIdxMap or item in self._idxToKeyMap
+
+ def __iter__(self):
+ return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
+
+ def __getitem__(self, item):
+ try:
+ return self._keyToIdxMap[item]
+
+ except KeyError:
+ return self._idxToKeyMap[item]
+
+ def getNameByPosition(self, idx):
+ try:
+ return self._idxToKeyMap[idx]
+
+ except KeyError:
+ raise error.PyAsn1Error('Type position out of range')
+
+ def getPositionByName(self, name):
+ try:
+ return self._keyToIdxMap[name]
+
+ except KeyError:
+ raise error.PyAsn1Error('Name %s not found' % (name,))
+
+ def addField(self, idx):
+ self._keyToIdxMap['field-%d' % idx] = idx
+ self._idxToKeyMap[idx] = 'field-%d' % idx
+
+
+ def __init__(self, **kwargs):
+ base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
+ self._componentTypeLen = len(self.componentType)
+ self._dynamicNames = self._componentTypeLen or self.DynamicNames()
+
+ def __getitem__(self, idx):
+ if octets.isStringType(idx):
+ try:
+ return self.getComponentByName(idx)
+
+ except error.PyAsn1Error:
+ # duck-typing dict
+ raise KeyError(sys.exc_info()[1])
+
+ else:
+ try:
+ return self.getComponentByPosition(idx)
+
+ except error.PyAsn1Error:
+ # duck-typing list
+ raise IndexError(sys.exc_info()[1])
+
+ def __setitem__(self, idx, value):
+ if octets.isStringType(idx):
+ try:
+ self.setComponentByName(idx, value)
+
+ except error.PyAsn1Error:
+ # duck-typing dict
+ raise KeyError(sys.exc_info()[1])
+
+ else:
+ try:
+ self.setComponentByPosition(idx, value)
+
+ except error.PyAsn1Error:
+ # duck-typing list
+ raise IndexError(sys.exc_info()[1])
+
+ def __contains__(self, key):
+ if self._componentTypeLen:
+ return key in self.componentType
+ else:
+ return key in self._dynamicNames
+
+ def __iter__(self):
+ return iter(self.componentType or self._dynamicNames)
+
+ # Python dict protocol
+
+ def values(self):
+ for idx in range(self._componentTypeLen or len(self._dynamicNames)):
+ yield self[idx]
+
+ def keys(self):
+ return iter(self)
+
+ def items(self):
+ for idx in range(self._componentTypeLen or len(self._dynamicNames)):
if self._componentTypeLen:
- self._verifyComponent(idx, value)
- self._verifySubtypeSpec(value, idx)
- if self._componentValues[idx] is None:
- self._componentValuesSet = self._componentValuesSet + 1
- self._componentValues[idx] = value
+ yield self.componentType[idx].name, self[idx]
+ else:
+ yield self._dynamicNames[idx], self[idx]
+
+ def update(self, *iterValue, **mappingValue):
+ for k, v in iterValue:
+ self[k] = v
+ for k in mappingValue:
+ self[k] = mappingValue[k]
+
+ def clear(self):
+ self._componentValues = []
+ self._dynamicNames = self.DynamicNames()
+
+ def _cloneComponentValues(self, myClone, cloneValueFlag):
+ for idx, componentValue in enumerate(self._componentValues):
+ if componentValue is not noValue:
+ if isinstance(componentValue, base.AbstractConstructedAsn1Item):
+ myClone.setComponentByPosition(
+ idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
+ )
+ else:
+ myClone.setComponentByPosition(idx, componentValue.clone())
+
+ def getComponentByName(self, name):
+ """Returns |ASN.1| type component by name.
+
+ Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ name : :class:`str`
+ |ASN.1| type component name
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.base.PyAsn1Item`
+ Instantiate |ASN.1| component type or return existing component value
+ """
+ if self._componentTypeLen:
+ idx = self.componentType.getPositionByName(name)
+ else:
+ try:
+ idx = self._dynamicNames.getPositionByName(name)
+
+ except KeyError:
+ raise error.PyAsn1Error('Name %s not found' % (name,))
+
+ return self.getComponentByPosition(idx)
+
+ def setComponentByName(self, name, value=noValue,
+ verifyConstraints=True,
+ matchTags=True,
+ matchConstraints=True):
+ """Assign |ASN.1| type component by name.
+
+ Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ name: :class:`str`
+ |ASN.1| type component name
+
+ value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A Python value to initialize |ASN.1| component with (if *componentType* is set)
+ or ASN.1 value object to assign to |ASN.1| component.
+
+ verifyConstraints: :class:`bool`
+ If `False`, skip constraints validation
+
+ matchTags: :class:`bool`
+ If `False`, skip component tags matching
+
+ matchConstraints: :class:`bool`
+ If `False`, skip component constraints matching
+
+ Returns
+ -------
+ self
+ """
+ if self._componentTypeLen:
+ idx = self.componentType.getPositionByName(name)
+ else:
+ try:
+ idx = self._dynamicNames.getPositionByName(name)
+
+ except KeyError:
+ raise error.PyAsn1Error('Name %s not found' % (name,))
+
+ return self.setComponentByPosition(
+ idx, value, verifyConstraints, matchTags, matchConstraints
+ )
+
+ def getComponentByPosition(self, idx):
+ """Returns |ASN.1| type component by index.
+
+ Equivalent to Python sequence subscription operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ idx : :class:`int`
+ Component index (zero-based). Must either refer to an existing
+ component or (if *componentType* is set) new ASN.1 type object gets
+ instantiated.
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.base.PyAsn1Item`
+ a PyASN1 object
+ """
+ try:
+ componentValue = self._componentValues[idx]
+ except IndexError:
+ componentValue = noValue
+
+ if componentValue is noValue:
+ self.setComponentByPosition(idx)
+
+ return self._componentValues[idx]
+
+ def setComponentByPosition(self, idx, value=noValue,
+ verifyConstraints=True,
+ matchTags=True,
+ matchConstraints=True):
+ """Assign |ASN.1| type component by position.
+
+ Equivalent to Python sequence item assignment operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ idx : :class:`int`
+ Component index (zero-based). Must either refer to existing
+ component (if *componentType* is set) or to N+1 component
+ otherwise. In the latter case a new component of given ASN.1
+ type gets instantiated and appended to |ASN.1| sequence.
+
+ value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A Python value to initialize |ASN.1| component with (if *componentType* is set)
+ or ASN.1 value object to assign to |ASN.1| component.
+
+ verifyConstraints : :class:`bool`
+ If `False`, skip constraints validation
+
+ matchTags: :class:`bool`
+ If `False`, skip component tags matching
+
+ matchConstraints: :class:`bool`
+ If `False`, skip component constraints matching
+
+ Returns
+ -------
+ self
+ """
+ if value is None: # backward compatibility
+ value = noValue
+
+ componentType = self.componentType
+ componentTypeLen = self._componentTypeLen
+
+ try:
+ currentValue = self._componentValues[idx]
+ except IndexError:
+ currentValue = noValue
+ if componentTypeLen:
+ if componentTypeLen < idx:
+ raise error.PyAsn1Error('component index out of range')
+ self._componentValues = [noValue] * componentTypeLen
+
+ if value is noValue:
+ if componentTypeLen:
+ value = componentType.getTypeByPosition(idx).clone()
+ elif currentValue is noValue:
+ raise error.PyAsn1Error('Component type not defined')
+ elif not isinstance(value, base.Asn1Item):
+ if componentTypeLen:
+ subComponentType = componentType.getTypeByPosition(idx)
+ if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
+ value = subComponentType.clone(value=value)
+ else:
+ raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
+ elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
+ value = currentValue.clone(value=value)
+ else:
+ raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
+ elif (matchTags or matchConstraints) and componentTypeLen:
+ subComponentType = componentType.getTypeByPosition(idx)
+ if subComponentType is not noValue:
+ if self.strictConstraints:
+ if not subComponentType.isSameTypeWith(value, matchTags, matchConstraints):
+ raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+ else:
+ if not subComponentType.isSuperTypeOf(value, matchTags, matchConstraints):
+ raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+
+ if verifyConstraints and value.isValue:
+ try:
+ self.subtypeSpec(value, idx)
+
+ except error.PyAsn1Error:
+ exType, exValue, exTb = sys.exc_info()
+ raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
+ if componentTypeLen or idx in self._dynamicNames:
+ self._componentValues[idx] = value
+ elif len(self._componentValues) == idx:
+ self._componentValues.append(value)
+ self._dynamicNames.addField(idx)
+ else:
+ raise error.PyAsn1Error('Component index out of range')
+
return self
- def getNameByPosition(self, idx):
- if self._componentTypeLen:
- return self._componentType.getNameByPosition(idx)
-
- def getDefaultComponentByPosition(self, idx):
- if self._componentTypeLen and self._componentType[idx].isDefaulted:
- return self._componentType[idx].getType()
+ @property
+ def isValue(self):
+ """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+ In other words, if *isValue* is `True`, then the ASN.1 object is
+ initialized.
+
+ For the purpose of check, the *OPTIONAL* and *DEFAULT* fields are
+ unconditionally considered as initialized.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if object represents ASN.1 value and type,
+ :class:`False` if object represents just ASN.1 type.
+
+ Note
+ ----
+ There is an important distinction between PyASN1 type and value objects.
+ The PyASN1 type objects can only participate in ASN.1 type
+ operations (subtyping, comparison etc) and serve as a
+ blueprint for serialization codecs to resolve ambiguous types.
+
+ The PyASN1 value objects can additionally participate in most
+ of built-in Python operations.
+ """
+ componentType = self.componentType
+
+ if componentType:
+ for idx, subComponentType in enumerate(componentType.namedTypes):
+ if subComponentType.isDefaulted or subComponentType.isOptional:
+ continue
+ if (not self._componentValues or
+ not self._componentValues[idx].isValue):
+ return False
+
+ else:
+ for componentValue in self._componentValues:
+ if not componentValue.isValue:
+ return False
+
+ return True
+
+ def prettyPrint(self, scope=0):
+ """Return an object representation string.
+
+ Returns
+ -------
+ : :class:`str`
+ Human-friendly object representation.
+ """
+ scope += 1
+ representation = self.__class__.__name__ + ':\n'
+ for idx, componentValue in enumerate(self._componentValues):
+ if componentValue is not noValue:
+ representation += ' ' * scope
+ if self.componentType:
+ representation += self.componentType.getNameByPosition(idx)
+ else:
+ representation += self._dynamicNames.getNameByPosition(idx)
+ representation = '%s=%s\n' % (
+ representation, componentValue.prettyPrint(scope)
+ )
+ return representation
+
+ def prettyPrintType(self, scope=0):
+ scope += 1
+ representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
+ for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
+ representation += ' ' * scope
+ if self.componentType:
+ representation += '"%s"' % self.componentType.getNameByPosition(idx)
+ else:
+ representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
+ representation = '%s = %s\n' % (
+ representation, componentType.prettyPrintType(scope)
+ )
+ return representation + '\n' + ' ' * (scope - 1) + '}'
+
+ # backward compatibility
+
+ def setDefaultComponents(self):
+ return self
def getComponentType(self):
if self._componentTypeLen:
- return self._componentType
-
- def setDefaultComponents(self):
- if self._componentTypeLen == self._componentValuesSet:
- return
- idx = self._componentTypeLen
- while idx:
- idx = idx - 1
- if self._componentType[idx].isDefaulted:
- if self.getComponentByPosition(idx) is None:
- self.setComponentByPosition(idx)
- elif not self._componentType[idx].isOptional:
- if self.getComponentByPosition(idx) is None:
- raise error.PyAsn1Error(
- 'Uninitialized component #%s at %r' % (idx, self)
- )
-
- def prettyPrint(self, scope=0):
- scope = scope + 1
- r = self.__class__.__name__ + ':\n'
- for idx in range(len(self._componentValues)):
- if self._componentValues[idx] is not None:
- r = r + ' '*scope
- componentType = self.getComponentType()
- if componentType is None:
- r = r + '<no-name>'
- else:
- r = r + componentType.getNameByPosition(idx)
- r = '%s=%s\n' % (
- r, self._componentValues[idx].prettyPrint(scope)
- )
- return r
+ return self.componentType
+
+ def getNameByPosition(self, idx):
+ if self._componentTypeLen:
+ return self.componentType[idx].name
+
class Sequence(SequenceAndSetBase):
- tagSet = baseTagSet = tag.initTagSet(
+ __doc__ = SequenceAndSetBase.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- )
- typeId = 3
+ )
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing constraints on |ASN.1| objects
+ sizeSpec = constraint.ConstraintsIntersection()
+
+ #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+ #: object imposing size constraint on |ASN.1| objects
+ componentType = namedtype.NamedTypes()
+
+ # Disambiguation ASN.1 types identification
+ typeId = SequenceAndSetBase.getTypeId()
+
+ # backward compatibility
def getComponentTagMapNearPosition(self, idx):
- if self._componentType:
- return self._componentType.getTagMapNearPosition(idx)
-
+ if self.componentType:
+ return self.componentType.getTagMapNearPosition(idx)
+
def getComponentPositionNearType(self, tagSet, idx):
- if self._componentType:
- return self._componentType.getPositionNearType(tagSet, idx)
+ if self.componentType:
+ return self.componentType.getPositionNearType(tagSet, idx)
else:
return idx
-
+
+
class Set(SequenceAndSetBase):
- tagSet = baseTagSet = tag.initTagSet(
+ __doc__ = SequenceAndSetBase.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+ )
+
+ #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+ #: object representing ASN.1 type allowed within |ASN.1| type
+ componentType = namedtype.NamedTypes()
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing constraints on |ASN.1| objects
+ sizeSpec = constraint.ConstraintsIntersection()
+
+ # Disambiguation ASN.1 types identification
+ typeId = SequenceAndSetBase.getTypeId()
+
+ def getComponent(self, innerFlag=False):
+ return self
+
+ def getComponentByType(self, tagSet, innerFlag=False):
+ """Returns |ASN.1| type component by ASN.1 tag.
+
+ Parameters
+ ----------
+ tagSet : :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tags to identify one of
+ |ASN.1| object component
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.base.PyAsn1Item`
+ a pyasn1 object
+ """
+ component = self.getComponentByPosition(
+ self.componentType.getPositionByType(tagSet)
)
- typeId = 4
-
- def getComponent(self, innerFlag=0): return self
-
- def getComponentByType(self, tagSet, innerFlag=0):
- c = self.getComponentByPosition(
- self._componentType.getPositionByType(tagSet)
- )
- if innerFlag and isinstance(c, Set):
+ if innerFlag and isinstance(component, Set):
# get inner component by inner tagSet
- return c.getComponent(1)
+ return component.getComponent(innerFlag=True)
else:
# get outer component by inner tagSet
- return c
-
- def setComponentByType(self, tagSet, value=None, innerFlag=0,
- verifyConstraints=True):
- idx = self._componentType.getPositionByType(tagSet)
- t = self._componentType.getTypeByPosition(idx)
+ return component
+
+ def setComponentByType(self, tagSet, value=noValue,
+ verifyConstraints=True,
+ matchTags=True,
+ matchConstraints=True,
+ innerFlag=False):
+ """Assign |ASN.1| type component by ASN.1 tag.
+
+ Parameters
+ ----------
+ tagSet : :py:class:`~pyasn1.type.tag.TagSet`
+ Object representing ASN.1 tags to identify one of
+ |ASN.1| object component
+
+ value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A Python value to initialize |ASN.1| component with (if *componentType* is set)
+ or ASN.1 value object to assign to |ASN.1| component.
+
+ verifyConstraints : :class:`bool`
+ If `False`, skip constraints validation
+
+ matchTags: :class:`bool`
+ If `False`, skip component tags matching
+
+ matchConstraints: :class:`bool`
+ If `False`, skip component constraints matching
+
+ innerFlag: :class:`bool`
+ If `True`, search for matching *tagSet* recursively.
+
+ Returns
+ -------
+ self
+ """
+ idx = self.componentType.getPositionByType(tagSet)
+
if innerFlag: # set inner component by inner tagSet
- if t.getTagSet():
+ componentType = self.componentType.getTypeByPosition(idx)
+
+ if componentType.tagSet:
return self.setComponentByPosition(
- idx, value, verifyConstraints
- )
+ idx, value, verifyConstraints, matchTags, matchConstraints
+ )
else:
- t = self.setComponentByPosition(idx).getComponentByPosition(idx)
- return t.setComponentByType(
- tagSet, value, innerFlag, verifyConstraints
- )
+ componentType = self.getComponentByPosition(idx)
+ return componentType.setComponentByType(
+ tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
+ )
else: # set outer component by inner tagSet
return self.setComponentByPosition(
- idx, value, verifyConstraints
- )
-
- def getComponentTagMap(self):
- if self._componentType:
- return self._componentType.getTagMap(True)
-
- def getComponentPositionByType(self, tagSet):
- if self._componentType:
- return self._componentType.getPositionByType(tagSet)
+ idx, value, verifyConstraints, matchTags, matchConstraints
+ )
+
+ @property
+ def componentTagMap(self):
+ if self.componentType:
+ return self.componentType.tagMapUnique
+
class Choice(Set):
- tagSet = baseTagSet = tag.TagSet() # untagged
+ __doc__ = Set.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.TagSet() # untagged
+
+ #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+ #: object representing ASN.1 type allowed within |ASN.1| type
+ componentType = namedtype.NamedTypes()
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+ #: object imposing size constraint on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection(
constraint.ValueSizeConstraint(1, 1)
- )
- typeId = 5
+ )
+
+ # Disambiguation ASN.1 types identification
+ typeId = Set.getTypeId()
+
_currentIdx = None
def __eq__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] == other
return NotImplemented
+
def __ne__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] != other
return NotImplemented
+
def __lt__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] < other
return NotImplemented
+
def __le__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] <= other
return NotImplemented
+
def __gt__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] > other
return NotImplemented
+
def __ge__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] >= other
return NotImplemented
+
if sys.version_info[0] <= 2:
- def __nonzero__(self): return bool(self._componentValues)
+ def __nonzero__(self):
+ return self._componentValues and True or False
else:
- def __bool__(self): return bool(self._componentValues)
-
- def __len__(self): return self._currentIdx is not None and 1 or 0
-
+ def __bool__(self):
+ return self._componentValues and True or False
+
+ def __len__(self):
+ return self._currentIdx is not None and 1 or 0
+
+ def __contains__(self, key):
+ if self._currentIdx is None:
+ return False
+ return key == self.componentType[self._currentIdx].getName()
+
+ def __iter__(self):
+ if self._currentIdx is None:
+ raise StopIteration
+ yield self.componentType[self._currentIdx].getName()
+
+ # Python dict protocol
+
+ def values(self):
+ if self._currentIdx is not None:
+ yield self._componentValues[self._currentIdx]
+
+ def keys(self):
+ if self._currentIdx is not None:
+ yield self.componentType[self._currentIdx].getName()
+
+ def items(self):
+ if self._currentIdx is not None:
+ yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
+
def verifySizeSpec(self):
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
- else:
- self._sizeSpec(' ')
def _cloneComponentValues(self, myClone, cloneValueFlag):
try:
- c = self.getComponent()
+ component = self.getComponent()
except error.PyAsn1Error:
pass
else:
- if isinstance(c, Choice):
- tagSet = c.getEffectiveTagSet()
- else:
- tagSet = c.getTagSet()
- if isinstance(c, base.AbstractConstructedAsn1Item):
- myClone.setComponentByType(
- tagSet, c.clone(cloneValueFlag=cloneValueFlag)
- )
+ if isinstance(component, Choice):
+ tagSet = component.effectiveTagSet
else:
- myClone.setComponentByType(tagSet, c.clone())
-
- def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
- l = len(self._componentValues)
- if idx >= l:
- self._componentValues = self._componentValues + (idx-l+1)*[None]
- if self._currentIdx is not None:
- self._componentValues[self._currentIdx] = None
- if value is None:
- if self._componentValues[idx] is None:
- self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
- self._componentValuesSet = 1
- self._currentIdx = idx
- return self
- elif not isinstance(value, base.Asn1Item):
- value = self._componentType.getTypeByPosition(idx).clone(
- value=value
+ tagSet = component.tagSet
+ if isinstance(component, base.AbstractConstructedAsn1Item):
+ myClone.setComponentByType(
+ tagSet, component.clone(cloneValueFlag=cloneValueFlag)
)
- if verifyConstraints:
- if self._componentTypeLen:
- self._verifyComponent(idx, value)
- self._verifySubtypeSpec(value, idx)
- self._componentValues[idx] = value
+ else:
+ myClone.setComponentByType(tagSet, component.clone())
+
+ def getComponentByPosition(self, idx):
+ __doc__ = Set.__doc__
+
+ if self._currentIdx is None or self._currentIdx != idx:
+ return Set.getComponentByPosition(self, idx)
+
+ return self._componentValues[idx]
+
+ def setComponentByPosition(self, idx, value=noValue,
+ verifyConstraints=True,
+ matchTags=True,
+ matchConstraints=True):
+ """Assign |ASN.1| type component by position.
+
+ Equivalent to Python sequence item assignment operation (e.g. `[]`).
+
+ Parameters
+ ----------
+ idx: :class:`int`
+ Component index (zero-based). Must either refer to existing
+ component or to N+1 component. In the latter case a new component
+ type gets instantiated (if *componentType* is set, or given ASN.1
+ object is taken otherwise) and appended to the |ASN.1| sequence.
+
+ value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+ A Python value to initialize |ASN.1| component with (if *componentType* is set)
+ or ASN.1 value object to assign to |ASN.1| component. Once a new value is
+ set to *idx* component, previous value is dropped.
+
+ verifyConstraints : :class:`bool`
+ If `False`, skip constraints validation
+
+ matchTags: :class:`bool`
+ If `False`, skip component tags matching
+
+ matchConstraints: :class:`bool`
+ If `False`, skip component constraints matching
+
+ Returns
+ -------
+ self
+ """
+ oldIdx = self._currentIdx
+ Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
self._currentIdx = idx
- self._componentValuesSet = 1
+ if oldIdx is not None and oldIdx != idx:
+ self._componentValues[oldIdx] = None
return self
- def getMinTagSet(self):
- if self._tagSet:
- return self._tagSet
+ @property
+ def minTagSet(self):
+ if self.tagSet:
+ return self.tagSet
else:
- return self._componentType.genMinTagSet()
-
- def getEffectiveTagSet(self):
- if self._tagSet:
- return self._tagSet
+ return self.componentType.minTagSet
+
+ @property
+ def effectiveTagSet(self):
+ """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
+ if self.tagSet:
+ return self.tagSet
else:
- c = self.getComponent()
- if isinstance(c, Choice):
- return c.getEffectiveTagSet()
- else:
- return c.getTagSet()
-
- def getTagMap(self):
- if self._tagSet:
- return Set.getTagMap(self)
+ component = self.getComponent()
+ return component.effectiveTagSet
+
+ @property
+ def tagMap(self):
+ """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
+ ASN.1 tags to ASN.1 objects contained within callee.
+ """
+ if self.tagSet:
+ return Set.tagMap.fget(self)
else:
- return Set.getComponentTagMap(self)
+ return self.componentType.tagMapUnique
def getComponent(self, innerFlag=0):
+ """Return currently assigned component of the |ASN.1| object.
+
+ Returns
+ -------
+ : :py:class:`~pyasn1.type.base.PyAsn1Item`
+ a PyASN1 object
+ """
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
else:
c = self._componentValues[self._currentIdx]
if innerFlag and isinstance(c, Choice):
return c.getComponent(innerFlag)
else:
return c
- def getName(self, innerFlag=0):
+ def getName(self, innerFlag=False):
+ """Return the name of currently assigned component of the |ASN.1| object.
+
+ Returns
+ -------
+ : :py:class:`str`
+ |ASN.1| component name
+ """
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
else:
if innerFlag:
c = self._componentValues[self._currentIdx]
if isinstance(c, Choice):
return c.getName(innerFlag)
- return self._componentType.getNameByPosition(self._currentIdx)
-
- def setDefaultComponents(self): pass
+ return self.componentType.getNameByPosition(self._currentIdx)
+
+ @property
+ def isValue(self):
+ """Indicate if |ASN.1| component is set and represents ASN.1 type or ASN.1 value.
+
+ The PyASN1 type objects can only participate in types comparison
+ and serve as a blueprint for serialization codecs to resolve
+ ambiguous types.
+
+ The PyASN1 value objects can additionally participate in most
+ of built-in Python operations.
+
+ Returns
+ -------
+ : :class:`bool`
+ :class:`True` if |ASN.1| component is set and represent value and type,
+ :class:`False` if |ASN.1| component is not set or it represents just ASN.1 type.
+ """
+ if self._currentIdx is None:
+ return False
+
+ return self._componentValues[self._currentIdx].isValue
+
+ # compatibility stubs
+
+ def getMinTagSet(self):
+ return self.minTagSet
+
class Any(OctetString):
- tagSet = baseTagSet = tag.TagSet() # untagged
- typeId = 6
-
- def getTagMap(self):
- return tagmap.TagMap(
- { self.getTagSet(): self },
- { eoo.endOfOctets.getTagSet(): eoo.endOfOctets },
- self
+ __doc__ = OctetString.__doc__
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+ #: associated with |ASN.1| type.
+ tagSet = tag.TagSet() # untagged
+
+ #: Set (on class, not on instance) or return a
+ #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+ #: imposing constraints on |ASN.1| type initialization values.
+ subtypeSpec = constraint.ConstraintsIntersection()
+
+ # Disambiguation ASN.1 types identification
+ typeId = OctetString.getTypeId()
+
+ @property
+ def tagMap(self):
+ """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
+ ASN.1 tags to ASN.1 objects contained within callee.
+ """
+ try:
+ return self._tagMap
+
+ except AttributeError:
+ self._tagMap = tagmap.TagMap(
+ {self.tagSet: self},
+ {eoo.endOfOctets.tagSet: eoo.endOfOctets},
+ self
)
+ return self._tagMap
+
# XXX
# coercion rules?
--- a/third_party/python/pyasn1/pyasn1/type/useful.py
+++ b/third_party/python/pyasn1/pyasn1/type/useful.py
@@ -1,12 +1,187 @@
-# ASN.1 "useful" types
-from pyasn1.type import char, tag
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import datetime
+from pyasn1.type import univ, char, tag
+from pyasn1.compat import string, dateandtime
+from pyasn1 import error
+
+__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime']
+
+NoValue = univ.NoValue
+noValue = univ.noValue
+
+
+class ObjectDescriptor(char.GraphicString):
+ __doc__ = char.GraphicString.__doc__
+
+ #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
+ tagSet = char.GraphicString.tagSet.tagImplicitly(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7)
+ )
+
+ # Optimization for faster codec lookup
+ typeId = char.GraphicString.getTypeId()
+
+
+class TimeMixIn(object):
+
+ _yearsDigits = 4
+ _hasSubsecond = False
+ _optionalMinutes = False
+ _shortTZ = False
+
+ class FixedOffset(datetime.tzinfo):
+ """Fixed offset in minutes east from UTC."""
+
+ # defaulted arguments required
+ # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html
+ def __init__(self, offset=0, name='UTC'):
+ self.__offset = datetime.timedelta(minutes=offset)
+ self.__name = name
+
+ def utcoffset(self, dt):
+ return self.__offset
+
+ def tzname(self, dt):
+ return self.__name
+
+ def dst(self, dt):
+ return datetime.timedelta(0)
+
+ UTC = FixedOffset()
+
+ @property
+ def asDateTime(self):
+ """Create :py:class:`datetime.datetime` object from a |ASN.1| object.
+
+ Returns
+ -------
+ :
+ new instance of :py:class:`datetime.datetime` object
+ """
+ text = str(self)
+ if text.endswith('Z'):
+ tzinfo = TimeMixIn.UTC
+ text = text[:-1]
+
+ elif '-' in text or '+' in text:
+ if '+' in text:
+ text, plusminus, tz = string.partition(text, '+')
+ else:
+ text, plusminus, tz = string.partition(text, '-')
+
+ if self._shortTZ and len(tz) == 2:
+ tz += '00'
-class GeneralizedTime(char.VisibleString):
+ if len(tz) != 4:
+ raise error.PyAsn1Error('malformed time zone offset %s' % tz)
+
+ try:
+ minutes = int(tz[:2]) * 60 + int(tz[2:])
+ if plusminus == '-':
+ minutes *= -1
+
+ except ValueError:
+ raise error.PyAsn1Error('unknown time specification %s' % self)
+
+ tzinfo = TimeMixIn.FixedOffset(minutes, '?')
+
+ else:
+ tzinfo = None
+
+ if '.' in text or ',' in text:
+ if '.' in text:
+ text, _, ms = string.partition(text, '.')
+ else:
+ text, _, ms = string.partition(text, ',')
+
+ try:
+ ms = int(ms) * 10000
+
+ except ValueError:
+ raise error.PyAsn1Error('bad sub-second time specification %s' % self)
+
+ else:
+ ms = 0
+
+ if self._optionalMinutes and len(text) - self._yearsDigits == 6:
+ text += '0000'
+ elif len(text) - self._yearsDigits == 8:
+ text += '00'
+
+ try:
+ dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
+
+ except ValueError:
+ raise error.PyAsn1Error('malformed datetime format %s' % self)
+
+ return dt.replace(microsecond=ms, tzinfo=tzinfo)
+
+ @classmethod
+ def fromDateTime(cls, dt):
+ """Create |ASN.1| object from a :py:class:`datetime.datetime` object.
+
+ Parameters
+ ----------
+ dt : :py:class:`datetime.datetime` object
+ The `datetime.datetime` object to initialize the |ASN.1| object from
+
+
+ Returns
+ -------
+ :
+ new instance of |ASN.1| value
+ """
+ text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
+ if cls._hasSubsecond:
+ text += '.%d' % (dt.microsecond // 10000)
+
+ if dt.utcoffset():
+ seconds = dt.utcoffset().seconds
+ if seconds < 0:
+ text += '-'
+ else:
+ text += '+'
+ text += '%.2d%.2d' % (seconds // 3600, seconds % 3600)
+ else:
+ text += 'Z'
+
+ return cls(text)
+
+
+class GeneralizedTime(char.VisibleString, TimeMixIn):
+ __doc__ = char.VisibleString.__doc__
+
+ #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
tagSet = char.VisibleString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24)
- )
+ )
+
+ # Optimization for faster codec lookup
+ typeId = char.VideotexString.getTypeId()
-class UTCTime(char.VisibleString):
+ _yearsDigits = 4
+ _hasSubsecond = True
+ _optionalMinutes = True
+ _shortTZ = True
+
+
+class UTCTime(char.VisibleString, TimeMixIn):
+ __doc__ = char.VisibleString.__doc__
+
+ #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
tagSet = char.VisibleString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23)
- )
+ )
+
+ # Optimization for faster codec lookup
+ typeId = char.VideotexString.getTypeId()
+
+ _yearsDigits = 2
+ _hasSubsecond = False
+ _optionalMinutes = False
+ _shortTZ = False
--- a/third_party/python/pyasn1/setup.cfg
+++ b/third_party/python/pyasn1/setup.cfg
@@ -1,5 +1,8 @@
+[bdist_wheel]
+universal = 1
+
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
--- a/third_party/python/pyasn1/setup.py
+++ b/third_party/python/pyasn1/setup.py
@@ -1,115 +1,120 @@
#!/usr/bin/env python
-"""ASN.1 types and codecs
-
- A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
-"""
-
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
import os
import sys
classifiers = """\
Development Status :: 5 - Production/Stable
Environment :: Console
Intended Audience :: Developers
Intended Audience :: Education
Intended Audience :: Information Technology
-Intended Audience :: Science/Research
Intended Audience :: System Administrators
Intended Audience :: Telecommunications Industry
License :: OSI Approved :: BSD License
Natural Language :: English
Operating System :: OS Independent
Programming Language :: Python :: 2
+Programming Language :: Python :: 2.4
+Programming Language :: Python :: 2.5
+Programming Language :: Python :: 2.6
+Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
+Programming Language :: Python :: 3.2
+Programming Language :: Python :: 3.3
+Programming Language :: Python :: 3.4
+Programming Language :: Python :: 3.5
+Programming Language :: Python :: 3.6
Topic :: Communications
-Topic :: Security :: Cryptography
Topic :: Software Development :: Libraries :: Python Modules
"""
-def howto_install_distribute():
- print("""
- Error: You need the distribute Python package!
-
- It's very easy to install it, just type (as root on Linux):
-
- wget http://python-distribute.org/distribute_setup.py
- python distribute_setup.py
-
- Then you could make eggs from this package.
-""")
def howto_install_setuptools():
print("""
Error: You need setuptools Python package!
- It's very easy to install it, just type (as root on Linux):
+ It's very easy to install it, just type:
- wget http://peak.telecommunity.com/dist/ez_setup.py
+ wget https://bootstrap.pypa.io/ez_setup.py
python ez_setup.py
Then you could make eggs from this package.
""")
+
+if sys.version_info[:2] < (2, 4):
+ print("ERROR: this package requires Python 2.4 or later!")
+ sys.exit(1)
+
try:
from setuptools import setup, Command
+
params = {
'zip_safe': True
- }
+ }
+
except ImportError:
for arg in sys.argv:
- if arg.find('egg') != -1:
- if sys.version_info[0] > 2:
- howto_install_distribute()
- else:
- howto_install_setuptools()
+ if 'egg' in arg:
+ howto_install_setuptools()
sys.exit(1)
from distutils.core import setup, Command
+
params = {}
-doclines = [ x.strip() for x in __doc__.split('\n') if x ]
-
-params.update( {
+params.update({
'name': 'pyasn1',
- 'version': open(os.path.join('pyasn1','__init__.py')).read().split('\'')[1],
- 'description': doclines[0],
- 'long_description': ' '.join(doclines[1:]),
- 'maintainer': 'Ilya Etingof <ilya@glas.net>',
+ 'version': open(os.path.join('pyasn1', '__init__.py')).read().split('\'')[1],
+ 'description': 'ASN.1 types and codecs',
+ 'long_description': 'Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)',
+ 'maintainer': 'Ilya Etingof <etingof@gmail.com>',
'author': 'Ilya Etingof',
- 'author_email': 'ilya@glas.net',
- 'url': 'http://sourceforge.net/projects/pyasn1/',
+ 'author_email': 'etingof@gmail.com',
+ 'url': 'https://github.com/etingof/pyasn1',
'platforms': ['any'],
- 'classifiers': [ x for x in classifiers.split('\n') if x ],
+ 'classifiers': [x for x in classifiers.split('\n') if x],
'license': 'BSD',
- 'packages': [ 'pyasn1',
- 'pyasn1.type',
- 'pyasn1.compat',
- 'pyasn1.codec',
- 'pyasn1.codec.ber',
- 'pyasn1.codec.cer',
- 'pyasn1.codec.der' ]
-} )
+ 'packages': ['pyasn1',
+ 'pyasn1.type',
+ 'pyasn1.compat',
+ 'pyasn1.codec',
+ 'pyasn1.codec.ber',
+ 'pyasn1.codec.cer',
+ 'pyasn1.codec.der',
+ 'pyasn1.codec.native']})
# handle unittest discovery feature
-if sys.version_info[0:2] < (2, 7) or \
- sys.version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- unittest = None
-else:
+try:
+ import unittest2 as unittest
+except ImportError:
import unittest
-if unittest:
- class PyTest(Command):
- user_options = []
+
+class PyTest(Command):
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
- def initialize_options(self): pass
- def finalize_options(self): pass
+ def run(self):
+ suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.__main__.suite']
+ )
- def run(self):
- suite = unittest.defaultTestLoader.discover('.')
- unittest.TextTestRunner(verbosity=2).run(suite)
+ unittest.TextTestRunner(verbosity=2).run(suite)
- params['cmdclass'] = { 'test': PyTest }
+params['cmdclass'] = {
+ 'test': PyTest,
+ 'tests': PyTest,
+}
setup(**params)
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'ber')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
- suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/test_decoder.py
+++ /dev/null
@@ -1,535 +0,0 @@
-from pyasn1.type import tag, namedtype, univ
-from pyasn1.codec.ber import decoder
-from pyasn1.compat.octets import ints2octs, str2octs, null
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class LargeTagDecoderTestCase(unittest.TestCase):
- def testLargeTag(self):
- assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null)
-
-class IntegerDecoderTestCase(unittest.TestCase):
- def testPosInt(self):
- assert decoder.decode(ints2octs((2, 1, 12))) == (12, null)
- def testNegInt(self):
- assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null)
- def testZero(self):
- assert decoder.decode(ints2octs((2, 0))) == (0, null)
- def testZeroLong(self):
- assert decoder.decode(ints2octs((2, 1, 0))) == (0, null)
- def testMinusOne(self):
- assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null)
- def testPosLong(self):
- assert decoder.decode(
- ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
- ) == (0xffffffffffffffff, null)
- def testNegLong(self):
- assert decoder.decode(
- ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
- ) == (-0xffffffffffffffff, null)
- def testSpec(self):
- try:
- decoder.decode(
- ints2octs((2, 1, 12)), asn1Spec=univ.Null()
- ) == (12, null)
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong asn1Spec worked out'
- assert decoder.decode(
- ints2octs((2, 1, 12)), asn1Spec=univ.Integer()
- ) == (12, null)
- def testTagFormat(self):
- try:
- decoder.decode(ints2octs((34, 1, 12)))
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class BooleanDecoderTestCase(unittest.TestCase):
- def testTrue(self):
- assert decoder.decode(ints2octs((1, 1, 1))) == (1, null)
- def testTrueNeg(self):
- assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
- def testExtraTrue(self):
- assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50)))
- def testFalse(self):
- assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
- def testTagFormat(self):
- try:
- decoder.decode(ints2octs((33, 1, 1)))
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class BitStringDecoderTestCase(unittest.TestCase):
- def testDefMode(self):
- assert decoder.decode(
- ints2octs((3, 3, 1, 169, 138))
- ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
- def testIndefMode(self):
- assert decoder.decode(
- ints2octs((3, 3, 1, 169, 138))
- ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
- def testDefModeChunked(self):
- assert decoder.decode(
- ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
- ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
- def testIndefModeChunked(self):
- assert decoder.decode(
- ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
- ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
- def testDefModeChunkedSubst(self):
- assert decoder.decode(
- ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), 8)
- def testIndefModeChunkedSubst(self):
- assert decoder.decode(
- ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), -1)
-
-class OctetStringDecoderTestCase(unittest.TestCase):
- def testDefMode(self):
- assert decoder.decode(
- ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
- ) == (str2octs('Quick brown fox'), null)
- def testIndefMode(self):
- assert decoder.decode(
- ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
- ) == (str2octs('Quick brown fox'), null)
- def testDefModeChunked(self):
- assert decoder.decode(
- ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
- ) == (str2octs('Quick brown fox'), null)
- def testIndefModeChunked(self):
- assert decoder.decode(
- ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0))
- ) == (str2octs('Quick brown fox'), null)
- def testDefModeChunkedSubst(self):
- assert decoder.decode(
- ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), 23)
- def testIndefModeChunkedSubst(self):
- assert decoder.decode(
- ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), -1)
-
-class ExpTaggedOctetStringDecoderTestCase(unittest.TestCase):
- def setUp(self):
- self.o = univ.OctetString(
- 'Quick brown fox',
- tagSet=univ.OctetString.tagSet.tagExplicitly(
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
- ))
-
- def testDefMode(self):
- assert self.o.isSameTypeWith(decoder.decode(
- ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
- )[0])
-
- def testIndefMode(self):
- v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)))
- assert self.o.isSameTypeWith(v)
- assert not s
-
- def testDefModeChunked(self):
- v, s = decoder.decode(ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)))
- assert self.o.isSameTypeWith(v)
- assert not s
-
- def testIndefModeChunked(self):
- v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0)))
- assert self.o.isSameTypeWith(v)
- assert not s
-
- def testDefModeSubst(self):
- assert decoder.decode(
- ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), 17)
-
- def testIndefModeSubst(self):
- assert decoder.decode(
- ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), -1)
-
-class NullDecoderTestCase(unittest.TestCase):
- def testNull(self):
- assert decoder.decode(ints2octs((5, 0))) == (null, null)
- def testTagFormat(self):
- try:
- decoder.decode(ints2octs((37, 0)))
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class ObjectIdentifierDecoderTestCase(unittest.TestCase):
- def testOID(self):
- assert decoder.decode(
- ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
- ) == ((1,3,6,0,0xffffe), null)
-
- def testEdges1(self):
- assert decoder.decode(
- ints2octs((6, 1, 255))
- ) == ((6,15), null)
-
- def testEdges2(self):
- assert decoder.decode(
- ints2octs((6, 1, 239))
- ) == ((5,39), null)
-
- def testEdges3(self):
- assert decoder.decode(
- ints2octs((6, 7, 43, 6, 143, 255, 255, 255, 127))
- ) == ((1, 3, 6, 4294967295), null)
-
- def testNonLeading0x80(self):
- assert decoder.decode(
- ints2octs((6, 5, 85, 4, 129, 128, 0)),
- ) == ((2, 5, 4, 16384), null)
-
- def testLeading0x80(self):
- try:
- decoder.decode(
- ints2octs((6, 5, 85, 4, 128, 129, 0))
- )
- except PyAsn1Error:
- pass
- else:
- assert 1, 'Leading 0x80 tolarated'
-
- def testTagFormat(self):
- try:
- decoder.decode(ints2octs((38, 1, 239)))
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class RealDecoderTestCase(unittest.TestCase):
- def testChar(self):
- assert decoder.decode(
- ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
- ) == (univ.Real((123, 10, 11)), null)
-
- def testBin1(self):
- assert decoder.decode(
- ints2octs((9, 4, 128, 245, 4, 77))
- ) == (univ.Real((1101, 2, -11)), null)
-
- def testBin2(self):
- assert decoder.decode(
- ints2octs((9, 4, 128, 11, 4, 77))
- ) == (univ.Real((1101, 2, 11)), null)
-
- def testBin3(self):
- assert decoder.decode(
- ints2octs((9, 3, 192, 10, 123))
- ) == (univ.Real((-123, 2, 10)), null)
-
-
- def testPlusInf(self):
- assert decoder.decode(
- ints2octs((9, 1, 64))
- ) == (univ.Real('inf'), null)
-
- def testMinusInf(self):
- assert decoder.decode(
- ints2octs((9, 1, 65))
- ) == (univ.Real('-inf'), null)
-
- def testEmpty(self):
- assert decoder.decode(
- ints2octs((9, 0))
- ) == (univ.Real(0.0), null)
-
- def testTagFormat(self):
- try:
- decoder.decode(ints2octs((41, 0)))
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class SequenceDecoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Sequence(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null(null)),
- namedtype.NamedType('first-name', univ.OctetString(null)),
- namedtype.NamedType('age', univ.Integer(33)),
- ))
- self.s.setComponentByPosition(0, univ.Null(null))
- self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
- self.s.setComponentByPosition(2, univ.Integer(1))
- self.s.setDefaultComponents()
-
- def testWithOptionalAndDefaultedDefMode(self):
- assert decoder.decode(
- ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedIndefMode(self):
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedDefModeChunked(self):
- assert decoder.decode(
- ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedIndefModeChunked(self):
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedDefModeSubst(self):
- assert decoder.decode(
- ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), 18)
-
- def testWithOptionalAndDefaultedIndefModeSubst(self):
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), -1)
-
- def testTagFormat(self):
- try:
- decoder.decode(
- ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
- )
- except PyAsn1Error:
- pass
- else:
- assert 0, 'wrong tagFormat worked out'
-
-class GuidedSequenceDecoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Sequence(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null(null)),
- namedtype.OptionalNamedType('first-name', univ.OctetString(null)),
- namedtype.DefaultedNamedType('age', univ.Integer(33)),
- ))
-
- def __init(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(null))
- self.s.setDefaultComponents()
-
- def __initWithOptional(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(null))
- self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
- self.s.setDefaultComponents()
-
- def __initWithDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(null))
- self.s.setComponentByPosition(2, univ.Integer(1))
- self.s.setDefaultComponents()
-
- def __initWithOptionalAndDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(null))
- self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
- self.s.setComponentByPosition(2, univ.Integer(1))
- self.s.setDefaultComponents()
-
- def testDefMode(self):
- self.__init()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testIndefMode(self):
- self.__init()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testDefModeChunked(self):
- self.__init()
- assert decoder.decode(
- ints2octs((48, 2, 5, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testIndefModeChunked(self):
- self.__init()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalDefMode(self):
- self.__initWithOptional()
- assert decoder.decode(
- ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionaIndefMode(self):
- self.__initWithOptional()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)),
- asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalDefModeChunked(self):
- self.__initWithOptional()
- assert decoder.decode(
- ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)),
- asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalIndefModeChunked(self):
- self.__initWithOptional()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)),
- asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithDefaultedDefMode(self):
- self.__initWithDefaulted()
- assert decoder.decode(
- ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithDefaultedIndefMode(self):
- self.__initWithDefaulted()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithDefaultedDefModeChunked(self):
- self.__initWithDefaulted()
- assert decoder.decode(
- ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithDefaultedIndefModeChunked(self):
- self.__initWithDefaulted()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedDefMode(self):
- self.__initWithOptionalAndDefaulted()
- assert decoder.decode(
- ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedIndefMode(self):
- self.__initWithOptionalAndDefaulted()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedDefModeChunked(self):
- self.__initWithOptionalAndDefaulted()
- assert decoder.decode(
- ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithOptionalAndDefaultedIndefModeChunked(self):
- self.__initWithOptionalAndDefaulted()
- assert decoder.decode(
- ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
-class ChoiceDecoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null(null)),
- namedtype.NamedType('number', univ.Integer(0)),
- namedtype.NamedType('string', univ.OctetString())
- ))
-
- def testBySpec(self):
- self.s.setComponentByPosition(0, univ.Null(null))
- assert decoder.decode(
- ints2octs((5, 0)), asn1Spec=self.s
- ) == (self.s, null)
-
- def testWithoutSpec(self):
- self.s.setComponentByPosition(0, univ.Null(null))
- assert decoder.decode(ints2octs((5, 0))) == (self.s, null)
- assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null)
-
- def testUndefLength(self):
- self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
- assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)), asn1Spec=self.s) == (self.s, null)
-
- def testExplicitTag(self):
- s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
- tag.tagFormatConstructed, 4))
- s.setComponentByPosition(0, univ.Null(null))
- assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null)
-
- def testExplicitTagUndefLength(self):
- s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
- tag.tagFormatConstructed, 4))
- s.setComponentByPosition(0, univ.Null(null))
- assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null)
-
-class AnyDecoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Any()
-
- def testByUntagged(self):
- assert decoder.decode(
- ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
- ) == (univ.Any('\004\003fox'), null)
-
- def testTaggedEx(self):
- s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
- assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
-
- def testTaggedIm(self):
- s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
- assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
-
- def testByUntaggedIndefMode(self):
- assert decoder.decode(
- ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
- ) == (univ.Any('\004\003fox'), null)
-
- def testTaggedExIndefMode(self):
- s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
- assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
-
- def testTaggedImIndefMode(self):
- s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
- assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
-
- def testByUntaggedSubst(self):
- assert decoder.decode(
- ints2octs((4, 3, 102, 111, 120)),
- asn1Spec=self.s,
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((4, 3, 102, 111, 120)), 5)
-
- def testTaggedExSubst(self):
- assert decoder.decode(
- ints2octs((164, 5, 4, 3, 102, 111, 120)),
- asn1Spec=self.s,
- substrateFun=lambda a,b,c: (b,c)
- ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), 7)
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/test_encoder.py
+++ /dev/null
@@ -1,338 +0,0 @@
-from pyasn1.type import tag, namedtype, univ
-from pyasn1.codec.ber import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class LargeTagEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.o = univ.Integer().subtype(
- value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf)
- )
- def testEncoder(self):
- assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))
-
-class IntegerEncoderTestCase(unittest.TestCase):
- def testPosInt(self):
- assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12))
-
- def testNegInt(self):
- assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244))
-
- def testZero(self):
- assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0))
-
- def testCompactZero(self):
- encoder.IntegerEncoder.supportCompactZero = True
- substrate = encoder.encode(univ.Integer(0))
- encoder.IntegerEncoder.supportCompactZero = False
- assert substrate == ints2octs((2, 0))
-
- def testMinusOne(self):
- assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255))
-
- def testPosLong(self):
- assert encoder.encode(
- univ.Integer(0xffffffffffffffff)
- ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
-
- def testNegLong(self):
- assert encoder.encode(
- univ.Integer(-0xffffffffffffffff)
- ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
-
-class BooleanEncoderTestCase(unittest.TestCase):
- def testTrue(self):
- assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1))
-
- def testFalse(self):
- assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
-
-class BitStringEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.b = univ.BitString((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1))
-
- def testDefMode(self):
- assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138))
-
- def testIndefMode(self):
- assert encoder.encode(
- self.b, defMode=0
- ) == ints2octs((3, 3, 1, 169, 138))
-
- def testDefModeChunked(self):
- assert encoder.encode(
- self.b, maxChunkSize=1
- ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
-
- def testIndefModeChunked(self):
- assert encoder.encode(
- self.b, defMode=0, maxChunkSize=1
- ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
-
- def testEmptyValue(self):
- assert encoder.encode(univ.BitString(())) == ints2octs((3, 1, 0))
-
-class OctetStringEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.o = univ.OctetString('Quick brown fox')
-
- def testDefMode(self):
- assert encoder.encode(self.o) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
- def testIndefMode(self):
- assert encoder.encode(
- self.o, defMode=0
- ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
- def testDefModeChunked(self):
- assert encoder.encode(
- self.o, maxChunkSize=4
- ) == ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
-
- def testIndefModeChunked(self):
- assert encoder.encode(
- self.o, defMode=0, maxChunkSize=4
- ) == ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0))
-
-class ExpTaggedOctetStringEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.o = univ.OctetString().subtype(
- value='Quick brown fox',
- explicitTag=tag.Tag(tag.tagClassApplication,tag.tagFormatSimple,5)
- )
- def testDefMode(self):
- assert encoder.encode(self.o) == ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
- def testIndefMode(self):
- assert encoder.encode(
- self.o, defMode=0
- ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
-
- def testDefModeChunked(self):
- assert encoder.encode(
- self.o, defMode=1, maxChunkSize=4
- ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
-
- def testIndefModeChunked(self):
- assert encoder.encode(
- self.o, defMode=0, maxChunkSize=4
- ) == ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
-
-class NullEncoderTestCase(unittest.TestCase):
- def testNull(self):
- assert encoder.encode(univ.Null('')) == ints2octs((5, 0))
-
-class ObjectIdentifierEncoderTestCase(unittest.TestCase):
- def testNull(self):
- assert encoder.encode(
- univ.ObjectIdentifier((1,3,6,0,0xffffe))
- ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
-
-class RealEncoderTestCase(unittest.TestCase):
- def testChar(self):
- assert encoder.encode(
- univ.Real((123, 10, 11))
- ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
-
- def testBin1(self):
- assert encoder.encode(
- univ.Real((1101, 2, 11))
- ) == ints2octs((9, 4, 128, 11, 4, 77))
-
- def testBin2(self):
- assert encoder.encode(
- univ.Real((1101, 2, -11))
- ) == ints2octs((9, 4, 128, 245, 4, 77))
-
- def testPlusInf(self):
- assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64))
-
- def testMinusInf(self):
- assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65))
-
- def testZero(self):
- assert encoder.encode(univ.Real(0)) == ints2octs((9, 0))
-
-class SequenceEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Sequence(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null('')),
- namedtype.OptionalNamedType('first-name', univ.OctetString('')),
- namedtype.DefaultedNamedType('age', univ.Integer(33)),
- ))
-
- def __init(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
-
- def __initWithOptional(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
- self.s.setComponentByPosition(1, 'quick brown')
-
- def __initWithDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
- self.s.setComponentByPosition(2, 1)
-
- def __initWithOptionalAndDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(''))
- self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
- self.s.setComponentByPosition(2, univ.Integer(1))
-
- def testDefMode(self):
- self.__init()
- assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0))
-
- def testIndefMode(self):
- self.__init()
- assert encoder.encode(
- self.s, defMode=0
- ) == ints2octs((48, 128, 5, 0, 0, 0))
-
- def testDefModeChunked(self):
- self.__init()
- assert encoder.encode(
- self.s, defMode=1, maxChunkSize=4
- ) == ints2octs((48, 2, 5, 0))
-
- def testIndefModeChunked(self):
- self.__init()
- assert encoder.encode(
- self.s, defMode=0, maxChunkSize=4
- ) == ints2octs((48, 128, 5, 0, 0, 0))
-
- def testWithOptionalDefMode(self):
- self.__initWithOptional()
- assert encoder.encode(self.s) == ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
-
- def testWithOptionalIndefMode(self):
- self.__initWithOptional()
- assert encoder.encode(
- self.s, defMode=0
- ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
-
- def testWithOptionalDefModeChunked(self):
- self.__initWithOptional()
- assert encoder.encode(
- self.s, defMode=1, maxChunkSize=4
- ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
-
- def testWithOptionalIndefModeChunked(self):
- self.__initWithOptional()
- assert encoder.encode(
- self.s, defMode=0, maxChunkSize=4
- ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
-
- def testWithDefaultedDefMode(self):
- self.__initWithDefaulted()
- assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1))
-
- def testWithDefaultedIndefMode(self):
- self.__initWithDefaulted()
- assert encoder.encode(
- self.s, defMode=0
- ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
-
- def testWithDefaultedDefModeChunked(self):
- self.__initWithDefaulted()
- assert encoder.encode(
- self.s, defMode=1, maxChunkSize=4
- ) == ints2octs((48, 5, 5, 0, 2, 1, 1))
-
- def testWithDefaultedIndefModeChunked(self):
- self.__initWithDefaulted()
- assert encoder.encode(
- self.s, defMode=0, maxChunkSize=4
- ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
-
- def testWithOptionalAndDefaultedDefMode(self):
- self.__initWithOptionalAndDefaulted()
- assert encoder.encode(self.s) == ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
-
- def testWithOptionalAndDefaultedIndefMode(self):
- self.__initWithOptionalAndDefaulted()
- assert encoder.encode(
- self.s, defMode=0
- ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
-
- def testWithOptionalAndDefaultedDefModeChunked(self):
- self.__initWithOptionalAndDefaulted()
- assert encoder.encode(
- self.s, defMode=1, maxChunkSize=4
- ) == ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
-
- def testWithOptionalAndDefaultedIndefModeChunked(self):
- self.__initWithOptionalAndDefaulted()
- assert encoder.encode(
- self.s, defMode=0, maxChunkSize=4
- ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
-
-class ChoiceEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null('')),
- namedtype.NamedType('number', univ.Integer(0)),
- namedtype.NamedType('string', univ.OctetString())
- ))
-
- def testEmpty(self):
- try:
- encoder.encode(self.s)
- except PyAsn1Error:
- pass
- else:
- assert 0, 'encoded unset choice'
-
- def testFilled(self):
- self.s.setComponentByPosition(0, univ.Null(''))
- assert encoder.encode(self.s) == ints2octs((5, 0))
-
- def testTagged(self):
- s = self.s.subtype(
- explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,4)
- )
- s.setComponentByPosition(0, univ.Null(''))
- assert encoder.encode(s) == ints2octs((164, 2, 5, 0))
-
- def testUndefLength(self):
- self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
- assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0))
-
- def testTaggedUndefLength(self):
- s = self.s.subtype(
- explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,4)
- )
- s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
- assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs((164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0))
-
-class AnyEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
-
- def testUntagged(self):
- assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120))
-
- def testTaggedEx(self):
- s = self.s.subtype(
- explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
- )
- assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120))
-
- def testTaggedIm(self):
- s = self.s.subtype(
- implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
- )
- assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120))
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'cer')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
- suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/test_decoder.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from pyasn1.type import univ
-from pyasn1.codec.cer import decoder
-from pyasn1.compat.octets import ints2octs, str2octs, null
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class BooleanDecoderTestCase(unittest.TestCase):
- def testTrue(self):
- assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
- def testFalse(self):
- assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
-
-class OctetStringDecoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert decoder.decode(
- ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
- ) == (str2octs('Quick brown fox'), null)
- def testLongMode(self):
- assert decoder.decode(
- ints2octs((36, 128, 4, 130, 3, 232) + (81,)*1000 + (4, 1, 81, 0, 0))
- ) == (str2octs('Q'*1001), null)
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/test_encoder.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.codec.cer import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class BooleanEncoderTestCase(unittest.TestCase):
- def testTrue(self):
- assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255))
- def testFalse(self):
- assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
-
-class BitStringEncoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert encoder.encode(
- univ.BitString((1,0)*501)
- ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
-
- def testLongMode(self):
- assert encoder.encode(
- univ.BitString((1,0)*501)
- ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
-
-class OctetStringEncoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert encoder.encode(
- univ.OctetString('Quick brown fox')
- ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
- def testLongMode(self):
- assert encoder.encode(
- univ.OctetString('Q'*1001)
- ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,)*1000 + (4, 1, 81, 0, 0))
-
-class SetEncoderTestCase(unittest.TestCase):
- def setUp(self):
- self.s = univ.Set(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null('')),
- namedtype.OptionalNamedType('first-name', univ.OctetString('')),
- namedtype.DefaultedNamedType('age', univ.Integer(33))
- ))
-
- def __init(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
- def __initWithOptional(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
- self.s.setComponentByPosition(1, 'quick brown')
-
- def __initWithDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0)
- self.s.setComponentByPosition(2, 1)
-
- def __initWithOptionalAndDefaulted(self):
- self.s.clear()
- self.s.setComponentByPosition(0, univ.Null(''))
- self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
- self.s.setComponentByPosition(2, univ.Integer(1))
-
- def testIndefMode(self):
- self.__init()
- assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0))
-
- def testWithOptionalIndefMode(self):
- self.__initWithOptional()
- assert encoder.encode(
- self.s
- ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
-
- def testWithDefaultedIndefMode(self):
- self.__initWithDefaulted()
- assert encoder.encode(
- self.s
- ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0))
-
- def testWithOptionalAndDefaultedIndefMode(self):
- self.__initWithOptionalAndDefaulted()
- assert encoder.encode(
- self.s
- ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
-
-class SetWithChoiceEncoderTestCase(unittest.TestCase):
- def setUp(self):
- c = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('actual', univ.Boolean(0))
- ))
- self.s = univ.Set(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null('')),
- namedtype.NamedType('status', c)
- ))
-
- def testIndefMode(self):
- self.s.setComponentByPosition(0)
- self.s.setComponentByName('status')
- self.s.getComponentByName('status').setComponentByPosition(0, 1)
- assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0))
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'der')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
- suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/test_decoder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from pyasn1.type import univ
-from pyasn1.codec.der import decoder
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class OctetStringDecoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert decoder.decode(
- '\004\017Quick brown fox'.encode()
- ) == ('Quick brown fox'.encode(), ''.encode())
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/test_encoder.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.codec.der import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class OctetStringEncoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert encoder.encode(
- univ.OctetString('Quick brown fox')
- ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
-class BitStringEncoderTestCase(unittest.TestCase):
- def testShortMode(self):
- assert encoder.encode(
- univ.BitString((1,))
- ) == ints2octs((3, 2, 7, 128))
-
-class SetWithChoiceEncoderTestCase(unittest.TestCase):
- def setUp(self):
- c = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('name', univ.OctetString('')),
- namedtype.NamedType('amount', univ.Integer(0))
- ))
- self.s = univ.Set(componentType=namedtype.NamedTypes(
- namedtype.NamedType('place-holder', univ.Null('')),
- namedtype.NamedType('status', c)
- ))
-
- def testDefMode(self):
- self.s.setComponentByPosition(0)
- self.s.setComponentByName('status')
- self.s.getComponentByName('status').setComponentByPosition(0, 'ann')
- assert encoder.encode(self.s) == ints2octs((49, 7, 4, 3, 97, 110, 110, 5, 0))
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/suite.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'codec'+sep+'ber')
-import ber.suite
-path.insert(1, path[0]+sep+'codec'+sep+'cer')
-import cer.suite
-path.insert(1, path[0]+sep+'codec'+sep+'der')
-import der.suite
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-for m in (
- ber.suite,
- cer.suite,
- der.suite
- ):
- suite.addTest(getattr(m, 'suite'))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/suite.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'type')
-import type.suite
-path.insert(1, path[0]+sep+'codec')
-import codec.suite
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-for m in (
- type.suite,
- codec.suite
- ):
- suite.addTest(getattr(m, 'suite'))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/suite.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import test_tag, test_constraint, test_namedtype, test_univ
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_tag, test_constraint, test_namedtype, test_univ):
- suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_constraint.py
+++ /dev/null
@@ -1,280 +0,0 @@
-from pyasn1.type import constraint, error
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class SingleValueConstraintTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.SingleValueConstraint(1,2)
- self.c2 = constraint.SingleValueConstraint(3,4)
-
- def testCmp(self): assert self.c1 == self.c1, 'comparation fails'
- def testHash(self): assert hash(self.c1) != hash(self.c2), 'hash() fails'
- def testGoodVal(self):
- try:
- self.c1(1)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(4)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ContainedSubtypeConstraintTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ContainedSubtypeConstraint(
- constraint.SingleValueConstraint(12)
- )
-
- def testGoodVal(self):
- try:
- self.c1(12)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(4)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ValueRangeConstraintTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ValueRangeConstraint(1,4)
-
- def testGoodVal(self):
- try:
- self.c1(1)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(-5)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ValueSizeConstraintTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ValueSizeConstraint(1,2)
-
- def testGoodVal(self):
- try:
- self.c1('a')
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1('abc')
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class PermittedAlphabetConstraintTestCase(SingleValueConstraintTestCase):
- def setUp(self):
- self.c1 = constraint.PermittedAlphabetConstraint('A', 'B', 'C')
- self.c2 = constraint.PermittedAlphabetConstraint('DEF')
-
- def testGoodVal(self):
- try:
- self.c1('A')
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1('E')
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ConstraintsIntersectionTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ConstraintsIntersection(
- constraint.SingleValueConstraint(4),
- constraint.ValueRangeConstraint(2, 4)
- )
-
- def testCmp1(self):
- assert constraint.SingleValueConstraint(4) in self.c1, '__cmp__() fails'
-
- def testCmp2(self):
- assert constraint.SingleValueConstraint(5) not in self.c1, \
- '__cmp__() fails'
-
- def testCmp3(self):
- c = constraint.ConstraintsUnion(constraint.ConstraintsIntersection(
- constraint.SingleValueConstraint(4),
- constraint.ValueRangeConstraint(2, 4)
- ))
- assert self.c1 in c, '__cmp__() fails'
- def testCmp4(self):
- c = constraint.ConstraintsUnion(
- constraint.ConstraintsIntersection(constraint.SingleValueConstraint(5))
- )
- assert self.c1 not in c, '__cmp__() fails'
-
- def testGoodVal(self):
- try:
- self.c1(4)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(-5)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class InnerTypeConstraintTestCase(unittest.TestCase):
- def testConst1(self):
- c = constraint.InnerTypeConstraint(
- constraint.SingleValueConstraint(4)
- )
- try:
- c(4, 32)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- try:
- c(5, 32)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
- def testConst2(self):
- c = constraint.InnerTypeConstraint(
- (0, constraint.SingleValueConstraint(4), 'PRESENT'),
- (1, constraint.SingleValueConstraint(4), 'ABSENT')
- )
- try:
- c(4, 0)
- except error.ValueConstraintError:
- raise
- assert 0, 'constraint check fails'
- try:
- c(4, 1)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
- try:
- c(3, 0)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-# Constraints compositions
-
-class ConstraintsIntersectionTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ConstraintsIntersection(
- constraint.ValueRangeConstraint(1, 9),
- constraint.ValueRangeConstraint(2, 5)
- )
-
- def testGoodVal(self):
- try:
- self.c1(3)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(0)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ConstraintsUnionTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ConstraintsUnion(
- constraint.SingleValueConstraint(5),
- constraint.ValueRangeConstraint(1, 3)
- )
-
- def testGoodVal(self):
- try:
- self.c1(2)
- self.c1(5)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(-5)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-class ConstraintsExclusionTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ConstraintsExclusion(
- constraint.ValueRangeConstraint(2, 4)
- )
-
- def testGoodVal(self):
- try:
- self.c1(6)
- except error.ValueConstraintError:
- assert 0, 'constraint check fails'
- def testBadVal(self):
- try:
- self.c1(2)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint check fails'
-
-# Constraints derivations
-
-class DirectDerivationTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.SingleValueConstraint(5)
- self.c2 = constraint.ConstraintsUnion(
- self.c1, constraint.ValueRangeConstraint(1, 3)
- )
-
- def testGoodVal(self):
- assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
- assert not self.c1.isSubTypeOf(self.c2) , 'isSubTypeOf failed'
- def testBadVal(self):
- assert not self.c2.isSuperTypeOf(self.c1) , 'isSuperTypeOf failed'
- assert self.c2.isSubTypeOf(self.c1) , 'isSubTypeOf failed'
-
-class IndirectDerivationTestCase(unittest.TestCase):
- def setUp(self):
- self.c1 = constraint.ConstraintsIntersection(
- constraint.ValueRangeConstraint(1, 30)
- )
- self.c2 = constraint.ConstraintsIntersection(
- self.c1, constraint.ValueRangeConstraint(1, 20)
- )
- self.c2 = constraint.ConstraintsIntersection(
- self.c2, constraint.ValueRangeConstraint(1, 10)
- )
-
- def testGoodVal(self):
- assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
- assert not self.c1.isSubTypeOf(self.c2) , 'isSubTypeOf failed'
- def testBadVal(self):
- assert not self.c2.isSuperTypeOf(self.c1) , 'isSuperTypeOf failed'
- assert self.c2.isSubTypeOf(self.c1) , 'isSubTypeOf failed'
-
-if __name__ == '__main__': unittest.main()
-
-# how to apply size constriants to constructed types?
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_namedtype.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class NamedTypeCaseBase(unittest.TestCase):
- def setUp(self):
- self.e = namedtype.NamedType('age', univ.Integer())
- def testIter(self):
- n, t = self.e
- assert n == 'age' or t == univ.Integer(), 'unpack fails'
-
-class NamedTypesCaseBase(unittest.TestCase):
- def setUp(self):
- self.e = namedtype.NamedTypes(
- namedtype.NamedType('first-name', univ.OctetString('')),
- namedtype.OptionalNamedType('age', univ.Integer(0)),
- namedtype.NamedType('family-name', univ.OctetString(''))
- )
- def testIter(self):
- for t in self.e:
- break
- else:
- assert 0, '__getitem__() fails'
-
- def testGetTypeByPosition(self):
- assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
- 'getTypeByPosition() fails'
-
- def testGetNameByPosition(self):
- assert self.e.getNameByPosition(0) == 'first-name', \
- 'getNameByPosition() fails'
-
- def testGetPositionByName(self):
- assert self.e.getPositionByName('first-name') == 0, \
- 'getPositionByName() fails'
-
- def testGetTypesNearPosition(self):
- assert self.e.getTagMapNearPosition(0).getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString('')
- }
- assert self.e.getTagMapNearPosition(1).getPosMap() == {
- univ.Integer.tagSet: univ.Integer(0),
- univ.OctetString.tagSet: univ.OctetString('')
- }
- assert self.e.getTagMapNearPosition(2).getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString('')
- }
-
- def testGetTagMap(self):
- assert self.e.getTagMap().getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString(''),
- univ.Integer.tagSet: univ.Integer(0)
- }
-
- def testGetTagMapWithDups(self):
- try:
- self.e.getTagMap(1)
- except PyAsn1Error:
- pass
- else:
- assert 0, 'Duped types not noticed'
-
- def testGetPositionNearType(self):
- assert self.e.getPositionNearType(univ.OctetString.tagSet, 0) == 0
- assert self.e.getPositionNearType(univ.Integer.tagSet, 1) == 1
- assert self.e.getPositionNearType(univ.OctetString.tagSet, 2) == 2
-
-class OrderedNamedTypesCaseBase(unittest.TestCase):
- def setUp(self):
- self.e = namedtype.NamedTypes(
- namedtype.NamedType('first-name', univ.OctetString('')),
- namedtype.NamedType('age', univ.Integer(0))
- )
-
- def testGetTypeByPosition(self):
- assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
- 'getTypeByPosition() fails'
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_tag.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from pyasn1.type import tag
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class TagTestCaseBase(unittest.TestCase):
- def setUp(self):
- self.t1 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
- self.t2 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
-
-class TagCmpTestCase(TagTestCaseBase):
- def testCmp(self):
- assert self.t1 == self.t2, 'tag comparation fails'
-
- def testHash(self):
- assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails'
-
- def testSequence(self):
- assert self.t1[0] == self.t2[0] and \
- self.t1[1] == self.t2[1] and \
- self.t1[2] == self.t2[2], 'tag sequence protocol fails'
-
-class TagSetTestCaseBase(unittest.TestCase):
- def setUp(self):
- self.ts1 = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
- )
- self.ts2 = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
- )
-
-class TagSetCmpTestCase(TagSetTestCaseBase):
- def testCmp(self):
- assert self.ts1 == self.ts2, 'tag set comparation fails'
-
- def testHash(self):
- assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails'
-
- def testLen(self):
- assert len(self.ts1) == len(self.ts2), 'tag length comparation fails'
-
-class TaggingTestSuite(TagSetTestCaseBase):
- def testImplicitTag(self):
- t = self.ts1.tagImplicitly(
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
- )
- assert t == tag.TagSet(
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
- ), 'implicit tagging went wrong'
-
- def testExplicitTag(self):
- t = self.ts1.tagExplicitly(
- tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 32)
- )
- assert t == tag.TagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassPrivate, tag.tagFormatConstructed, 32)
- ), 'explicit tagging went wrong'
-
-class TagSetAddTestSuite(TagSetTestCaseBase):
- def testAdd(self):
- t = self.ts1 + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
- assert t == tag.TagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
- ), 'TagSet.__add__() fails'
-
- def testRadd(self):
- t = tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + self.ts1
- assert t == tag.TagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
- ), 'TagSet.__radd__() fails'
-
-class SuperTagSetTestCase(TagSetTestCaseBase):
- def testSuperTagCheck1(self):
- assert self.ts1.isSuperTagSetOf(
- tag.TagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
- )), 'isSuperTagSetOf() fails'
-
- def testSuperTagCheck2(self):
- assert not self.ts1.isSuperTagSetOf(
- tag.TagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 13)
- )), 'isSuperTagSetOf() fails'
-
- def testSuperTagCheck3(self):
- assert self.ts1.isSuperTagSetOf(
- tag.TagSet((), tag.Tag(tag.tagClassUniversal,
- tag.tagFormatSimple, 12))
- ), 'isSuperTagSetOf() fails'
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_univ.py
+++ /dev/null
@@ -1,479 +0,0 @@
-from pyasn1.type import univ, tag, constraint, namedtype, namedval, error
-from pyasn1.compat.octets import str2octs, ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
- version_info[0:2] in ( (3, 0), (3, 1) ):
- try:
- import unittest2 as unittest
- except ImportError:
- import unittest
-else:
- import unittest
-
-class IntegerTestCase(unittest.TestCase):
- def testStr(self): assert str(univ.Integer(1)) in ('1','1L'),'str() fails'
- def testAnd(self): assert univ.Integer(1) & 0 == 0, '__and__() fails'
- def testOr(self): assert univ.Integer(1) | 0 == 1, '__or__() fails'
- def testXor(self): assert univ.Integer(1) ^ 0 == 1, '__xor__() fails'
- def testRand(self): assert 0 & univ.Integer(1) == 0, '__rand__() fails'
- def testRor(self): assert 0 | univ.Integer(1) == 1, '__ror__() fails'
- def testRxor(self): assert 0 ^ univ.Integer(1) == 1, '__rxor__() fails'
- def testAdd(self): assert univ.Integer(-4) + 6 == 2, '__add__() fails'
- def testRadd(self): assert 4 + univ.Integer(5) == 9, '__radd__() fails'
- def testSub(self): assert univ.Integer(3) - 6 == -3, '__sub__() fails'
- def testRsub(self): assert 6 - univ.Integer(3) == 3, '__rsub__() fails'
- def testMul(self): assert univ.Integer(3) * -3 == -9, '__mul__() fails'
- def testRmul(self): assert 2 * univ.Integer(3) == 6, '__rmul__() fails'
- def testDiv(self): assert univ.Integer(3) / 2 == 1, '__div__() fails'
- def testRdiv(self): assert 6 / univ.Integer(3) == 2, '__rdiv__() fails'
- def testMod(self): assert univ.Integer(3) % 2 == 1, '__mod__() fails'
- def testRmod(self): assert 4 % univ.Integer(3) == 1, '__rmod__() fails'
- def testPow(self): assert univ.Integer(3) ** 2 == 9, '__pow__() fails'
- def testRpow(self): assert 2 ** univ.Integer(2) == 4, '__rpow__() fails'
- def testLshift(self): assert univ.Integer(1) << 1 == 2, '<< fails'
- def testRshift(self): assert univ.Integer(2) >> 1 == 1, '>> fails'
- def testInt(self): assert int(univ.Integer(3)) == 3, '__int__() fails'
- def testLong(self): assert int(univ.Integer(8)) == 8, '__long__() fails'
- def testFloat(self): assert float(univ.Integer(4))==4.0,'__float__() fails'
- def testPrettyIn(self): assert univ.Integer('3') == 3, 'prettyIn() fails'
- def testTag(self):
- assert univ.Integer().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
- )
- def testNamedVals(self):
- i = univ.Integer(
- 'asn1', namedValues=univ.Integer.namedValues.clone(('asn1', 1))
- )
- assert i == 1, 'named val fails'
- assert str(i) != 'asn1', 'named val __str__() fails'
-
-class BooleanTestCase(unittest.TestCase):
- def testTruth(self):
- assert univ.Boolean(True) and univ.Boolean(1), 'Truth initializer fails'
- def testFalse(self):
- assert not univ.Boolean(False) and not univ.Boolean(0), 'False initializer fails'
- def testStr(self):
- assert str(univ.Boolean(1)) in ('1', '1L'), 'str() fails'
- def testTag(self):
- assert univ.Boolean().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01)
- )
- def testConstraints(self):
- try:
- univ.Boolean(2)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint fail'
- def testSubtype(self):
- assert univ.Integer().subtype(
- value=1,
- implicitTag=tag.Tag(tag.tagClassPrivate,tag.tagFormatSimple,2),
- subtypeSpec=constraint.SingleValueConstraint(1,3)
- ) == univ.Integer(
- value=1,
- tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
- tag.tagFormatSimple,2)),
- subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1,3))
- )
-
-class BitStringTestCase(unittest.TestCase):
- def setUp(self):
- self.b = univ.BitString(
- namedValues=namedval.NamedValues(('Active', 0), ('Urgent', 1))
- )
- def testSet(self):
- assert self.b.clone('Active') == (1,)
- assert self.b.clone("'1010100110001010'B") == (1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,0)
- assert self.b.clone("'A98A'H") == (1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,0)
- assert self.b.clone((1,0,1)) == (1,0,1)
- def testStr(self):
- assert str(self.b.clone('Urgent,Active')) == '(1, 1)'
- def testRepr(self):
- assert repr(self.b.clone('Urgent,Active')) == 'BitString("\'11\'B")'
- def testTag(self):
- assert univ.BitString().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
- )
- def testLen(self): assert len(self.b.clone("'A98A'H")) == 16
- def testIter(self):
- assert self.b.clone("'A98A'H")[0] == 1
- assert self.b.clone("'A98A'H")[1] == 0
- assert self.b.clone("'A98A'H")[2] == 1
-
-class OctetStringTestCase(unittest.TestCase):
- def testInit(self):
- assert univ.OctetString(str2octs('abcd')) == str2octs('abcd'), '__init__() fails'
- def testBinStr(self):
- assert univ.OctetString(binValue="1000010111101110101111000000111011") == ints2octs((133, 238, 188, 14, 192)), 'bin init fails'
- def testHexStr(self):
- assert univ.OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32)), 'hex init fails'
- def testTuple(self):
- assert univ.OctetString((1,2,3,4,5)) == ints2octs((1,2,3,4,5)), 'tuple init failed'
- def testStr(self):
- assert str(univ.OctetString('q')) == 'q', '__str__() fails'
- def testSeq(self):
- assert univ.OctetString('q')[0] == str2octs('q')[0],'__getitem__() fails'
- def testAsOctets(self):
- assert univ.OctetString('abcd').asOctets() == str2octs('abcd'), 'testAsOctets() fails'
- def testAsInts(self):
- assert univ.OctetString('abcd').asNumbers() == (97, 98, 99, 100), 'testAsNumbers() fails'
-
- def testEmpty(self):
- try:
- str(univ.OctetString())
- except PyAsn1Error:
- pass
- else:
- assert 0, 'empty OctetString() not reported'
-
- def testAdd(self):
- assert univ.OctetString('') + 'q' == str2octs('q'), '__add__() fails'
- def testRadd(self):
- assert 'b' + univ.OctetString('q') == str2octs('bq'), '__radd__() fails'
- def testMul(self):
- assert univ.OctetString('a') * 2 == str2octs('aa'), '__mul__() fails'
- def testRmul(self):
- assert 2 * univ.OctetString('b') == str2octs('bb'), '__rmul__() fails'
- def testTag(self):
- assert univ.OctetString().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
- )
-
-class Null(unittest.TestCase):
- def testStr(self): assert str(univ.Null('')) == '', 'str() fails'
- def testTag(self):
- assert univ.Null().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
- )
- def testConstraints(self):
- try:
- univ.Null(2)
- except error.ValueConstraintError:
- pass
- else:
- assert 0, 'constraint fail'
-
-class RealTestCase(unittest.TestCase):
- def testStr(self): assert str(univ.Real(1.0)) == '1.0','str() fails'
- def testRepr(self): assert repr(univ.Real(-4.1)) == 'Real((-41, 10, -1))','repr() fails'
- def testAdd(self): assert univ.Real(-4.1) + 1.4 == -2.7, '__add__() fails'
- def testRadd(self): assert 4 + univ.Real(0.5) == 4.5, '__radd__() fails'
- def testSub(self): assert univ.Real(3.9) - 1.7 == 2.2, '__sub__() fails'
- def testRsub(self): assert 6.1 - univ.Real(0.1) == 6, '__rsub__() fails'
- def testMul(self): assert univ.Real(3.0) * -3 == -9, '__mul__() fails'
- def testRmul(self): assert 2 * univ.Real(3.0) == 6, '__rmul__() fails'
- def testDiv(self): assert univ.Real(3.0) / 2 == 1.5, '__div__() fails'
- def testRdiv(self): assert 6 / univ.Real(3.0) == 2, '__rdiv__() fails'
- def testMod(self): assert univ.Real(3.0) % 2 == 1, '__mod__() fails'
- def testRmod(self): assert 4 % univ.Real(3.0) == 1, '__rmod__() fails'
- def testPow(self): assert univ.Real(3.0) ** 2 == 9, '__pow__() fails'
- def testRpow(self): assert 2 ** univ.Real(2.0) == 4, '__rpow__() fails'
- def testInt(self): assert int(univ.Real(3.0)) == 3, '__int__() fails'
- def testLong(self): assert int(univ.Real(8.0)) == 8, '__long__() fails'
- def testFloat(self): assert float(univ.Real(4.0))==4.0,'__float__() fails'
- def testPrettyIn(self): assert univ.Real((3,10,0)) == 3, 'prettyIn() fails'
- # infinite float values
- def testStrInf(self):
- assert str(univ.Real('inf')) == 'inf','str() fails'
- def testReprInf(self):
- assert repr(univ.Real('inf')) == 'Real(\'inf\')','repr() fails'
- def testAddInf(self):
- assert univ.Real('inf') + 1 == float('inf'), '__add__() fails'
- def testRaddInf(self):
- assert 1 + univ.Real('inf') == float('inf'), '__radd__() fails'
- def testIntInf(self):
- try:
- assert int(univ.Real('inf'))
- except OverflowError:
- pass
- else:
- assert 0, '__int__() fails'
- def testLongInf(self):
- try:
- assert int(univ.Real('inf'))
- except OverflowError:
- pass
- else:
- assert 0, '__long__() fails'
- assert int(univ.Real(8.0)) == 8, '__long__() fails'
- def testFloatInf(self):
- assert float(univ.Real('-inf')) == float('-inf'),'__float__() fails'
- def testPrettyInInf(self):
- assert univ.Real(float('inf')) == float('inf'), 'prettyIn() fails'
- def testPlusInf(self):
- assert univ.Real('inf').isPlusInfinity(), 'isPlusInfinity failed'
- def testMinusInf(self):
- assert univ.Real('-inf').isMinusInfinity(), 'isMinusInfinity failed'
-
- def testTag(self):
- assert univ.Real().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
- )
-
-class ObjectIdentifier(unittest.TestCase):
- def testStr(self):
- assert str(univ.ObjectIdentifier((1,3,6))) == '1.3.6'
- def testEq(self):
- assert univ.ObjectIdentifier((1,3,6)) == (1,3,6), '__cmp__() fails'
- def testAdd(self):
- assert univ.ObjectIdentifier((1,3)) + (6,)==(1,3,6),'__add__() fails'
- def testRadd(self):
- assert (1,) + univ.ObjectIdentifier((3,6))==(1,3,6),'__radd__() fails'
- def testLen(self):
- assert len(univ.ObjectIdentifier((1,3))) == 2,'__len__() fails'
- def testPrefix(self):
- o = univ.ObjectIdentifier('1.3.6')
- assert o.isPrefixOf((1,3,6)), 'isPrefixOf() fails'
- assert o.isPrefixOf((1,3,6,1)), 'isPrefixOf() fails'
- assert not o.isPrefixOf((1,3)), 'isPrefixOf() fails'
- def testInput(self):
- assert univ.ObjectIdentifier('1.3.6')==(1,3,6),'prettyIn() fails'
- def testTag(self):
- assert univ.ObjectIdentifier().getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
- )
-
-class SequenceOf(unittest.TestCase):
- def setUp(self):
- self.s1 = univ.SequenceOf(
- componentType=univ.OctetString('')
- )
- self.s2 = self.s1.clone()
- def testTag(self):
- assert self.s1.getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- ), 'wrong tagSet'
- def testSeq(self):
- self.s1.setComponentByPosition(0, univ.OctetString('abc'))
- assert self.s1[0] == str2octs('abc'), 'set by idx fails'
- self.s1[0] = 'cba'
- assert self.s1[0] == str2octs('cba'), 'set by idx fails'
- def testCmp(self):
- self.s1.clear()
- self.s1.setComponentByPosition(0, 'abc')
- self.s2.clear()
- self.s2.setComponentByPosition(0, univ.OctetString('abc'))
- assert self.s1 == self.s2, '__cmp__() fails'
- def testSubtypeSpec(self):
- s = self.s1.clone(subtypeSpec=constraint.ConstraintsUnion(
- constraint.SingleValueConstraint(str2octs('abc'))
- ))
- try:
- s.setComponentByPosition(0, univ.OctetString('abc'))
- except:
- assert 0, 'constraint fails'
- try:
- s.setComponentByPosition(1, univ.OctetString('Abc'))
- except:
- pass
- else:
- assert 0, 'constraint fails'
- def testSizeSpec(self):
- s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion(
- constraint.ValueSizeConstraint(1,1)
- ))
- s.setComponentByPosition(0, univ.OctetString('abc'))
- try:
- s.verifySizeSpec()
- except:
- assert 0, 'size spec fails'
- s.setComponentByPosition(1, univ.OctetString('abc'))
- try:
- s.verifySizeSpec()
- except:
- pass
- else:
- assert 0, 'size spec fails'
- def testGetComponentTagMap(self):
- assert self.s1.getComponentTagMap().getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString('')
- }
- def testSubtype(self):
- self.s1.clear()
- assert self.s1.subtype(
- implicitTag=tag.Tag(tag.tagClassPrivate,tag.tagFormatSimple,2),
- subtypeSpec=constraint.SingleValueConstraint(1,3),
- sizeSpec=constraint.ValueSizeConstraint(0,1)
- ) == self.s1.clone(
- tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
- tag.tagFormatSimple,2)),
- subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1,3)),
- sizeSpec=constraint.ValueSizeConstraint(0,1)
- )
- def testClone(self):
- self.s1.setComponentByPosition(0, univ.OctetString('abc'))
- s = self.s1.clone()
- assert len(s) == 0
- s = self.s1.clone(cloneValueFlag=1)
- assert len(s) == 1
- assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
-
-class Sequence(unittest.TestCase):
- def setUp(self):
- self.s1 = univ.Sequence(componentType=namedtype.NamedTypes(
- namedtype.NamedType('name', univ.OctetString('')),
- namedtype.OptionalNamedType('nick', univ.OctetString('')),
- namedtype.DefaultedNamedType('age', univ.Integer(34))
- ))
- def testTag(self):
- assert self.s1.getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- ), 'wrong tagSet'
- def testById(self):
- self.s1.setComponentByName('name', univ.OctetString('abc'))
- assert self.s1.getComponentByName('name') == str2octs('abc'), 'set by name fails'
- def testByKey(self):
- self.s1['name'] = 'abc'
- assert self.s1['name'] == str2octs('abc'), 'set by key fails'
- def testGetNearPosition(self):
- assert self.s1.getComponentTagMapNearPosition(1).getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString(''),
- univ.Integer.tagSet: univ.Integer(34)
- }
- assert self.s1.getComponentPositionNearType(
- univ.OctetString.tagSet, 1
- ) == 1
- def testGetDefaultComponentByPosition(self):
- self.s1.clear()
- assert self.s1.getDefaultComponentByPosition(0) == None
- assert self.s1.getDefaultComponentByPosition(2) == univ.Integer(34)
- def testSetDefaultComponents(self):
- self.s1.clear()
- assert self.s1.getComponentByPosition(2) == None
- self.s1.setComponentByPosition(0, univ.OctetString('Ping'))
- self.s1.setComponentByPosition(1, univ.OctetString('Pong'))
- self.s1.setDefaultComponents()
- assert self.s1.getComponentByPosition(2) == 34
- def testClone(self):
- self.s1.setComponentByPosition(0, univ.OctetString('abc'))
- self.s1.setComponentByPosition(1, univ.OctetString('def'))
- self.s1.setComponentByPosition(2, univ.Integer(123))
- s = self.s1.clone()
- assert s.getComponentByPosition(0) != self.s1.getComponentByPosition(0)
- assert s.getComponentByPosition(1) != self.s1.getComponentByPosition(1)
- assert s.getComponentByPosition(2) != self.s1.getComponentByPosition(2)
- s = self.s1.clone(cloneValueFlag=1)
- assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
- assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1)
- assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2)
-
-class SetOf(unittest.TestCase):
- def setUp(self):
- self.s1 = univ.SetOf(componentType=univ.OctetString(''))
- def testTag(self):
- assert self.s1.getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
- ), 'wrong tagSet'
- def testSeq(self):
- self.s1.setComponentByPosition(0, univ.OctetString('abc'))
- assert self.s1[0] == str2octs('abc'), 'set by idx fails'
- self.s1.setComponentByPosition(0, self.s1[0].clone('cba'))
- assert self.s1[0] == str2octs('cba'), 'set by idx fails'
-
-class Set(unittest.TestCase):
- def setUp(self):
- self.s1 = univ.Set(componentType=namedtype.NamedTypes(
- namedtype.NamedType('name', univ.OctetString('')),
- namedtype.OptionalNamedType('null', univ.Null('')),
- namedtype.DefaultedNamedType('age', univ.Integer(34))
- ))
- self.s2 = self.s1.clone()
- def testTag(self):
- assert self.s1.getTagSet() == tag.TagSet(
- (),
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
- ), 'wrong tagSet'
- def testByTypeWithPythonValue(self):
- self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
- assert self.s1.getComponentByType(
- univ.OctetString.tagSet
- ) == str2octs('abc'), 'set by name fails'
- def testByTypeWithInstance(self):
- self.s1.setComponentByType(univ.OctetString.tagSet, univ.OctetString('abc'))
- assert self.s1.getComponentByType(
- univ.OctetString.tagSet
- ) == str2octs('abc'), 'set by name fails'
- def testGetTagMap(self):
- assert self.s1.getTagMap().getPosMap() == {
- univ.Set.tagSet: univ.Set()
- }
- def testGetComponentTagMap(self):
- assert self.s1.getComponentTagMap().getPosMap() == {
- univ.OctetString.tagSet: univ.OctetString(''),
- univ.Null.tagSet: univ.Null(''),
- univ.Integer.tagSet: univ.Integer(34)
- }
- def testGetPositionByType(self):
- assert self.s1.getComponentPositionByType(
- univ.Null().getTagSet()
- ) == 1
-
-class Choice(unittest.TestCase):
- def setUp(self):
- innerComp = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('count', univ.Integer()),
- namedtype.NamedType('flag', univ.Boolean())
- ))
- self.s1 = univ.Choice(componentType=namedtype.NamedTypes(
- namedtype.NamedType('name', univ.OctetString()),
- namedtype.NamedType('sex', innerComp)
- ))
- def testTag(self):
- assert self.s1.getTagSet() == tag.TagSet(), 'wrong tagSet'
- def testOuterByTypeWithPythonValue(self):
- self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
- assert self.s1.getComponentByType(
- univ.OctetString.tagSet
- ) == str2octs('abc')
- def testOuterByTypeWithInstanceValue(self):
- self.s1.setComponentByType(
- univ.OctetString.tagSet, univ.OctetString('abc')
- )
- assert self.s1.getComponentByType(
- univ.OctetString.tagSet
- ) == str2octs('abc')
- def testInnerByTypeWithPythonValue(self):
- self.s1.setComponentByType(univ.Integer.tagSet, 123, 1)
- assert self.s1.getComponentByType(
- univ.Integer.tagSet, 1
- ) == 123
- def testInnerByTypeWithInstanceValue(self):
- self.s1.setComponentByType(
- univ.Integer.tagSet, univ.Integer(123), 1
- )
- assert self.s1.getComponentByType(
- univ.Integer.tagSet, 1
- ) == 123
- def testCmp(self):
- self.s1.setComponentByName('name', univ.OctetString('abc'))
- assert self.s1 == str2octs('abc'), '__cmp__() fails'
- def testGetComponent(self):
- self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
- assert self.s1.getComponent() == str2octs('abc'), 'getComponent() fails'
- def testGetName(self):
- self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
- assert self.s1.getName() == 'name', 'getName() fails'
- def testSetComponentByPosition(self):
- self.s1.setComponentByPosition(0, univ.OctetString('Jim'))
- assert self.s1 == str2octs('Jim')
- def testClone(self):
- self.s1.setComponentByPosition(0, univ.OctetString('abc'))
- s = self.s1.clone()
- assert len(s) == 0
- s = self.s1.clone(cloneValueFlag=1)
- assert len(s) == 1
- assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
-
-if __name__ == '__main__': unittest.main()
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/__main__.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.test_debug.suite',
+ 'tests.type.__main__.suite',
+ 'tests.codec.__main__.suite',
+ 'tests.compat.__main__.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/base.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from pyasn1 import debug
+
+
+class BaseTestCase(unittest.TestCase):
+
+ def setUp(self):
+ debug.setLogger(debug.Debug('all', printer=lambda *x: None))
+
+ def tearDown(self):
+ debug.setLogger(None)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/__main__.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.codec.ber.__main__.suite',
+ 'tests.codec.cer.__main__.suite',
+ 'tests.codec.der.__main__.suite',
+ 'tests.codec.native.__main__.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/ber/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.codec.ber.test_encoder.suite',
+ 'tests.codec.ber.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/test_decoder.py
@@ -0,0 +1,1294 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag, namedtype, univ, char
+from pyasn1.codec.ber import decoder, eoo
+from pyasn1.compat.octets import ints2octs, str2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class LargeTagDecoderTestCase(BaseTestCase):
+ def testLargeTag(self):
+ assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null)
+
+ def testLongTag(self):
+ assert decoder.decode(ints2octs((0x1f, 2, 1, 0)))[0].tagSet == univ.Integer.tagSet
+
+ def testTagsEquivalence(self):
+ integer = univ.Integer(2).subtype(implicitTag=tag.Tag(tag.tagClassContext, 0, 0))
+ assert decoder.decode(ints2octs((0x9f, 0x80, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) == decoder.decode(
+ ints2octs((0x9f, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer)
+
+
+class DecoderCacheTestCase(BaseTestCase):
+ def testCache(self):
+ assert decoder.decode(ints2octs((0x1f, 2, 1, 0))) == decoder.decode(ints2octs((0x1f, 2, 1, 0)))
+
+
+class IntegerDecoderTestCase(BaseTestCase):
+ def testPosInt(self):
+ assert decoder.decode(ints2octs((2, 1, 12))) == (12, null)
+
+ def testNegInt(self):
+ assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null)
+
+ def testZero(self):
+ assert decoder.decode(ints2octs((2, 0))) == (0, null)
+
+ def testZeroLong(self):
+ assert decoder.decode(ints2octs((2, 1, 0))) == (0, null)
+
+ def testMinusOne(self):
+ assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null)
+
+ def testPosLong(self):
+ assert decoder.decode(
+ ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
+ ) == (0xffffffffffffffff, null)
+
+ def testNegLong(self):
+ assert decoder.decode(
+ ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
+ ) == (-0xffffffffffffffff, null)
+
+ def testSpec(self):
+ try:
+ decoder.decode(
+ ints2octs((2, 1, 12)), asn1Spec=univ.Null()
+ ) == (12, null)
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong asn1Spec worked out'
+ assert decoder.decode(
+ ints2octs((2, 1, 12)), asn1Spec=univ.Integer()
+ ) == (12, null)
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(ints2octs((34, 1, 12)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert decoder.decode(ints2octs((1, 1, 1))) == (1, null)
+
+ def testTrueNeg(self):
+ assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
+
+ def testExtraTrue(self):
+ assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50)))
+
+ def testFalse(self):
+ assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(ints2octs((33, 1, 1)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((3, 3, 1, 169, 138))
+ ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((3, 3, 1, 169, 138))
+ ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+ ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+ ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+ def testDefModeChunkedSubst(self):
+ assert decoder.decode(
+ ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)),
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), str2octs(''))
+
+ def testIndefModeChunkedSubst(self):
+ assert decoder.decode(
+ ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)),
+ substrateFun=lambda a, b, c: (b, str2octs(''))
+ ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), str2octs(''))
+
+ def testTypeChecking(self):
+ try:
+ decoder.decode(ints2octs((35, 4, 2, 2, 42, 42)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'accepted mis-encoded bit-string constructed out of an integer'
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+ ) == (str2octs('Quick brown fox'), null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+ ) == (str2octs('Quick brown fox'), null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs(
+ (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
+ ) == (str2octs('Quick brown fox'), null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111,
+ 120, 0, 0))
+ ) == (str2octs('Quick brown fox'), null)
+
+ def testDefModeChunkedSubst(self):
+ assert decoder.decode(
+ ints2octs(
+ (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)),
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), str2octs(''))
+
+ def testIndefModeChunkedSubst(self):
+ assert decoder.decode(
+ ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111,
+ 120, 0, 0)),
+ substrateFun=lambda a, b, c: (b, str2octs(''))
+ ) == (ints2octs(
+ (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), str2octs(''))
+
+
+class ExpTaggedOctetStringDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.o = univ.OctetString(
+ 'Quick brown fox',
+ tagSet=univ.OctetString.tagSet.tagExplicitly(
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
+ ))
+
+ def testDefMode(self):
+ o, r = decoder.decode(
+ ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+ )
+ assert not r
+ assert self.o == o
+ assert self.o.tagSet == o.tagSet
+ assert self.o.isSameTypeWith(o)
+
+ def testIndefMode(self):
+ o, r = decoder.decode(
+ ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0))
+ )
+ assert not r
+ assert self.o == o
+ assert self.o.tagSet == o.tagSet
+ assert self.o.isSameTypeWith(o)
+
+ def testDefModeChunked(self):
+ o, r = decoder.decode(
+ ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
+ )
+ assert not r
+ assert self.o == o
+ assert self.o.tagSet == o.tagSet
+ assert self.o.isSameTypeWith(o)
+
+ def testIndefModeChunked(self):
+ o, r = decoder.decode(
+ ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
+ )
+ assert not r
+ assert self.o == o
+ assert self.o.tagSet == o.tagSet
+ assert self.o.isSameTypeWith(o)
+
+ def testDefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), str2octs(''))
+
+ def testIndefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((
+ 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0,
+ 0, 0, 0)),
+ substrateFun=lambda a, b, c: (b, str2octs(''))
+ ) == (ints2octs(
+ (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), str2octs(''))
+
+
+class NullDecoderTestCase(BaseTestCase):
+ def testNull(self):
+ assert decoder.decode(ints2octs((5, 0))) == (null, null)
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(ints2octs((37, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+
+# Useful analysis of OID encoding issues could be found here:
+# http://www.viathinksoft.de/~daniel-marschall/asn.1/oid_facts.html
+class ObjectIdentifierDecoderTestCase(BaseTestCase):
+ def testOne(self):
+ assert decoder.decode(
+ ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+ ) == ((1, 3, 6, 0, 0xffffe), null)
+
+ def testEdge1(self):
+ assert decoder.decode(
+ ints2octs((6, 1, 39))
+ ) == ((0, 39), null)
+
+ def testEdge2(self):
+ assert decoder.decode(
+ ints2octs((6, 1, 79))
+ ) == ((1, 39), null)
+
+ def testEdge3(self):
+ assert decoder.decode(
+ ints2octs((6, 1, 120))
+ ) == ((2, 40), null)
+
+ def testEdge4(self):
+ assert decoder.decode(
+ ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F))
+ ) == ((2, 0xffffffff), null)
+
+ def testEdge5(self):
+ assert decoder.decode(
+ ints2octs((6, 1, 0x7F))
+ ) == ((2, 47), null)
+
+ def testEdge6(self):
+ assert decoder.decode(
+ ints2octs((6, 2, 0x81, 0x00))
+ ) == ((2, 48), null)
+
+ def testEdge7(self):
+ assert decoder.decode(
+ ints2octs((6, 3, 0x81, 0x34, 0x03))
+ ) == ((2, 100, 3), null)
+
+ def testEdge8(self):
+ assert decoder.decode(
+ ints2octs((6, 2, 133, 0))
+ ) == ((2, 560), null)
+
+ def testEdge9(self):
+ assert decoder.decode(
+ ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02))
+ ) == ((2, 16843570), null)
+
+ def testNonLeading0x80(self):
+ assert decoder.decode(
+ ints2octs((6, 5, 85, 4, 129, 128, 0)),
+ ) == ((2, 5, 4, 16384), null)
+
+ def testLeading0x80Case1(self):
+ try:
+ decoder.decode(
+ ints2octs((6, 5, 85, 4, 128, 129, 0))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Leading 0x80 tolarated'
+
+ def testLeading0x80Case2(self):
+ try:
+ decoder.decode(
+ ints2octs((6, 7, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7F))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Leading 0x80 tolarated'
+
+ def testLeading0x80Case3(self):
+ try:
+ decoder.decode(
+ ints2octs((6, 2, 0x80, 1))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Leading 0x80 tolarated'
+
+ def testLeading0x80Case4(self):
+ try:
+ decoder.decode(
+ ints2octs((6, 2, 0x80, 0x7F))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Leading 0x80 tolarated'
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(ints2octs((38, 1, 239)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+ def testZeroLength(self):
+ try:
+ decoder.decode(ints2octs((6, 0, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'zero length tolarated'
+
+ def testIndefiniteLength(self):
+ try:
+ decoder.decode(ints2octs((6, 128, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'indefinite length tolarated'
+
+ def testReservedLength(self):
+ try:
+ decoder.decode(ints2octs((6, 255, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'reserved length tolerated'
+
+ def testLarge1(self):
+ assert decoder.decode(
+ ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB,
+ 0xE2, 0xB7, 0x17))
+ ) == ((2, 18446744073709551535184467440737095), null)
+
+ def testLarge2(self):
+ assert decoder.decode(
+ ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6,
+ 0xB8, 0xCB, 0xE2, 0xB6, 0x47))
+ ) == ((2, 999, 18446744073709551535184467440737095), null)
+
+
+class RealDecoderTestCase(BaseTestCase):
+ def testChar(self):
+ assert decoder.decode(
+ ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
+ ) == (univ.Real((123, 10, 11)), null)
+
+ def testBin1(self): # check base = 2
+ assert decoder.decode( # (0.5, 2, 0) encoded with base = 2
+ ints2octs((9, 3, 128, 255, 1))
+ ) == (univ.Real((1, 2, -1)), null)
+
+ def testBin2(self): # check base = 2 and scale factor
+ assert decoder.decode( # (3.25, 2, 0) encoded with base = 8
+ ints2octs((9, 3, 148, 255, 13))
+ ) == (univ.Real((26, 2, -3)), null)
+
+ def testBin3(self): # check base = 16
+ assert decoder.decode( # (0.00390625, 2, 0) encoded with base = 16
+ ints2octs((9, 3, 160, 254, 1))
+ ) == (univ.Real((1, 2, -8)), null)
+
+ def testBin4(self): # check exponenta = 0
+ assert decoder.decode( # (1, 2, 0) encoded with base = 2
+ ints2octs((9, 3, 128, 0, 1))
+ ) == (univ.Real((1, 2, 0)), null)
+
+ def testBin5(self): # case of 2 octs for exponenta and negative exponenta
+ assert decoder.decode( # (3, 2, -1020) encoded with base = 16
+ ints2octs((9, 4, 161, 255, 1, 3))
+ ) == (univ.Real((3, 2, -1020)), null)
+
+# TODO: this requires Real type comparison fix
+
+# def testBin6(self):
+# assert decoder.decode(
+# ints2octs((9, 5, 162, 0, 255, 255, 1))
+# ) == (univ.Real((1, 2, 262140)), null)
+
+# def testBin7(self):
+# assert decoder.decode(
+# ints2octs((9, 7, 227, 4, 1, 35, 69, 103, 1))
+# ) == (univ.Real((-1, 2, 76354972)), null)
+
+ def testPlusInf(self):
+ assert decoder.decode(
+ ints2octs((9, 1, 64))
+ ) == (univ.Real('inf'), null)
+
+ def testMinusInf(self):
+ assert decoder.decode(
+ ints2octs((9, 1, 65))
+ ) == (univ.Real('-inf'), null)
+
+ def testEmpty(self):
+ assert decoder.decode(
+ ints2octs((9, 0))
+ ) == (univ.Real(0.0), null)
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(ints2octs((41, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+ def testShortEncoding(self):
+ try:
+ decoder.decode(ints2octs((9, 1, 131)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'accepted too-short real'
+
+
+if sys.version_info[0:2] > (2, 5):
+ class UniversalStringDecoderTestCase(BaseTestCase):
+ def testDecoder(self):
+ assert decoder.decode(ints2octs((28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99))) == (char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class BMPStringDecoderTestCase(BaseTestCase):
+ def testDecoder(self):
+ assert decoder.decode(ints2octs((30, 6, 0, 97, 0, 98, 0, 99))) == (char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class UTF8StringDecoderTestCase(BaseTestCase):
+ def testDecoder(self):
+ assert decoder.decode(ints2octs((12, 3, 97, 98, 99))) == (char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class SequenceOfDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.SequenceOf(componentType=univ.OctetString())
+ self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+ ) == (self.s, null)
+
+ def testSchemalessDecoder(self):
+ assert decoder.decode(
+ ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=univ.SequenceOf()
+ ) == (self.s, null)
+
+
+class ExpTaggedSequenceOfDecoderTestCase(BaseTestCase):
+
+ def testWithSchema(self):
+ s = univ.SequenceOf().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))
+ s2, r = decoder.decode(
+ ints2octs((163, 15, 48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=s
+ )
+ assert not r
+ assert s2 == [str2octs('quick brown')]
+ assert s.tagSet == s2.tagSet
+
+ def testWithoutSchema(self):
+ s = univ.SequenceOf().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))
+ s2, r = decoder.decode(
+ ints2octs((163, 15, 48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+ )
+ assert not r
+ assert s2 == [str2octs('quick brown')]
+ assert s.tagSet == s2.tagSet
+
+
+class SequenceOfDecoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SequenceOf(componentType=univ.OctetString())
+ self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+
+class SetOfDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SetOf(componentType=univ.OctetString())
+ self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+ ) == (self.s, null)
+
+ def testSchemalessDecoder(self):
+ assert decoder.decode(
+ ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=univ.SetOf()
+ ) == (self.s, null)
+
+
+class SetOfDecoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SetOf(componentType=univ.OctetString())
+ self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+ def testDefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+
+class SequenceDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.NamedType('first-name', univ.OctetString(null)),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs(
+ (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs(''))
+
+ def testWithOptionalAndDefaultedIndefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
+ substrateFun=lambda a, b, c: (b, str2octs(''))
+ ) == (ints2octs(
+ (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs(''))
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(
+ ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+
+class SequenceDecoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((48, 2, 5, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalDefMode(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionaIndefMode(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)),
+ asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalDefModeChunked(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)),
+ asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalIndefModeChunked(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+ 0, 0, 0)),
+ asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedDefMode(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedDefModeChunked(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedIndefModeChunked(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+ asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1,
+ 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs(
+ (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)),
+ asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+ 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+
+class SetDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.NamedType('first-name', univ.OctetString(null)),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ assert decoder.decode(
+ ints2octs(
+ (49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs(''))
+
+ def testWithOptionalAndDefaultedIndefModeSubst(self):
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
+ substrateFun=lambda a, b, c: (b, str2octs(''))
+ ) == (ints2octs(
+ (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs(''))
+
+ def testTagFormat(self):
+ try:
+ decoder.decode(
+ ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'wrong tagFormat worked out'
+
+
+class SetDecoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefMode(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((49, 2, 5, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalDefMode(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((49, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionaIndefMode(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalDefModeChunked(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((49, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalIndefModeChunked(self):
+ self.__initWithOptional()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedDefMode(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedDefModeChunked(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithDefaultedIndefModeChunked(self):
+ self.__initWithDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeReordered(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 18, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefModeReordered(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 128, 2, 1, 1, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert decoder.decode(
+ ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+
+class SequenceOfWithExpTaggedOctetStringDecoder(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SequenceOf(
+ componentType=univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
+ )
+ self.s.setComponentByPosition(0, 'q')
+ self.s2 = univ.SequenceOf()
+
+ def testDefModeSchema(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeSchema(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testDefModeNoComponent(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s2)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeNoComponent(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s2)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testDefModeSchemaless(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)))
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeSchemaless(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)))
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+
+class SequenceWithExpTaggedOctetStringDecoder(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType(
+ 'x', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
+ )
+ )
+ )
+ self.s.setComponentByPosition(0, 'q')
+ self.s2 = univ.Sequence()
+
+ def testDefModeSchema(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeSchema(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testDefModeNoComponent(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s2)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeNoComponent(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s2)
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testDefModeSchemaless(self):
+ s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)))
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+ def testIndefModeSchemaless(self):
+ s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)))
+ assert not r
+ assert s == self.s
+ assert s.tagSet == self.s.tagSet
+
+
+class ChoiceDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.NamedType('number', univ.Integer(0)),
+ namedtype.NamedType('string', univ.OctetString())
+ )
+ )
+
+ def testBySpec(self):
+ self.s.setComponentByPosition(0, univ.Null(null))
+ assert decoder.decode(
+ ints2octs((5, 0)), asn1Spec=self.s
+ ) == (self.s, null)
+
+ def testWithoutSpec(self):
+ self.s.setComponentByPosition(0, univ.Null(null))
+ assert decoder.decode(ints2octs((5, 0))) == (self.s, null)
+ assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null)
+
+ def testUndefLength(self):
+ self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+ assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)),
+ asn1Spec=self.s) == (self.s, null)
+
+ def testExplicitTag(self):
+ s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
+ tag.tagFormatConstructed, 4))
+ s.setComponentByPosition(0, univ.Null(null))
+ assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null)
+
+ def testExplicitTagUndefLength(self):
+ s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
+ tag.tagFormatConstructed, 4))
+ s.setComponentByPosition(0, univ.Null(null))
+ assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null)
+
+
+class AnyDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Any()
+
+ def testByUntagged(self):
+ assert decoder.decode(
+ ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
+ ) == (univ.Any('\004\003fox'), null)
+
+ def testTaggedEx(self):
+ s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+ assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
+
+ def testTaggedIm(self):
+ s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+ assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
+
+ def testByUntaggedIndefMode(self):
+ assert decoder.decode(
+ ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
+ ) == (univ.Any('\004\003fox'), null)
+
+ def testTaggedExIndefMode(self):
+ s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+ assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
+
+ def testTaggedImIndefMode(self):
+ s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+ assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
+
+ def testByUntaggedSubst(self):
+ assert decoder.decode(
+ ints2octs((4, 3, 102, 111, 120)),
+ asn1Spec=self.s,
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((4, 3, 102, 111, 120)), str2octs(''))
+
+ def testTaggedExSubst(self):
+ assert decoder.decode(
+ ints2octs((164, 5, 4, 3, 102, 111, 120)),
+ asn1Spec=self.s,
+ substrateFun=lambda a, b, c: (b, b[c:])
+ ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), str2octs(''))
+
+
+class EndOfOctetsTestCase(BaseTestCase):
+ def testUnexpectedEoo(self):
+ try:
+ decoder.decode(ints2octs((0, 0)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'end-of-contents octets accepted at top level'
+
+ def testExpectedEoo(self):
+ result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True)
+ assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets and result is eoo.endOfOctets
+ assert remainder == null
+
+ def testDefiniteNoEoo(self):
+ try:
+ decoder.decode(ints2octs((0x23, 0x02, 0x00, 0x00)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'end-of-contents octets accepted inside definite-length encoding'
+
+ def testIndefiniteEoo(self):
+ result, remainder = decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x00)))
+ assert result == () and remainder == null, 'incorrect decoding of indefinite length end-of-octets'
+
+ def testNoLongFormEoo(self):
+ try:
+ decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x81, 0x00)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'end-of-contents octets accepted with invalid long-form length'
+
+ def testNoConstructedEoo(self):
+ try:
+ decoder.decode(ints2octs((0x23, 0x80, 0x20, 0x00)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'end-of-contents octets accepted with invalid constructed encoding'
+
+ def testNoEooData(self):
+ try:
+ decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x01, 0x00)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'end-of-contents octets accepted with unexpected data'
+
+
+class NonStringDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.NamedType('first-name', univ.OctetString(null)),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ self.substrate = ints2octs([48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1])
+
+ def testOctetString(self):
+ s, _ = decoder.decode(univ.OctetString(self.substrate), asn1Spec=self.s)
+ assert self.s == s
+
+ def testAny(self):
+ s, _ = decoder.decode(univ.Any(self.substrate), asn1Spec=self.s)
+ assert self.s == s
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/test_encoder.py
@@ -0,0 +1,940 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag, namedtype, univ, char
+from pyasn1.codec.ber import encoder
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class LargeTagEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.o = univ.Integer().subtype(
+ value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf)
+ )
+
+ def testEncoder(self):
+ assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))
+
+
+class IntegerEncoderTestCase(BaseTestCase):
+ def testPosInt(self):
+ assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12))
+
+ def testNegInt(self):
+ assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244))
+
+ def testZero(self):
+ assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0))
+
+ def testCompactZero(self):
+ encoder.IntegerEncoder.supportCompactZero = True
+ substrate = encoder.encode(univ.Integer(0))
+ encoder.IntegerEncoder.supportCompactZero = False
+ assert substrate == ints2octs((2, 0))
+
+ def testMinusOne(self):
+ assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255))
+
+ def testPosLong(self):
+ assert encoder.encode(
+ univ.Integer(0xffffffffffffffff)
+ ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
+
+ def testNegLong(self):
+ assert encoder.encode(
+ univ.Integer(-0xffffffffffffffff)
+ ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1))
+
+ def testFalse(self):
+ assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1))
+
+ def testDefMode(self):
+ assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.b, defMode=False
+ ) == ints2octs((3, 3, 1, 169, 138))
+
+ def testDefModeChunked(self):
+ assert encoder.encode(
+ self.b, maxChunkSize=1
+ ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+
+ def testIndefModeChunked(self):
+ assert encoder.encode(
+ self.b, defMode=False, maxChunkSize=1
+ ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+
+ def testEmptyValue(self):
+ assert encoder.encode(univ.BitString([])) == ints2octs((3, 1, 0))
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.o = univ.OctetString('Quick brown fox')
+
+ def testDefMode(self):
+ assert encoder.encode(self.o) == ints2octs(
+ (4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.o, defMode=False
+ ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+ def testDefModeChunked(self):
+ assert encoder.encode(
+ self.o, maxChunkSize=4
+ ) == ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119,
+ 110, 32, 4, 3, 102, 111, 120))
+
+ def testIndefModeChunked(self):
+ assert encoder.encode(
+ self.o, defMode=False, maxChunkSize=4
+ ) == ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110,
+ 32, 4, 3, 102, 111, 120, 0, 0))
+
+
+class ExpTaggedOctetStringEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.o = univ.OctetString().subtype(
+ value='Quick brown fox',
+ explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
+ )
+
+ def testDefMode(self):
+ assert encoder.encode(self.o) == ints2octs(
+ (101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.o, defMode=False
+ ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+
+ def testDefModeChunked(self):
+ assert encoder.encode(
+ self.o, defMode=True, maxChunkSize=4
+ ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3,
+ 102, 111, 120))
+
+ def testIndefModeChunked(self):
+ assert encoder.encode(
+ self.o, defMode=False, maxChunkSize=4
+ ) == ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
+
+
+class NullEncoderTestCase(BaseTestCase):
+ def testNull(self):
+ assert encoder.encode(univ.Null('')) == ints2octs((5, 0))
+
+
+class ObjectIdentifierEncoderTestCase(BaseTestCase):
+ def testOne(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((1, 3, 6, 0, 0xffffe))
+ ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+
+ def testEdge1(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((0, 39))
+ ) == ints2octs((6, 1, 39))
+
+ def testEdge2(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((1, 39))
+ ) == ints2octs((6, 1, 79))
+
+ def testEdge3(self):
+ # 01111111
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 40))
+ ) == ints2octs((6, 1, 120))
+
+ def testEdge4(self):
+ # 10010000|10000000|10000000|10000000|01001111
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 0xffffffff))
+ ) == ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F))
+
+ def testEdge5(self):
+ # 01111111
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 47))
+ ) == ints2octs((6, 1, 0x7F))
+
+ def testEdge6(self):
+ # 10000001|00000000
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 48))
+ ) == ints2octs((6, 2, 0x81, 0x00))
+
+ def testEdge7(self):
+ # 10000001|00110100|00000003
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 100, 3))
+ ) == ints2octs((6, 3, 0x81, 0x34, 0x03))
+
+ def testEdge8(self):
+ # 10000101|00000000
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 560))
+ ) == ints2octs((6, 2, 133, 0))
+
+ def testEdge9(self):
+ # 10001000|10000100|10000111|0000010
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 16843570))
+ ) == ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02))
+
+ def testEdgeA(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 5))
+ ) == ints2octs((6, 1, 85))
+
+ def testImpossible1(self):
+ try:
+ encoder.encode(univ.ObjectIdentifier((3, 1, 2)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'impossible leading arc tolerated'
+
+ def testImpossible2(self):
+ try:
+ encoder.encode(univ.ObjectIdentifier((0,)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'single arc OID tolerated'
+
+ def testImpossible3(self):
+ try:
+ encoder.encode(univ.ObjectIdentifier((0, 40)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'second arc overflow tolerated'
+
+ def testImpossible4(self):
+ try:
+ encoder.encode(univ.ObjectIdentifier((1, 40)))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'second arc overflow tolerated'
+
+ def testLarge1(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 18446744073709551535184467440737095))
+ ) == ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB,
+ 0xE2, 0xB7, 0x17))
+
+ def testLarge2(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((2, 999, 18446744073709551535184467440737095))
+ ) == ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6,
+ 0xB8, 0xCB, 0xE2, 0xB6, 0x47))
+
+
+class RealEncoderTestCase(BaseTestCase):
+ def testChar(self):
+ assert encoder.encode(
+ univ.Real((123, 10, 11))
+ ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
+
+ def testBin1(self):
+ assert encoder.encode( # default binEncBase = 2
+ univ.Real((0.5, 2, 0)) # check encbase = 2 and exponent = -1
+ ) == ints2octs((9, 3, 128, 255, 1))
+
+ def testBin2(self):
+ r = univ.Real((3.25, 2, 0))
+ r.binEncBase = 8 # change binEncBase only for this instance of Real
+ assert encoder.encode(
+ r # check encbase = 8
+ ) == ints2octs((9, 3, 148, 255, 13))
+
+ def testBin3(self):
+ # change binEncBase in the RealEncoder instance => for all further Real
+ binEncBase, encoder.typeMap[univ.Real.typeId].binEncBase = encoder.typeMap[univ.Real.typeId].binEncBase, 16
+ assert encoder.encode(
+ univ.Real((0.00390625, 2, 0)) # check encbase = 16
+ ) == ints2octs((9, 3, 160, 254, 1))
+ encoder.typeMap[univ.Real.typeId].binEncBase = binEncBase
+
+ def testBin4(self):
+ # choose binEncBase automatically for all further Real (testBin[4-7])
+ binEncBase, encoder.typeMap[univ.Real.typeId].binEncBase = encoder.typeMap[univ.Real.typeId].binEncBase, None
+ assert encoder.encode(
+ univ.Real((1, 2, 0)) # check exponenta = 0
+ ) == ints2octs((9, 3, 128, 0, 1))
+ encoder.typeMap[univ.Real.typeId].binEncBase = binEncBase
+
+ def testBin5(self):
+ assert encoder.encode(
+ univ.Real((3, 2, -1020)) # case of 2 octs for exponent and
+ # negative exponenta and abs(exponent) is
+ # all 1's and fills the whole octet(s)
+ ) == ints2octs((9, 4, 129, 252, 4, 3))
+
+ def testBin6(self):
+ assert encoder.encode(
+ univ.Real((1, 2, 262140)) # case of 3 octs for exponent and
+ # check that first 9 bits for exponent
+ # are not all 1's
+ ) == ints2octs((9, 5, 130, 3, 255, 252, 1))
+
+ def testBin7(self):
+ assert encoder.encode(
+ univ.Real((-1, 2, 76354972)) # case of >3 octs for exponent and
+ # mantissa < 0
+ ) == ints2octs((9, 7, 195, 4, 4, 141, 21, 156, 1))
+
+ def testPlusInf(self):
+ assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64))
+
+ def testMinusInf(self):
+ assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65))
+
+ def testZero(self):
+ assert encoder.encode(univ.Real(0)) == ints2octs((9, 0))
+
+
+if sys.version_info[0:2] > (2, 5):
+ class UniversalStringEncoderTestCase(BaseTestCase):
+ def testEncoding(self):
+ assert encoder.encode(char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+ (28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99)), 'Incorrect encoding'
+
+
+class BMPStringEncoderTestCase(BaseTestCase):
+ def testEncoding(self):
+ assert encoder.encode(char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+ (30, 6, 0, 97, 0, 98, 0, 99)), 'Incorrect encoding'
+
+
+class UTF8StringEncoderTestCase(BaseTestCase):
+ def testEncoding(self):
+ assert encoder.encode(char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+ (12, 3, 97, 98, 99)), 'Incorrect encoding'
+
+
+class SequenceOfEncoderTestCase(BaseTestCase):
+ def testEmpty(self):
+ s = univ.SequenceOf()
+ assert encoder.encode(s) == ints2octs((48, 0))
+
+ def testDefMode(self):
+ s = univ.SequenceOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(s) == ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testIndefMode(self):
+ s = univ.SequenceOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False
+ ) == ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testDefModeChunked(self):
+ s = univ.SequenceOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testIndefModeChunked(self):
+ s = univ.SequenceOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SequenceOfEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SequenceOf(componentType=univ.OctetString())
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, 'quick brown')
+
+ def testDefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+ def testEmpty(self):
+ s = univ.SetOf()
+ assert encoder.encode(s) == ints2octs((49, 0))
+
+ def testDefMode(self):
+ s = univ.SetOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(s) == ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testIndefMode(self):
+ s = univ.SetOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False
+ ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testDefModeChunked(self):
+ s = univ.SetOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testIndefModeChunked(self):
+ s = univ.SetOf()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SetOfEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SetOf(componentType=univ.OctetString())
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, 'quick brown')
+
+ def testDefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ assert encoder.encode(self.s) == ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testDefModeChunked(self):
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+ def testIndefModeChunked(self):
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class SequenceEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null()),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(1, 'quick brown')
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, '')
+ self.s.setComponentByPosition(2, 1)
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 5, 0, 0, 0))
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 2, 5, 0))
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 5, 0, 0, 0))
+
+ def testWithOptionalDefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(self.s) == ints2octs(
+ (48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testWithOptionalIndefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testWithOptionalDefModeChunked(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testWithOptionalIndefModeChunked(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs(
+ (48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+ def testWithDefaultedDefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1))
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+ def testWithDefaultedDefModeChunked(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((48, 5, 5, 0, 2, 1, 1))
+
+ def testWithDefaultedIndefModeChunked(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(self.s) == ints2octs(
+ (48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs(
+ (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+ 0, 2, 1, 1, 0, 0))
+
+
+class ExpTaggedSequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('number', univ.Integer()),
+ )
+ )
+
+ s = s.subtype(
+ explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 5)
+ )
+
+ s[0] = 12
+
+ self.s = s
+
+ def testDefMode(self):
+ assert encoder.encode(self.s) == ints2octs((101, 5, 48, 3, 2, 1, 12))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((101, 128, 48, 128, 2, 1, 12, 0, 0, 0, 0))
+
+
+class ExpTaggedSequenceComponentEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('number', univ.Boolean().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ )
+ )
+
+ self.s[0] = True
+
+ def testDefMode(self):
+ assert encoder.encode(self.s) == ints2octs((48, 5, 160, 3, 1, 1, 1))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 160, 3, 1, 1, 1, 0, 0, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ assert encoder.encode(self.s) == ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testDefModeChunked(self):
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+ def testIndefModeChunked(self):
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class SetEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null()),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(1, 'quick brown')
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, '')
+ self.s.setComponentByPosition(2, 1)
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testDefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((49, 2, 5, 0))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 5, 0, 0, 0))
+
+ def testDefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 2, 5, 0))
+
+ def testIndefModeChunked(self):
+ self.__init()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 5, 0, 0, 0))
+
+ def testWithOptionalDefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(self.s) == ints2octs(
+ (49, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testWithOptionalIndefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testWithOptionalDefModeChunked(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testWithOptionalIndefModeChunked(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs(
+ (49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+ def testWithDefaultedDefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(self.s) == ints2octs((49, 5, 5, 0, 2, 1, 1))
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0))
+
+ def testWithDefaultedDefModeChunked(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs((49, 5, 5, 0, 2, 1, 1))
+
+ def testWithDefaultedIndefModeChunked(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedDefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(self.s) == ints2octs(
+ (49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedDefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=True, maxChunkSize=4
+ ) == ints2octs(
+ (49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+ def testWithOptionalAndDefaultedIndefModeChunked(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s, defMode=False, maxChunkSize=4
+ ) == ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class ChoiceEncoderTestCase(BaseTestCase):
+
+ def testEmpty(self):
+ s = univ.Choice()
+ try:
+ encoder.encode(s)
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'encoded unset choice'
+
+ def testDefModeOptionOne(self):
+ s = univ.Choice()
+ s.setComponentByPosition(0, univ.Null(''))
+ assert encoder.encode(s) == ints2octs((5, 0))
+
+ def testDefModeOptionTwo(self):
+ s = univ.Choice()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(s) == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testIndefMode(self):
+ s = univ.Choice()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False
+ ) == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+ def testDefModeChunked(self):
+ s = univ.Choice()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=True, maxChunkSize=4
+ ) == ints2octs((36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+ def testIndefModeChunked(self):
+ s = univ.Choice()
+ s.setComponentByPosition(0, univ.OctetString('quick brown'))
+ assert encoder.encode(
+ s, defMode=False, maxChunkSize=4
+ ) == ints2octs((36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0))
+
+
+class ChoiceEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.NamedType('number', univ.Integer(0)),
+ namedtype.NamedType('string', univ.OctetString())
+ )
+ )
+
+ def testEmpty(self):
+ try:
+ encoder.encode(self.s)
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'encoded unset choice'
+
+ def testFilled(self):
+ self.s.setComponentByPosition(0, univ.Null(''))
+ assert encoder.encode(self.s) == ints2octs((5, 0))
+
+ def testTagged(self):
+ s = self.s.subtype(
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)
+ )
+ s.setComponentByPosition(0, univ.Null(''))
+ assert encoder.encode(s) == ints2octs((164, 2, 5, 0))
+
+ def testUndefLength(self):
+ self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+ assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs(
+ (36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0))
+
+ def testTaggedUndefLength(self):
+ s = self.s.subtype(
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)
+ )
+ s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+ assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs(
+ (164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0))
+
+
+class AnyEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
+
+ def testUntagged(self):
+ assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120))
+
+ def testTaggedEx(self):
+ s = self.s.subtype(
+ explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
+ )
+ assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120))
+
+ def testTaggedIm(self):
+ s = self.s.subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
+ )
+ assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/cer/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.codec.cer.test_encoder.suite',
+ 'tests.codec.cer.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/test_decoder.py
@@ -0,0 +1,71 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.codec.cer import decoder
+from pyasn1.compat.octets import ints2octs, str2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
+
+ def testFalse(self):
+ assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
+
+ def testEmpty(self):
+ try:
+ decoder.decode(ints2octs((1, 0)))
+ except PyAsn1Error:
+ pass
+
+ def testOverflow(self):
+ try:
+ decoder.decode(ints2octs((1, 2, 0, 0)))
+ except PyAsn1Error:
+ pass
+
+class BitStringDecoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert decoder.decode(
+ ints2octs((3, 3, 6, 170, 128))
+ ) == (((1, 0) * 5), null)
+
+ def testLongMode(self):
+ assert decoder.decode(
+ ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+ ) == (((1, 0) * 501), null)
+
+ # TODO: test failures on short chunked and long unchunked substrate samples
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert decoder.decode(
+ ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
+ ) == (str2octs('Quick brown fox'), null)
+
+ def testLongMode(self):
+ assert decoder.decode(
+ ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0))
+ ) == (str2octs('Q' * 1001), null)
+
+ # TODO: test failures on short chunked and long unchunked substrate samples
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/test_encoder.py
@@ -0,0 +1,677 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ, useful
+from pyasn1.codec.cer import encoder
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255))
+
+ def testFalse(self):
+ assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert encoder.encode(
+ univ.BitString((1, 0) * 5)
+ ) == ints2octs((3, 3, 6, 170, 128))
+
+ def testLongMode(self):
+ assert encoder.encode(univ.BitString((1, 0) * 501)) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert encoder.encode(
+ univ.OctetString('Quick brown fox')
+ ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+ def testLongMode(self):
+ assert encoder.encode(
+ univ.OctetString('Q' * 1001)
+ ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0))
+
+
+class GeneralizedTimeEncoderTestCase(BaseTestCase):
+ # def testExtraZeroInSeconds(self):
+ # try:
+ # assert encoder.encode(
+ # useful.GeneralizedTime('20150501120112.10Z')
+ # )
+ # except PyAsn1Error:
+ # pass
+ # else:
+ # assert 0, 'Meaningless trailing zero in fraction part tolerated'
+
+ def testLocalTimezone(self):
+ try:
+ assert encoder.encode(
+ useful.GeneralizedTime('20150501120112.1+0200')
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Local timezone tolerated'
+
+ def testMissingTimezone(self):
+ try:
+ assert encoder.encode(
+ useful.GeneralizedTime('20150501120112.1')
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Missing timezone tolerated'
+
+
+ def testDecimalCommaPoint(self):
+ try:
+ assert encoder.encode(
+ useful.GeneralizedTime('20150501120112,1Z')
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Decimal comma tolerated'
+
+ def testWithSubseconds(self):
+ assert encoder.encode(
+ useful.GeneralizedTime('20170801120112.59Z')
+ ) == ints2octs((24, 18, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 46, 53, 57, 90))
+
+ def testWithSeconds(self):
+ assert encoder.encode(
+ useful.GeneralizedTime('20170801120112Z')
+ ) == ints2octs((24, 15, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+
+ def testWithMinutes(self):
+ assert encoder.encode(
+ useful.GeneralizedTime('201708011201Z')
+ ) == ints2octs((24, 13, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 90))
+
+
+class UTCTimeEncoderTestCase(BaseTestCase):
+ def testFractionOfSecond(self):
+ try:
+ assert encoder.encode(
+ useful.UTCTime('150501120112.10Z')
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Decimal point tolerated'
+
+ def testMissingTimezone(self):
+ try:
+ assert encoder.encode(
+ useful.UTCTime('150501120112')
+ ) == ints2octs((23, 13, 49, 53, 48, 53, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Missing timezone tolerated'
+
+ def testLocalTimezone(self):
+ try:
+ assert encoder.encode(
+ useful.UTCTime('150501120112+0200')
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Local timezone tolerated'
+
+ def testWithSeconds(self):
+ assert encoder.encode(
+ useful.UTCTime('990801120112Z')
+ ) == ints2octs((23, 13, 57, 57, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+
+ def testWithMinutes(self):
+ assert encoder.encode(
+ useful.UTCTime('9908011201Z')
+ ) == ints2octs((23, 11, 57, 57, 48, 56, 48, 49, 49, 50, 48, 49, 90))
+
+
+class SequenceOfEncoderTestCase(BaseTestCase):
+ def testEmpty(self):
+ s = univ.SequenceOf()
+ assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+ def testDefMode1(self):
+ s = univ.SequenceOf()
+ s.append(univ.OctetString('a'))
+ s.append(univ.OctetString('ab'))
+ assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testDefMode2(self):
+ s = univ.SequenceOf()
+ s.append(univ.OctetString('ab'))
+ s.append(univ.OctetString('a'))
+ assert encoder.encode(s) == ints2octs((48, 128, 4, 2, 97, 98, 4, 1, 97, 0, 0))
+
+ def testDefMode3(self):
+ s = univ.SequenceOf()
+ s.append(univ.OctetString('b'))
+ s.append(univ.OctetString('a'))
+ assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 98, 4, 1, 97, 0, 0))
+
+ def testDefMode4(self):
+ s = univ.SequenceOf()
+ s.append(univ.OctetString('a'))
+ s.append(univ.OctetString('b'))
+ assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SequenceOfEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SequenceOf(componentType=univ.OctetString())
+
+ def testEmpty(self):
+ self.s.clear()
+ assert encoder.encode(self.s) == ints2octs((48, 128, 0, 0))
+
+ def testIndefMode1(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('ab')
+ assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testIndefMode2(self):
+ self.s.clear()
+ self.s.append('ab')
+ self.s.append('a')
+ assert encoder.encode(self.s) == ints2octs((48, 128, 4, 2, 97, 98, 4, 1, 97, 0, 0))
+
+ def testIndefMode3(self):
+ self.s.clear()
+ self.s.append('b')
+ self.s.append('a')
+ assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 98, 4, 1, 97, 0, 0))
+
+ def testIndefMode4(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('b')
+ assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+ def testEmpty(self):
+ s = univ.SetOf()
+ assert encoder.encode(s) == ints2octs((49, 128, 0, 0))
+
+ def testDefMode1(self):
+ s = univ.SetOf()
+ s.append(univ.OctetString('a'))
+ s.append(univ.OctetString('ab'))
+ assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testDefMode2(self):
+ s = univ.SetOf()
+ s.append(univ.OctetString('ab'))
+ s.append(univ.OctetString('a'))
+ assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testDefMode3(self):
+ s = univ.SetOf()
+ s.append(univ.OctetString('b'))
+ s.append(univ.OctetString('a'))
+ assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+ def testDefMode4(self):
+ s = univ.SetOf()
+ s.append(univ.OctetString('a'))
+ s.append(univ.OctetString('b'))
+ assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetOfEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.SetOf(componentType=univ.OctetString())
+
+ def testEmpty(self):
+ self.s.clear()
+ assert encoder.encode(self.s) == ints2octs((49, 128, 0, 0))
+
+ def testIndefMode1(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('ab')
+
+ assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testIndefMode2(self):
+ self.s.clear()
+ self.s.append('ab')
+ self.s.append('a')
+
+ assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+ def testIndefMode3(self):
+ self.s.clear()
+ self.s.append('b')
+ self.s.append('a')
+
+ assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+ def testIndefMode4(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('b')
+
+ assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testIndefMode(self):
+ assert encoder.encode(self.s) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithOptionalIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SetEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33))
+ ))
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(1, 'quick brown')
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(2, 1)
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0))
+
+ def testWithOptionalIndefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SetWithChoiceWithSchemaEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ c = univ.Choice(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('actual', univ.Boolean(0))
+ ))
+ self.s = univ.Set(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.NamedType('status', c)
+ ))
+
+ def testIndefMode(self):
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByName('status')
+ self.s.getComponentByName('status').setComponentByPosition(0, 1)
+ assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Set()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testIndefMode(self):
+ assert encoder.encode(self.s) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithOptionalIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testIndefMode(self):
+ assert encoder.encode(self.s) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testWithOptionalIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testWithDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+
+class SequenceEncoderWithSchemaTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33))
+ )
+ )
+
+ def __init(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+
+ def __initWithOptional(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(1, 'quick brown')
+
+ def __initWithDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0)
+ self.s.setComponentByPosition(2, 1)
+
+ def __initWithOptionalAndDefaulted(self):
+ self.s.clear()
+ self.s.setComponentByPosition(0, univ.Null(''))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ def testIndefMode(self):
+ self.__init()
+ assert encoder.encode(self.s) == ints2octs((48, 128, 5, 0, 0, 0))
+
+ def testWithOptionalIndefMode(self):
+ self.__initWithOptional()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+ def testWithDefaultedIndefMode(self):
+ self.__initWithDefaulted()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+ def testWithOptionalAndDefaultedIndefMode(self):
+ self.__initWithOptionalAndDefaulted()
+ assert encoder.encode(
+ self.s
+ ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+
+class NestedOptionalSequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ inner = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ outerWithOptional = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', inner),
+ )
+ )
+
+ outerWithDefault = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.DefaultedNamedType('inner', inner),
+ )
+ )
+
+ self.s1 = outerWithOptional
+ self.s2 = outerWithDefault
+
+ def __initOptionalWithDefaultAndOptional(self):
+ self.s1.clear()
+ self.s1[0][0] = 'test'
+ self.s1[0][1] = 123
+ return self.s1
+
+ def __initOptionalWithDefault(self):
+ self.s1.clear()
+ self.s1[0][1] = 123
+ return self.s1
+
+ def __initOptionalWithOptional(self):
+ self.s1.clear()
+ self.s1[0][0] = 'test'
+ return self.s1
+
+ def __initOptional(self):
+ self.s1.clear()
+ return self.s1
+
+ def __initDefaultWithDefaultAndOptional(self):
+ self.s2.clear()
+ self.s2[0][0] = 'test'
+ self.s2[0][1] = 123
+ return self.s2
+
+ def __initDefaultWithDefault(self):
+ self.s2.clear()
+ self.s2[0][0] = 'test'
+ return self.s2
+
+ def __initDefaultWithOptional(self):
+ self.s2.clear()
+ self.s2[0][1] = 123
+ return self.s2
+
+ def testOptionalWithDefaultAndOptional(self):
+ s = self.__initOptionalWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+ def testOptionalWithDefault(self):
+ s = self.__initOptionalWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+ def testOptionalWithOptional(self):
+ s = self.__initOptionalWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+ def testOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+ def testDefaultWithDefaultAndOptional(self):
+ s = self.__initDefaultWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+ def testDefaultWithDefault(self):
+ s = self.__initDefaultWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+ def testDefaultWithOptional(self):
+ s = self.__initDefaultWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+
+class NestedOptionalChoiceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ layer3 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ layer2 = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('inner', layer3),
+ namedtype.NamedType('first-name', univ.OctetString())
+ )
+ )
+
+ layer1 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', layer2),
+ )
+ )
+
+ self.s = layer1
+
+ def __initOptionalWithDefaultAndOptional(self):
+ self.s.clear()
+ self.s[0][0][0] = 'test'
+ self.s[0][0][1] = 123
+ return self.s
+
+ def __initOptionalWithDefault(self):
+ self.s.clear()
+ self.s[0][0][1] = 123
+ return self.s
+
+ def __initOptionalWithOptional(self):
+ self.s.clear()
+ self.s[0][0][0] = 'test'
+ return self.s
+
+ def __initOptional(self):
+ self.s.clear()
+ return self.s
+
+ def testOptionalWithDefaultAndOptional(self):
+ s = self.__initOptionalWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+ def testOptionalWithDefault(self):
+ s = self.__initOptionalWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+ def testOptionalWithOptional(self):
+ s = self.__initOptionalWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+ def testOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+
+class NestedOptionalSequenceOfEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ layer2 = univ.SequenceOf(
+ componentType=univ.OctetString()
+ )
+
+ layer1 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', layer2),
+ )
+ )
+
+ self.s = layer1
+
+ def __initOptionalWithValue(self):
+ self.s.clear()
+ self.s[0][0] = 'test'
+ return self.s
+
+ def __initOptional(self):
+ self.s.clear()
+ return self.s
+
+ def testOptionalWithValue(self):
+ s = self.__initOptionalWithValue()
+ assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+ def testOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/der/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.codec.der.test_encoder.suite',
+ 'tests.codec.der.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/test_decoder.py
@@ -0,0 +1,78 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.codec.der import decoder
+from pyasn1.compat.octets import ints2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert decoder.decode(
+ ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+ ) == (((1, 0) * 501), null)
+
+ def testIndefMode(self):
+ try:
+ decoder.decode(
+ ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'indefinite length encoding tolerated'
+
+ def testDefModeChunked(self):
+ try:
+ assert decoder.decode(
+ ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'chunked encoding tolerated'
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+ def testShortMode(self):
+ assert decoder.decode(
+ '\004\017Quick brown fox'.encode()
+ ) == ('Quick brown fox'.encode(), ''.encode())
+
+ def testIndefMode(self):
+ try:
+ decoder.decode(
+ ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'indefinite length encoding tolerated'
+
+ def testChunkedMode(self):
+ try:
+ decoder.decode(
+ ints2octs((36, 23, 4, 2, 81, 117, 4, 2, 105, 99, 4, 2, 107, 32, 4, 2, 98, 114, 4, 2, 111, 119, 4, 1, 110))
+ )
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'chunked encoding tolerated'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/test_encoder.py
@@ -0,0 +1,295 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.der import encoder
+from pyasn1.compat.octets import ints2octs
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+ def testDefModeShort(self):
+ assert encoder.encode(
+ univ.OctetString('Quick brown fox')
+ ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+ def testDefModeLong(self):
+ assert encoder.encode(
+ univ.OctetString('Q' * 10000)
+ ) == ints2octs((4, 130, 39, 16) + (81,) * 10000)
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+ def testDefModeShort(self):
+ assert encoder.encode(
+ univ.BitString((1,))
+ ) == ints2octs((3, 2, 7, 128))
+
+ def testDefModeLong(self):
+ assert encoder.encode(
+ univ.BitString((1,) * 80000)
+ ) == ints2octs((3, 130, 39, 17, 0) + (255,) * 10000)
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.SetOf(componentType=univ.OctetString())
+
+ def testDefMode1(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('ab')
+
+ assert encoder.encode(self.s) == ints2octs((49, 7, 4, 1, 97, 4, 2, 97, 98))
+
+ def testDefMode2(self):
+ self.s.clear()
+ self.s.append('ab')
+ self.s.append('a')
+
+ assert encoder.encode(self.s) == ints2octs((49, 7, 4, 1, 97, 4, 2, 97, 98))
+
+ def testDefMode3(self):
+ self.s.clear()
+ self.s.append('b')
+ self.s.append('a')
+
+ assert encoder.encode(self.s) == ints2octs((49, 6, 4, 1, 97, 4, 1, 98))
+
+ def testDefMode4(self):
+ self.s.clear()
+ self.s.append('a')
+ self.s.append('b')
+
+ assert encoder.encode(self.s) == ints2octs((49, 6, 4, 1, 97, 4, 1, 98))
+
+class SetWithChoiceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ c = univ.Choice(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('amount', univ.Boolean()))
+ )
+
+ self.s = univ.Set(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('value', univ.Integer(5)),
+ namedtype.NamedType('status', c))
+ )
+
+ def testComponentsOrdering1(self):
+ self.s.setComponentByName('status')
+ self.s.getComponentByName('status').setComponentByPosition(0, 'A')
+ assert encoder.encode(self.s) == ints2octs((49, 6, 2, 1, 5, 4, 1, 65))
+
+ def testComponentsOrdering2(self):
+ self.s.setComponentByName('status')
+ self.s.getComponentByName('status').setComponentByPosition(1, True)
+ assert encoder.encode(self.s) == ints2octs((49, 6, 1, 1, 255, 2, 1, 5))
+
+
+class NestedOptionalSequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ inner = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ outerWithOptional = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', inner),
+ )
+ )
+
+ outerWithDefault = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.DefaultedNamedType('inner', inner),
+ )
+ )
+
+ self.s1 = outerWithOptional
+ self.s2 = outerWithDefault
+
+ def __initOptionalWithDefaultAndOptional(self):
+ self.s1.clear()
+ self.s1[0][0] = 'test'
+ self.s1[0][1] = 123
+ return self.s1
+
+ def __initOptionalWithDefault(self):
+ self.s1.clear()
+ self.s1[0][1] = 123
+ return self.s1
+
+ def __initOptionalWithOptional(self):
+ self.s1.clear()
+ self.s1[0][0] = 'test'
+ return self.s1
+
+ def __initOptional(self):
+ self.s1.clear()
+ return self.s1
+
+ def __initDefaultWithDefaultAndOptional(self):
+ self.s2.clear()
+ self.s2[0][0] = 'test'
+ self.s2[0][1] = 123
+ return self.s2
+
+ def __initDefaultWithDefault(self):
+ self.s2.clear()
+ self.s2[0][0] = 'test'
+ return self.s2
+
+ def __initDefaultWithOptional(self):
+ self.s2.clear()
+ self.s2[0][1] = 123
+ return self.s2
+
+ def testDefModeOptionalWithDefaultAndOptional(self):
+ s = self.__initOptionalWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+ def testDefModeOptionalWithDefault(self):
+ s = self.__initOptionalWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+ def testDefModeOptionalWithOptional(self):
+ s = self.__initOptionalWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+ def testDefModeOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 0))
+
+ def testDefModeDefaultWithDefaultAndOptional(self):
+ s = self.__initDefaultWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+ def testDefModeDefaultWithDefault(self):
+ s = self.__initDefaultWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+ def testDefModeDefaultWithOptional(self):
+ s = self.__initDefaultWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+
+class NestedOptionalChoiceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ layer3 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('first-name', univ.OctetString()),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ )
+ )
+
+ layer2 = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('inner', layer3),
+ namedtype.NamedType('first-name', univ.OctetString())
+ )
+ )
+
+ layer1 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', layer2),
+ )
+ )
+
+ self.s = layer1
+
+ def __initOptionalWithDefaultAndOptional(self):
+ self.s.clear()
+ self.s[0][0][0] = 'test'
+ self.s[0][0][1] = 123
+ return self.s
+
+ def __initOptionalWithDefault(self):
+ self.s.clear()
+ self.s[0][0][1] = 123
+ return self.s
+
+ def __initOptionalWithOptional(self):
+ self.s.clear()
+ self.s[0][0][0] = 'test'
+ return self.s
+
+ def __initOptional(self):
+ self.s.clear()
+ return self.s
+
+ def testDefModeOptionalWithDefaultAndOptional(self):
+ s = self.__initOptionalWithDefaultAndOptional()
+ assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+ def testDefModeOptionalWithDefault(self):
+ s = self.__initOptionalWithDefault()
+ assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+ def testDefModeOptionalWithOptional(self):
+ s = self.__initOptionalWithOptional()
+ assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+ def testDefModeOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 0))
+
+
+class NestedOptionalSequenceOfEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ layer2 = univ.SequenceOf(
+ componentType=univ.OctetString()
+ )
+
+ layer1 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.OptionalNamedType('inner', layer2),
+ )
+ )
+
+ self.s = layer1
+
+ def __initOptionalWithValue(self):
+ self.s.clear()
+ self.s[0][0] = 'test'
+ return self.s
+
+ def __initOptional(self):
+ self.s.clear()
+ return self.s
+
+ def testDefModeOptionalWithValue(self):
+ s = self.__initOptionalWithValue()
+ assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+ def testDefModeOptional(self):
+ s = self.__initOptional()
+ assert encoder.encode(s) == ints2octs((48, 0))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/native/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/__main__.py
@@ -0,0 +1,19 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.codec.native.test_encoder.suite',
+ 'tests.codec.native.test_decoder.suite']
+)
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/test_decoder.py
@@ -0,0 +1,123 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.native import decoder
+from pyasn1.error import PyAsn1Error
+
+
+class BadAsn1SpecTestCase(BaseTestCase):
+ def testBadSpec(self):
+ try:
+ decoder.decode('', asn1Spec='not an Asn1Item')
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Invalid asn1Spec accepted'
+
+
+class IntegerDecoderTestCase(BaseTestCase):
+ def testPosInt(self):
+ assert decoder.decode(12, asn1Spec=univ.Integer()) == univ.Integer(12)
+
+ def testNegInt(self):
+ assert decoder.decode(-12, asn1Spec=univ.Integer()) == univ.Integer(-12)
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert decoder.decode(True, asn1Spec=univ.Boolean()) == univ.Boolean(True)
+
+ def testTrueNeg(self):
+ assert decoder.decode(False, asn1Spec=univ.Boolean()) == univ.Boolean(False)
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+ def testSimple(self):
+ assert decoder.decode('11111111', asn1Spec=univ.BitString()) == univ.BitString(hexValue='ff')
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+ def testSimple(self):
+ assert decoder.decode('Quick brown fox', asn1Spec=univ.OctetString()) == univ.OctetString('Quick brown fox')
+
+
+class NullDecoderTestCase(BaseTestCase):
+ def testNull(self):
+ assert decoder.decode(None, asn1Spec=univ.Null()) == univ.Null()
+
+
+class ObjectIdentifierDecoderTestCase(BaseTestCase):
+ def testOne(self):
+ assert decoder.decode('1.3.6.11', asn1Spec=univ.ObjectIdentifier()) == univ.ObjectIdentifier('1.3.6.11')
+
+
+class RealDecoderTestCase(BaseTestCase):
+ def testSimple(self):
+ assert decoder.decode(1.33, asn1Spec=univ.Real()) == univ.Real(1.33)
+
+
+class SequenceDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null()),
+ namedtype.NamedType('first-name', univ.OctetString()),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+
+ def testSimple(self):
+ s = self.s.clone()
+ s[0] = univ.Null()
+ s[1] = univ.OctetString('xx')
+ s[2] = univ.Integer(33)
+ assert decoder.decode({'place-holder': None, 'first-name': 'xx', 'age': 33}, asn1Spec=self.s) == s
+
+
+class ChoiceDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null()),
+ namedtype.NamedType('first-name', univ.OctetString()),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+
+ def testSimple(self):
+ s = self.s.clone()
+ s[1] = univ.OctetString('xx')
+ assert decoder.decode({'first-name': 'xx'}, asn1Spec=self.s) == s
+
+
+class AnyDecoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.Any()
+
+ def testSimple(self):
+ assert decoder.decode('fox', asn1Spec=univ.Any()) == univ.Any('fox')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/test_encoder.py
@@ -0,0 +1,144 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.native import encoder
+from pyasn1.compat.octets import str2octs
+from pyasn1.error import PyAsn1Error
+
+
+class BadAsn1SpecTestCase(BaseTestCase):
+ def testBadValueType(self):
+ try:
+ encoder.encode('not an Asn1Item')
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert 0, 'Invalid value type accepted'
+
+
+class IntegerEncoderTestCase(BaseTestCase):
+ def testPosInt(self):
+ assert encoder.encode(univ.Integer(12)) == 12
+
+ def testNegInt(self):
+ assert encoder.encode(univ.Integer(-12)) == -12
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+ def testTrue(self):
+ assert encoder.encode(univ.Boolean(1)) is True
+
+ def testFalse(self):
+ assert encoder.encode(univ.Boolean(0)) is False
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1))
+
+ def testValue(self):
+ assert encoder.encode(self.b) == '101010011000101'
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.o = univ.OctetString('Quick brown fox')
+
+ def testValue(self):
+ assert encoder.encode(self.o) == str2octs('Quick brown fox')
+
+
+class NullEncoderTestCase(BaseTestCase):
+ def testNull(self):
+ assert encoder.encode(univ.Null('')) is None
+
+
+class ObjectIdentifierEncoderTestCase(BaseTestCase):
+ def testOne(self):
+ assert encoder.encode(univ.ObjectIdentifier((1, 3, 6, 0, 12345))) == '1.3.6.0.12345'
+
+
+class RealEncoderTestCase(BaseTestCase):
+ def testChar(self):
+ assert encoder.encode(univ.Real((123, 10, 11))) == 1.23e+13
+
+ def testPlusInf(self):
+ assert encoder.encode(univ.Real('inf')) == float('inf')
+
+ def testMinusInf(self):
+ assert encoder.encode(univ.Real('-inf')) == float('-inf')
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.Sequence(componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.OptionalNamedType('first-name', univ.OctetString('')),
+ namedtype.DefaultedNamedType('age', univ.Integer(33)),
+ ))
+
+ def testSimple(self):
+ s = self.s.clone()
+ s[0] = univ.Null('')
+ s[1] = 'abc'
+ s[2] = 123
+ assert encoder.encode(s) == {'place-holder': None, 'first-name': str2octs('abc'), 'age': 123}
+
+
+class ChoiceEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null('')),
+ namedtype.NamedType('number', univ.Integer(0)),
+ namedtype.NamedType('string', univ.OctetString())
+ )
+ )
+
+ def testEmpty(self):
+ try:
+ encoder.encode(self.s)
+ except PyAsn1Error:
+ pass
+ else:
+ assert False, 'encoded unset choice'
+
+ def testFilled(self):
+ self.s.setComponentByPosition(0, univ.Null(''))
+ assert encoder.encode(self.s) == {'place-holder': None}
+
+
+class AnyEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
+
+ def testSimple(self):
+ assert encoder.encode(self.s) == str2octs('fox')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/compat/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/__main__.py
@@ -0,0 +1,21 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.compat.test_binary.suite',
+ 'tests.compat.test_integer.suite',
+ 'tests.compat.test_octets.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_binary.py
@@ -0,0 +1,56 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import binary
+
+
+class BinaryTestCase(BaseTestCase):
+
+ def test_bin_zero(self):
+ assert '0b0' == binary.bin(0)
+
+
+ def test_bin_noarg(self):
+ try:
+ binary.bin()
+
+ except TypeError:
+ pass
+
+ except:
+ assert 0, 'bin() tolerates no arguments'
+
+
+ def test_bin_allones(self):
+ assert '0b1111111111111111111111111111111111111111111111111111111111111111' == binary.bin(0xffffffffffffffff)
+
+
+ def test_bin_allzeros(self):
+ assert '0b0' == binary.bin(0x0000000)
+
+
+
+ def test_bin_pos(self):
+ assert '0b1000000010000000100000001' == binary.bin(0x01010101)
+
+
+ def test_bin_neg(self):
+ assert '-0b1000000010000000100000001' == binary.bin(-0x01010101)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_integer.py
@@ -0,0 +1,53 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import integer
+
+
+class IntegerTestCase(BaseTestCase):
+
+ if sys.version_info[0] > 2:
+
+ def test_from_bytes_zero(self):
+ assert 0 == integer.from_bytes(bytes([0]), signed=False)
+
+ def test_from_bytes_unsigned(self):
+ assert -66051 == integer.from_bytes(bytes([254, 253, 253]), signed=True)
+
+ def test_from_bytes_signed(self):
+ assert 66051 == integer.from_bytes(bytes([0, 1, 2, 3]), signed=False)
+
+ def test_from_bytes_empty(self):
+ assert 0 == integer.from_bytes(bytes([]))
+
+ else:
+
+ def test_from_bytes_zero(self):
+ assert 0 == integer.from_bytes('\x00', signed=False)
+
+ def test_from_bytes_unsigned(self):
+ assert -66051 == integer.from_bytes('\xfe\xfd\xfd', signed=True)
+
+ def test_from_bytes_signed(self):
+ assert 66051 == integer.from_bytes('\x01\x02\x03', signed=False)
+
+ def test_from_bytes_empty(self):
+ assert 0 == integer.from_bytes('')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_octets.py
@@ -0,0 +1,117 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import octets
+
+
+class OctetsTestCase(BaseTestCase):
+
+ if sys.version_info[0] > 2:
+
+ def test_ints2octs(self):
+ assert [1, 2, 3] == list(octets.ints2octs([1, 2, 3]))
+
+ def test_ints2octs_empty(self):
+ assert not octets.ints2octs([])
+
+ def test_int2oct(self):
+ assert [12] == list(octets.int2oct(12))
+
+ def test_octs2ints(self):
+ assert [1, 2, 3] == list(octets.octs2ints(bytes([1, 2, 3])))
+
+ def test_octs2ints_empty(self):
+ assert not octets.octs2ints(bytes([]))
+
+ def test_oct2int(self):
+ assert 12 == octets.oct2int(bytes([12]))[0]
+
+ def test_str2octs(self):
+ assert bytes([1, 2, 3]) == octets.str2octs('\x01\x02\x03')
+
+ def test_str2octs_empty(self):
+ assert not octets.str2octs('')
+
+ def test_octs2str(self):
+ assert '\x01\x02\x03' == octets.octs2str(bytes([1, 2, 3]))
+
+ def test_octs2str_empty(self):
+ assert not octets.octs2str(bytes([]))
+
+ def test_isOctetsType(self):
+ assert octets.isOctetsType('abc') == False
+ assert octets.isOctetsType(123) == False
+ assert octets.isOctetsType(bytes()) == True
+
+ def test_isStringType(self):
+ assert octets.isStringType('abc') == True
+ assert octets.isStringType(123) == False
+ assert octets.isStringType(bytes()) == False
+
+ def test_ensureString(self):
+ assert 'abc'.encode() == octets.ensureString('abc'.encode())
+ assert bytes([1, 2, 3]) == octets.ensureString([1, 2, 3])
+
+ else:
+
+ def test_ints2octs(self):
+ assert '\x01\x02\x03' == octets.ints2octs([1, 2, 3])
+
+ def test_ints2octs_empty(self):
+ assert not octets.ints2octs([])
+
+ def test_int2oct(self):
+ assert '\x0c' == octets.int2oct(12)
+
+ def test_octs2ints(self):
+ assert [1, 2, 3] == octets.octs2ints('\x01\x02\x03')
+
+ def test_octs2ints_empty(self):
+ assert not octets.octs2ints('')
+
+ def test_oct2int(self):
+ assert 12 == octets.oct2int('\x0c')
+
+ def test_str2octs(self):
+ assert '\x01\x02\x03' == octets.str2octs('\x01\x02\x03')
+
+ def test_str2octs_empty(self):
+ assert not octets.str2octs('')
+
+ def test_octs2str(self):
+ assert '\x01\x02\x03' == octets.octs2str('\x01\x02\x03')
+
+ def test_octs2str_empty(self):
+ assert not octets.octs2str('')
+
+ def test_isOctetsType(self):
+ assert octets.isOctetsType('abc') == True
+ assert octets.isOctetsType(123) == False
+ assert octets.isOctetsType(unicode('abc')) == False
+
+ def test_isStringType(self):
+ assert octets.isStringType('abc') == True
+ assert octets.isStringType(123) == False
+ assert octets.isStringType(unicode('abc')) == True
+
+ def test_ensureString(self):
+ assert 'abc' == octets.ensureString('abc')
+ assert '123' == octets.ensureString(123)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/test_debug.py
@@ -0,0 +1,42 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1 import debug
+from pyasn1 import error
+
+class DebugCaseBase(BaseTestCase):
+ def testKnownFlags(self):
+ debug.setLogger(0)
+ debug.setLogger(debug.Debug('all', 'encoder', 'decoder'))
+ debug.setLogger(0)
+
+ def testUnknownFlags(self):
+ try:
+ debug.setLogger(debug.Debug('all', 'unknown', loggerName='xxx'))
+
+ except error.PyAsn1Error:
+ debug.setLogger(0)
+ return
+
+ else:
+ debug.setLogger(0)
+ assert 0, 'unknown debug flag tolerated'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/type/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/__main__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+ ['tests.type.test_constraint.suite',
+ 'tests.type.test_namedtype.suite',
+ 'tests.type.test_namedval.suite',
+ 'tests.type.test_tag.suite',
+ 'tests.type.test_univ.suite',
+ 'tests.type.test_char.suite',
+ 'tests.type.test_useful.suite']
+)
+
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_char.py
@@ -0,0 +1,156 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import char, univ, constraint
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class AbstractStringTestCase(object):
+
+ initializer = ()
+ encoding = 'us-ascii'
+ asn1Type = None
+
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.asn1String = self.asn1Type(ints2octs(self.initializer), encoding=self.encoding)
+ self.pythonString = ints2octs(self.initializer).decode(self.encoding)
+
+ def testUnicode(self):
+ assert self.asn1String == self.pythonString, 'unicode init fails'
+
+ def testLength(self):
+ assert len(self.asn1String) == len(self.pythonString), 'unicode len() fails'
+
+ def testSizeConstraint(self):
+ asn1Spec = self.asn1Type(subtypeSpec=constraint.ValueSizeConstraint(1, 1))
+
+ try:
+ asn1Spec.clone(self.pythonString)
+ except PyAsn1Error:
+ pass
+ else:
+ assert False, 'Size constraint tolerated'
+
+ try:
+ asn1Spec.clone(self.pythonString[0])
+ except PyAsn1Error:
+ assert False, 'Size constraint failed'
+
+ def testSerialized(self):
+ if sys.version_info[0] < 3:
+ assert str(self.asn1String) == self.pythonString.encode(self.encoding), '__str__() fails'
+ else:
+ assert bytes(self.asn1String) == self.pythonString.encode(self.encoding), '__str__() fails'
+
+ def testPrintable(self):
+ if sys.version_info[0] < 3:
+ assert unicode(self.asn1String) == self.pythonString, '__str__() fails'
+ else:
+ assert str(self.asn1String) == self.pythonString, '__str__() fails'
+
+ def testInit(self):
+ assert self.asn1Type(self.pythonString) == self.pythonString
+ assert self.asn1Type(self.pythonString.encode(self.encoding)) == self.pythonString
+ assert self.asn1Type(univ.OctetString(self.pythonString.encode(self.encoding))) == self.pythonString
+ assert self.asn1Type(self.asn1Type(self.pythonString)) == self.pythonString
+ assert self.asn1Type(self.initializer, encoding=self.encoding) == self.pythonString
+
+ def testInitFromAsn1(self):
+ assert self.asn1Type(self.asn1Type(self.pythonString)) == self.pythonString
+ assert self.asn1Type(univ.OctetString(self.pythonString.encode(self.encoding), encoding=self.encoding)) == self.pythonString
+
+ def testAsOctets(self):
+ assert self.asn1String.asOctets() == self.pythonString.encode(self.encoding), 'testAsOctets() fails'
+
+ def testAsNumbers(self):
+ assert self.asn1String.asNumbers() == self.initializer, 'testAsNumbers() fails'
+
+ def testSeq(self):
+ assert self.asn1String[0] == self.pythonString[0], '__getitem__() fails'
+
+ def testEmpty(self):
+ try:
+ str(self.asn1Type())
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Value operation on ASN1 type tolerated'
+
+ def testAdd(self):
+ assert self.asn1String + self.pythonString.encode(self.encoding) == self.pythonString + self.pythonString, '__add__() fails'
+
+ def testRadd(self):
+ assert self.pythonString.encode(self.encoding) + self.asn1String == self.pythonString + self.pythonString, '__radd__() fails'
+
+ def testMul(self):
+ assert self.asn1String * 2 == self.pythonString * 2, '__mul__() fails'
+
+ def testRmul(self):
+ assert 2 * self.asn1String == 2 * self.pythonString, '__rmul__() fails'
+
+ def testContains(self):
+ assert self.pythonString in self.asn1String
+ assert self.pythonString + self.pythonString not in self.asn1String
+
+ if sys.version_info[:2] > (2, 4):
+ def testReverse(self):
+ assert list(reversed(self.asn1String)) == list(reversed(self.pythonString))
+
+
+class VisibleStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+ initializer = (97, 102)
+ encoding = 'us-ascii'
+ asn1Type = char.VisibleString
+
+
+class GeneralStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+ initializer = (169, 174)
+ encoding = 'iso-8859-1'
+ asn1Type = char.GeneralString
+
+
+class UTF8StringTestCase(AbstractStringTestCase, BaseTestCase):
+
+ initializer = (209, 132, 208, 176)
+ encoding = 'utf-8'
+ asn1Type = char.UTF8String
+
+
+class BMPStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+ initializer = (4, 48, 4, 68)
+ encoding = 'utf-16-be'
+ asn1Type = char.BMPString
+
+
+if sys.version_info[0] > 2:
+
+ # Somehow comparison of UTF-32 encoded strings does not work in Py2
+
+ class UniversalStringTestCase(AbstractStringTestCase, BaseTestCase):
+ initializer = (0, 0, 4, 48, 0, 0, 4, 68)
+ encoding = 'utf-32-be'
+ asn1Type = char.UniversalString
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_constraint.py
@@ -0,0 +1,334 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import constraint, error
+
+
+class SingleValueConstraintTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.SingleValueConstraint(1, 2)
+ self.c2 = constraint.SingleValueConstraint(3, 4)
+
+ def testCmp(self):
+ assert self.c1 == self.c1, 'comparation fails'
+
+ def testHash(self):
+ assert hash(self.c1) != hash(self.c2), 'hash() fails'
+
+ def testGoodVal(self):
+ try:
+ self.c1(1)
+
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(4)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ContainedSubtypeConstraintTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ContainedSubtypeConstraint(
+ constraint.SingleValueConstraint(12)
+ )
+
+ def testGoodVal(self):
+ try:
+ self.c1(12)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(4)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ValueRangeConstraintTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ValueRangeConstraint(1, 4)
+
+ def testGoodVal(self):
+ try:
+ self.c1(1)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(-5)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ValueSizeConstraintTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ValueSizeConstraint(1, 2)
+
+ def testGoodVal(self):
+ try:
+ self.c1('a')
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1('abc')
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class PermittedAlphabetConstraintTestCase(SingleValueConstraintTestCase):
+ def setUp(self):
+ self.c1 = constraint.PermittedAlphabetConstraint('A', 'B', 'C')
+ self.c2 = constraint.PermittedAlphabetConstraint('DEF')
+
+ def testGoodVal(self):
+ try:
+ self.c1('A')
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1('E')
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ConstraintsIntersectionTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ConstraintsIntersection(
+ constraint.SingleValueConstraint(4),
+ constraint.ValueRangeConstraint(2, 4)
+ )
+
+ def testCmp1(self):
+ assert constraint.SingleValueConstraint(4) in self.c1, '__cmp__() fails'
+
+ def testCmp2(self):
+ assert constraint.SingleValueConstraint(5) not in self.c1, \
+ '__cmp__() fails'
+
+ def testCmp3(self):
+ c = constraint.ConstraintsUnion(constraint.ConstraintsIntersection(
+ constraint.SingleValueConstraint(4),
+ constraint.ValueRangeConstraint(2, 4))
+ )
+ assert self.c1 in c, '__cmp__() fails'
+
+ def testCmp4(self):
+ c = constraint.ConstraintsUnion(
+ constraint.ConstraintsIntersection(constraint.SingleValueConstraint(5))
+ )
+ assert self.c1 not in c, '__cmp__() fails'
+
+ def testGoodVal(self):
+ try:
+ self.c1(4)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(-5)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class InnerTypeConstraintTestCase(BaseTestCase):
+ def testConst1(self):
+ c = constraint.InnerTypeConstraint(
+ constraint.SingleValueConstraint(4)
+ )
+ try:
+ c(4, 32)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+ try:
+ c(5, 32)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+ def testConst2(self):
+ c = constraint.InnerTypeConstraint(
+ (0, constraint.SingleValueConstraint(4), 'PRESENT'),
+ (1, constraint.SingleValueConstraint(4), 'ABSENT')
+ )
+ try:
+ c(4, 0)
+ except error.ValueConstraintError:
+ raise
+ assert 0, 'constraint check fails'
+ try:
+ c(4, 1)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+ try:
+ c(3, 0)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+ # Constraints compositions
+
+
+class ConstraintsIntersectionRangeTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ConstraintsIntersection(
+ constraint.ValueRangeConstraint(1, 9),
+ constraint.ValueRangeConstraint(2, 5)
+ )
+
+ def testGoodVal(self):
+ try:
+ self.c1(3)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(0)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ConstraintsUnionTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ConstraintsUnion(
+ constraint.SingleValueConstraint(5),
+ constraint.ValueRangeConstraint(1, 3)
+ )
+
+ def testGoodVal(self):
+ try:
+ self.c1(2)
+ self.c1(5)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(-5)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+class ConstraintsExclusionTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.c1 = constraint.ConstraintsExclusion(
+ constraint.ValueRangeConstraint(2, 4)
+ )
+
+ def testGoodVal(self):
+ try:
+ self.c1(6)
+ except error.ValueConstraintError:
+ assert 0, 'constraint check fails'
+
+ def testBadVal(self):
+ try:
+ self.c1(2)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint check fails'
+
+
+# Constraints derivations
+
+class DirectDerivationTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.c1 = constraint.SingleValueConstraint(5)
+
+ self.c2 = constraint.ConstraintsUnion(
+ self.c1, constraint.ValueRangeConstraint(1, 3)
+ )
+
+ def testGoodVal(self):
+ assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
+ assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed'
+
+ def testBadVal(self):
+ assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed'
+ assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed'
+
+
+class IndirectDerivationTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.c1 = constraint.ConstraintsIntersection(
+ constraint.ValueRangeConstraint(1, 30)
+ )
+
+ self.c2 = constraint.ConstraintsIntersection(
+ self.c1, constraint.ValueRangeConstraint(1, 20)
+ )
+
+ self.c2 = constraint.ConstraintsIntersection(
+ self.c2, constraint.ValueRangeConstraint(1, 10)
+ )
+
+ def testGoodVal(self):
+ assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
+ assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed'
+
+ def testBadVal(self):
+ assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed'
+ assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed'
+
+# TODO: how to apply size constraints to constructed types?
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_namedtype.py
@@ -0,0 +1,147 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.error import PyAsn1Error
+
+
+class NamedTypeCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.e = namedtype.NamedType('age', univ.Integer(0))
+
+ def testIter(self):
+ n, t = self.e
+ assert n == 'age' or t == univ.Integer(), 'unpack fails'
+
+ def testRepr(self):
+ assert eval(repr(self.e), {'NamedType': namedtype.NamedType, 'Integer': univ.Integer}) == self.e, 'repr() fails'
+
+
+class NamedTypesCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.e = namedtype.NamedTypes(
+ namedtype.NamedType('first-name', univ.OctetString('')),
+ namedtype.OptionalNamedType('age', univ.Integer(0)),
+ namedtype.NamedType('family-name', univ.OctetString(''))
+ )
+
+ def testRepr(self):
+ assert eval(
+ repr(self.e), {
+ 'NamedTypes': namedtype.NamedTypes,
+ 'NamedType': namedtype.NamedType,
+ 'OptionalNamedType': namedtype.OptionalNamedType,
+ 'Integer': univ.Integer,
+ 'OctetString': univ.OctetString
+ }
+ ) == self.e, 'repr() fails'
+
+ def testContains(self):
+ assert 'first-name' in self.e
+ assert '<missing>' not in self.e
+
+ # noinspection PyUnusedLocal
+ def testGetItem(self):
+ assert self.e[0] == namedtype.NamedType('first-name', univ.OctetString(''))
+
+ def testIter(self):
+ assert list(self.e) == ['first-name', 'age', 'family-name']
+
+ def testGetTypeByPosition(self):
+ assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
+ 'getTypeByPosition() fails'
+
+ def testGetNameByPosition(self):
+ assert self.e.getNameByPosition(0) == 'first-name', \
+ 'getNameByPosition() fails'
+
+ def testGetPositionByName(self):
+ assert self.e.getPositionByName('first-name') == 0, \
+ 'getPositionByName() fails'
+
+ def testGetTypesNearPosition(self):
+ assert self.e.getTagMapNearPosition(0).presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString('')
+ }
+ assert self.e.getTagMapNearPosition(1).presentTypes == {
+ univ.Integer.tagSet: univ.Integer(0),
+ univ.OctetString.tagSet: univ.OctetString('')
+ }
+ assert self.e.getTagMapNearPosition(2).presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString('')
+ }
+
+ def testGetTagMap(self):
+ assert self.e.tagMap.presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString(''),
+ univ.Integer.tagSet: univ.Integer(0)
+ }
+
+ def testStrTagMap(self):
+ assert 'TagMap' in str(self.e.tagMap)
+ assert 'OctetString' in str(self.e.tagMap)
+ assert 'Integer' in str(self.e.tagMap)
+
+ def testReprTagMap(self):
+ assert 'TagMap' in repr(self.e.tagMap)
+ assert 'OctetString' in repr(self.e.tagMap)
+ assert 'Integer' in repr(self.e.tagMap)
+
+ def testGetTagMapWithDups(self):
+ try:
+ self.e.tagMapUnique[0]
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'Duped types not noticed'
+
+ def testGetPositionNearType(self):
+ assert self.e.getPositionNearType(univ.OctetString.tagSet, 0) == 0
+ assert self.e.getPositionNearType(univ.Integer.tagSet, 1) == 1
+ assert self.e.getPositionNearType(univ.OctetString.tagSet, 2) == 2
+
+
+class OrderedNamedTypesCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.e = namedtype.NamedTypes(
+ namedtype.NamedType('first-name', univ.OctetString('')),
+ namedtype.NamedType('age', univ.Integer(0))
+ )
+
+ def testGetTypeByPosition(self):
+ assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
+ 'getTypeByPosition() fails'
+
+
+class DuplicateNamedTypesCaseBase(BaseTestCase):
+ def testDuplicateDefaultTags(self):
+ nt = namedtype.NamedTypes(
+ namedtype.NamedType('first-name', univ.Any()),
+ namedtype.NamedType('age', univ.Any())
+ )
+
+ assert isinstance(nt.tagMap, namedtype.NamedTypes.PostponedError)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_namedval.py
@@ -0,0 +1,58 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedval
+
+
+class NamedValuesCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.e = namedval.NamedValues(('off', 0), ('on', 1))
+
+ def testDict(self):
+ assert set(self.e.items()) == set([('off', 0), ('on', 1)])
+ assert set(self.e.keys()) == set(['off', 'on'])
+ assert set(self.e) == set(['off', 'on'])
+ assert set(self.e.values()) == set([0, 1])
+ assert 'on' in self.e and 'off' in self.e and 'xxx' not in self.e
+ assert 0 in self.e and 1 in self.e and 2 not in self.e
+
+ def testInit(self):
+ assert namedval.NamedValues(off=0, on=1) == {'off': 0, 'on': 1}
+ assert namedval.NamedValues('off', 'on') == {'off': 0, 'on': 1}
+ assert namedval.NamedValues(('c', 0)) == {'c': 0}
+ assert namedval.NamedValues('a', 'b', ('c', 0), d=1) == {'c': 0, 'd': 1, 'a': 2, 'b': 3}
+
+ def testLen(self):
+ assert len(self.e) == 2
+ assert len(namedval.NamedValues()) == 0
+
+ def testAdd(self):
+ assert namedval.NamedValues(off=0) + namedval.NamedValues(on=1) == {'off': 0, 'on': 1}
+
+ def testClone(self):
+ assert namedval.NamedValues(off=0).clone(('on', 1)) == {'off': 0, 'on': 1}
+ assert namedval.NamedValues(off=0).clone(on=1) == {'off': 0, 'on': 1}
+
+ def testStrRepr(self):
+ assert str(self.e)
+ assert repr(self.e)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_tag.py
@@ -0,0 +1,138 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag
+
+
+class TagTestCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.t1 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
+ self.t2 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
+
+
+class TagReprTestCase(TagTestCaseBase):
+ def testRepr(self):
+ assert eval(repr(self.t1), {'Tag': tag.Tag}) == self.t1, 'repr() fails'
+
+
+class TagCmpTestCase(TagTestCaseBase):
+ def testCmp(self):
+ assert self.t1 == self.t2, 'tag comparation fails'
+
+ def testHash(self):
+ assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails'
+
+ def testSequence(self):
+ assert self.t1[0] == self.t2[0] and \
+ self.t1[1] == self.t2[1] and \
+ self.t1[2] == self.t2[2], 'tag sequence protocol fails'
+
+
+class TagSetTestCaseBase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.ts1 = tag.initTagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+ )
+
+ self.ts2 = tag.initTagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+ )
+
+
+class TagSetReprTestCase(TagSetTestCaseBase):
+ def testRepr(self):
+ assert eval(repr(self.ts1), {'TagSet': tag.TagSet, 'Tag': tag.Tag}) == self.ts1, 'repr() fails'
+
+
+class TagSetCmpTestCase(TagSetTestCaseBase):
+ def testCmp(self):
+ assert self.ts1 == self.ts2, 'tag set comparation fails'
+
+ def testHash(self):
+ assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails'
+
+ def testLen(self):
+ assert len(self.ts1) == len(self.ts2), 'tag length comparation fails'
+
+
+class TaggingTestSuite(TagSetTestCaseBase):
+ def testImplicitTag(self):
+ t = self.ts1.tagImplicitly(
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
+ )
+ assert t == tag.TagSet(
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
+ ), 'implicit tagging went wrong'
+
+ def testExplicitTag(self):
+ t = self.ts1.tagExplicitly(
+ tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 32)
+ )
+ assert t == tag.TagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassPrivate, tag.tagFormatConstructed, 32)
+ ), 'explicit tagging went wrong'
+
+
+class TagSetAddTestSuite(TagSetTestCaseBase):
+ def testAdd(self):
+ t = self.ts1 + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
+ assert t == tag.TagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
+ ), 'TagSet.__add__() fails'
+
+ def testRadd(self):
+ t = tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + self.ts1
+ assert t == tag.TagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+ ), 'TagSet.__radd__() fails'
+
+
+class SuperTagSetTestCase(TagSetTestCaseBase):
+ def testSuperTagCheck1(self):
+ assert self.ts1.isSuperTagSetOf(
+ tag.TagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+ )), 'isSuperTagSetOf() fails'
+
+ def testSuperTagCheck2(self):
+ assert not self.ts1.isSuperTagSetOf(
+ tag.TagSet(
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 13)
+ )), 'isSuperTagSetOf() fails'
+
+ def testSuperTagCheck3(self):
+ assert self.ts1.isSuperTagSetOf(
+ tag.TagSet((), tag.Tag(tag.tagClassUniversal,
+ tag.tagFormatSimple, 12))
+ ), 'isSuperTagSetOf() fails'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_univ.py
@@ -0,0 +1,1503 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import math
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import univ, tag, constraint, namedtype, namedval, error
+from pyasn1.compat.octets import str2octs, ints2octs, octs2ints
+from pyasn1.error import PyAsn1Error
+
+
+class NoValueTestCase(BaseTestCase):
+ def testSingleton(self):
+ assert univ.NoValue() is univ.NoValue(), 'NoValue is not a singleton'
+
+ def testRepr(self):
+ try:
+ repr(univ.noValue)
+
+ except PyAsn1Error:
+ assert False, 'repr() on NoValue object fails'
+
+ def testIsInstance(self):
+ try:
+ assert isinstance(univ.noValue, univ.NoValue), 'isinstance() on NoValue() object fails'
+
+ except PyAsn1Error:
+ assert False, 'isinstance() on NoValue object fails'
+
+ def testStr(self):
+ try:
+ str(univ.noValue)
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'str() works for NoValue object'
+
+ def testLen(self):
+ try:
+ len(univ.noValue)
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'len() works for NoValue object'
+
+ def testCmp(self):
+ try:
+ univ.noValue == 1
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'comparison works for NoValue object'
+
+ def testSubs(self):
+ try:
+ univ.noValue[0]
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, '__getitem__() works for NoValue object'
+
+ def testKey(self):
+ try:
+ univ.noValue['key']
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, '__getitem__() works for NoValue object'
+
+ def testKeyAssignment(self):
+ try:
+ univ.noValue['key'] = 123
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, '__setitem__() works for NoValue object'
+
+ def testInt(self):
+ try:
+ int(univ.noValue)
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'integer conversion works for NoValue object'
+
+ def testAdd(self):
+ try:
+ univ.noValue + univ.noValue
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'addition works for NoValue object'
+
+ def testBitShift(self):
+ try:
+ univ.noValue << 1
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'bitshift works for NoValue object'
+
+ def testBooleanEvaluation(self):
+ try:
+ if univ.noValue:
+ pass
+
+ except PyAsn1Error:
+ pass
+
+ else:
+ assert False, 'boolean evaluation works for NoValue object'
+
+ def testSizeOf(self):
+ try:
+ if hasattr(sys, 'getsizeof'):
+ sys.getsizeof(univ.noValue)
+
+ except PyAsn1Error:
+ assert False, 'sizeof failed for NoValue object'
+
+
+class IntegerTestCase(BaseTestCase):
+ def testStr(self):
+ assert str(univ.Integer(1)) in ('1', '1L'), 'str() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.Integer(123)), {'Integer': univ.Integer}) == univ.Integer(123), 'repr() fails'
+
+ def testAnd(self):
+ assert univ.Integer(1) & 0 == 0, '__and__() fails'
+
+ def testOr(self):
+ assert univ.Integer(1) | 0 == 1, '__or__() fails'
+
+ def testXor(self):
+ assert univ.Integer(1) ^ 0 == 1, '__xor__() fails'
+
+ def testRand(self):
+ assert 0 & univ.Integer(1) == 0, '__rand__() fails'
+
+ def testRor(self):
+ assert 0 | univ.Integer(1) == 1, '__ror__() fails'
+
+ def testRxor(self):
+ assert 0 ^ univ.Integer(1) == 1, '__rxor__() fails'
+
+ def testAdd(self):
+ assert univ.Integer(-4) + 6 == 2, '__add__() fails'
+
+ def testRadd(self):
+ assert 4 + univ.Integer(5) == 9, '__radd__() fails'
+
+ def testSub(self):
+ assert univ.Integer(3) - 6 == -3, '__sub__() fails'
+
+ def testRsub(self):
+ assert 6 - univ.Integer(3) == 3, '__rsub__() fails'
+
+ def testMul(self):
+ assert univ.Integer(3) * -3 == -9, '__mul__() fails'
+
+ def testRmul(self):
+ assert 2 * univ.Integer(3) == 6, '__rmul__() fails'
+
+ def testDivInt(self):
+ assert univ.Integer(4) / 2 == 2, '__div__() fails'
+
+ if sys.version_info[0] > 2:
+ def testDivFloat(self):
+ assert univ.Integer(3) / 2 == 1.5, '__div__() fails'
+
+ def testRdivFloat(self):
+ assert 3 / univ.Integer(2) == 1.5, '__rdiv__() fails'
+ else:
+ def testDivFloat(self):
+ assert univ.Integer(3) / 2 == 1, '__div__() fails'
+
+ def testRdivFloat(self):
+ assert 3 / univ.Integer(2) == 1, '__rdiv__() fails'
+
+ def testRdivInt(self):
+ assert 6 / univ.Integer(3) == 2, '__rdiv__() fails'
+
+ if sys.version_info[0] > 2:
+ def testTrueDiv(self):
+ assert univ.Integer(3) / univ.Integer(2) == 1.5, '__truediv__() fails'
+
+ def testFloorDiv(self):
+ assert univ.Integer(3) // univ.Integer(2) == 1, '__floordiv__() fails'
+
+ def testMod(self):
+ assert univ.Integer(3) % 2 == 1, '__mod__() fails'
+
+ def testRmod(self):
+ assert 4 % univ.Integer(3) == 1, '__rmod__() fails'
+
+ def testPow(self):
+ assert univ.Integer(3) ** 2 == 9, '__pow__() fails'
+
+ def testRpow(self):
+ assert 2 ** univ.Integer(2) == 4, '__rpow__() fails'
+
+ def testLshift(self):
+ assert univ.Integer(1) << 1 == 2, '<< fails'
+
+ def testRshift(self):
+ assert univ.Integer(2) >> 1 == 1, '>> fails'
+
+ def testInt(self):
+ assert int(univ.Integer(3)) == 3, '__int__() fails'
+
+ def testLong(self):
+ assert int(univ.Integer(8)) == 8, '__long__() fails'
+
+ def testFloat(self):
+ assert float(univ.Integer(4)) == 4.0, '__float__() fails'
+
+ def testPos(self):
+ assert +univ.Integer(1) == 1, '__pos__() fails'
+
+ def testNeg(self):
+ assert -univ.Integer(1) == -1, '__neg__() fails'
+
+ def testInvert(self):
+ assert ~univ.Integer(1) == -2, '__invert__() fails'
+
+ def testRound(self):
+ assert round(univ.Integer(1), 3) == 1.0, '__round__() fails'
+
+ def testFloor(self):
+ assert math.floor(univ.Integer(1)) == 1, '__floor__() fails'
+
+ def testCeil(self):
+ assert math.ceil(univ.Integer(1)) == 1, '__ceil__() fails'
+
+ if sys.version_info[0:2] > (2, 5):
+ def testTrunc(self):
+ assert math.trunc(univ.Integer(1)) == 1, '__trunc__() fails'
+
+ def testPrettyIn(self):
+ assert univ.Integer('3') == 3, 'prettyIn() fails'
+
+ def testTag(self):
+ assert univ.Integer().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
+ )
+
+ def testNamedVals(self):
+
+ class Integer(univ.Integer):
+ namedValues = univ.Integer.namedValues.clone(('asn1', 1))
+
+ assert Integer('asn1') == 1, 'named val fails'
+ assert str(Integer('asn1')) != 'asn1', 'named val __str__() fails'
+
+ def testSubtype(self):
+ assert univ.Integer().subtype(
+ value=1,
+ implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2),
+ subtypeSpec=constraint.SingleValueConstraint(1, 3)
+ ) == univ.Integer(
+ value=1,
+ tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
+ tag.tagFormatSimple, 2)),
+ subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3))
+ )
+
+
+class BooleanTestCase(BaseTestCase):
+ def testTruth(self):
+ assert univ.Boolean(True) and univ.Boolean(1), 'Truth initializer fails'
+
+ def testFalse(self):
+ assert not univ.Boolean(False) and not univ.Boolean(0), 'False initializer fails'
+
+ def testStr(self):
+ assert str(univ.Boolean(1)) in ('1', '1L'), 'str() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.Boolean(1)), {'Boolean': univ.Boolean}) == univ.Boolean(1), 'repr() fails'
+
+ def testTag(self):
+ assert univ.Boolean().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01)
+ )
+
+ def testConstraints(self):
+
+ class Boolean(univ.Boolean):
+ pass
+
+ try:
+ Boolean(2)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint fail'
+
+
+class BitStringTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.b = univ.BitString(
+ namedValues=namedval.NamedValues(('Active', 0), ('Urgent', 1))
+ )
+
+ def testBinDefault(self):
+
+ class BinDefault(univ.BitString):
+ defaultBinValue = '1010100110001010'
+
+ assert BinDefault() == univ.BitString(binValue='1010100110001010')
+
+ def testHexDefault(self):
+
+ class HexDefault(univ.BitString):
+ defaultHexValue = 'A98A'
+
+ assert HexDefault() == univ.BitString(hexValue='A98A')
+
+ def testSet(self):
+ assert self.b.clone('Active') == (1,)
+ assert self.b.clone('Urgent') == (0, 1)
+ assert self.b.clone('Urgent, Active') == (1, 1)
+ assert self.b.clone("'1010100110001010'B") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+ assert self.b.clone("'A98A'H") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+ assert self.b.clone(binValue='1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+ assert self.b.clone(hexValue='A98A') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+ assert self.b.clone('1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+ assert self.b.clone((1, 0, 1)) == (1, 0, 1)
+
+ def testStr(self):
+ assert str(self.b.clone('Urgent')) == '01'
+
+ def testRepr(self):
+ assert eval(repr(self.b.clone('Urgent,Active')), {'BitString': univ.BitString}) == self.b.clone(
+ 'Urgent,Active'), 'repr() fails'
+
+ def testTag(self):
+ assert univ.BitString().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
+ )
+
+ def testLen(self):
+ assert len(self.b.clone("'A98A'H")) == 16
+
+ def testGetItem(self):
+ assert self.b.clone("'A98A'H")[0] == 1
+ assert self.b.clone("'A98A'H")[1] == 0
+ assert self.b.clone("'A98A'H")[2] == 1
+
+ if sys.version_info[:2] > (2, 4):
+ def testReverse(self):
+ assert list(reversed(univ.BitString([0, 0, 1]))) == list(univ.BitString([1, 0, 0]))
+
+ def testAsOctets(self):
+ assert self.b.clone(hexValue='A98A').asOctets() == ints2octs((0xa9, 0x8a)), 'testAsOctets() fails'
+
+ def testAsInts(self):
+ assert self.b.clone(hexValue='A98A').asNumbers() == (0xa9, 0x8a), 'testAsNumbers() fails'
+
+ def testMultipleOfEightPadding(self):
+ assert self.b.clone((1, 0, 1)).asNumbers() == (5,)
+
+ def testAsInteger(self):
+ assert self.b.clone('11000000011001').asInteger() == 12313
+ assert self.b.clone('1100110011011111').asInteger() == 52447
+
+ def testStaticDef(self):
+
+ class BitString(univ.BitString):
+ pass
+
+ assert BitString('11000000011001').asInteger() == 12313
+
+
+class OctetStringWithUnicodeMixIn(object):
+
+ initializer = ()
+ encoding = 'us-ascii'
+
+ def setUp(self):
+ self.pythonString = ints2octs(self.initializer).decode(self.encoding)
+ self.encodedPythonString = self.pythonString.encode(self.encoding)
+ self.numbersString = tuple(octs2ints(self.encodedPythonString))
+
+ def testInit(self):
+ assert univ.OctetString(self.encodedPythonString) == self.encodedPythonString, '__init__() fails'
+
+ def testInitFromAsn1(self):
+ assert univ.OctetString(univ.OctetString(self.encodedPythonString)) == self.encodedPythonString
+ assert univ.OctetString(univ.Integer(123)) == univ.OctetString('123')
+
+ def testSerialized(self):
+ if sys.version_info[0] < 3:
+ assert str(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+ else:
+ assert bytes(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+
+ def testPrintable(self):
+ if sys.version_info[0] < 3:
+ assert str(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+ assert unicode(univ.OctetString(self.pythonString, encoding=self.encoding)) == self.pythonString, 'unicode init fails'
+ else:
+ assert str(univ.OctetString(self.pythonString, encoding=self.encoding)) == self.pythonString, 'unicode init fails'
+
+ def testSeq(self):
+ assert univ.OctetString(self.encodedPythonString)[0] == self.encodedPythonString[0], '__getitem__() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.OctetString('abc')), {'OctetString': univ.OctetString}) == univ.OctetString('abc'), 'repr() fails'
+
+ def testAsOctets(self):
+ assert univ.OctetString(self.encodedPythonString).asOctets() == self.encodedPythonString, 'testAsOctets() fails'
+
+ def testAsInts(self):
+ assert univ.OctetString(self.encodedPythonString).asNumbers() == self.numbersString, 'testAsNumbers() fails'
+
+ def testAdd(self):
+ assert univ.OctetString(self.encodedPythonString) + self.encodedPythonString == self.encodedPythonString + self.encodedPythonString, '__add__() fails'
+
+ def testRadd(self):
+ assert self.encodedPythonString + univ.OctetString(self.encodedPythonString) == self.encodedPythonString + self.encodedPythonString, '__radd__() fails'
+
+ def testMul(self):
+ assert univ.OctetString(self.encodedPythonString) * 2 == self.encodedPythonString * 2, '__mul__() fails'
+
+ def testRmul(self):
+ assert 2 * univ.OctetString(self.encodedPythonString) == 2 * self.encodedPythonString, '__rmul__() fails'
+
+ def testContains(self):
+ s = univ.OctetString(self.encodedPythonString)
+ assert self.encodedPythonString in s
+ assert self.encodedPythonString * 2 not in s
+
+ if sys.version_info[:2] > (2, 4):
+ def testReverse(self):
+ assert list(reversed(univ.OctetString(self.encodedPythonString))) == list(reversed(self.encodedPythonString))
+
+
+class OctetStringWithAsciiTestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+ initializer = (97, 102)
+ encoding = 'us-ascii'
+
+
+class OctetStringWithUtf8TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+ initializer = (208, 176, 208, 177, 208, 178)
+ encoding = 'utf-8'
+
+
+class OctetStringWithUtf16TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+ initializer = (4, 48, 4, 49, 4, 50)
+ encoding = 'utf-16-be'
+
+
+if sys.version_info[0] > 2:
+
+ # Somehow comparison of UTF-32 encoded strings does not work in Py2
+
+ class OctetStringWithUtf32TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+ initializer = (0, 0, 4, 48, 0, 0, 4, 49, 0, 0, 4, 50)
+ encoding = 'utf-32-be'
+
+
+class OctetStringTestCase(BaseTestCase):
+
+ def testBinDefault(self):
+
+ class BinDefault(univ.OctetString):
+ defaultBinValue = '1000010111101110101111000000111011'
+
+ assert BinDefault() == univ.OctetString(binValue='1000010111101110101111000000111011')
+
+ def testHexDefault(self):
+
+ class HexDefault(univ.OctetString):
+ defaultHexValue = 'FA9823C43E43510DE3422'
+
+ assert HexDefault() == univ.OctetString(hexValue='FA9823C43E43510DE3422')
+
+ def testBinStr(self):
+ assert univ.OctetString(binValue="1000010111101110101111000000111011") == ints2octs((133, 238, 188, 14, 192)), 'bin init fails'
+
+ def testHexStr(self):
+ assert univ.OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32)), 'hex init fails'
+
+ def testTuple(self):
+ assert univ.OctetString((1, 2, 3, 4, 5)) == ints2octs((1, 2, 3, 4, 5)), 'tuple init failed'
+
+ def testRepr(self):
+ assert eval(repr(univ.OctetString('abc')), {'OctetString': univ.OctetString}) == univ.OctetString('abc'), 'repr() fails'
+
+ def testEmpty(self):
+ try:
+ str(univ.OctetString())
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'empty OctetString() not reported'
+
+ def testTag(self):
+ assert univ.OctetString().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
+ )
+
+ def testStaticDef(self):
+
+ class OctetString(univ.OctetString):
+ pass
+
+ assert OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32))
+
+
+class Null(BaseTestCase):
+ def testStr(self):
+ assert str(univ.Null('')) == '', 'str() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.Null()), {'Null': univ.Null}) == univ.Null(), 'repr() fails'
+
+ def testTag(self):
+ assert univ.Null().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
+ )
+
+ def testConstraints(self):
+ try:
+ univ.Null(2)
+ except error.ValueConstraintError:
+ pass
+ else:
+ assert 0, 'constraint fail'
+
+ def testStaticDef(self):
+
+ class Null(univ.Null):
+ pass
+
+ assert not Null()
+
+
+class RealTestCase(BaseTestCase):
+ def testFloat4BinEnc(self):
+ assert univ.Real((0.25, 2, 3)) == 2.0, 'float initializer for binary encoding fails'
+
+ def testStr(self):
+ assert str(univ.Real(1.0)) == '1.0', 'str() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.Real(-4.1)), {'Real': univ.Real}) == univ.Real(-4.1), 'repr() fails'
+ assert repr(univ.Real(-4.1)) == 'Real((-41, 10, -1))', 'repr() fails'
+ assert eval(repr(univ.Real('inf')), {'Real': univ.Real}) == univ.Real('inf'), 'repr() fails'
+ assert repr(univ.Real('inf')) == 'Real(\'inf\')', 'repr() fails'
+
+ def testAdd(self):
+ assert univ.Real(-4.1) + 1.4 == -2.7, '__add__() fails'
+
+ def testRadd(self):
+ assert 4 + univ.Real(0.5) == 4.5, '__radd__() fails'
+
+ def testSub(self):
+ assert univ.Real(3.9) - 1.7 == 2.2, '__sub__() fails'
+
+ def testRsub(self):
+ assert 6.1 - univ.Real(0.1) == 6, '__rsub__() fails'
+
+ def testMul(self):
+ assert univ.Real(3.0) * -3 == -9, '__mul__() fails'
+
+ def testRmul(self):
+ assert 2 * univ.Real(3.0) == 6, '__rmul__() fails'
+
+ def testDiv(self):
+ assert univ.Real(3.0) / 2 == 1.5, '__div__() fails'
+
+ def testRdiv(self):
+ assert 6 / univ.Real(3.0) == 2, '__rdiv__() fails'
+
+ def testMod(self):
+ assert univ.Real(3.0) % 2 == 1, '__mod__() fails'
+
+ def testRmod(self):
+ assert 4 % univ.Real(3.0) == 1, '__rmod__() fails'
+
+ def testPow(self):
+ assert univ.Real(3.0) ** 2 == 9, '__pow__() fails'
+
+ def testRpow(self):
+ assert 2 ** univ.Real(2.0) == 4, '__rpow__() fails'
+
+ def testInt(self):
+ assert int(univ.Real(3.0)) == 3, '__int__() fails'
+
+ def testLong(self):
+ assert int(univ.Real(8.0)) == 8, '__long__() fails'
+
+ def testFloat(self):
+ assert float(univ.Real(4.0)) == 4.0, '__float__() fails'
+
+ def testPrettyIn(self):
+ assert univ.Real((3, 10, 0)) == 3, 'prettyIn() fails'
+
+ # infinite float values
+ def testStrInf(self):
+ assert str(univ.Real('inf')) == 'inf', 'str() fails'
+
+ def testAddInf(self):
+ assert univ.Real('inf') + 1 == float('inf'), '__add__() fails'
+
+ def testRaddInf(self):
+ assert 1 + univ.Real('inf') == float('inf'), '__radd__() fails'
+
+ def testIntInf(self):
+ try:
+ assert int(univ.Real('inf'))
+ except OverflowError:
+ pass
+ else:
+ assert 0, '__int__() fails'
+
+ def testLongInf(self):
+ try:
+ assert int(univ.Real('inf'))
+ except OverflowError:
+ pass
+ else:
+ assert 0, '__long__() fails'
+ assert int(univ.Real(8.0)) == 8, '__long__() fails'
+
+ def testFloatInf(self):
+ assert float(univ.Real('-inf')) == float('-inf'), '__float__() fails'
+
+ def testPrettyInInf(self):
+ assert univ.Real(float('inf')) == float('inf'), 'prettyIn() fails'
+
+ def testPlusInf(self):
+ assert univ.Real('inf').isPlusInf, 'isPlusInfinity failed'
+
+ def testMinusInf(self):
+ assert univ.Real('-inf').isMinusInf, 'isMinusInfinity failed'
+
+ def testPos(self):
+ assert +univ.Real(1.0) == 1.0, '__pos__() fails'
+
+ def testNeg(self):
+ assert -univ.Real(1.0) == -1.0, '__neg__() fails'
+
+ def testRound(self):
+ assert round(univ.Real(1.123), 2) == 1.12, '__round__() fails'
+
+ def testFloor(self):
+ assert math.floor(univ.Real(1.6)) == 1.0, '__floor__() fails'
+
+ def testCeil(self):
+ assert math.ceil(univ.Real(1.2)) == 2.0, '__ceil__() fails'
+
+ if sys.version_info[0:2] > (2, 5):
+ def testTrunc(self):
+ assert math.trunc(univ.Real(1.1)) == 1.0, '__trunc__() fails'
+
+ def testTag(self):
+ assert univ.Real().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
+ )
+
+ def testStaticDef(self):
+
+ class Real(univ.Real):
+ pass
+
+ assert Real(1.0) == 1.0
+
+
+class ObjectIdentifier(BaseTestCase):
+ def testStr(self):
+ assert str(univ.ObjectIdentifier((1, 3, 6))) == '1.3.6', 'str() fails'
+
+ def testRepr(self):
+ assert eval(repr(univ.ObjectIdentifier('1.3.6')),
+ {'ObjectIdentifier': univ.ObjectIdentifier}) == univ.ObjectIdentifier('1.3.6'), 'repr() fails'
+
+ def testEq(self):
+ assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), '__cmp__() fails'
+
+ def testAdd(self):
+ assert univ.ObjectIdentifier((1, 3)) + (6,) == (1, 3, 6), '__add__() fails'
+
+ def testRadd(self):
+ assert (1,) + univ.ObjectIdentifier((3, 6)) == (1, 3, 6), '__radd__() fails'
+
+ def testLen(self):
+ assert len(univ.ObjectIdentifier((1, 3))) == 2, '__len__() fails'
+
+ def testPrefix(self):
+ o = univ.ObjectIdentifier('1.3.6')
+ assert o.isPrefixOf((1, 3, 6)), 'isPrefixOf() fails'
+ assert o.isPrefixOf((1, 3, 6, 1)), 'isPrefixOf() fails'
+ assert not o.isPrefixOf((1, 3)), 'isPrefixOf() fails'
+
+ def testInput1(self):
+ assert univ.ObjectIdentifier('1.3.6') == (1, 3, 6), 'prettyIn() fails'
+
+ def testInput2(self):
+ assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), 'prettyIn() fails'
+
+ def testInput3(self):
+ assert univ.ObjectIdentifier(univ.ObjectIdentifier('1.3') + (6,)) == (1, 3, 6), 'prettyIn() fails'
+
+ def testUnicode(self):
+ s = '1.3.6'
+ if sys.version_info[0] < 3:
+ s = s.decode()
+ assert univ.ObjectIdentifier(s) == (1, 3, 6), 'unicode init fails'
+
+ def testTag(self):
+ assert univ.ObjectIdentifier().tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
+ )
+
+ def testContains(self):
+ s = univ.ObjectIdentifier('1.3.6.1234.99999')
+ assert 1234 in s
+ assert 4321 not in s
+
+ def testStaticDef(self):
+
+ class ObjectIdentifier(univ.ObjectIdentifier):
+ pass
+
+ assert str(ObjectIdentifier((1, 3, 6))) == '1.3.6'
+
+
+class SequenceOf(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s1 = univ.SequenceOf(
+ componentType=univ.OctetString('')
+ )
+ self.s2 = self.s1.clone()
+
+ def testRepr(self):
+ assert eval(repr(self.s1.clone().setComponents('a', 'b')),
+ {'SequenceOf': univ.SequenceOf,
+ 'OctetString': univ.OctetString}) == self.s1.clone().setComponents(
+ 'a', 'b'), 'repr() fails'
+
+ def testTag(self):
+ assert self.s1.tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+ ), 'wrong tagSet'
+
+ def testSeq(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ assert self.s1[0] == str2octs('abc'), 'set by idx fails'
+ self.s1[0] = 'cba'
+ assert self.s1[0] == str2octs('cba'), 'set by idx fails'
+
+ def testCmp(self):
+ self.s1.clear()
+ self.s1.setComponentByPosition(0, 'abc')
+ self.s2.clear()
+ self.s2.setComponentByPosition(0, univ.OctetString('abc'))
+ assert self.s1 == self.s2, '__cmp__() fails'
+
+ def testSubtypeSpec(self):
+ s = self.s1.clone(subtypeSpec=constraint.ConstraintsUnion(
+ constraint.SingleValueConstraint(str2octs('abc'))
+ ))
+ try:
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ except PyAsn1Error:
+ assert 0, 'constraint fails'
+ try:
+ s.setComponentByPosition(1, univ.OctetString('Abc'))
+ except PyAsn1Error:
+ try:
+ s.setComponentByPosition(1, univ.OctetString('Abc'),
+ verifyConstraints=False)
+ except PyAsn1Error:
+ assert 0, 'constraint failes with verifyConstraints=True'
+ else:
+ assert 0, 'constraint fails'
+
+ def testComponentTagsMatching(self):
+ s = self.s1.clone()
+ s.strictConstraints = True # This requires types equality
+ o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12))
+ try:
+ s.setComponentByPosition(0, o)
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'inner supertype tag allowed'
+
+ def testComponentConstraintsMatching(self):
+ s = self.s1.clone()
+ o = univ.OctetString().subtype(
+ subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba'))))
+ s.strictConstraints = True # This requires types equality
+ try:
+ s.setComponentByPosition(0, o.clone('cba'))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'inner supertype constraint allowed'
+ s.strictConstraints = False # This requires subtype relationships
+ try:
+ s.setComponentByPosition(0, o.clone('cba'))
+ except PyAsn1Error:
+ assert 0, 'inner supertype constraint disallowed'
+ else:
+ pass
+
+ def testSizeSpec(self):
+ s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion(
+ constraint.ValueSizeConstraint(1, 1)
+ ))
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ try:
+ s.verifySizeSpec()
+ except PyAsn1Error:
+ assert 0, 'size spec fails'
+ s.setComponentByPosition(1, univ.OctetString('abc'))
+ try:
+ s.verifySizeSpec()
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'size spec fails'
+
+ def testGetComponentTagMap(self):
+ assert self.s1.componentType.tagMap.presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString('')
+ }
+
+ def testSubtype(self):
+ self.s1.clear()
+ assert self.s1.subtype(
+ implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2),
+ subtypeSpec=constraint.SingleValueConstraint(1, 3),
+ sizeSpec=constraint.ValueSizeConstraint(0, 1)
+ ) == self.s1.clone(
+ tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
+ tag.tagFormatSimple, 2)),
+ subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3)),
+ sizeSpec=constraint.ValueSizeConstraint(0, 1)
+ )
+
+ def testClone(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ s = self.s1.clone()
+ assert len(s) == 0
+ s = self.s1.clone(cloneValueFlag=1)
+ assert len(s) == 1
+ assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+
+ def testSetComponents(self):
+ assert self.s1.clone().setComponents('abc', 'def') == \
+ self.s1.setComponentByPosition(0, 'abc').setComponentByPosition(1, 'def')
+
+ def testGetItem(self):
+ s = self.s1.clone()
+ s.append('xxx')
+ assert s[0]
+
+ try:
+ s[2]
+
+ except IndexError:
+ pass
+
+ else:
+ assert False, 'IndexError not raised'
+
+ # this is a deviation from standart sequence protocol
+ assert not s[1]
+
+ def testSetItem(self):
+ s = self.s1.clone()
+ s.append('xxx')
+
+ try:
+
+ s[2] = 'xxx'
+
+ except IndexError:
+ pass
+
+ else:
+ assert False, 'IndexError not raised'
+
+ def testAppend(self):
+ self.s1.clear()
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ assert len(self.s1) == 1
+ self.s1.append('def')
+ assert len(self.s1) == 2
+ assert list(self.s1) == [str2octs(x) for x in ['abc', 'def']]
+
+ def testExtend(self):
+ self.s1.clear()
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ assert len(self.s1) == 1
+ self.s1.extend(['def', 'ghi'])
+ assert len(self.s1) == 3
+ assert list(self.s1) == [str2octs(x) for x in ['abc', 'def', 'ghi']]
+
+ def testCount(self):
+ self.s1.clear()
+ for x in ['abc', 'def', 'abc']:
+ self.s1.append(x)
+ assert self.s1.count(str2octs('abc')) == 2
+ assert self.s1.count(str2octs('def')) == 1
+ assert self.s1.count(str2octs('ghi')) == 0
+
+ def testIndex(self):
+ self.s1.clear()
+ for x in ['abc', 'def', 'abc']:
+ self.s1.append(x)
+ assert self.s1.index(str2octs('abc')) == 0
+ assert self.s1.index(str2octs('def')) == 1
+ assert self.s1.index(str2octs('abc'), 1) == 2
+
+ def testSort(self):
+ self.s1.clear()
+ self.s1[0] = 'b'
+ self.s1[1] = 'a'
+ assert list(self.s1) == [str2octs('b'), str2octs('a')]
+ self.s1.sort()
+ assert list(self.s1) == [str2octs('a'), str2octs('b')]
+
+ def testStaticDef(self):
+
+ class SequenceOf(univ.SequenceOf):
+ componentType = univ.OctetString('')
+
+ s = SequenceOf()
+ s[0] = 'abc'
+ assert len(s) == 1
+ assert s == [str2octs('abc')]
+
+ def testLegacyInitializer(self):
+ n = univ.SequenceOf(
+ componentType=univ.OctetString()
+ )
+ o = univ.SequenceOf(
+ univ.OctetString() # this is the old way
+ )
+
+ assert n.isSameTypeWith(o) and o.isSameTypeWith(n)
+
+ n[0] = 'fox'
+ o[0] = 'fox'
+
+ assert n == o
+
+class Sequence(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s1 = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString('')),
+ namedtype.OptionalNamedType('nick', univ.OctetString('')),
+ namedtype.DefaultedNamedType('age', univ.Integer(34))
+ )
+ )
+
+ def testRepr(self):
+ assert eval(
+ repr(self.s1.clone().setComponents('a', 'b')),
+ {'Sequence': univ.Sequence,
+ 'OctetString': univ.OctetString,
+ 'Integer': univ.Integer,
+ 'NamedTypes': namedtype.NamedTypes,
+ 'NamedType': namedtype.NamedType,
+ 'OptionalNamedType': namedtype.OptionalNamedType,
+ 'DefaultedNamedType': namedtype.DefaultedNamedType}
+ ) == self.s1.clone().setComponents('a', 'b'), 'repr() fails'
+
+ def testTag(self):
+ assert self.s1.tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+ ), 'wrong tagSet'
+
+ def testById(self):
+ self.s1.setComponentByName('name', univ.OctetString('abc'))
+ assert self.s1.getComponentByName('name') == str2octs('abc'), 'set by name fails'
+
+ def testByKey(self):
+ self.s1['name'] = 'abc'
+ assert self.s1['name'] == str2octs('abc'), 'set by key fails'
+
+ def testContains(self):
+ assert 'name' in self.s1
+ assert '<missing>' not in self.s1
+
+ def testGetNearPosition(self):
+ assert self.s1.componentType.getTagMapNearPosition(1).presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString(''),
+ univ.Integer.tagSet: univ.Integer(34)
+ }
+ assert self.s1.componentType.getPositionNearType(
+ univ.OctetString.tagSet, 1
+ ) == 1
+
+ def testSetDefaultComponents(self):
+ self.s1.clear()
+ self.s1.setComponentByPosition(0, univ.OctetString('Ping'))
+ self.s1.setComponentByPosition(1, univ.OctetString('Pong'))
+ assert self.s1.getComponentByPosition(2) == 34
+
+ def testClone(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ self.s1.setComponentByPosition(1, univ.OctetString('def'))
+ self.s1.setComponentByPosition(2, univ.Integer(123))
+ s = self.s1.clone()
+ assert s.getComponentByPosition(0) != self.s1.getComponentByPosition(0)
+ assert s.getComponentByPosition(1) != self.s1.getComponentByPosition(1)
+ assert s.getComponentByPosition(2) != self.s1.getComponentByPosition(2)
+ s = self.s1.clone(cloneValueFlag=1)
+ assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+ assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1)
+ assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2)
+
+ def testComponentTagsMatching(self):
+ s = self.s1.clone()
+ s.strictConstraints = True # This requires types equality
+ o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12))
+ try:
+ s.setComponentByName('name', o)
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'inner supertype tag allowed'
+
+ def testComponentConstraintsMatching(self):
+ s = self.s1.clone()
+ o = univ.OctetString().subtype(
+ subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba'))))
+ s.strictConstraints = True # This requires types equality
+ try:
+ s.setComponentByName('name', o.clone('cba'))
+ except PyAsn1Error:
+ pass
+ else:
+ assert 0, 'inner supertype constraint allowed'
+ s.strictConstraints = False # This requires subtype relationships
+ try:
+ s.setComponentByName('name', o.clone('cba'))
+ except PyAsn1Error:
+ assert 0, 'inner supertype constraint disallowed'
+ else:
+ pass
+
+ def testSetComponents(self):
+ assert self.s1.clone().setComponents(name='a', nick='b', age=1) == \
+ self.s1.setComponentByPosition(0, 'a').setComponentByPosition(1, 'b').setComponentByPosition(2, 1)
+
+ def testSetToDefault(self):
+ s = self.s1.clone()
+ s.setComponentByPosition(0, univ.noValue)
+ s[2] = univ.noValue
+ assert s[0] == univ.OctetString('')
+ assert s[2] == univ.Integer(34)
+
+ def testGetItem(self):
+ s = self.s1.clone()
+ s['name'] = 'xxx'
+ assert s['name']
+ assert s[0]
+
+ try:
+ s['xxx']
+
+ except KeyError:
+ pass
+
+ else:
+ assert False, 'KeyError not raised'
+
+ try:
+ s[100]
+
+ except IndexError:
+ pass
+
+ else:
+ assert False, 'IndexError not raised'
+
+ def testSetItem(self):
+ s = self.s1.clone()
+ s['name'] = 'xxx'
+
+ try:
+
+ s['xxx'] = 'xxx'
+
+ except KeyError:
+ pass
+
+ else:
+ assert False, 'KeyError not raised'
+
+ try:
+
+ s[100] = 'xxx'
+
+ except IndexError:
+ pass
+
+ else:
+ assert False, 'IndexError not raised'
+
+ def testIter(self):
+ assert list(self.s1) == ['name', 'nick', 'age']
+
+ def testKeys(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ self.s1.setComponentByPosition(1, univ.OctetString('def'))
+ self.s1.setComponentByPosition(2, univ.Integer(123))
+ assert list(self.s1.keys()) == ['name', 'nick', 'age']
+
+ def testValues(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ self.s1.setComponentByPosition(1, univ.OctetString('def'))
+ self.s1.setComponentByPosition(2, univ.Integer(123))
+ assert list(self.s1.values()) == [str2octs('abc'), str2octs('def'), 123]
+
+ def testItems(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ self.s1.setComponentByPosition(1, univ.OctetString('def'))
+ self.s1.setComponentByPosition(2, univ.Integer(123))
+ assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)]
+
+ def testUpdate(self):
+ self.s1.clear()
+ assert list(self.s1.values()) == [str2octs(''), str2octs(''), 34]
+ self.s1.update(**{'name': 'abc', 'nick': 'def', 'age': 123})
+ assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)]
+ self.s1.update(('name', 'ABC'))
+ assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'ABC'), ('nick', 'def')]] + [('age', 123)]
+ self.s1.update(name='CBA')
+ assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'CBA'), ('nick', 'def')]] + [('age', 123)]
+
+ def testStaticDef(self):
+
+ class Sequence(univ.Sequence):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString('')),
+ namedtype.OptionalNamedType('nick', univ.OctetString('')),
+ namedtype.DefaultedNamedType('age', univ.Integer(34))
+ )
+
+ s = Sequence()
+ s['name'] = 'abc'
+ assert s['name'] == str2octs('abc')
+
+
+class SequenceWithoutSchema(BaseTestCase):
+
+ def testGetItem(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s[0] = 'abc'
+ assert s['field-0']
+ assert s[0]
+
+ try:
+ s['field-1']
+
+ except KeyError:
+ pass
+
+ else:
+ assert False, 'KeyError not raised'
+
+ def testSetItem(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s['field-0'] = 'xxx'
+
+ try:
+
+ s['field-1'] = 'xxx'
+
+ except KeyError:
+ pass
+
+ else:
+ assert False, 'KeyError not raised'
+
+ def testIter(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s.setComponentByPosition(1, univ.Integer(123))
+ assert list(s) == ['field-0', 'field-1']
+
+ def testKeys(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s.setComponentByPosition(1, univ.Integer(123))
+ assert list(s.keys()) == ['field-0', 'field-1']
+
+ def testValues(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s.setComponentByPosition(1, univ.Integer(123))
+ assert list(s.values()) == [str2octs('abc'), 123]
+
+ def testItems(self):
+ s = univ.Sequence()
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s.setComponentByPosition(1, univ.Integer(123))
+ assert list(s.items()) == [('field-0', str2octs('abc')), ('field-1', 123)]
+
+ def testUpdate(self):
+ s = univ.Sequence()
+ assert not s
+ s.setComponentByPosition(0, univ.OctetString('abc'))
+ s.setComponentByPosition(1, univ.Integer(123))
+ assert s
+ assert list(s.keys()) == ['field-0', 'field-1']
+ assert list(s.values()) == [str2octs('abc'), 123]
+ assert list(s.items()) == [('field-0', str2octs('abc')), ('field-1', 123)]
+ s['field-0'] = univ.OctetString('def')
+ assert list(s.values()) == [str2octs('def'), 123]
+ s['field-1'] = univ.OctetString('ghi')
+ assert list(s.values()) == [str2octs('def'), str2octs('ghi')]
+ try:
+ s['field-2'] = univ.OctetString('xxx')
+ except KeyError:
+ pass
+ else:
+ assert False, 'unknown field at schema-less object tolerated'
+ assert 'field-0' in s
+ s.clear()
+ assert 'field-0' not in s
+
+
+class SetOf(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s1 = univ.SetOf(componentType=univ.OctetString(''))
+
+ def testTag(self):
+ assert self.s1.tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+ ), 'wrong tagSet'
+
+ def testSeq(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ assert self.s1[0] == str2octs('abc'), 'set by idx fails'
+ self.s1.setComponentByPosition(0, self.s1[0].clone('cba'))
+ assert self.s1[0] == str2octs('cba'), 'set by idx fails'
+
+ def testStaticDef(self):
+
+ class SetOf(univ.SequenceOf):
+ componentType = univ.OctetString('')
+
+ s = SetOf()
+ s[0] = 'abc'
+ assert len(s) == 1
+ assert s == [str2octs('abc')]
+
+
+class Set(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ self.s1 = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString('')),
+ namedtype.OptionalNamedType('null', univ.Null('')),
+ namedtype.DefaultedNamedType('age', univ.Integer(34))
+ )
+ )
+ self.s2 = self.s1.clone()
+
+ def testTag(self):
+ assert self.s1.tagSet == tag.TagSet(
+ (),
+ tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+ ), 'wrong tagSet'
+
+ def testByTypeWithPythonValue(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert self.s1.getComponentByType(
+ univ.OctetString.tagSet
+ ) == str2octs('abc'), 'set by name fails'
+
+ def testByTypeWithInstance(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, univ.OctetString('abc'))
+ assert self.s1.getComponentByType(
+ univ.OctetString.tagSet
+ ) == str2octs('abc'), 'set by name fails'
+
+ def testGetTagMap(self):
+ assert self.s1.tagMap.presentTypes == {
+ univ.Set.tagSet: univ.Set()
+ }
+
+ def testGetComponentTagMap(self):
+ assert self.s1.componentType.tagMapUnique.presentTypes == {
+ univ.OctetString.tagSet: univ.OctetString(''),
+ univ.Null.tagSet: univ.Null(''),
+ univ.Integer.tagSet: univ.Integer(34)
+ }
+
+ def testGetPositionByType(self):
+ assert self.s1.componentType.getPositionByType(univ.Null().tagSet) == 1
+
+ def testSetToDefault(self):
+ self.s1.setComponentByName('name', univ.noValue)
+ assert self.s1['name'] == univ.OctetString('')
+
+ def testIter(self):
+ assert list(self.s1) == ['name', 'null', 'age']
+
+ def testStaticDef(self):
+
+ class Set(univ.Set):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString('')),
+ namedtype.OptionalNamedType('nick', univ.OctetString('')),
+ namedtype.DefaultedNamedType('age', univ.Integer(34))
+ )
+
+ s = Set()
+ s['name'] = 'abc'
+ assert s['name'] == str2octs('abc')
+
+
+class Choice(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+
+ innerComp = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('count', univ.Integer()),
+ namedtype.NamedType('flag', univ.Boolean())
+ )
+ )
+ self.s1 = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('sex', innerComp)
+ )
+ )
+
+ def testTag(self):
+ assert self.s1.tagSet == tag.TagSet(), 'wrong tagSet'
+
+ def testRepr(self):
+ assert eval(repr(self.s1.clone().setComponents('a')),
+ {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer,
+ 'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes,
+ 'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents('a'), 'repr() fails'
+ assert eval(repr(self.s1.clone().setComponents(
+ sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents(
+ count=univ.Integer(123)))),
+ {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer,
+ 'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes,
+ 'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents(
+ sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents(
+ count=univ.Integer(123))), 'repr() fails'
+
+ def testContains(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert 'name' in self.s1
+ assert 'sex' not in self.s1
+
+ self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+ assert 'name' not in self.s1
+ assert 'sex' in self.s1
+
+ def testIter(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert list(self.s1) == ['name']
+ self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+ assert list(self.s1) == ['sex']
+
+ def testOuterByTypeWithPythonValue(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert self.s1.getComponentByType(
+ univ.OctetString.tagSet
+ ) == str2octs('abc')
+
+ def testOuterByTypeWithInstanceValue(self):
+ self.s1.setComponentByType(
+ univ.OctetString.tagSet, univ.OctetString('abc')
+ )
+ assert self.s1.getComponentByType(
+ univ.OctetString.tagSet
+ ) == str2octs('abc')
+
+ def testInnerByTypeWithPythonValue(self):
+ self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+ assert self.s1.getComponentByType(
+ univ.Integer.tagSet, 1
+ ) == 123
+
+ def testInnerByTypeWithInstanceValue(self):
+ self.s1.setComponentByType(
+ univ.Integer.tagSet, univ.Integer(123), innerFlag=True
+ )
+ assert self.s1.getComponentByType(
+ univ.Integer.tagSet, 1
+ ) == 123
+
+ def testCmp(self):
+ self.s1.setComponentByName('name', univ.OctetString('abc'))
+ assert self.s1 == str2octs('abc'), '__cmp__() fails'
+
+ def testGetComponent(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert self.s1.getComponent() == str2octs('abc'), 'getComponent() fails'
+
+ def testGetName(self):
+ self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert self.s1.getName() == 'name', 'getName() fails'
+
+ def testSetComponentByPosition(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('Jim'))
+ assert self.s1 == str2octs('Jim')
+
+ def testClone(self):
+ self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+ s = self.s1.clone()
+ assert len(s) == 0
+ s = self.s1.clone(cloneValueFlag=1)
+ assert len(s) == 1
+ assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+
+ def testSetToDefault(self):
+ s = self.s1.clone()
+ s.setComponentByName('sex', univ.noValue)
+ assert s['sex'] is not univ.noValue
+
+ def testStaticDef(self):
+
+ class InnerChoice(univ.Choice):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('count', univ.Integer()),
+ namedtype.NamedType('flag', univ.Boolean())
+ )
+
+ class OuterChoice(univ.Choice):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('sex', InnerChoice())
+ )
+
+ c = OuterChoice()
+
+ c.setComponentByType(univ.OctetString.tagSet, 'abc')
+ assert c.getName() == 'name'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_useful.py
@@ -0,0 +1,104 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import datetime
+from copy import deepcopy
+
+try:
+ import unittest2 as unittest
+
+except ImportError:
+ import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import useful
+
+class FixedOffset(datetime.tzinfo):
+ def __init__(self, offset, name):
+ self.__offset = datetime.timedelta(minutes=offset)
+ self.__name = name
+
+ def utcoffset(self, dt):
+ return self.__offset
+
+ def tzname(self, dt):
+ return self.__name
+
+ def dst(self, dt):
+ return datetime.timedelta(0)
+
+
+UTC = FixedOffset(0, 'UTC')
+UTC2 = FixedOffset(120, 'UTC')
+
+
+class ObjectDescriptorTestCase(BaseTestCase):
+ pass
+
+
+class GeneralizedTimeTestCase(BaseTestCase):
+
+ def testFromDateTime(self):
+ assert useful.GeneralizedTime.fromDateTime(datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC)) == '20170711000102.3Z'
+
+ def testToDateTime0(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2) == useful.GeneralizedTime('20170711000102').asDateTime
+
+ def testToDateTime1(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.GeneralizedTime('20170711000102Z').asDateTime
+
+ def testToDateTime2(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102.3Z').asDateTime
+
+ def testToDateTime3(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102,3Z').asDateTime
+
+ def testToDateTime4(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102.3+0000').asDateTime
+
+ def testToDateTime5(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC2) == useful.GeneralizedTime('20170711000102.3+0200').asDateTime
+
+ def testToDateTime6(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC2) == useful.GeneralizedTime('20170711000102.3+02').asDateTime
+
+ def testToDateTime7(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1) == useful.GeneralizedTime('201707110001').asDateTime
+
+ def testToDateTime8(self):
+ assert datetime.datetime(2017, 7, 11, 0) == useful.GeneralizedTime('2017071100').asDateTime
+
+ def testCopy(self):
+ dt = useful.GeneralizedTime("20170916234254+0130").asDateTime
+ assert dt == deepcopy(dt)
+
+
+class UTCTimeTestCase(BaseTestCase):
+
+ def testFromDateTime(self):
+ assert useful.UTCTime.fromDateTime(datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC)) == '170711000102Z'
+
+ def testToDateTime0(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2) == useful.UTCTime('170711000102').asDateTime
+
+ def testToDateTime1(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.UTCTime('170711000102Z').asDateTime
+
+ def testToDateTime2(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.UTCTime('170711000102+0000').asDateTime
+
+ def testToDateTime3(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC2) == useful.UTCTime('170711000102+0200').asDateTime
+
+ def testToDateTime4(self):
+ assert datetime.datetime(2017, 7, 11, 0, 1) == useful.UTCTime('1707110001').asDateTime
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ unittest.TextTestRunner(verbosity=2).run(suite)