diff options
author | Ilya Etingof <etingof@gmail.com> | 2019-07-06 14:04:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-06 14:04:53 +0200 |
commit | b5e2eebe53736eb96f3baf5c17ae953261e09d6c (patch) | |
tree | dac2f96248bee477ef0a25a67fb34090bd1eca65 /tests/codec/ber/test_encoder.py | |
parent | ba302699d8fc791760829aa9a6b014563eedbf2c (diff) | |
download | pyasn1-b5e2eebe53736eb96f3baf5c17ae953261e09d6c.tar.gz |
Add `SET|SEQUENCE OF ANY` encoding support (#165)
For example:
AttributeTypeAndValues ::= SEQUENCE {
type OBJECT IDENTIFIER,
values SET OF ANY DEFINED BY type
}
This patch adds support of the above ASN.1 syntax to BER/DER/CER
codecs.
It appears that to implement this feature properly, `SetOf`/`SequenceOf`
pyasn1 types need to have `.componentType` wrapped into something
similar to `NamedType` that `Set`/`Sequence` have. That additional
layer would then carry the open type meta information. Without it,
`Sequence`/`Set` codec needs to signal `SetOf`/`SequenceOf` codec
of the open type being processed, which is a slight hack.
A other inconvenience is that when `SetOf`/`SequenceOf` deal with
an open type component, they should not verify types on component
assignment. Without open type property in `SetOf`/`SequenceOf`,
the code checks for `Any` component type which is another hack.
The above shortcomings should be addressed in the follow up patch.
Diffstat (limited to 'tests/codec/ber/test_encoder.py')
-rw-r--r-- | tests/codec/ber/test_encoder.py | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py index da14830..26236af 100644 --- a/tests/codec/ber/test_encoder.py +++ b/tests/codec/ber/test_encoder.py @@ -854,6 +854,130 @@ class SequenceEncoderWithExplicitlyTaggedOpenTypesTestCase(BaseTestCase): ) +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, 8, 2, 1, 1, 49, 3, 2, 1, 12) + ) + + 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, 18, 2, 1, 2, 49, 13, 4, 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, 10, 2, 1, 1, 49, 5, 131, 3, 2, 1, 12) + ) + + +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, 10, 2, 1, 1, 49, 5, 163, 3, 2, 1, 12) + ) + + class SequenceEncoderWithComponentsSchemaTestCase(BaseTestCase): def setUp(self): BaseTestCase.setUp(self) |