• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import pytest
8
9import six
10
11from cryptography.exceptions import AlreadyFinalized
12from cryptography.hazmat.primitives import padding
13
14
15class TestPKCS7(object):
16    @pytest.mark.parametrize("size", [127, 4096, -2])
17    def test_invalid_block_size(self, size):
18        with pytest.raises(ValueError):
19            padding.PKCS7(size)
20
21    @pytest.mark.parametrize(
22        ("size", "padded"),
23        [
24            (128, b"1111"),
25            (128, b"1111111111111111"),
26            (128, b"111111111111111\x06"),
27            (128, b""),
28            (128, b"\x06" * 6),
29            (128, b"\x00" * 16),
30        ],
31    )
32    def test_invalid_padding(self, size, padded):
33        unpadder = padding.PKCS7(size).unpadder()
34        with pytest.raises(ValueError):
35            unpadder.update(padded)
36            unpadder.finalize()
37
38    def test_non_bytes(self):
39        padder = padding.PKCS7(128).padder()
40        with pytest.raises(TypeError):
41            padder.update(u"abc")
42        unpadder = padding.PKCS7(128).unpadder()
43        with pytest.raises(TypeError):
44            unpadder.update(u"abc")
45
46    def test_zany_py2_bytes_subclass(self):
47        class mybytes(bytes):  # noqa: N801
48            def __str__(self):
49                return "broken"
50
51        str(mybytes())
52        padder = padding.PKCS7(128).padder()
53        padder.update(mybytes(b"abc"))
54        unpadder = padding.PKCS7(128).unpadder()
55        unpadder.update(mybytes(padder.finalize()))
56        assert unpadder.finalize() == b"abc"
57
58    @pytest.mark.parametrize(
59        ("size", "unpadded", "padded"),
60        [
61            (128, b"1111111111", b"1111111111\x06\x06\x06\x06\x06\x06"),
62            (
63                128,
64                b"111111111111111122222222222222",
65                b"111111111111111122222222222222\x02\x02",
66            ),
67            (128, b"1" * 16, b"1" * 16 + b"\x10" * 16),
68            (128, b"1" * 17, b"1" * 17 + b"\x0F" * 15),
69        ],
70    )
71    def test_pad(self, size, unpadded, padded):
72        padder = padding.PKCS7(size).padder()
73        result = padder.update(unpadded)
74        result += padder.finalize()
75        assert result == padded
76
77    @pytest.mark.parametrize(
78        ("size", "unpadded", "padded"),
79        [
80            (128, b"1111111111", b"1111111111\x06\x06\x06\x06\x06\x06"),
81            (
82                128,
83                b"111111111111111122222222222222",
84                b"111111111111111122222222222222\x02\x02",
85            ),
86        ],
87    )
88    def test_unpad(self, size, unpadded, padded):
89        unpadder = padding.PKCS7(size).unpadder()
90        result = unpadder.update(padded)
91        result += unpadder.finalize()
92        assert result == unpadded
93
94    def test_use_after_finalize(self):
95        padder = padding.PKCS7(128).padder()
96        b = padder.finalize()
97        with pytest.raises(AlreadyFinalized):
98            padder.update(b"")
99        with pytest.raises(AlreadyFinalized):
100            padder.finalize()
101
102        unpadder = padding.PKCS7(128).unpadder()
103        unpadder.update(b)
104        unpadder.finalize()
105        with pytest.raises(AlreadyFinalized):
106            unpadder.update(b"")
107        with pytest.raises(AlreadyFinalized):
108            unpadder.finalize()
109
110    def test_large_padding(self):
111        padder = padding.PKCS7(2040).padder()
112        padded_data = padder.update(b"")
113        padded_data += padder.finalize()
114
115        for i in six.iterbytes(padded_data):
116            assert i == 255
117
118        unpadder = padding.PKCS7(2040).unpadder()
119        data = unpadder.update(padded_data)
120        data += unpadder.finalize()
121
122        assert data == b""
123
124    def test_bytearray(self):
125        padder = padding.PKCS7(128).padder()
126        unpadded = bytearray(b"t" * 38)
127        padded = (
128            padder.update(unpadded)
129            + padder.update(unpadded)
130            + padder.finalize()
131        )
132        unpadder = padding.PKCS7(128).unpadder()
133        final = unpadder.update(padded) + unpadder.finalize()
134        assert final == unpadded + unpadded
135
136
137class TestANSIX923(object):
138    @pytest.mark.parametrize("size", [127, 4096, -2])
139    def test_invalid_block_size(self, size):
140        with pytest.raises(ValueError):
141            padding.ANSIX923(size)
142
143    @pytest.mark.parametrize(
144        ("size", "padded"),
145        [
146            (128, b"1111"),
147            (128, b"1111111111111111"),
148            (128, b"111111111111111\x06"),
149            (128, b"1111111111\x06\x06\x06\x06\x06\x06"),
150            (128, b""),
151            (128, b"\x06" * 6),
152            (128, b"\x00" * 16),
153        ],
154    )
155    def test_invalid_padding(self, size, padded):
156        unpadder = padding.ANSIX923(size).unpadder()
157        with pytest.raises(ValueError):
158            unpadder.update(padded)
159            unpadder.finalize()
160
161    def test_non_bytes(self):
162        padder = padding.ANSIX923(128).padder()
163        with pytest.raises(TypeError):
164            padder.update(u"abc")
165        unpadder = padding.ANSIX923(128).unpadder()
166        with pytest.raises(TypeError):
167            unpadder.update(u"abc")
168
169    def test_zany_py2_bytes_subclass(self):
170        class mybytes(bytes):  # noqa: N801
171            def __str__(self):
172                return "broken"
173
174        str(mybytes())
175        padder = padding.ANSIX923(128).padder()
176        padder.update(mybytes(b"abc"))
177        unpadder = padding.ANSIX923(128).unpadder()
178        unpadder.update(mybytes(padder.finalize()))
179        assert unpadder.finalize() == b"abc"
180
181    @pytest.mark.parametrize(
182        ("size", "unpadded", "padded"),
183        [
184            (128, b"1111111111", b"1111111111\x00\x00\x00\x00\x00\x06"),
185            (
186                128,
187                b"111111111111111122222222222222",
188                b"111111111111111122222222222222\x00\x02",
189            ),
190            (128, b"1" * 16, b"1" * 16 + b"\x00" * 15 + b"\x10"),
191            (128, b"1" * 17, b"1" * 17 + b"\x00" * 14 + b"\x0F"),
192        ],
193    )
194    def test_pad(self, size, unpadded, padded):
195        padder = padding.ANSIX923(size).padder()
196        result = padder.update(unpadded)
197        result += padder.finalize()
198        assert result == padded
199
200    @pytest.mark.parametrize(
201        ("size", "unpadded", "padded"),
202        [
203            (128, b"1111111111", b"1111111111\x00\x00\x00\x00\x00\x06"),
204            (
205                128,
206                b"111111111111111122222222222222",
207                b"111111111111111122222222222222\x00\x02",
208            ),
209        ],
210    )
211    def test_unpad(self, size, unpadded, padded):
212        unpadder = padding.ANSIX923(size).unpadder()
213        result = unpadder.update(padded)
214        result += unpadder.finalize()
215        assert result == unpadded
216
217    def test_use_after_finalize(self):
218        padder = padding.ANSIX923(128).padder()
219        b = padder.finalize()
220        with pytest.raises(AlreadyFinalized):
221            padder.update(b"")
222        with pytest.raises(AlreadyFinalized):
223            padder.finalize()
224
225        unpadder = padding.ANSIX923(128).unpadder()
226        unpadder.update(b)
227        unpadder.finalize()
228        with pytest.raises(AlreadyFinalized):
229            unpadder.update(b"")
230        with pytest.raises(AlreadyFinalized):
231            unpadder.finalize()
232
233    def test_bytearray(self):
234        padder = padding.ANSIX923(128).padder()
235        unpadded = bytearray(b"t" * 38)
236        padded = (
237            padder.update(unpadded)
238            + padder.update(unpadded)
239            + padder.finalize()
240        )
241        unpadder = padding.ANSIX923(128).unpadder()
242        final = unpadder.update(padded) + unpadder.finalize()
243        assert final == unpadded + unpadded
244