Repository: pyca/cryptography

Issue:
Uh-oh, master is broken on Fedora 20
`tox` output.

```
[ayrx@c00kies cryptography]$ tox
GLOB sdist-make: /run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/setup.py
ERROR: invocation failed, logfile: /run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/.tox/log/tox-0.log
ERROR: actionid=tox
msg=packaging
cmdargs=['/usr/bin/python', local('/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/setup.py'), 'sdist', '--formats=zip', '--dist-dir', local('/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/.tox/dist')]
env=None
running sdist
running egg_info
writing requirements to cryptography.egg-info/requires.txt
writing cryptography.egg-info/PKG-INFO
writing top-level names to cryptography.egg-info/top_level.txt
writing dependency_links to cryptography.egg-info/dependency_links.txt
Traceback (most recent call last):
  File "setup.py", line 173, in <module>
    "test": PyTest,
  File "/usr/lib64/python2.7/distutils/core.py", line 152, in setup
    dist.run_commands()
  File "/usr/lib64/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/usr/lib64/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.7/site-packages/setuptools/command/sdist.py", line 86, in run
    self.run_command('egg_info')
  File "/usr/lib64/python2.7/distutils/cmd.py", line 326, in run_command
    self.distribution.run_command(command)
  File "/usr/lib64/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "/usr/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 187, in run
    self.find_sources()
  File "/usr/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 230, in find_sources
    mm.run()
  File "/usr/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 296, in run
    self.add_defaults()
  File "/usr/lib/python2.7/site-packages/setuptools/command/egg_info.py", line 332, in add_defaults
    sdist.add_defaults(self)
  File "/usr/lib/python2.7/site-packages/setuptools/command/sdist.py", line 161, in add_defaults
    build_py = self.get_finalized_command('build_py')
  File "/usr/lib64/python2.7/distutils/cmd.py", line 312, in get_finalized_command
    cmd_obj.ensure_finalized()
  File "/usr/lib64/python2.7/distutils/cmd.py", line 109, in ensure_finalized
    self.finalize_options()
  File "/usr/lib/python2.7/site-packages/setuptools/command/build_py.py", line 73, in finalize_options
    _build_py.finalize_options(self)
  File "/usr/lib64/python2.7/distutils/command/build_py.py", line 46, in finalize_options
    ('force', 'force'))
  File "/usr/lib64/python2.7/distutils/cmd.py", line 298, in set_undefined_options
    src_cmd_obj.ensure_finalized()
  File "/usr/lib64/python2.7/distutils/cmd.py", line 109, in ensure_finalized
    self.finalize_options()
  File "setup.py", line 87, in finalize_options
    self.distribution.ext_modules = get_ext_modules()
  File "setup.py", line 67, in get_ext_modules
    OpenSSLBinding().ffi.verifier.get_extension(),
  File "/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/cryptography/hazmat/bindings/openssl/binding.py", line 84, in __init__
    self._ensure_ffi_initialized()
  File "/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/cryptography/hazmat/bindings/openssl/binding.py", line 100, in _ensure_ffi_initialized
    libraries)
  File "/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/cryptography/hazmat/bindings/utils.py", line 77, in build_ffi
    ext_package="cryptography",
  File "/usr/lib/python2.7/site-packages/cffi-0.8.1-py2.7-linux-x86_64.egg/cffi/api.py", line 339, in verify
    lib = self.verifier.load_library()
  File "/usr/lib/python2.7/site-packages/cffi-0.8.1-py2.7-linux-x86_64.egg/cffi/verifier.py", line 75, in load_library
    return self._load_library()
  File "/usr/lib/python2.7/site-packages/cffi-0.8.1-py2.7-linux-x86_64.egg/cffi/verifier.py", line 151, in _load_library
    return self._vengine.load_library()
  File "/usr/lib/python2.7/site-packages/cffi-0.8.1-py2.7-linux-x86_64.egg/cffi/vengine_cpy.py", line 138, in load_library
    raise ffiplatform.VerificationError(error)
cffi.ffiplatform.VerificationError: importing '/run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/cryptography/hazmat/bindings/__pycache__/_Cryptography_cffi_ca252f7dxca868440.so': /run/media/ayrx/FE4E6F994E6F498B/Codes/cryptography/cryptography/hazmat/bindings/__pycache__/_Cryptography_cffi_ca252f7dxca868440.so: undefined symbol: EC_GROUP_new_curve_GF2m

ERROR: FAIL could not package project
```

Some other stuff @public asked for.

```
[ayrx@c00kies cryptography]$ grep OPENSSL_NO_ /usr/include/openssl/*conf*.h
/usr/include/openssl/conf.h:#ifndef OPENSSL_NO_FP_API
/usr/include/openssl/conf.h:#ifndef OPENSSL_NO_FP_API
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_EC2M
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_EC2M
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_EC_NISTP_64_GCC_128
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_GMP
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_GMP
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_GOST
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_GOST
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_JPAKE
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_JPAKE
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_MDC2
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_MDC2
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_RC5
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_RC5
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_RSAX
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_RSAX
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_SCTP
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_SCTP
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_SRP
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_SRP
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_STORE
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_STORE
/usr/include/openssl/opensslconf-x86_64.h:#ifndef OPENSSL_NO_STATIC_ENGINE
/usr/include/openssl/opensslconf-x86_64.h:# define OPENSSL_NO_STATIC_ENGINE
/usr/include/openssl/opensslconf-x86_64.h:/* The OPENSSL_NO_* macros are also defined as NO_* if the application
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_EC2M) && !defined(NO_EC2M)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_SRP) && !defined(NO_SRP)
/usr/include/openssl/opensslconf-x86_64.h:# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
```

