aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography/hazmat/backends
diff options
context:
space:
mode:
Diffstat (limited to 'cryptography/hazmat/backends')
-rw-r--r--cryptography/hazmat/backends/interfaces.py7
-rw-r--r--cryptography/hazmat/backends/openssl/asn1.py6
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py75
-rw-r--r--cryptography/hazmat/backends/openssl/bignum.py2
-rw-r--r--cryptography/hazmat/backends/openssl/bio.py2
-rw-r--r--cryptography/hazmat/backends/openssl/conf.py2
-rw-r--r--cryptography/hazmat/backends/openssl/crypto.py10
-rw-r--r--cryptography/hazmat/backends/openssl/dh.py2
-rw-r--r--cryptography/hazmat/backends/openssl/dsa.py2
-rw-r--r--cryptography/hazmat/backends/openssl/engine.py2
-rw-r--r--cryptography/hazmat/backends/openssl/err.py2
-rw-r--r--cryptography/hazmat/backends/openssl/evp.py27
-rw-r--r--cryptography/hazmat/backends/openssl/hmac.py2
-rw-r--r--cryptography/hazmat/backends/openssl/nid.py2
-rw-r--r--cryptography/hazmat/backends/openssl/opensslv.py3
-rw-r--r--cryptography/hazmat/backends/openssl/pem.py2
-rw-r--r--cryptography/hazmat/backends/openssl/pkcs12.py2
-rw-r--r--cryptography/hazmat/backends/openssl/pkcs7.py2
-rw-r--r--cryptography/hazmat/backends/openssl/rand.py3
-rw-r--r--cryptography/hazmat/backends/openssl/rsa.py2
-rw-r--r--cryptography/hazmat/backends/openssl/ssl.py101
-rw-r--r--cryptography/hazmat/backends/openssl/x509.py2
-rw-r--r--cryptography/hazmat/backends/openssl/x509name.py2
-rw-r--r--cryptography/hazmat/backends/openssl/x509v3.py2
24 files changed, 237 insertions, 27 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index 912476bb..9a570968 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -60,6 +60,13 @@ class HashBackend(six.with_metaclass(abc.ABCMeta)):
class HMACBackend(six.with_metaclass(abc.ABCMeta)):
@abc.abstractmethod
+ def hmac_supported(self, algorithm):
+ """
+ Return True if the hash algorithm is supported for HMAC by this
+ backend.
+ """
+
+ @abc.abstractmethod
def create_hmac_ctx(self, key, algorithm):
"""
Create a HashContext for calculating a message authentication code.
diff --git a/cryptography/hazmat/backends/openssl/asn1.py b/cryptography/hazmat/backends/openssl/asn1.py
index 719a523c..b56932fa 100644
--- a/cryptography/hazmat/backends/openssl/asn1.py
+++ b/cryptography/hazmat/backends/openssl/asn1.py
@@ -41,7 +41,7 @@ typedef ... ASN1_VALUE;
typedef struct {
...;
} ASN1_TIME;
-typedef const ASN1_ITEM ASN1_ITEM_EXP;
+typedef ... ASN1_ITEM_EXP;
typedef ... ASN1_UTCTIME;
@@ -102,7 +102,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long,
MACROS = """
ASN1_TIME *M_ASN1_TIME_dup(void *);
-ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM *);
+ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *);
/* These aren't macros these arguments are all const X on openssl > 1.0.x */
@@ -122,3 +122,5 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index bd092bec..7b67fb0b 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -56,7 +56,22 @@ _OSX_POST_INCLUDE = """
class Backend(object):
"""
OpenSSL API wrapper.
+
+ Modules listed in the ``_modules`` listed should have the following
+ attributes:
+
+ * ``INCLUDES``: A string containg C includes.
+ * ``TYPES``: A string containing C declarations for types.
+ * ``FUNCTIONS``: A string containing C declarations for functions.
+ * ``MACROS``: A string containing C declarations for any macros.
+ * ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this
+ can be used to do things like test for a define and provide an
+ alternate implementation based on that.
+ * ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the
+ library to a list of names which will not be present without the
+ condition.
"""
+ _module_prefix = "cryptography.hazmat.backends.openssl."
_modules = [
"asn1",
"bignum",
@@ -102,7 +117,7 @@ class Backend(object):
macros = []
customizations = []
for name in cls._modules:
- module_name = "cryptography.hazmat.backends.openssl." + name
+ module_name = cls._module_prefix + name
__import__(module_name)
module = sys.modules[module_name]
@@ -141,6 +156,14 @@ class Backend(object):
libraries=["crypto", "ssl"],
)
+ for name in cls._modules:
+ module_name = cls._module_prefix + name
+ module = sys.modules[module_name]
+ for condition, names in module.CONDITIONAL_NAMES.items():
+ if not getattr(lib, condition):
+ for name in names:
+ delattr(lib, name)
+
cls.ffi = ffi
cls.lib = lib
cls.lib.OpenSSL_add_all_algorithms()
@@ -161,6 +184,9 @@ class Backend(object):
digest = self.lib.EVP_get_digestbyname(algorithm.name.encode("ascii"))
return digest != self.ffi.NULL
+ def hmac_supported(self, algorithm):
+ return self.hash_supported(algorithm)
+
def create_hash_ctx(self, algorithm):
return _HashContext(self, algorithm)
@@ -276,6 +302,11 @@ class _CipherContext(object):
self._operation = operation
self._tag = None
+ if isinstance(self._cipher, interfaces.BlockCipherAlgorithm):
+ self._block_size = self._cipher.block_size
+ else:
+ self._block_size = 1
+
ctx = self._backend.lib.EVP_CIPHER_CTX_new()
ctx = self._backend.ffi.gc(ctx, self._backend.lib.EVP_CIPHER_CTX_free)
@@ -283,11 +314,19 @@ class _CipherContext(object):
try:
adapter = registry[type(cipher), type(mode)]
except KeyError:
- raise UnsupportedAlgorithm
+ raise UnsupportedAlgorithm(
+ "cipher {0} in {1} mode is not supported "
+ "by this backend".format(
+ cipher.name, mode.name if mode else mode)
+ )
evp_cipher = adapter(self._backend, cipher, mode)
if evp_cipher == self._backend.ffi.NULL:
- raise UnsupportedAlgorithm
+ raise UnsupportedAlgorithm(
+ "cipher {0} in {1} mode is not supported "
+ "by this backend".format(
+ cipher.name, mode.name if mode else mode)
+ )
if isinstance(mode, interfaces.ModeWithInitializationVector):
iv_nonce = mode.initialization_vector
@@ -309,16 +348,16 @@ class _CipherContext(object):
assert res != 0
if isinstance(mode, GCM):
res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
- ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_IVLEN,
+ ctx, self._backend.lib.EVP_CTRL_GCM_SET_IVLEN,
len(iv_nonce), self._backend.ffi.NULL
)
assert res != 0
if operation == self._DECRYPT:
- if not mode.tag:
- raise ValueError("Authentication tag must be supplied "
- "when decrypting")
+ if not mode.tag or len(mode.tag) < 4:
+ raise ValueError("Authentication tag must be provided and "
+ "be 4 bytes or longer when decrypting")
res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
- ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG,
+ ctx, self._backend.lib.EVP_CTRL_GCM_SET_TAG,
len(mode.tag), mode.tag
)
assert res != 0
@@ -341,7 +380,7 @@ class _CipherContext(object):
def update(self, data):
buf = self._backend.ffi.new("unsigned char[]",
- len(data) + self._cipher.block_size - 1)
+ len(data) + self._block_size - 1)
outlen = self._backend.ffi.new("int *")
res = self._backend.lib.EVP_CipherUpdate(self._ctx, buf, outlen, data,
len(data))
@@ -349,7 +388,7 @@ class _CipherContext(object):
return self._backend.ffi.buffer(buf)[:outlen[0]]
def finalize(self):
- buf = self._backend.ffi.new("unsigned char[]", self._cipher.block_size)
+ buf = self._backend.ffi.new("unsigned char[]", self._block_size)
outlen = self._backend.ffi.new("int *")
res = self._backend.lib.EVP_CipherFinal_ex(self._ctx, buf, outlen)
if res == 0:
@@ -357,10 +396,10 @@ class _CipherContext(object):
if (isinstance(self._mode, GCM) and
self._operation == self._ENCRYPT):
- block_byte_size = self._cipher.block_size // 8
+ block_byte_size = self._block_size // 8
tag_buf = self._backend.ffi.new("unsigned char[]", block_byte_size)
res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
- self._ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_GET_TAG,
+ self._ctx, self._backend.lib.EVP_CTRL_GCM_GET_TAG,
block_byte_size, tag_buf
)
assert res != 0
@@ -395,7 +434,11 @@ class _HashContext(object):
self._backend.lib.EVP_MD_CTX_destroy)
evp_md = self._backend.lib.EVP_get_digestbyname(
algorithm.name.encode("ascii"))
- assert evp_md != self._backend.ffi.NULL
+ if evp_md == self._backend.ffi.NULL:
+ raise UnsupportedAlgorithm(
+ "{0} is not a supported hash on this backend".format(
+ algorithm.name)
+ )
res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md,
self._backend.ffi.NULL)
assert res != 0
@@ -437,7 +480,11 @@ class _HMACContext(object):
ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup)
evp_md = self._backend.lib.EVP_get_digestbyname(
algorithm.name.encode('ascii'))
- assert evp_md != self._backend.ffi.NULL
+ if evp_md == self._backend.ffi.NULL:
+ raise UnsupportedAlgorithm(
+ "{0} is not a supported hash on this backend".format(
+ algorithm.name)
+ )
res = self._backend.lib.Cryptography_HMAC_Init_ex(
ctx, key, len(key), evp_md, self._backend.ffi.NULL
)
diff --git a/cryptography/hazmat/backends/openssl/bignum.py b/cryptography/hazmat/backends/openssl/bignum.py
index 1b0fe5ab..68d0c3a2 100644
--- a/cryptography/hazmat/backends/openssl/bignum.py
+++ b/cryptography/hazmat/backends/openssl/bignum.py
@@ -38,3 +38,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/bio.py b/cryptography/hazmat/backends/openssl/bio.py
index c23dd0d8..d164804f 100644
--- a/cryptography/hazmat/backends/openssl/bio.py
+++ b/cryptography/hazmat/backends/openssl/bio.py
@@ -171,3 +171,5 @@ long BIO_set_buffer_read_data(BIO *, void *, long);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/conf.py b/cryptography/hazmat/backends/openssl/conf.py
index 4846252c..6d818cf1 100644
--- a/cryptography/hazmat/backends/openssl/conf.py
+++ b/cryptography/hazmat/backends/openssl/conf.py
@@ -27,3 +27,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py
index 773d9b14..71d32c52 100644
--- a/cryptography/hazmat/backends/openssl/crypto.py
+++ b/cryptography/hazmat/backends/openssl/crypto.py
@@ -16,6 +16,11 @@ INCLUDES = """
"""
TYPES = """
+static const int SSLEAY_VERSION;
+static const int SSLEAY_CFLAGS;
+static const int SSLEAY_PLATFORM;
+static const int SSLEAY_DIR;
+static const int SSLEAY_BUILT_ON;
"""
FUNCTIONS = """
@@ -24,12 +29,15 @@ int CRYPTO_mem_ctrl(int);
int CRYPTO_is_mem_check_on();
void CRYPTO_mem_leaks(struct bio_st *);
void CRYPTO_cleanup_all_ex_data();
+
+void OPENSSL_free(void *);
"""
MACROS = """
void CRYPTO_add(int *, int, int);
void CRYPTO_malloc_init();
void CRYPTO_malloc_debug_init();
+
#define CRYPTO_MEM_CHECK_ON ...
#define CRYPTO_MEM_CHECK_OFF ...
#define CRYPTO_MEM_CHECK_ENABLE ...
@@ -38,3 +46,5 @@ void CRYPTO_malloc_debug_init();
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/dh.py b/cryptography/hazmat/backends/openssl/dh.py
index b8fbf368..56fa8b46 100644
--- a/cryptography/hazmat/backends/openssl/dh.py
+++ b/cryptography/hazmat/backends/openssl/dh.py
@@ -29,3 +29,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/dsa.py b/cryptography/hazmat/backends/openssl/dsa.py
index e6c369a6..3b77d7ae 100644
--- a/cryptography/hazmat/backends/openssl/dsa.py
+++ b/cryptography/hazmat/backends/openssl/dsa.py
@@ -31,3 +31,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/engine.py b/cryptography/hazmat/backends/openssl/engine.py
index 1f377665..cc214f84 100644
--- a/cryptography/hazmat/backends/openssl/engine.py
+++ b/cryptography/hazmat/backends/openssl/engine.py
@@ -63,3 +63,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/err.py b/cryptography/hazmat/backends/openssl/err.py
index f31c2405..2fb8bbe1 100644
--- a/cryptography/hazmat/backends/openssl/err.py
+++ b/cryptography/hazmat/backends/openssl/err.py
@@ -74,3 +74,5 @@ int ERR_FATAL_ERROR(unsigned long);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py
index 8cb44610..8cf96b2d 100644
--- a/cryptography/hazmat/backends/openssl/evp.py
+++ b/cryptography/hazmat/backends/openssl/evp.py
@@ -32,9 +32,11 @@ typedef struct evp_pkey_st {
} EVP_PKEY;
static const int EVP_PKEY_RSA;
static const int EVP_PKEY_DSA;
-static const int Cryptography_EVP_CTRL_GCM_SET_IVLEN;
-static const int Cryptography_EVP_CTRL_GCM_GET_TAG;
-static const int Cryptography_EVP_CTRL_GCM_SET_TAG;
+static const int EVP_CTRL_GCM_SET_IVLEN;
+static const int EVP_CTRL_GCM_GET_TAG;
+static const int EVP_CTRL_GCM_SET_TAG;
+
+static const int Cryptography_HAS_GCM;
"""
FUNCTIONS = """
@@ -101,12 +103,19 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *);
CUSTOMIZATIONS = """
#ifdef EVP_CTRL_GCM_SET_TAG
-const int Cryptography_EVP_CTRL_GCM_GET_TAG = EVP_CTRL_GCM_GET_TAG;
-const int Cryptography_EVP_CTRL_GCM_SET_TAG = EVP_CTRL_GCM_SET_TAG;
-const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = EVP_CTRL_GCM_SET_IVLEN;
+const int Cryptography_HAS_GCM = 1;
#else
-const int Cryptography_EVP_CTRL_GCM_GET_TAG = -1;
-const int Cryptography_EVP_CTRL_GCM_SET_TAG = -1;
-const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = -1;
+const int Cryptography_HAS_GCM = 0;
+const int EVP_CTRL_GCM_GET_TAG = -1;
+const int EVP_CTRL_GCM_SET_TAG = -1;
+const int EVP_CTRL_GCM_SET_IVLEN = -1;
#endif
"""
+
+CONDITIONAL_NAMES = {
+ "Cryptography_HAS_GCM": [
+ "EVP_CTRL_GCM_GET_TAG",
+ "EVP_CTRL_GCM_SET_TAG",
+ "EVP_CTRL_GCM_SET_IVLEN",
+ ]
+}
diff --git a/cryptography/hazmat/backends/openssl/hmac.py b/cryptography/hazmat/backends/openssl/hmac.py
index 10e67141..5f9e0945 100644
--- a/cryptography/hazmat/backends/openssl/hmac.py
+++ b/cryptography/hazmat/backends/openssl/hmac.py
@@ -88,3 +88,5 @@ int Cryptography_HMAC_CTX_copy(HMAC_CTX *dst_ctx, HMAC_CTX *src_ctx) {
#endif
}
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/nid.py b/cryptography/hazmat/backends/openssl/nid.py
index 9816dde4..111f82f9 100644
--- a/cryptography/hazmat/backends/openssl/nid.py
+++ b/cryptography/hazmat/backends/openssl/nid.py
@@ -47,3 +47,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/opensslv.py b/cryptography/hazmat/backends/openssl/opensslv.py
index d463776c..4e110327 100644
--- a/cryptography/hazmat/backends/openssl/opensslv.py
+++ b/cryptography/hazmat/backends/openssl/opensslv.py
@@ -16,6 +16,7 @@ INCLUDES = """
"""
TYPES = """
+static const int OPENSSL_VERSION_NUMBER;
static char *const OPENSSL_VERSION_TEXT;
"""
@@ -27,3 +28,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/pem.py b/cryptography/hazmat/backends/openssl/pem.py
index cef7839f..ee5552c5 100644
--- a/cryptography/hazmat/backends/openssl/pem.py
+++ b/cryptography/hazmat/backends/openssl/pem.py
@@ -55,3 +55,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/pkcs12.py b/cryptography/hazmat/backends/openssl/pkcs12.py
index d91d100f..b3ecd0aa 100644
--- a/cryptography/hazmat/backends/openssl/pkcs12.py
+++ b/cryptography/hazmat/backends/openssl/pkcs12.py
@@ -35,3 +35,5 @@ PKCS12 *PKCS12_create(char *, char *, EVP_PKEY *, X509 *,
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/pkcs7.py b/cryptography/hazmat/backends/openssl/pkcs7.py
index 60ea3c52..43f9540b 100644
--- a/cryptography/hazmat/backends/openssl/pkcs7.py
+++ b/cryptography/hazmat/backends/openssl/pkcs7.py
@@ -35,3 +35,5 @@ int PKCS7_type_is_data(PKCS7 *);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/rand.py b/cryptography/hazmat/backends/openssl/rand.py
index 848ee05a..5ac36cac 100644
--- a/cryptography/hazmat/backends/openssl/rand.py
+++ b/cryptography/hazmat/backends/openssl/rand.py
@@ -19,6 +19,7 @@ TYPES = """
"""
FUNCTIONS = """
+void ERR_load_RAND_strings();
void RAND_seed(const void *, int);
void RAND_add(const void *, int, double);
int RAND_status();
@@ -38,3 +39,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/rsa.py b/cryptography/hazmat/backends/openssl/rsa.py
index ad0d37b4..e3a24d0f 100644
--- a/cryptography/hazmat/backends/openssl/rsa.py
+++ b/cryptography/hazmat/backends/openssl/rsa.py
@@ -57,3 +57,5 @@ MACROS = """
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py
index 04611309..3fd0bf23 100644
--- a/cryptography/hazmat/backends/openssl/ssl.py
+++ b/cryptography/hazmat/backends/openssl/ssl.py
@@ -16,6 +16,22 @@ INCLUDES = """
"""
TYPES = """
+/* Internally invented symbol to tell us if SSLv2 is supported */
+static const int Cryptography_HAS_SSL2;
+
+/* Internally invented symbol to tell us if SNI is supported */
+static const int Cryptography_HAS_TLSEXT_HOSTNAME;
+
+/* Internally invented symbol to tell us if SSL_MODE_RELEASE_BUFFERS is
+ * supported
+ */
+static const int Cryptography_HAS_RELEASE_BUFFERS;
+
+/* Internally invented symbol to tell us if SSL_OP_NO_COMPRESSION is
+ * supported
+ */
+static const int Cryptography_HAS_OP_NO_COMPRESSION;
+
static const int SSL_FILETYPE_PEM;
static const int SSL_FILETYPE_ASN1;
static const int SSL_ERROR_NONE;
@@ -30,6 +46,7 @@ static const int SSL_RECEIVED_SHUTDOWN;
static const int SSL_OP_NO_SSLv2;
static const int SSL_OP_NO_SSLv3;
static const int SSL_OP_NO_TLSv1;
+static const int SSL_OP_NO_COMPRESSION;
static const int SSL_OP_SINGLE_DH_USE;
static const int SSL_OP_EPHEMERAL_RSA;
static const int SSL_OP_MICROSOFT_SESS_ID_BUG;
@@ -84,6 +101,7 @@ static const int SSL_CB_CONNECT_LOOP;
static const int SSL_CB_CONNECT_EXIT;
static const int SSL_CB_HANDSHAKE_START;
static const int SSL_CB_HANDSHAKE_DONE;
+static const int SSL_MODE_RELEASE_BUFFERS;
static const int SSL_MODE_ENABLE_PARTIAL_WRITE;
static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
static const int SSL_MODE_AUTO_RETRY;
@@ -116,7 +134,6 @@ static const int TLSEXT_NAMETYPE_host_name;
FUNCTIONS = """
void SSL_load_error_strings();
-
int SSL_library_init();
/* SSL */
@@ -126,6 +143,9 @@ int SSL_set_session(SSL *, SSL_SESSION *);
int SSL_get_verify_mode(const SSL *);
void SSL_set_verify_depth(SSL *, int);
int SSL_get_verify_depth(const SSL *);
+int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *);
+void SSL_set_info_callback(SSL *, void (*)());
+void (*SSL_get_info_callback(const SSL *))();
SSL *SSL_new(SSL_CTX *);
void SSL_free(SSL *);
int SSL_set_fd(SSL *, int);
@@ -147,7 +167,11 @@ const char *SSL_get_cipher_list(const SSL *, int);
void SSL_CTX_free(SSL_CTX *);
long SSL_CTX_set_timeout(SSL_CTX *, long);
int SSL_CTX_set_default_verify_paths(SSL_CTX *);
+void SSL_CTX_set_verify(SSL_CTX *, int, int (*)(int, X509_STORE_CTX *));
void SSL_CTX_set_verify_depth(SSL_CTX *, int);
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *);
+void SSL_CTX_set_info_callback(SSL_CTX *, void (*)(const SSL *, int, int));
+void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int);
int SSL_CTX_get_verify_mode(const SSL_CTX *);
int SSL_CTX_get_verify_depth(const SSL_CTX *);
int SSL_CTX_set_cipher_list(SSL_CTX *, const char *);
@@ -173,7 +197,7 @@ X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *);
void SSL_SESSION_free(SSL_SESSION *);
"""
-MACROS = MACROS = """
+MACROS = """
long SSL_set_mode(SSL *, long);
long SSL_get_mode(SSL *);
@@ -196,6 +220,15 @@ long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *);
/*- These aren't macros these functions are all const X on openssl > 1.0.x -*/
+/* SSLv2 support is compiled out of some versions of OpenSSL. These will
+ * get special support when we generate the bindings so that if they are
+ * available they will be wrapped, but if they are not they won't cause
+ * problems (like link errors).
+ */
+const SSL_METHOD *SSLv2_method();
+const SSL_METHOD *SSLv2_server_method();
+const SSL_METHOD *SSLv2_client_method();
+
/* methods */
const SSL_METHOD *SSLv3_method();
const SSL_METHOD *SSLv3_server_method();
@@ -210,7 +243,71 @@ const SSL_METHOD *SSLv23_client_method();
/*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/
SSL_CTX *SSL_CTX_new(const SSL_METHOD *);
long SSL_CTX_get_timeout(const SSL_CTX *);
+
+/* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support
+ * earlier versions some special handling of these is necessary.
+ */
+void SSL_set_tlsext_host_name(SSL *, char *);
+void SSL_CTX_set_tlsext_servername_callback(
+ SSL_CTX *,
+ int (*)(const SSL *, int *, void *));
"""
CUSTOMIZATIONS = """
+#ifdef OPENSSL_NO_SSL2
+static const int Cryptography_HAS_SSL2 = 0;
+SSL_METHOD* (*SSLv2_method)() = NULL;
+SSL_METHOD* (*SSLv2_client_method)() = NULL;
+SSL_METHOD* (*SSLv2_server_method)() = NULL;
+#else
+static const int Cryptography_HAS_SSL2 = 1;
+#endif
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+static const int Cryptography_HAS_TLSEXT_HOSTNAME = 1;
+#else
+static const int Cryptography_HAS_TLSEXT_HOSTNAME = 0;
+void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL;
+const char* (*SSL_get_servername)(const SSL *, const int) = NULL;
+void (*SSL_CTX_set_tlsext_servername_callback)(
+ SSL_CTX *,
+ int (*)(const SSL *, int *, void *)) = NULL;
+#endif
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+static const int Cryptography_HAS_RELEASE_BUFFERS = 1;
+#else
+static const int Cryptography_HAS_RELEASE_BUFFERS = 0;
+const int SSL_MODE_RELEASE_BUFFERS = 0;
+#endif
+
+#ifdef SSL_OP_NO_COMPRESSION
+static const int Cryptography_HAS_OP_NO_COMPRESSION = 1;
+#else
+static const int Cryptography_HAS_OP_NO_COMPRESSION = 0;
+const int SSL_OP_NO_COMPRESSION = 0;
+#endif
"""
+
+CONDITIONAL_NAMES = {
+ "Cryptography_HAS_SSL2": [
+ "SSLv2_method",
+ "SSLv2_client_method",
+ "SSLv2_server_method",
+ ],
+
+ "Cryptography_HAS_TLSEXT_HOSTNAME": [
+ "SSL_set_tlsext_host_name",
+ "SSL_get_servername",
+ "SSL_CTX_set_tlsext_servername_callback",
+ ],
+
+ "Cryptography_HAS_RELEASE_BUFFERS": [
+ "SSL_MODE_RELEASE_BUFFERS",
+ ],
+
+ "Cryptography_HAS_OP_NO_COMPRESSION": [
+ "SSL_OP_NO_COMPRESSION",
+ ],
+
+}
diff --git a/cryptography/hazmat/backends/openssl/x509.py b/cryptography/hazmat/backends/openssl/x509.py
index b2ee672e..dd7815fa 100644
--- a/cryptography/hazmat/backends/openssl/x509.py
+++ b/cryptography/hazmat/backends/openssl/x509.py
@@ -188,3 +188,5 @@ int X509_CRL_set_nextUpdate(X509_CRL *, const ASN1_TIME *);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/x509name.py b/cryptography/hazmat/backends/openssl/x509name.py
index 896f0ae4..4be39b53 100644
--- a/cryptography/hazmat/backends/openssl/x509name.py
+++ b/cryptography/hazmat/backends/openssl/x509name.py
@@ -49,3 +49,5 @@ void sk_X509_NAME_free(struct stack_st_X509_NAME *);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}
diff --git a/cryptography/hazmat/backends/openssl/x509v3.py b/cryptography/hazmat/backends/openssl/x509v3.py
index bc26236c..6d2d2361 100644
--- a/cryptography/hazmat/backends/openssl/x509v3.py
+++ b/cryptography/hazmat/backends/openssl/x509v3.py
@@ -95,3 +95,5 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int);
CUSTOMIZATIONS = """
"""
+
+CONDITIONAL_NAMES = {}