diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e9358c9..4644c78 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,8 +5,10 @@ Python-RSA changelog Version 3.4 - in development ---------------------------------------- -- Moved development to Github. +- Moved development to Github: https://github.com/sybrenstuvel/python-rsa - Solved side-channel vulnerability by implementing blinding, fixes #19 +- Deprecated the VARBLOCK format and rsa.bigfile module due to security issues, see + https://github.com/sybrenstuvel/python-rsa/issues/13 - Fixed bugs #14, #27, #30 diff --git a/doc/reference.rst b/doc/reference.rst index 53dee63..d80416a 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -44,6 +44,12 @@ Exceptions Module: rsa.bigfile -------------------------------------------------- +.. warning:: + + The :py:mod:`rsa.bigfile` module is NOT recommended for general use, has been + deprecated since Python-RSA 3.4, and will be removed in a future release. It's + vulnerable to a number of attacks. See :ref:`bigfiles` for more information. + The :py:mod:`rsa.bigfile` module contains functions for encrypting and decrypting files that are larger than the RSA key. See :ref:`bigfiles` for more information. @@ -57,6 +63,12 @@ decrypting files that are larger than the RSA key. See The VARBLOCK file format ++++++++++++++++++++++++++++++++++++++++++++++++++ +.. warning:: + + The VARBLOCK format is NOT recommended for general use, has been deprecated since + Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a + number of attacks. See :ref:`bigfiles` for more information. + The VARBLOCK file format allows us to encrypt files that are larger than the RSA key. The format is as follows; || denotes byte string concatenation:: diff --git a/doc/usage.rst b/doc/usage.rst index 363788f..6e11a35 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -282,6 +282,24 @@ the encrypted key to the recipient. The complete flow is: Only using Python-RSA: the VARBLOCK format +++++++++++++++++++++++++++++++++++++++++++ +.. warning:: + + The VARBLOCK format is NOT recommended for general use, has been deprecated since + Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a + number of attacks: + + 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor + uses MACs to verify messages before decrypting public key encrypted messages. + + 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA) + and has no method for chaining, so block reordering is possible. + + See `issue #19 on Github`_ for more information. + +.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption +.. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 + + As far as we know, there is no pure-Python AES encryption. Previous versions of Python-RSA included functionality to encrypt large files with just RSA, and so does this version. The format has been improved, diff --git a/rsa/bigfile.py b/rsa/bigfile.py index c2c2234..8d8f210 100644 --- a/rsa/bigfile.py +++ b/rsa/bigfile.py @@ -16,6 +16,26 @@ """Large file support +.. deprecated:: 3.4 + + The VARBLOCK format is NOT recommended for general use, has been deprecated since + Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a + number of attacks: + + 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor + uses MACs to verify messages before decrypting public key encrypted messages. + + 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA) + and has no method for chaining, so block reordering is possible. + + See `issue #19 on Github`_ for more information. + +.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption +.. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 + + +This module contains functions to: + - break a file into smaller blocks, and encrypt them, and store the encrypted blocks in another file. @@ -39,6 +59,8 @@ """ +import warnings + from rsa import key, common, pkcs1, varblock from rsa._compat import byte @@ -46,12 +68,24 @@ def encrypt_bigfile(infile, outfile, pub_key): """Encrypts a file, writing it to 'outfile' in VARBLOCK format. + .. deprecated:: 3.4 + This function was deprecated in Python-RSA version 3.4 due to security issues + in the VARBLOCK format. See the documentation_ for more information. + + .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files + :param infile: file-like object to read the cleartext from :param outfile: file-like object to write the crypto in VARBLOCK format to :param pub_key: :py:class:`rsa.PublicKey` to encrypt with """ + warnings.warn("The 'rsa.bigfile.encrypt_bigfile' function was deprecated in Python-RSA version " + "3.4 due to security issues in the VARBLOCK format. See " + "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files " + "for more information.", + DeprecationWarning, stacklevel=2) + if not isinstance(pub_key, key.PublicKey): raise TypeError('Public key required, but got %r' % pub_key) @@ -72,12 +106,24 @@ def encrypt_bigfile(infile, outfile, pub_key): def decrypt_bigfile(infile, outfile, priv_key): """Decrypts an encrypted VARBLOCK file, writing it to 'outfile' + .. deprecated:: 3.4 + This function was deprecated in Python-RSA version 3.4 due to security issues + in the VARBLOCK format. See the documentation_ for more information. + + .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files + :param infile: file-like object to read the crypto in VARBLOCK format from :param outfile: file-like object to write the cleartext to :param priv_key: :py:class:`rsa.PrivateKey` to decrypt with """ + warnings.warn("The 'rsa.bigfile.decrypt_bigfile' function was deprecated in Python-RSA version " + "3.4 due to security issues in the VARBLOCK format. See " + "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files " + "for more information.", + DeprecationWarning, stacklevel=2) + if not isinstance(priv_key, key.PrivateKey): raise TypeError('Private key required, but got %r' % priv_key) diff --git a/rsa/varblock.py b/rsa/varblock.py index ba72bb5..97ab762 100644 --- a/rsa/varblock.py +++ b/rsa/varblock.py @@ -16,6 +16,24 @@ """VARBLOCK file support +.. deprecated:: 3.4 + + The VARBLOCK format is NOT recommended for general use, has been deprecated since + Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a + number of attacks: + + 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor + uses MACs to verify messages before decrypting public key encrypted messages. + + 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA) + and has no method for chaining, so block reordering is possible. + + See `issue #19 on Github`_ for more information. + +.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption +.. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 + + The VARBLOCK file format is as follows, where || denotes byte concatenation: FILE := VERSION || BLOCK || BLOCK ... @@ -33,11 +51,18 @@ """ +import warnings + from rsa._compat import byte, b ZERO_BYTE = b('\x00') VARBLOCK_VERSION = 1 +warnings.warn("The 'rsa.varblock' module was deprecated in Python-RSA version " + "3.4 due to security issues in the VARBLOCK format. See " + "https://github.com/sybrenstuvel/python-rsa/issues/13 for more information.", + DeprecationWarning) + def read_varint(infile): """Reads a varint from the file.