[python-crypto/el5] Fix insecure ElGamal key generation (#825165, CVE-2012-2417)

Paul Howarth pghmcfc at fedoraproject.org
Fri May 25 15:00:02 UTC 2012


commit 38bbfd9677fac0845e903abd200de1119b5558ee
Author: Paul Howarth <paul at city-fan.org>
Date:   Fri May 25 14:55:03 2012 +0100

    Fix insecure ElGamal key generation (#825165, CVE-2012-2417)
    
    - Fix LP#985164: insecure ElGamal key generation (#825165, CVE-2012-2417)
    - Update URL
    - Fix shellbangs and permissions of installed files

 .gitignore                         |    3 +-
 pycrypto-2.0.1-CVE-2012-2417.patch |   90 ++++++++++++++++++++++++++++++++++++
 python-crypto.spec                 |   39 ++++++++++++----
 3 files changed, 120 insertions(+), 12 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index bc34bf7..0452e1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
-pycrypto-2.0.1.tar.gz
-/pycrypto-2.0.1-hobbled.tar.gz
+/pycrypto-[0-9.-]*.tar.gz
diff --git a/pycrypto-2.0.1-CVE-2012-2417.patch b/pycrypto-2.0.1-CVE-2012-2417.patch
new file mode 100644
index 0000000..364caa7
--- /dev/null
+++ b/pycrypto-2.0.1-CVE-2012-2417.patch
@@ -0,0 +1,90 @@
+--- PublicKey/ElGamal.py
++++ PublicKey/ElGamal.py
+@@ -25,39 +25,54 @@
+     Generate an ElGamal key of length 'bits', using 'randfunc' to get
+     random data and 'progress_func', if present, to display
+     the progress of the key generation.
++
++    The key will be safe for use for both encryption and signature
++    (although it should be used for **only one** purpose).
++
+     """
+     obj=ElGamalobj()
+-    # Generate prime p
++    # Generate a safe prime p
++    # See Algorithm 4.86 in Handbook of Applied Cryptography
+     if progress_func:
+         progress_func('p\n')
+-    obj.p=bignum(getPrime(bits, randfunc))
+-    # Generate random number g
++    while 1:
++        q = bignum(getPrime(bits-1, randfunc))
++        obj.p = 2*q+1
++        if number.isPrime(obj.p, randfunc=randfunc):
++            break
++    # Generate generator g
++    # See Algorithm 4.80 in Handbook of Applied Cryptography
++    # Note that the order of the group is n=p-1=2q, where q is prime
+     if progress_func:
+         progress_func('g\n')
+-    size=bits-1-(ord(randfunc(1)) & 63) # g will be from 1--64 bits smaller than p
+-    if size<1:
+-        size=bits-1
+-    while (1):
+-        obj.g=bignum(getPrime(size, randfunc))
+-        if obj.g < obj.p:
++    while 1:
++        # We must avoid g=2 because of Bleichenbacher's attack described
++        # in "Generating ElGamal signatures without knowning the secret key",
++        # 1996
++        #
++        obj.g = number.getRandomRange(3, obj.p, randfunc)
++        safe = 1
++        if pow(obj.g, 2, obj.p)==1:
++            safe=0
++        if safe and pow(obj.g, q, obj.p)==1:
++            safe=0
++        # Discard g if it divides p-1 because of the attack described
++        # in Note 11.67 (iii) in HAC
++        if safe and divmod(obj.p-1, obj.g)[1]==0:
++            safe=0
++        # g^{-1} must not divide p-1 because of Khadir's attack
++        # described in "Conditions of the generator for forging ElGamal
++        # signature", 2011
++        ginv = number.inverse(obj.g, obj.p)
++        if safe and divmod(obj.p-1, ginv)[1]==0:
++            safe=0
++        if safe:
+             break
+-        size=(size+1) % bits
+-        if size==0:
+-            size=4
+-    # Generate random number x
++    # Generate private key x
+     if progress_func:
+         progress_func('x\n')
+-    while (1):
+-        size=bits-1-ord(randfunc(1)) # x will be from 1 to 256 bits smaller than p
+-        if size>2:
+-            break
+-    while (1):
+-        obj.x=bignum(getPrime(size, randfunc))
+-        if obj.x < obj.p:
+-            break
+-        size = (size+1) % bits
+-        if size==0:
+-            size=4
++    obj.x=number.getRandomRange(2, obj.p-1, randfunc)
++    # Generate public key y
+     if progress_func:
+         progress_func('y\n')
+     obj.y = pow(obj.g, obj.x, obj.p)
+@@ -105,6 +120,8 @@
+         return (a, b)
+ 
+     def _verify(self, M, sig):
++        if sig[0]<1 or sig[0]>p-1:
++            return 0
+         v1=pow(self.y, sig[0], self.p)
+         v1=(v1*pow(sig[0], sig[1], self.p)) % self.p
+         v2=pow(self.g, M, self.p)
diff --git a/python-crypto.spec b/python-crypto.spec
index de3804e..a27dfe6 100644
--- a/python-crypto.spec
+++ b/python-crypto.spec
@@ -4,10 +4,10 @@
 Summary:	Cryptography library for Python
 Name:		python-crypto
 Version:	2.0.1
-Release:	4%{?dist}.2
+Release:	5%{?dist}
 License:	Public Domain
 Group:		Development/Libraries
-URL:		http://www.amk.ca/python/code/crypto.html
+URL:		http://www.pycrypto.org/
 
 # The original tarball:
 #  http://www.amk.ca/files/python/crypto/pycrypto-2.0.1.tar.gz
@@ -18,10 +18,14 @@ Source:		pycrypto-2.0.1-hobbled.tar.gz
 
 # patch taken from 
 # http://gitweb2.dlitz.net/?p=crypto/pycrypto-2.x.git;a=commitdiff;h=d1c4875e1f220652fe7ff8358f56dee3b2aba31b
-Patch0: 	%{name}-fix_buffer_overflow.patch
+Patch0:		%{name}-fix_buffer_overflow.patch
 
 # Remove references to IDEA and RC5:
-Patch1:         python-crypto-hobble.patch
+Patch1:		python-crypto-hobble.patch
+
+# Backport to pycrypto 2.0.1 of:
+# https://github.com/Legrandin/pycrypto/commit/9f912f13df99ad3421eff360d6a62d7dbec755c2
+Patch2:		pycrypto-2.0.1-CVE-2012-2417.patch
 
 BuildRequires:	python >= 2.2
 BuildRequires:	python-devel >= 2.2
@@ -38,19 +42,29 @@ SHA), and various encryption algorithms (AES, DES, RSA, ElGamal, etc.).
 
 %prep
 %setup -n pycrypto-%{version} -q
-sed -i s:/lib:/%_lib:g setup.py
+
+# C source should not be executable
+find . -name '*.c' | xargs chmod -c -x
+
+# Remove redundant shellbang
+sed -i -e '/#!\/usr\/local\/bin\/python/d' Util/RFC1751.py
+
+# Fix setup.py for lib64 if necessary
+sed -i -e 's|/lib|/%_lib|g' setup.py
+
 %patch0 -b .patch0 -p1
 %patch1 -p1
+%patch2
 
 %build
 CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build
 
-
 %install
 rm -rf $RPM_BUILD_ROOT
 %{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT
-find -name "*.py"|xargs %{__perl} -pi -e "s:/usr/local/bin/python:%{__python}:"
 
+# Remove group write permissions on shared objects
+find %{buildroot}%{python_sitearch} -name '*.so' -exec chmod -c g-w {} \;
 
 %check
 %{__python} test.py
@@ -81,15 +95,20 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri May 25 2012 Paul Howarth <paul at city-fan.org> - 2.0.1-5
+- Fix LP#985164: insecure ElGamal key generation (#825165, CVE-2012-2417)
+- Update URL
+- Fix shellbangs and permissions of installed files
+
 * Wed Sep 22 2010 David Malcolm <dmalcolm at redhat.com> - 2.0.1-4.2
 - remove IDEA and RC5 implementations
 - add %%check section
 
 * Fri Feb 13 2009 Thorsten Leemhuis <fedora[AT]leemhuis[DOT]info> - 2.0.1-4.1
 - some improvements from fedora branch
--- add patch to fix #485298 / CVE-2009-0544
--- provide pycrypto
--- drop patch0 and fix libdir handling so it works on more arches than x86_64
+  - add patch to fix #485298 / CVE-2009-0544
+  - provide pycrypto
+  - drop patch0 and fix libdir handling so it works on more arches than x86_64
 
 * Thu Sep 07 2006 Thorsten Leemhuis <fedora[AT]leemhuis.info> - 2.0.1-4
 - Don't ghost pyo files (#205408)


More information about the scm-commits mailing list