Merge pull request #2798 from reaperhulk/110-patch-19

opaque X509_EXTENSION
diff --git a/src/_cffi_src/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py
index b40dae8..9357815 100644
--- a/src/_cffi_src/openssl/crypto.py
+++ b/src/_cffi_src/openssl/crypto.py
@@ -40,8 +40,6 @@
 void CRYPTO_cleanup_all_ex_data(void);
 int CRYPTO_num_locks(void);
 void CRYPTO_set_locking_callback(void(*)(int, int, const char *, int));
-void CRYPTO_set_id_callback(unsigned long (*)(void));
-unsigned long (*CRYPTO_get_id_callback(void))(void);
 void (*CRYPTO_get_locking_callback(void))(int, int, const char *, int);
 void CRYPTO_lock(int, int, const char *, int);
 
@@ -57,7 +55,6 @@
 const char *OpenSSL_version(int);
 
 void CRYPTO_add(int *, int, int);
-void CRYPTO_malloc_init(void);
 """
 
 CUSTOMIZATIONS = """
diff --git a/src/_cffi_src/openssl/ecdsa.py b/src/_cffi_src/openssl/ecdsa.py
index 7cbe521..f3e9fba 100644
--- a/src/_cffi_src/openssl/ecdsa.py
+++ b/src/_cffi_src/openssl/ecdsa.py
@@ -13,10 +13,7 @@
 TYPES = """
 static const int Cryptography_HAS_ECDSA;
 
-typedef struct {
-    BIGNUM *r;
-    BIGNUM *s;
-} ECDSA_SIG;
+typedef ... ECDSA_SIG;
 
 typedef ... CRYPTO_EX_new;
 typedef ... CRYPTO_EX_dup;
diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py
index 60c6f3e..77c97fe 100644
--- a/src/_cffi_src/openssl/engine.py
+++ b/src/_cffi_src/openssl/engine.py
@@ -14,8 +14,6 @@
 typedef ... ENGINE;
 typedef ... RSA_METHOD;
 typedef ... DSA_METHOD;
-typedef ... ECDH_METHOD;
-typedef ... ECDSA_METHOD;
 typedef ... DH_METHOD;
 typedef struct {
     void (*seed)(const void *, int);
@@ -25,7 +23,6 @@
     int (*pseudorand)(unsigned char *, int);
     int (*status)();
 } RAND_METHOD;
-typedef ... STORE_METHOD;
 typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
 typedef ... *ENGINE_CTRL_FUNC_PTR;
 typedef ... *ENGINE_LOAD_KEY_PTR;
@@ -37,11 +34,8 @@
 static const unsigned int ENGINE_METHOD_RSA;
 static const unsigned int ENGINE_METHOD_DSA;
 static const unsigned int ENGINE_METHOD_RAND;
-static const unsigned int ENGINE_METHOD_ECDH;
-static const unsigned int ENGINE_METHOD_ECDSA;
 static const unsigned int ENGINE_METHOD_CIPHERS;
 static const unsigned int ENGINE_METHOD_DIGESTS;
-static const unsigned int ENGINE_METHOD_STORE;
 static const unsigned int ENGINE_METHOD_ALL;
 static const unsigned int ENGINE_METHOD_NONE;
 
@@ -58,22 +52,16 @@
 ENGINE *ENGINE_by_id(const char *);
 int ENGINE_init(ENGINE *);
 int ENGINE_finish(ENGINE *);
-void ENGINE_load_openssl(void);
-void ENGINE_load_dynamic(void);
 void ENGINE_load_builtin_engines(void);
 void ENGINE_cleanup(void);
 ENGINE *ENGINE_get_default_RSA(void);
 ENGINE *ENGINE_get_default_DSA(void);
-ENGINE *ENGINE_get_default_ECDH(void);
-ENGINE *ENGINE_get_default_ECDSA(void);
 ENGINE *ENGINE_get_default_DH(void);
 ENGINE *ENGINE_get_default_RAND(void);
 ENGINE *ENGINE_get_cipher_engine(int);
 ENGINE *ENGINE_get_digest_engine(int);
 int ENGINE_set_default_RSA(ENGINE *);
 int ENGINE_set_default_DSA(ENGINE *);
-int ENGINE_set_default_ECDH(ENGINE *);
-int ENGINE_set_default_ECDSA(ENGINE *);
 int ENGINE_set_default_DH(ENGINE *);
 int ENGINE_set_default_RAND(ENGINE *);
 int ENGINE_set_default_ciphers(ENGINE *);
@@ -88,21 +76,12 @@
 int ENGINE_register_DSA(ENGINE *);
 void ENGINE_unregister_DSA(ENGINE *);
 void ENGINE_register_all_DSA(void);
-int ENGINE_register_ECDH(ENGINE *);
-void ENGINE_unregister_ECDH(ENGINE *);
-void ENGINE_register_all_ECDH(void);
-int ENGINE_register_ECDSA(ENGINE *);
-void ENGINE_unregister_ECDSA(ENGINE *);
-void ENGINE_register_all_ECDSA(void);
 int ENGINE_register_DH(ENGINE *);
 void ENGINE_unregister_DH(ENGINE *);
 void ENGINE_register_all_DH(void);
 int ENGINE_register_RAND(ENGINE *);
 void ENGINE_unregister_RAND(ENGINE *);
 void ENGINE_register_all_RAND(void);
-int ENGINE_register_STORE(ENGINE *);
-void ENGINE_unregister_STORE(ENGINE *);
-void ENGINE_register_all_STORE(void);
 int ENGINE_register_ciphers(ENGINE *);
 void ENGINE_unregister_ciphers(ENGINE *);
 void ENGINE_register_all_ciphers(void);
@@ -123,11 +102,8 @@
 int ENGINE_set_name(ENGINE *, const char *);
 int ENGINE_set_RSA(ENGINE *, const RSA_METHOD *);
 int ENGINE_set_DSA(ENGINE *, const DSA_METHOD *);
-int ENGINE_set_ECDH(ENGINE *, const ECDH_METHOD *);
-int ENGINE_set_ECDSA(ENGINE *, const ECDSA_METHOD *);
 int ENGINE_set_DH(ENGINE *, const DH_METHOD *);
 int ENGINE_set_RAND(ENGINE *, const RAND_METHOD *);
-int ENGINE_set_STORE(ENGINE *, const STORE_METHOD *);
 int ENGINE_set_destroy_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
 int ENGINE_set_init_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
 int ENGINE_set_finish_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
@@ -142,11 +118,8 @@
 const char *ENGINE_get_name(const ENGINE *);
 const RSA_METHOD *ENGINE_get_RSA(const ENGINE *);
 const DSA_METHOD *ENGINE_get_DSA(const ENGINE *);
-const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *);
-const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *);
 const DH_METHOD *ENGINE_get_DH(const ENGINE *);
 const RAND_METHOD *ENGINE_get_RAND(const ENGINE *);
-const STORE_METHOD *ENGINE_get_STORE(const ENGINE *);
 
 const EVP_CIPHER *ENGINE_get_cipher(ENGINE *, int);
 const EVP_MD *ENGINE_get_digest(ENGINE *, int);
@@ -158,6 +131,10 @@
 """
 
 MACROS = """
+/* these became macros in 1.1.0 */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+
 void ENGINE_load_cryptodev(void);
 """
 
diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py
index 1d37b81..a91a966 100644
--- a/src/_cffi_src/openssl/evp.py
+++ b/src/_cffi_src/openssl/evp.py
@@ -10,12 +10,7 @@
 
 TYPES = """
 typedef ... EVP_CIPHER;
-typedef struct {
-    const EVP_CIPHER *cipher;
-    ENGINE *engine;
-    int encrypt;
-    ...;
-} EVP_CIPHER_CTX;
+typedef ... EVP_CIPHER_CTX;
 typedef ... EVP_MD;
 typedef struct env_md_ctx_st {
     ...;
@@ -56,7 +51,6 @@
                      const unsigned char *, int);
 int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int);
@@ -124,6 +118,9 @@
 """
 
 MACROS = """
+/* became a macro in 1.1.0 */
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
+
 void OpenSSL_add_all_algorithms(void);
 int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
 int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *);
diff --git a/src/_cffi_src/openssl/rand.py b/src/_cffi_src/openssl/rand.py
index 91e1a39..0a94d70 100644
--- a/src/_cffi_src/openssl/rand.py
+++ b/src/_cffi_src/openssl/rand.py
@@ -22,7 +22,6 @@
 int RAND_write_file(const char *);
 void RAND_cleanup(void);
 int RAND_bytes(unsigned char *, int);
-int RAND_pseudo_bytes(unsigned char *, int);
 """
 
 MACROS = """
@@ -32,7 +31,7 @@
 """
 
 CUSTOMIZATIONS = """
-#if defined(LIBRESSL_VERSION_NUMBER)
+#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000L
 static const long Cryptography_HAS_EGD = 0;
 int (*RAND_egd)(const char *) = NULL;
 int (*RAND_egd_bytes)(const char *, int) = NULL;
diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
index 98b396d..e97a1d7 100644
--- a/src/_cffi_src/openssl/ssl.py
+++ b/src/_cffi_src/openssl/ssl.py
@@ -162,9 +162,6 @@
 """
 
 FUNCTIONS = """
-void SSL_load_error_strings(void);
-int SSL_library_init(void);
-
 /*  SSL */
 const char *SSL_state_string_long(const SSL *);
 SSL_SESSION *SSL_get1_session(SSL *);
@@ -253,20 +250,25 @@
 
 size_t SSL_get_finished(const SSL *, void *, size_t);
 size_t SSL_get_peer_finished(const SSL *, void *, size_t);
-
-/* CRYPTO_EX_DATA */
-int SSL_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
-                         CRYPTO_EX_free *);
-int SSL_set_ex_data(SSL *, int, void *);
-
-int SSL_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
-                             CRYPTO_EX_free *);
-int SSL_CTX_set_ex_data(SSL_CTX *, int, void *);
-
 Cryptography_STACK_OF_X509_NAME *SSL_load_client_CA_file(const char *);
 """
 
 MACROS = """
+/* These became macros in 1.1.0 */
+int SSL_library_init(void);
+void SSL_load_error_strings(void);
+
+/* these CRYPTO_EX_DATA functions became macros in 1.1.0 */
+int SSL_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
+                         CRYPTO_EX_free *);
+int SSL_set_ex_data(SSL *, int, void *);
+int SSL_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
+                             CRYPTO_EX_free *);
+int SSL_CTX_set_ex_data(SSL_CTX *, int, void *);
+
+SSL_SESSION *SSL_get_session(const SSL *);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *, unsigned int *);
+
 /* not a macro, but older OpenSSLs don't pass the args as const */
 char *SSL_CIPHER_description(const SSL_CIPHER *, char *, int);
 int SSL_SESSION_print(BIO *, const SSL_SESSION *);
diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py
index 7b833d6..86d50bb 100644
--- a/src/_cffi_src/openssl/x509name.py
+++ b/src/_cffi_src/openssl/x509name.py
@@ -16,10 +16,7 @@
 
 TYPES = """
 typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY;
-typedef struct {
-    Cryptography_STACK_OF_X509_NAME_ENTRY *entries;
-    ...;
-} X509_NAME;
+typedef ... X509_NAME;
 typedef ... X509_NAME_ENTRY;
 typedef ... Cryptography_STACK_OF_X509_NAME;
 """
@@ -47,6 +44,10 @@
 int X509_NAME_cmp(const X509_NAME *, const X509_NAME *);
 char *X509_NAME_oneline(X509_NAME *, char *, int);
 X509_NAME *X509_NAME_dup(X509_NAME *);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **,
+                                               ASN1_OBJECT *, int,
+                                               const unsigned char *, int);
+int X509_NAME_add_entry(X509_NAME *, X509_NAME_ENTRY *, int, int);
 """
 
 MACROS = """
@@ -56,6 +57,9 @@
 X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
 void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
 int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *);
+Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_new_null(void);
+int sk_X509_NAME_ENTRY_push(Cryptography_STACK_OF_X509_NAME_ENTRY *,
+                            X509_NAME_ENTRY *);
 X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value(
     Cryptography_STACK_OF_X509_NAME_ENTRY *, int);
 Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_dup(
diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
index 8cdf4c4..b56dfa7 100644
--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
@@ -97,17 +97,8 @@
     """
     subject = backend._lib.X509_NAME_new()
     for attribute in attributes:
-        value = attribute.value.encode('utf8')
-        obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
-        if attribute.oid == NameOID.COUNTRY_NAME:
-            # Per RFC5280 Appendix A.1 countryName should be encoded as
-            # PrintableString, not UTF8String
-            type = backend._lib.MBSTRING_ASC
-        else:
-            type = backend._lib.MBSTRING_UTF8
-        res = backend._lib.X509_NAME_add_entry_by_OBJ(
-            subject, obj, type, value, -1, -1, 0,
-        )
+        name_entry = _encode_name_entry(backend, attribute)
+        res = backend._lib.X509_NAME_add_entry(subject, name_entry, -1, 0)
         backend.openssl_assert(res == 1)
     return subject
 
@@ -118,6 +109,33 @@
     return subject
 
 
+def _encode_sk_name_entry(backend, attributes):
+    """
+    The sk_X50_NAME_ENTRY created will not be gc'd.
+    """
+    stack = backend._lib.sk_X509_NAME_ENTRY_new_null()
+    for attribute in attributes:
+        name_entry = _encode_name_entry(backend, attribute)
+        res = backend._lib.sk_X509_NAME_ENTRY_push(stack, name_entry)
+        backend.openssl_assert(res == 1)
+    return stack
+
+
+def _encode_name_entry(backend, attribute):
+    value = attribute.value.encode('utf8')
+    obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
+    if attribute.oid == NameOID.COUNTRY_NAME:
+        # Per RFC5280 Appendix A.1 countryName should be encoded as
+        # PrintableString, not UTF8String
+        type = backend._lib.MBSTRING_ASC
+    else:
+        type = backend._lib.MBSTRING_UTF8
+    name_entry = backend._lib.X509_NAME_ENTRY_create_by_OBJ(
+        backend._ffi.NULL, obj, type, value, -1
+    )
+    return name_entry
+
+
 def _encode_crl_number(backend, crl_number):
     asn1int = _encode_asn1_int_gc(backend, crl_number.crl_number)
     return _encode_extension_to_der(
@@ -516,8 +534,7 @@
             dpn = backend._lib.DIST_POINT_NAME_new()
             backend.openssl_assert(dpn != backend._ffi.NULL)
             dpn.type = _DISTPOINT_TYPE_RELATIVENAME
-            name = _encode_name_gc(backend, point.relative_name)
-            relativename = backend._lib.sk_X509_NAME_ENTRY_dup(name.entries)
+            relativename = _encode_sk_name_entry(backend, point.relative_name)
             backend.openssl_assert(relativename != backend._ffi.NULL)
             dpn.name.relativename = relativename
             dp.distpoint = dpn