diff options
author | Cédric Krier <ced@b2ck.com> | 2016-02-26 18:40:20 +0100 |
---|---|---|
committer | Cédric Krier <ced@b2ck.com> | 2016-02-27 19:24:40 +0100 |
commit | bf0f464ab62d2e69ebfacd80fad2de46e862fcbc (patch) | |
tree | 84c009e637e2d93ebe293847240858a0984798d5 | |
parent | af95980e394a27355531c9aad474d39253755f81 (diff) | |
download | cryptography-bf0f464ab62d2e69ebfacd80fad2de46e862fcbc.tar.gz cryptography-bf0f464ab62d2e69ebfacd80fad2de46e862fcbc.tar.bz2 cryptography-bf0f464ab62d2e69ebfacd80fad2de46e862fcbc.zip |
Added support for padding ANSI X.923
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | docs/hazmat/primitives/padding.rst | 41 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/padding.py | 37 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_padding.py | 48 | ||||
-rw-r--r-- | tests/hypothesis/test_padding.py | 13 |
5 files changed, 136 insertions, 5 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a203a164..60d46d58 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ Changelog .. note:: This version is not yet released and is under active development. +* Added support for padding ANSI X.923 with + :class:`~cryptography.hazmat.primitives.padding.ANSIX923`. * Deprecated support for OpenSSL 0.9.8. Support will be removed in ``cryptography`` 1.4. diff --git a/docs/hazmat/primitives/padding.rst b/docs/hazmat/primitives/padding.rst index a60f5ac8..37e4252d 100644 --- a/docs/hazmat/primitives/padding.rst +++ b/docs/hazmat/primitives/padding.rst @@ -54,6 +54,47 @@ multiple of the block size. provider. +.. class:: ANSIX923(block_size) + + ANSI X.923 padding works by appending ``N-1`` bytes with the value of ``0`` + and a last byte with the value of ``chr(N)``, where ``N`` is the number of + bytes required to make the final block of data the same size as the block + size. A simple example of padding is: + + .. doctest:: + + >>> padder = padding.ANSIX923(128).padder() + >>> padded_data = padder.update(b"11111111111111112222222222") + >>> padded_data + '1111111111111111' + >>> padded_data += padder.finalize() + >>> padded_data + '11111111111111112222222222\x00\x00\x00\x00\x00\x06' + >>> unpadder = padding.ANSIX923(128).unpadder() + >>> data = unpadder.update(padded_data) + >>> data + '1111111111111111' + >>> data + unpadder.finalize() + '11111111111111112222222222' + + :param block_size: The size of the block in bits that the data is being + padded to. + :raises ValueError: Raised if block size is not a multiple of 8 or is not + between 0 and 256. + + .. method:: padder() + + :returns: A padding + :class:`~cryptography.hazmat.primitives.padding.PaddingContext` + provider + + .. method:: unpadder() + + :returns: An unpadding + :class:`~cryptography.hazmat.primitives.padding.PaddingContext` + provider. + + .. class:: PaddingContext When calling ``padder()`` or ``unpadder()`` the result will conform to the diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py index f6491eb7..72ebff2b 100644 --- a/src/cryptography/hazmat/primitives/padding.py +++ b/src/cryptography/hazmat/primitives/padding.py @@ -68,12 +68,15 @@ class _PKCS7PaddingContext(object): return result + def _padding(self, size): + return six.int2byte(size) * size + def finalize(self): if self._buffer is None: raise AlreadyFinalized("Context was already finalized.") pad_size = self.block_size // 8 - len(self._buffer) - result = self._buffer + six.int2byte(pad_size) * pad_size + result = self._buffer + self._padding(pad_size) self._buffer = None return result @@ -104,6 +107,11 @@ class _PKCS7UnpaddingContext(object): return result + def _check_padding(self): + return lib.Cryptography_check_pkcs7_padding( + self._buffer, self.block_size // 8 + ) + def finalize(self): if self._buffer is None: raise AlreadyFinalized("Context was already finalized.") @@ -111,9 +119,7 @@ class _PKCS7UnpaddingContext(object): if len(self._buffer) != self.block_size // 8: raise ValueError("Invalid padding bytes.") - valid = lib.Cryptography_check_pkcs7_padding( - self._buffer, self.block_size // 8 - ) + valid = self._check_padding() if not valid: raise ValueError("Invalid padding bytes.") @@ -122,3 +128,26 @@ class _PKCS7UnpaddingContext(object): res = self._buffer[:-pad_size] self._buffer = None return res + + +class ANSIX923(PKCS7): + + def padder(self): + return _ANSIX923PaddingContext(self.block_size) + + def unpadder(self): + return _ANSIX923UnpaddingContext(self.block_size) + + +@utils.register_interface(PaddingContext) +class _ANSIX923PaddingContext(_PKCS7PaddingContext): + + def _padding(self, size): + return six.int2byte(0) * (size - 1) + six.int2byte(size) + + +@utils.register_interface(PaddingContext) +class _ANSIX923UnpaddingContext(_PKCS7UnpaddingContext): + + def _check_padding(self): + return True diff --git a/tests/hazmat/primitives/test_padding.py b/tests/hazmat/primitives/test_padding.py index 392ea737..9da8ea7a 100644 --- a/tests/hazmat/primitives/test_padding.py +++ b/tests/hazmat/primitives/test_padding.py @@ -99,3 +99,51 @@ class TestPKCS7(object): unpadder.update(b"") with pytest.raises(AlreadyFinalized): unpadder.finalize() + + +class TestANSIX923(object): + @pytest.mark.parametrize(("size", "unpadded", "padded"), [ + ( + 128, + b"1111111111", + b"1111111111\x00\x00\x00\x00\x00\x06", + ), + ( + 128, + b"111111111111111122222222222222", + b"111111111111111122222222222222\x00\x02", + ), + ( + 128, + b"1" * 16, + b"1" * 16 + b"\x00" * 15 + b"\x10", + ), + ( + 128, + b"1" * 17, + b"1" * 17 + b"\x00" * 14 + b"\x0F", + ) + ]) + def test_pad(self, size, unpadded, padded): + padder = padding.ANSIX923(size).padder() + result = padder.update(unpadded) + result += padder.finalize() + assert result == padded + + @pytest.mark.parametrize(("size", "unpadded", "padded"), [ + ( + 128, + b"1111111111", + b"1111111111\x00\x00\x00\x00\x00\x06", + ), + ( + 128, + b"111111111111111122222222222222", + b"111111111111111122222222222222\x00\x02", + ), + ]) + def test_unpad(self, size, unpadded, padded): + unpadder = padding.ANSIX923(size).unpadder() + result = unpadder.update(padded) + result += unpadder.finalize() + assert result == unpadded diff --git a/tests/hypothesis/test_padding.py b/tests/hypothesis/test_padding.py index 21c9a234..29d726f1 100644 --- a/tests/hypothesis/test_padding.py +++ b/tests/hypothesis/test_padding.py @@ -5,7 +5,7 @@ from hypothesis import given from hypothesis.strategies import binary, integers -from cryptography.hazmat.primitives.padding import PKCS7 +from cryptography.hazmat.primitives.padding import ANSIX923, PKCS7 @given(integers(min_value=1, max_value=31), binary()) @@ -19,3 +19,14 @@ def test_pkcs7(block_size, data): padded = padder.update(data) + padder.finalize() assert unpadder.update(padded) + unpadder.finalize() == data + + +@given(integers(min_value=1, max_value=31), binary()) +def test_ansix923(block_size, data): + a = ANSIX923(block_size=block_size * 8) + padder = a.padder() + unpadder = a.unpadder() + + padded = padder.update(data) + padder.finalize() + + assert unpadder.update(padded) + unpadder.finalize() == data |