```
[ayrx@c00kies cryptography]$ grep OPENSSL_VER /usr/include/openssl/opensslv.h
#define OPENSSL_VERSION_NUMBER  0x1000105fL
#define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1e-fips 11 Feb 2013"
#define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1e 11 Feb 2013"
#define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
```



Discussion:
I think this is because they have patched out EC entirely without bothering to set the OPENSSL_NO_EC define, but they did set some of the other ones. Very weird. Since this is 1.0.1 I guess we need some sort of specific RHEL detection `ifdef` rather than relying on their ancient OPENSSL_VERSION_NUMBER values like we did before?

It appears as though Fedora 20 only patches out _some_ of the EC stuff. Here is a dump of the `ec.h` file.

https://gist.github.com/Ayrx/9c81f389b1b40e96cdc9

Hmm nope, this is my bug :) I need to move some of the `*GF2m` methods in to the OPENSSL_NO_EC2M block.


Resolving patch:
diff --git a/cryptography/hazmat/bindings/openssl/ec.py b/cryptography/hazmat/bindings/openssl/ec.py
--- a/cryptography/hazmat/bindings/openssl/ec.py
+++ b/cryptography/hazmat/bindings/openssl/ec.py
@@ -240,9 +240,6 @@
 EC_GROUP *(*EC_GROUP_new_curve_GFp)(
     const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
 
-EC_GROUP *(*EC_GROUP_new_curve_GF2m)(
-    const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
-
 EC_GROUP *(*EC_GROUP_new_by_curve_name)(int);
 
 int (*EC_GROUP_set_curve_GFp)(
@@ -251,12 +248,6 @@
 int (*EC_GROUP_get_curve_GFp)(
     const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
 
-int (*EC_GROUP_set_curve_GF2m)(
-    EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
-
-int (*EC_GROUP_get_curve_GF2m)(
-    const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
-
 const EC_METHOD *(*EC_GROUP_method_of)(const EC_GROUP *) = NULL;
 const EC_POINT *(*EC_GROUP_get0_generator)(const EC_GROUP *) = NULL;
 int (*EC_GROUP_get_curve_name)(const EC_GROUP *) = NULL;
@@ -283,15 +274,6 @@
 int (*EC_POINT_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
     const BIGNUM *, int, BN_CTX *) = NULL;
 
-int (*EC_POINT_set_affine_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
-    const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
-
-int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *,
-    const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL;
-
-int (*EC_POINT_set_compressed_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
-    const BIGNUM *, int, BN_CTX *) = NULL;
-
 size_t (*EC_POINT_point2oct)(const EC_GROUP *, const EC_POINT *,
     point_conversion_form_t,
     unsigned char *, size_t, BN_CTX *) = NULL;
@@ -380,6 +362,24 @@
 static const long Cryptography_HAS_EC2M = 0;
 
 const EC_METHOD *(*EC_GF2m_simple_method)() = NULL;
+
+int (*EC_POINT_set_affine_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
+    const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
+
+int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *,
+    const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL;
+
+int (*EC_POINT_set_compressed_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
+    const BIGNUM *, int, BN_CTX *) = NULL;
+
+int (*EC_GROUP_set_curve_GF2m)(
+    EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+
+int (*EC_GROUP_get_curve_GF2m)(
+    const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
+
+EC_GROUP *(*EC_GROUP_new_curve_GF2m)(
+    const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
 #else
 static const long Cryptography_HAS_EC2M = 1;
 #endif
@@ -391,12 +391,9 @@
         "EC_GROUP_free",
         "EC_GROUP_clear_free",
         "EC_GROUP_new_curve_GFp",
-        "EC_GROUP_new_curve_GF2m",
         "EC_GROUP_new_by_curve_name",
         "EC_GROUP_set_curve_GFp",
         "EC_GROUP_get_curve_GFp",
-        "EC_GROUP_set_curve_GF2m",
-        "EC_GROUP_get_curve_GF2m",
         "EC_GROUP_method_of",
         "EC_GROUP_get0_generator",
         "EC_GROUP_get_curve_name",
@@ -431,9 +428,6 @@
         "EC_POINT_set_affine_coordinates_GFp",
         "EC_POINT_get_affine_coordinates_GFp",
         "EC_POINT_set_compressed_coordinates_GFp",
-        "EC_POINT_set_affine_coordinates_GF2m",
-        "EC_POINT_get_affine_coordinates_GF2m",
-        "EC_POINT_set_compressed_coordinates_GF2m",
         "EC_POINT_point2oct",
         "EC_POINT_oct2point",
         "EC_POINT_point2bn",
@@ -473,5 +467,11 @@
 
     "Cryptography_HAS_EC2M": [
         "EC_GF2m_simple_method",
+        "EC_POINT_set_affine_coordinates_GF2m",
+        "EC_POINT_get_affine_coordinates_GF2m",
+        "EC_POINT_set_compressed_coordinates_GF2m",
+        "EC_GROUP_set_curve_GF2m",
+        "EC_GROUP_get_curve_GF2m",
+        "EC_GROUP_new_curve_GF2m",
     ],
 }


Test patch: