summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dev-python/rsa/files/rsa-3.2.3-CVE-2016-1494.patch')
-rw-r--r--dev-python/rsa/files/rsa-3.2.3-CVE-2016-1494.patch104
1 files changed, 104 insertions, 0 deletions
diff --git a/dev-python/rsa/files/rsa-3.2.3-CVE-2016-1494.patch b/dev-python/rsa/files/rsa-3.2.3-CVE-2016-1494.patch
new file mode 100644
index 000000000000..bfcfc33ed01b
--- /dev/null
+++ b/dev-python/rsa/files/rsa-3.2.3-CVE-2016-1494.patch
@@ -0,0 +1,104 @@
+# HG changeset patch
+# User Filippo Valsorda <hi@filippo.io>
+# Date 1450226563 0
+# Node ID 0cbcc529926afd61c6df4f50cfc29971beafd2c2
+# Parent 2baab06c8b867b01ec82b02118d4872a931a0437
+Fix BB'06 attack in verify() by switching from parsing to comparison
+
+diff --git a/rsa/pkcs1.py b/rsa/pkcs1.py
+--- a/rsa/pkcs1.py
++++ b/rsa/pkcs1.py
+@@ -22,10 +22,10 @@
+ At least 8 bytes of random padding is used when encrypting a message. This makes
+ these methods much more secure than the ones in the ``rsa`` module.
+
+-WARNING: this module leaks information when decryption or verification fails.
+-The exceptions that are raised contain the Python traceback information, which
+-can be used to deduce where in the process the failure occurred. DO NOT PASS
+-SUCH INFORMATION to your users.
++WARNING: this module leaks information when decryption fails. The exceptions
++that are raised contain the Python traceback information, which can be used to
++deduce where in the process the failure occurred. DO NOT PASS SUCH INFORMATION
++to your users.
+ '''
+
+ import hashlib
+@@ -288,37 +288,23 @@
+ :param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
+ :raise VerificationError: when the signature doesn't match the message.
+
+- .. warning::
+-
+- Never display the stack trace of a
+- :py:class:`rsa.pkcs1.VerificationError` exception. It shows where in
+- the code the exception occurred, and thus leaks information about the
+- key. It's only a tiny bit of information, but every bit makes cracking
+- the keys easier.
+-
+ '''
+
+- blocksize = common.byte_size(pub_key.n)
++ keylength = common.byte_size(pub_key.n)
+ encrypted = transform.bytes2int(signature)
+ decrypted = core.decrypt_int(encrypted, pub_key.e, pub_key.n)
+- clearsig = transform.int2bytes(decrypted, blocksize)
+-
+- # If we can't find the signature marker, verification failed.
+- if clearsig[0:2] != b('\x00\x01'):
+- raise VerificationError('Verification failed')
++ clearsig = transform.int2bytes(decrypted, keylength)
+
+- # Find the 00 separator between the padding and the payload
+- try:
+- sep_idx = clearsig.index(b('\x00'), 2)
+- except ValueError:
+- raise VerificationError('Verification failed')
+-
+- # Get the hash and the hash method
+- (method_name, signature_hash) = _find_method_hash(clearsig[sep_idx+1:])
++ # Get the hash method
++ method_name = _find_method_hash(clearsig)
+ message_hash = _hash(message, method_name)
+
+- # Compare the real hash to the hash in the signature
+- if message_hash != signature_hash:
++ # Reconstruct the expected padded hash
++ cleartext = HASH_ASN1[method_name] + message_hash
++ expected = _pad_for_signing(cleartext, keylength)
++
++ # Compare with the signed one
++ if expected != clearsig:
+ raise VerificationError('Verification failed')
+
+ return True
+@@ -351,24 +337,20 @@
+ return hasher.digest()
+
+
+-def _find_method_hash(method_hash):
+- '''Finds the hash method and the hash itself.
++def _find_method_hash(clearsig):
++ '''Finds the hash method.
+
+- :param method_hash: ASN1 code for the hash method concatenated with the
+- hash itself.
++ :param clearsig: full padded ASN1 and hash.
+
+- :return: tuple (method, hash) where ``method`` is the used hash method, and
+- ``hash`` is the hash itself.
++ :return: the used hash method.
+
+ :raise VerificationFailed: when the hash method cannot be found
+
+ '''
+
+ for (hashname, asn1code) in HASH_ASN1.items():
+- if not method_hash.startswith(asn1code):
+- continue
+-
+- return (hashname, method_hash[len(asn1code):])
++ if asn1code in clearsig:
++ return hashname
+
+ raise VerificationError('Verification failed')
+