Beispiel #1
0
    def test_sequence_custom_builder(self):
        """Test custom builder in Decoder.read_sequence"""
        class TracingSequenceDecodingBuilder(SequenceDecodingBuilder):
            def __init__(self, *args, **kwargs):
                super(TracingSequenceDecodingBuilder,
                      self).__init__(*args, **kwargs)
                self.trace = []

            def begin_sequence(self):
                super(TracingSequenceDecodingBuilder, self).begin_sequence()
                self.trace.append('[')

            def end_sequence(self):
                super(TracingSequenceDecodingBuilder, self).end_sequence()
                self.trace.append(']')

            def handle(self, tag):
                data = super(TracingSequenceDecodingBuilder, self).handle(tag)
                self.trace.append((tag, data))
                return data

        # taken from test_sequence (see above)
        bio = BytesIO(
            # noqa: E131
            b'\x30\x80'
            # noqa: E131
            b'\x30\x0F'
            # noqa: E131
            b'\x30\x0D'
            # noqa: E131
            b'\x05\x00'
            b'\x04\x03foo'
            b'\x30\x80'
            # noqa: E131
            b'\x05\x00'
            b'\x00\x00'
            b'\x00\x00')
        dec = Decoder(bio)
        builder = TracingSequenceDecodingBuilder(dec)
        self.assertEqual([[[None, b'foo', [None]]]],
                         dec.read_sequence(builder))
        expected_trace = [
            # noqa: E131
            '[',
            # noqa: E131
            '[',
            # noqa: E131
            '[',
            # noqa: E131
            (Tag.NULL, None),
            (Tag.OCTETSTRING_PRIMITIVE, b'foo'),
            '[',
            # noqa: E131
            (Tag.NULL, None),
            ']',
            ']',
            ']',
            ']',
        ]
        self.assertEqual(expected_trace, builder.trace)
Beispiel #2
0
 def test_octetstring_constructed(self):
     """Decode an octetstring (constructed)"""
     bio = BytesIO(
         # noqa: E131
         b'\x24\x80'
         # noqa: E131
         b'\x24\x80'
         b'\x04\x0A0123456789'
         b'\x00\x00'
         b'\x24\x80'
         # noqa: E131
         b'\x04\x03foo'
         b'\x04\x06\x03\x04\x02\xEA\xAF\x4C'
         b'\x24\x80'
         # noqa: E131
         b'\x04\x05abcde'
         b'\x24\x80'
         b'\x00\x00'
         b'\x24\x80'
         b'\x00\x00'
         b'\x04\x02\x00\x00'
         b'\x00\x00'
         b'\x00\x00'
         b'\x24\x80'
         b'\x24\x80'
         b'\x00\x00'
         b'\x00\x00'
         b'\x24\x80'
         b'\x00\x00'
         b'\x00\x00')
     dec = Decoder(bio)
     self.assertEqual(b'0123456789foo\x03\x04\x02\xEA\xAF\x4Cabcde\x00\x00',
                      dec.read_octetstring())
Beispiel #3
0
 def _assert_tag(self, *tag):
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_tag(*tag)
     bio.seek(0, os.SEEK_SET)
     dec = Decoder(bio)
     actual_tag = dec.read_tag()
     self.assertEqual(tag, actual_tag)
Beispiel #4
0
 def test_boolean(self):
     """Encode and decode booleans"""
     self._assert_boolean(True)
     self._assert_boolean(False)
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_boolean(42)
     self.assertEqual(b'\x01\x01\xff', bio.getvalue())
     dec = Decoder(BytesIO(b'\x01\x01\x01'))
     self.assertTrue(dec.read_boolean())
Beispiel #5
0
 def test_printablestring(self):
     """Encode and decode printable string values"""
     self._assert_printablestring('')
     self._assert_printablestring('foo bar 1337')
     self._assert_printablestring('Aa09 \'()+,-./:=?')
     # The following examples are adopted from X.690 (see around 8.23.6)
     # primitive form
     bio = BytesIO(b'\x13\x05\x4A\x6F\x6E\x65\x73')
     dec = Decoder(bio)
     self.assertEqual('Jones', dec.read_printablestring())
     # constructor form, definite length
     bio = BytesIO(
         # noqa: E131
         b'\x33\x09'
         # noqa: E131
         b'\x04\x03\x4A\x6F\x6E'
         b'\x04\x02\x65\x73')
     dec = Decoder(bio)
     self.assertEqual('Jones', dec.read_printablestring())
     # constructor form, indefinite length
     bio = BytesIO(
         # noqa: E131
         b'\x33\x80'
         # noqa: E131
         b'\x04\x03\x4A\x6F\x6E'
         b'\x04\x02\x65\x73'
         b'\x00\x00')
     dec = Decoder(bio)
     self.assertEqual('Jones', dec.read_printablestring())
     # test encoding
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_printablestring('Fo0')
     self.assertEqual(b'\x13\x03\x46\x6F\x30', bio.getvalue())
