From 62efcb94b15ca7fbd5261ca999bf5eca5680de5f Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Fri, 12 Jul 2019 22:42:04 +0200 Subject: Fix CER/DER encoders to respect open types (#167) * Fix CER/DER encoders to respect open types Added a bunch of unit tests to CER/DER codecs covering open types. --- pyasn1/codec/ber/encoder.py | 80 +++++------ pyasn1/codec/cer/encoder.py | 76 +++++----- tests/codec/ber/test_decoder.py | 2 +- tests/codec/ber/test_encoder.py | 20 +-- tests/codec/cer/test_decoder.py | 302 ++++++++++++++++++++++++++++++++++++++++ tests/codec/cer/test_encoder.py | 274 ++++++++++++++++++++++++++++++++---- tests/codec/der/test_decoder.py | 294 ++++++++++++++++++++++++++++++++++++++ tests/codec/der/test_encoder.py | 241 ++++++++++++++++++++++++++++++++ 8 files changed, 1165 insertions(+), 124 deletions(-) diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py index b17fca8..fbad7e7 100644 --- a/pyasn1/codec/ber/encoder.py +++ b/pyasn1/codec/ber/encoder.py @@ -559,20 +559,20 @@ class SequenceEncoder(AbstractItemEncoder): options.update(ifNotEmpty=namedType.isOptional) # wrap open type blob if needed - if (namedTypes and namedType.openType - and namedType.asn1Object.tagSet): + if namedTypes and namedType.openType: - if component.typeId in ( - univ.SetOf.typeId, univ.SequenceOf.typeId): - substrate += encodeFun( + wrapType = namedType.asn1Object + + if wrapType.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + substrate += encodeFun( component, asn1Spec, - **dict(options, openType=True)) + **dict(options, wrapType=wrapType.componentType)) else: chunk = encodeFun(component, asn1Spec, **options) - wrapType = namedType.asn1Object - if wrapType.isSameTypeWith(component): substrate += chunk @@ -609,67 +609,69 @@ class SequenceEncoder(AbstractItemEncoder): if omitEmptyOptionals: options.update(ifNotEmpty=namedType.isOptional) + componentSpec = namedType.asn1Object + # wrap open type blob if needed - if namedType.openType and namedType.asn1Object.tagSet: + if namedType.openType: - if component.typeId in ( - univ.SetOf.typeId, univ.SequenceOf.typeId): - substrate += encodeFun( - component, asn1Spec[idx], - **dict(options, openType=True)) + if componentSpec.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): - else: - chunk = encodeFun(component, asn1Spec[idx], **options) + substrate += encodeFun( + component, componentSpec, + **dict(options, wrapType=componentSpec.componentType)) - wrapType = namedType.asn1Object + else: + chunk = encodeFun(component, componentSpec, **options) - if wrapType.isSameTypeWith(component): + if componentSpec.isSameTypeWith(component): substrate += chunk else: - substrate += encodeFun(chunk, wrapType, **options) + substrate += encodeFun(chunk, componentSpec, **options) if LOG: - LOG('wrapped with wrap type %r' % (wrapType,)) + LOG('wrapped with wrap type %r' % (componentSpec,)) else: - substrate += encodeFun(component, asn1Spec[idx], **options) + substrate += encodeFun(component, componentSpec, **options) return substrate, True, True class SequenceOfEncoder(AbstractItemEncoder): - def encodeValue(self, value, asn1Spec, encodeFun, **options): + def _encodeComponents(self, value, asn1Spec, encodeFun, **options): + if asn1Spec is None: value.verifySizeSpec() - wrapType = value.componentType - else: - asn1Spec = wrapType = asn1Spec.componentType + asn1Spec = asn1Spec.componentType - openType = options.pop('openType', False) + chunks = [] - substrate = null + wrapType = options.pop('wrapType', None) for idx, component in enumerate(value): - if openType: - # do not use asn1Spec even if given because it's a wrapper - chunk = encodeFun(component, **options) + chunk = encodeFun(component, asn1Spec, **options) - if not wrapType.isSameTypeWith(component): - # wrap encoded value with wrapper container (e.g. ANY) - chunk = encodeFun(chunk, wrapType, **options) + if (wrapType is not None and + not wrapType.isSameTypeWith(component)): + # wrap encoded value with wrapper container (e.g. ANY) + chunk = encodeFun(chunk, wrapType, **options) - if LOG: - LOG('wrapped with wrap type %r' % (wrapType,)) + if LOG: + LOG('wrapped with wrap type %r' % (wrapType,)) - else: - chunk = encodeFun(component, asn1Spec, **options) + chunks.append(chunk) - substrate += chunk + return chunks - return substrate, True, True + def encodeValue(self, value, asn1Spec, encodeFun, **options): + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + return null.join(chunks), True, True class ChoiceEncoder(AbstractItemEncoder): diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py index 3fdcc1d..d7a1dfe 100644 --- a/pyasn1/codec/cer/encoder.py +++ b/pyasn1/codec/cer/encoder.py @@ -109,6 +109,37 @@ class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder): MAX_LENGTH = 14 +class SetOfEncoder(encoder.SequenceOfEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + # sort by serialised and padded components + if len(chunks) > 1: + zero = str2octs('\x00') + maxLen = max(map(len, chunks)) + paddedChunks = [ + (x.ljust(maxLen, zero), x) for x in chunks + ] + paddedChunks.sort(key=lambda x: x[0]) + + chunks = [x[1] for x in paddedChunks] + + return null.join(chunks), True, True + + +class SequenceOfEncoder(encoder.SequenceOfEncoder): + def encodeValue(self, value, asn1Spec, encodeFun, **options): + + if options.get('ifNotEmpty', False) and not len(value): + return null, True, True + + chunks = self._encodeComponents( + value, asn1Spec, encodeFun, **options) + + return null.join(chunks), True, True + + class SetEncoder(encoder.SequenceEncoder): @staticmethod def _componentSortKey(componentAndType): @@ -197,55 +228,10 @@ class SetEncoder(encoder.SequenceEncoder): return substrate, True, True -class SetOfEncoder(encoder.SequenceOfEncoder): - def encodeValue(self, value, asn1Spec, encodeFun, **options): - if asn1Spec is None: - value.verifySizeSpec() - else: - asn1Spec = asn1Spec.componentType - - components = [encodeFun(x, asn1Spec, **options) - for x in value] - - # sort by serialised 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): omitEmptyOptionals = True -class SequenceOfEncoder(encoder.SequenceOfEncoder): - def encodeValue(self, value, asn1Spec, encodeFun, **options): - - if options.get('ifNotEmpty', False) and not len(value): - return null, True, True - - if asn1Spec is None: - value.verifySizeSpec() - else: - asn1Spec = asn1Spec.componentType - - substrate = null - - for idx, component in enumerate(value): - substrate += encodeFun(value[idx], asn1Spec, **options) - - return substrate, True, True - - tagMap = encoder.tagMap.copy() tagMap.update({ univ.Boolean.tagSet: BooleanEncoder(), diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py index 95f6c91..089f0f3 100644 --- a/tests/codec/ber/test_decoder.py +++ b/tests/codec/ber/test_decoder.py @@ -835,7 +835,7 @@ class SequenceDecoderWithSchemaTestCase(BaseTestCase): ) == (self.s, null) -class SequenceDecoderWithUnaggedOpenTypesTestCase(BaseTestCase): +class SequenceDecoderWithUntaggedOpenTypesTestCase(BaseTestCase): def setUp(self): openType = opentype.OpenType( 'id', diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py index 26236af..38d75c0 100644 --- a/tests/codec/ber/test_encoder.py +++ b/tests/codec/ber/test_encoder.py @@ -762,7 +762,7 @@ class SequenceEncoderWithUntaggedOpenTypesTestCase(BaseTestCase): self.s[1] = univ.Integer(12) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 6, 2, 1, 1, 2, 1, 12) + (48, 5, 2, 1, 1, 49, 50) ) def testEncodeOpenTypeChoiceTwo(self): @@ -772,7 +772,7 @@ class SequenceEncoderWithUntaggedOpenTypesTestCase(BaseTestCase): self.s[1] = univ.OctetString('quick brown') assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 16, 2, 1, 2, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110) + (48, 14, 2, 1, 2, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110) ) def testEncodeOpenTypeUnknownId(self): @@ -823,7 +823,7 @@ class SequenceEncoderWithImplicitlyTaggedOpenTypesTestCase(BaseTestCase): self.s[1] = univ.Integer(12) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 8, 2, 1, 1, 131, 3, 2, 1, 12) + (48, 9, 2, 1, 1, 131, 4, 131, 2, 49, 50) ) @@ -850,8 +850,8 @@ class SequenceEncoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): self.s[1] = univ.Integer(12) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 8, 2, 1, 1, 163, 3, 2, 1, 12) - ) + (48, 9, 2, 1, 1, 163, 4, 163, 2, 49, 50) + ) class SequenceEncoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): @@ -878,7 +878,7 @@ class SequenceEncoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): self.s[1].append(univ.Integer(12)) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 8, 2, 1, 1, 49, 3, 2, 1, 12) + (48, 7, 2, 1, 1, 49, 2, 49, 50) ) def testEncodeOpenTypeChoiceTwo(self): @@ -888,8 +888,8 @@ class SequenceEncoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): self.s[1].append(univ.OctetString('quick brown')) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 18, 2, 1, 2, 49, 13, 4, 11, 113, 117, 105, 99, - 107, 32, 98, 114, 111, 119, 110) + (48, 16, 2, 1, 2, 49, 11, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110) ) def testEncodeOpenTypeUnknownId(self): @@ -944,7 +944,7 @@ class SequenceEncoderWithImplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): self.s[1].append(univ.Integer(12)) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12) + (48, 11, 2, 1, 1, 49, 6, 131, 4, 131, 2, 49, 50) ) @@ -974,7 +974,7 @@ class SequenceEncoderWithExplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): self.s[1].append(univ.Integer(12)) assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( - (48, 10, 2, 1, 1, 49, 5, 163, 3, 2, 1, 12) + (48, 11, 2, 1, 1, 49, 6, 163, 4, 163, 2, 49, 50) ) diff --git a/tests/codec/cer/test_decoder.py b/tests/codec/cer/test_decoder.py index d4e00ab..bb5ce93 100644 --- a/tests/codec/cer/test_decoder.py +++ b/tests/codec/cer/test_decoder.py @@ -13,6 +13,10 @@ except ImportError: from tests.base import BaseTestCase +from pyasn1.type import tag +from pyasn1.type import namedtype +from pyasn1.type import opentype +from pyasn1.type import univ from pyasn1.codec.cer import decoder from pyasn1.compat.octets import ints2octs, str2octs, null from pyasn1.error import PyAsn1Error @@ -65,6 +69,304 @@ class OctetStringDecoderTestCase(BaseTestCase): # TODO: test failures on short chunked and long unchunked substrate samples +class SequenceDecoderWithUntaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any(), openType=openType) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 2, 1, 12, 0, 0)), + asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 2, 4, 11, 113, 117, 105, 99, 107, 32, 98, + 114, 111, 119, 110, 0, 0)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 2 + assert s[1] == univ.OctetString('quick brown') + + def testDecodeOpenTypesUnknownType(self): + try: + s, r = decoder.decode( + ints2octs((48, 128, 6, 1, 1, 2, 1, 12, 0, 0)), asn1Spec=self.s, + decodeOpenTypes=True + ) + + except PyAsn1Error: + pass + + else: + assert False, 'unknown open type tolerated' + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 3, 6, 1, 12, 0, 0)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='06010c') + + def testDontDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 2, 1, 12, 0, 0)), asn1Spec=self.s + ) + assert not r + assert s[0] == 1 + assert s[1] == ints2octs((2, 1, 12)) + + def testDontDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 2, 4, 11, 113, 117, 105, 99, 107, 32, 98, + 114, 111, 119, 110, 0, 0)), asn1Spec=self.s + ) + assert not r + assert s[0] == 2 + assert s[1] == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)) + + +class SequenceDecoderWithImplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 163, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 3, 163, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 163, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 3, 163, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf(componentType=univ.Any()), + openType=openType) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 49, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 2, 49, 128, 4, 11, 113, 117, 105, 99, + 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 2 + assert s[1][0] == univ.OctetString('quick brown') + + def testDecodeOpenTypesUnknownType(self): + try: + s, r = decoder.decode( + ints2octs((48, 128, 6, 1, 1, 49, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + + except PyAsn1Error: + pass + + else: + assert False, 'unknown open type tolerated' + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 3, 49, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010c') + + def testDontDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 1, 49, 128, 2, 1, 12, 0, 0, 0, 0)), + asn1Spec=self.s + ) + assert not r + assert s[0] == 1 + assert s[1][0] == ints2octs((2, 1, 12)) + + def testDontDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 128, 2, 1, 2, 49, 128, 4, 11, 113, 117, 105, 99, 107, 32, + 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s + ) + assert not r + assert s[0] == 2 + assert s[1][0] == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110)) + + +class SequenceDecoderWithImplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.SetOf( + componentType=univ.Any().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 3, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithExplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.SetOf( + componentType=univ.Any().subtype( + explicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs( (48, 10, 2, 1, 3, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010C') + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': diff --git a/tests/codec/cer/test_encoder.py b/tests/codec/cer/test_encoder.py index 130fe17..e155571 100644 --- a/tests/codec/cer/test_encoder.py +++ b/tests/codec/cer/test_encoder.py @@ -15,6 +15,7 @@ from tests.base import BaseTestCase from pyasn1.type import tag from pyasn1.type import namedtype +from pyasn1.type import opentype from pyasn1.type import univ from pyasn1.type import useful from pyasn1.codec.cer import encoder @@ -385,7 +386,7 @@ class SetEncoderWithSchemaTestCase(BaseTestCase): ) == 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): +class SetEncoderWithChoiceWithSchemaEncoderTestCase(BaseTestCase): def setUp(self): BaseTestCase.setUp(self) c = univ.Choice(componentType=namedtype.NamedTypes( @@ -403,7 +404,7 @@ class SetWithChoiceWithSchemaEncoderTestCase(BaseTestCase): assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0)) -class SetWithTaggedChoiceEncoderTestCase(BaseTestCase): +class SetEncoderWithTaggedChoiceEncoderTestCase(BaseTestCase): def testWithUntaggedChoice(self): @@ -446,33 +447,6 @@ class SetWithTaggedChoiceEncoderTestCase(BaseTestCase): assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 65, 167, 128, 1, 1, 255, 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 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) @@ -554,6 +528,248 @@ class SequenceEncoderWithSchemaTestCase(BaseTestCase): ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0)) +class SequenceEncoderWithUntaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any(), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 49, 50, 0, 0) + ) + + def testEncodeOpenTypeChoiceTwo(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.OctetString('quick brown') + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 2, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110, 0, 0) + ) + + def testEncodeOpenTypeUnknownId(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.ObjectIdentifier('1.3.6') + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + def testEncodeOpenTypeIncompatibleType(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.ObjectIdentifier('1.3.6') + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + +class SequenceEncoderWithImplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 163, 128, 163, 128, 49, 50, 0, 0, 0, 0, 0, 0) + ) + + +class SequenceEncoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 163, 128, 163, 128, 49, 50, 0, 0, 0, 0, 0, 0) + ) + + +class SequenceEncoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any()), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 49, 128, 49, 50, 0, 0, 0, 0) + ) + + def testEncodeOpenTypeChoiceTwo(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.OctetString('quick brown')) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 2, 49, 128, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110, 0, 0, 0, 0) + ) + + def testEncodeOpenTypeUnknownId(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.ObjectIdentifier('1.3.6')) + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + def testEncodeOpenTypeIncompatibleType(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.ObjectIdentifier('1.3.6')) + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + +class SequenceEncoderWithImplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 49, 128, 163, 128, 163, 128, 49, 50, 0, 0, + 0, 0, 0, 0, 0, 0) + ) + + +class SequenceEncoderWithExplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 128, 2, 1, 1, 49, 128, 163, 128, 163, 128, 49, 50, 0, 0, + 0, 0, 0, 0, 0, 0) + ) + + class NestedOptionalSequenceEncoderTestCase(BaseTestCase): def setUp(self): BaseTestCase.setUp(self) diff --git a/tests/codec/der/test_decoder.py b/tests/codec/der/test_decoder.py index a76c435..51ce296 100644 --- a/tests/codec/der/test_decoder.py +++ b/tests/codec/der/test_decoder.py @@ -14,6 +14,10 @@ except ImportError: from tests.base import BaseTestCase +from pyasn1.type import tag +from pyasn1.type import namedtype +from pyasn1.type import opentype +from pyasn1.type import univ from pyasn1.codec.der import decoder from pyasn1.compat.octets import ints2octs, null from pyasn1.error import PyAsn1Error @@ -73,6 +77,296 @@ class OctetStringDecoderTestCase(BaseTestCase): assert 0, 'chunked encoding tolerated' +class SequenceDecoderWithUntaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any(), openType=openType) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 6, 2, 1, 1, 2, 1, 12)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 16, 2, 1, 2, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 2 + assert s[1] == univ.OctetString('quick brown') + + def testDecodeOpenTypesUnknownType(self): + try: + s, r = decoder.decode( + ints2octs((48, 6, 2, 1, 2, 6, 1, 39)), asn1Spec=self.s, + decodeOpenTypes=True + ) + + except PyAsn1Error: + pass + + else: + assert False, 'unknown open type tolerated' + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 6, 2, 1, 3, 6, 1, 39)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='060127') + + def testDontDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 6, 2, 1, 1, 2, 1, 12)), asn1Spec=self.s + ) + assert not r + assert s[0] == 1 + assert s[1] == ints2octs((2, 1, 12)) + + def testDontDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 16, 2, 1, 2, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s + ) + assert not r + assert s[0] == 2 + assert s[1] == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)) + + +class SequenceDecoderWithImplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 1, 131, 3, 2, 1, 12)), asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 3, 131, 3, 2, 1, 12)), asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 1, 163, 3, 2, 1, 12)), asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 3, 163, 3, 2, 1, 12)), asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithUnaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf(componentType=univ.Any()), + openType=openType) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 1, 49, 3, 2, 1, 12)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 18, 2, 1, 2, 49, 13, 4, 11, 113, 117, 105, 99, + 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 2 + assert s[1][0] == univ.OctetString('quick brown') + + def testDecodeOpenTypesUnknownType(self): + try: + s, r = decoder.decode( + ints2octs((48, 6, 2, 1, 2, 6, 1, 39)), asn1Spec=self.s, + decodeOpenTypes=True + ) + + except PyAsn1Error: + pass + + else: + assert False, 'unknown open type tolerated' + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 3, 49, 3, 2, 1, 12)), asn1Spec=self.s, + decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010c') + + def testDontDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 8, 2, 1, 1, 49, 3, 2, 1, 12)), asn1Spec=self.s + ) + assert not r + assert s[0] == 1 + assert s[1][0] == ints2octs((2, 1, 12)) + + def testDontDecodeOpenTypesChoiceTwo(self): + s, r = decoder.decode( + ints2octs((48, 18, 2, 1, 2, 49, 13, 4, 11, 113, 117, 105, 99, + 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s + ) + assert not r + assert s[0] == 2 + assert s[1][0] == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110)) + + +class SequenceDecoderWithImplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.SetOf( + componentType=univ.Any().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 3, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010C') + + +class SequenceDecoderWithExplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType( + 'blob', univ.SetOf( + componentType=univ.Any().subtype( + explicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType + ) + ) + ) + + def testDecodeOpenTypesChoiceOne(self): + s, r = decoder.decode( + ints2octs((48, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 1 + assert s[1][0] == 12 + + def testDecodeOpenTypesUnknownId(self): + s, r = decoder.decode( + ints2octs( (48, 10, 2, 1, 3, 49, 5, 131, 3, 2, 1, 12)), + asn1Spec=self.s, decodeOpenTypes=True + ) + assert not r + assert s[0] == 3 + assert s[1][0] == univ.OctetString(hexValue='02010C') + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py index 75835f2..912e32c 100644 --- a/tests/codec/der/test_encoder.py +++ b/tests/codec/der/test_encoder.py @@ -16,6 +16,7 @@ from tests.base import BaseTestCase from pyasn1.type import tag from pyasn1.type import namedtype +from pyasn1.type import opentype from pyasn1.type import univ from pyasn1.codec.der import encoder from pyasn1.compat.octets import ints2octs @@ -148,6 +149,246 @@ class SetWithTaggedChoiceEncoderTestCase(BaseTestCase): assert encoder.encode(s) == ints2octs((49, 8, 4, 1, 65, 167, 3, 1, 1, 255)) +class SequenceEncoderWithUntaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any(), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 5, 2, 1, 1, 49, 50) + ) + + def testEncodeOpenTypeChoiceTwo(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.OctetString('quick brown') + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 14, 2, 1, 2, 113, 117, 105, 99, 107, 32, + 98, 114, 111, 119, 110) + ) + + def testEncodeOpenTypeUnknownId(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.ObjectIdentifier('1.3.6') + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + def testEncodeOpenTypeIncompatibleType(self): + self.s.clear() + + self.s[0] = 2 + self.s[1] = univ.ObjectIdentifier('1.3.6') + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + +class SequenceEncoderWithImplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 9, 2, 1, 1, 131, 4, 131, 2, 49, 50) + ) + + +class SequenceEncoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1] = univ.Integer(12) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 9, 2, 1, 1, 163, 4, 163, 2, 49, 50) + ) + + +class SequenceEncoderWithUntaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any()), openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 7, 2, 1, 1, 49, 2, 49, 50) + ) + + def testEncodeOpenTypeChoiceTwo(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.OctetString('quick brown')) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 16, 2, 1, 2, 49, 11, 113, 117, 105, 99, 107, 32, 98, 114, + 111, 119, 110) + ) + + def testEncodeOpenTypeUnknownId(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.ObjectIdentifier('1.3.6')) + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + def testEncodeOpenTypeIncompatibleType(self): + self.s.clear() + + self.s[0] = 2 + self.s[1].append(univ.ObjectIdentifier('1.3.6')) + + try: + encoder.encode(self.s, asn1Spec=self.s) + + except PyAsn1Error: + assert False, 'incompatible open type tolerated' + + +class SequenceEncoderWithImplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 11, 2, 1, 1, 49, 6, 131, 4, 131, 2, 49, 50) + ) + + +class SequenceEncoderWithExplicitlyTaggedSetOfOpenTypesTestCase(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + + openType = opentype.OpenType( + 'id', + {1: univ.Integer(), + 2: univ.OctetString()} + ) + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('id', univ.Integer()), + namedtype.NamedType('blob', univ.SetOf( + componentType=univ.Any().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), + openType=openType) + ) + ) + + def testEncodeOpenTypeChoiceOne(self): + self.s.clear() + + self.s[0] = 1 + self.s[1].append(univ.Integer(12)) + + assert encoder.encode(self.s, asn1Spec=self.s) == ints2octs( + (48, 11, 2, 1, 1, 49, 6, 163, 4, 163, 2, 49, 50) + ) + + class NestedOptionalSequenceEncoderTestCase(BaseTestCase): def setUp(self): BaseTestCase.setUp(self) -- cgit v1.2.1