# define HAVE_TLSv1_2 0
#endif
+/* SNI support (client- and server-side) appeared in OpenSSL 0.9.8n.
+ * This includes the SSL_set_SSL_CTX() function.
+ */
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+# define HAVE_SNI 1
+#else
+# define HAVE_SNI 0
+#endif
+
enum py_ssl_error {
/* these mirror ssl.h */
PY_SSL_ERROR_NONE,
SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY);
#endif
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#if HAVE_SNI
if (server_hostname != NULL)
SSL_set_tlsext_host_name(self->ssl, server_hostname);
#endif
void *closure) {
if (PyObject_TypeCheck(value, &PySSLContext_Type)) {
-
+#if !HAVE_SNI
+ PyErr_SetString(PyExc_NotImplementedError, "setting a socket's "
+ "context is not supported by your OpenSSL library");
+ return NULL;
+#else
Py_INCREF(value);
Py_DECREF(self->ctx);
self->ctx = (PySSLContext *) value;
SSL_set_SSL_CTX(self->ssl, self->ctx->ctx);
+#endif
} else {
PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext");
return -1;
&sock, &server_side,
"idna", &hostname))
return NULL;
-#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#if !HAVE_SNI
PyMem_Free(hostname);
PyErr_SetString(PyExc_ValueError, "server_hostname is not supported "
"by your OpenSSL library");
}
#endif
-#ifndef OPENSSL_NO_TLSEXT
+#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT)
static int
_servername_callback(SSL *s, int *al, void *args)
{
static PyObject *
set_servername_callback(PySSLContext *self, PyObject *args)
{
-#ifndef OPENSSL_NO_TLSEXT
+#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT)
PyObject *cb;
if (!PyArg_ParseTuple(args, "O", &cb))
ADD_AD_CONSTANT(INTERNAL_ERROR);
ADD_AD_CONSTANT(USER_CANCELLED);
ADD_AD_CONSTANT(NO_RENEGOTIATION);
+ /* Not all constants are in old OpenSSL versions */
+#ifdef SSL_AD_UNSUPPORTED_EXTENSION
ADD_AD_CONSTANT(UNSUPPORTED_EXTENSION);
+#endif
+#ifdef SSL_AD_CERTIFICATE_UNOBTAINABLE
ADD_AD_CONSTANT(CERTIFICATE_UNOBTAINABLE);
+#endif
+#ifdef SSL_AD_UNRECOGNIZED_NAME
ADD_AD_CONSTANT(UNRECOGNIZED_NAME);
- /* Not all constants are in old OpenSSL versions */
+#endif
#ifdef SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE
ADD_AD_CONSTANT(BAD_CERTIFICATE_STATUS_RESPONSE);
#endif
SSL_OP_NO_COMPRESSION);
#endif
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#if HAVE_SNI
r = Py_True;
#else
r = Py_False;