Beispiel #6
0
 def test_utctime(self):
     """Encode and decode utctime values"""
     self._assert_utctime('920622123421Z')
     self._assert_utctime('210526000000Z')
     # invalid dates are supported (february does not have 31 days)
     self._assert_utctime('210231000000Z')
     bio = BytesIO(b'\x17\x0D001231235959Z')
     dec = Decoder(bio)
     self.assertEqual('001231235959Z', dec.read_utctime())
     # encode
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_utctime('990101000000Z')
     self.assertEqual(b'\x17\x0D990101000000Z', bio.getvalue())
Beispiel #7
0
 def test_printablestring_errors(self):
     """Try to encode/decode non-printable strings"""
     # newline '\n' is not allowed
     bio = BytesIO(b'\x13\x01\x0A')
     dec = Decoder(bio)
     with self.assertRaises(DecodingError):
         print(dec.read_printablestring().encode())
     # encode
     bio = BytesIO()
     enc = Encoder(bio)
     with self.assertRaises(ValueError):
         enc.write_printablestring('foo\0bar')
     with self.assertRaises(ValueError):
         enc.write_printablestring('foo\nbar')
Beispiel #8
0
 def test_length(self):
     """Encode and decode various lengths"""
     self._assert_length(0)
     self._assert_length(42)
     self._assert_length(127)
     self._assert_length(128)
     self._assert_length(255)
     self._assert_length(256)
     self._assert_length(1337)
     self._assert_length(0xdeadbeef)
     self._assert_length(18345736593467563457631984)
     # indefinite test
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_indefinite_length()
     self.assertEqual(b'\x80', bio.getvalue())
     dec = Decoder(BytesIO(b'\x80'))
     self.assertEqual(-1, dec.read_length())
Beispiel #9
0
 def _assert_function(self, what, data):
     bio = BytesIO()
     enc = Encoder(bio)
     enc_meth = getattr(enc, "write_{}".format(what))
     enc_meth(data)
     bio.seek(0, os.SEEK_SET)
     dec = Decoder(bio)
     dec_meth = getattr(dec, "read_{}".format(what))
     actual_data = dec_meth()
     self.assertEqual(data, actual_data)
     self._assert_empty_bio(bio)
Beispiel #10
0
 def test_utf8string(self):
     """Encode and decode utf8 string values"""
     self._assert_utf8string('')
     self._assert_utf8string('\0\n\r\n\t')
     self._assert_utf8string('foo\nbar\0baz')
     self._assert_utf8string('teSt \xFF \x00 \x61 4711')
     bio = BytesIO(b'\x0C\x05\x66\x6F\x6F\xC3\xBF')
     dec = Decoder(bio)
     self.assertEqual('foo\xff', dec.read_utf8string())
     # as above but split the encoding of 0xFF into two octets
     bio = BytesIO(
         # noqa: E131
         b'\x2C\x0D'
         # noqa: E131
         b'\x04\x01\x66'  # f
         b'\x04\x02\x6F\x6F'  # oo
         b'\x04\x01\xC3'  # first part of 0xFF's encoding
         b'\x04\x01\xBF'  # second part of 0xFF's encoding
     )
     dec = Decoder(bio)
     self.assertEqual('foo\xff', dec.read_utf8string())
     # encode
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_utf8string('foo\nbar')
     self.assertEqual(b'\x0C\x07\x66\x6F\x6F\x0A\x62\x61\x72',
                      bio.getvalue())
Beispiel #11
0
 def test_utf8string_errors(self):
     """Try to decode an invalid utf8 encoding"""
     bio = BytesIO(b'\x0C\x01\x61\x0C\x01\xFF\x0C\x01\x62\x0C\x01\x63')
     dec = Decoder(bio)
     self.assertEqual('a', dec.read_utf8string())
     with self.assertRaises(UnicodeDecodeError):
         dec.read_utf8string()
     self.assertEqual('b', dec.read_utf8string())
     self.assertEqual('c', dec.read_utf8string())
Beispiel #12
0
 def test_bitstring_no_unused_bits(self):
     """Decode a non-empty bitstring with no unused bits"""
     bio = BytesIO(b'\x03\x04\x00\x00\x00\xff')
     dec = Decoder(bio)
     raw = bytearray([0x00, 0x00, 0xFF])
     self.assertEqual(raw, dec.read_bitstring())
     bio = BytesIO(b'\x03\x04\x00\x00\x00\x00')
     dec = Decoder(bio)
     raw = bytearray([0x00, 0x00, 0x00])
     self.assertEqual(raw, dec.read_bitstring())
Beispiel #13
0
 def test_bitstring_constructed(self):
     """Decode a bitstring (constructed)"""
     # see X.690 (8.6.4.2)
     raw = bytearray([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0])
     bio = BytesIO(
         b'\x23\x80\x03\x03\x00\x0A\x3B\x03\x05\x04\x5F\x29\x1C\xD0\x00\x00'
     )
     dec = Decoder(bio)
     self.assertEqual(raw, dec.read_bitstring())
     # nested encoding
     bio = BytesIO(
         # noqa: E131
         b'\x23\x80'
         # noqa: E131
         b'\x23\x80'
         # noqa: E131
         b'\x23\x80'
         # noqa: E131
         b'\x23\x80'
         # noqa: E131
         b'\x03\x01\x00'  # empty bitstring
         b'\x03\x04\01\xAF\x00\x3E'
         b'\x03\x02\x00\xFF'
         b'\x00\x00'
         b'\x03\x03\x07\x11\x80'
         b'\x00\x00'
         b'\x23\x80'
         b'\x03\x02\x00\x0F'
         b'\x00\x00'
         b'\x00\x00'
         b'\x23\x80'
         b'\x00\x00'
         b'\x23\x80'
         b'\x03\x01\x00'  # empty bitstring
         b'\x00\x00'
         b'\x03\x04\x02\xEA\xAF\x4C'
         b'\x00\x00')
     dec = Decoder(bio)
     self.assertEqual(b'\xAF\x00\x3E\xFF\x11\x80\x0F\xEA\xAF\x4C',
                      dec.read_bitstring())
Beispiel #14
0
 def test_sequence(self):
     """Encode and decode sequence values"""
     self._assert_sequence([])
     self._assert_sequence([
         4, 5, True, b'an octet string', [],
         [b'', 42, 1337, [[], [], [[[]]]]], [4711]
     ])
     bio = BytesIO()
     enc = Encoder(bio)
     enc.write_sequence([b'foo', [], [True, [], [None, False, b'x']], None])
     self.assertEqual(
         # noqa: E131
         b'\x30\x1A'
         # noqa: E131
         b'\x04\x03foo'
         b'\x30\x00'
         b'\x30\x0F'
         # noqa: E131
         b'\x01\x01\xFF'
         b'\x30\x00'
         b'\x30\x08'
         # noqa: E131
         b'\x05\x00'
         b'\x01\x01\x00'
         b'\x04\x01x'
         b'\x05\x00',
         bio.getvalue())
     # indefinite length
     bio = BytesIO(b'\x30\x80\x04\x03foo\x30\x80\x00\x00\x05\x00\x00\x00')
     dec = Decoder(bio)
     self.assertEqual([b'foo', [], None], dec.read_sequence())
     # mix indefinite + definite lengths
     bio = BytesIO(
         # noqa: E131
         b'\x30\x80'
         # noqa: E131
         b'\x30\x0F'
         # noqa: E131
         b'\x30\x0D'
         # noqa: E131
         b'\x05\x00'
         b'\x04\x03foo'
         b'\x30\x80'
         # noqa: E131
         b'\x05\x00'
         b'\x00\x00'
         b'\x00\x00')
     dec = Decoder(bio)
     self.assertEqual([[[None, b'foo', [None]]]], dec.read_sequence())
     # "excess" end of contents is not considered
     bio = BytesIO(b'\x30\x80\x00\x00\x00\x00')
     dec = Decoder(bio)
     self.assertEqual([], dec.read_sequence())
     dec.read_end_of_contents()
Beispiel #15
0
    def test_bitstring_unused_bits_errors(self):
        """Error out on illegal unused bit values"""
        # 7 bits should be unused but the last bit is set
        bio = BytesIO(b'\x03\x06\x07\x00\x00\x01\x00\x01')
        dec = Decoder(bio)
        with self.assertRaises(DecodingError):
            dec.read_bitstring()

        # 7 bits should be unused but bit 4 (from lsb to msb) is set
        bio = BytesIO(b'\x03\x06\x07\x00\x00\x01\x00\x10')
        dec = Decoder(bio)
        with self.assertRaises(DecodingError):
            dec.read_bitstring()

        # the last 3 bits should be unset
        bio = BytesIO(b'\x03\x06\x03\x00\x00\x01\x00\x14')
        dec = Decoder(bio)
        with self.assertRaises(DecodingError):
            dec.read_bitstring()
Beispiel #16
0
 def test_bitstring_max_unused_bits(self):
     """Decode a non-empty bitstring with seven unused bits"""
     bio = BytesIO(b'\x03\x06\x07\x00\x00\x01\x00\x00')
     dec = Decoder(bio)
     raw = bytearray([0x00, 0x00, 0x01, 0x00, 0x00])
     self.assertEqual(raw, dec.read_bitstring())