mirror of
https://github.com/python/cpython
synced 2024-09-16 00:27:20 +00:00
gh-112454: Disable TLS-PSK if OpenSSL was built without PSK support (#112491)
If OpenSSL was built without PSK support, the python TLS-PSK methods will raise "NotImplementedError" if called. Add a constant "ssl.HAS_PSK" to check if TLS-PSK is supported
This commit is contained in:
parent
48dfd74a9d
commit
e413daf5f6
|
@ -908,6 +908,12 @@ Constants
|
||||||
|
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
.. data:: HAS_PSK
|
||||||
|
|
||||||
|
Whether the OpenSSL library has built-in support for TLS-PSK.
|
||||||
|
|
||||||
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
.. data:: CHANNEL_BINDING_TYPES
|
.. data:: CHANNEL_BINDING_TYPES
|
||||||
|
|
||||||
List of supported TLS channel binding types. Strings in this list
|
List of supported TLS channel binding types. Strings in this list
|
||||||
|
@ -2050,6 +2056,9 @@ to speed up repeated connections from the same clients.
|
||||||
return 'ClientId_1', psk_table.get(hint, b'')
|
return 'ClientId_1', psk_table.get(hint, b'')
|
||||||
context.set_psk_client_callback(callback)
|
context.set_psk_client_callback(callback)
|
||||||
|
|
||||||
|
This method will raise :exc:`NotImplementedError` if :data:`HAS_PSK` is
|
||||||
|
``False``.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
.. method:: SSLContext.set_psk_server_callback(callback, identity_hint=None)
|
.. method:: SSLContext.set_psk_server_callback(callback, identity_hint=None)
|
||||||
|
@ -2092,6 +2101,9 @@ to speed up repeated connections from the same clients.
|
||||||
return psk_table.get(identity, b'')
|
return psk_table.get(identity, b'')
|
||||||
context.set_psk_server_callback(callback, 'ServerId_1')
|
context.set_psk_server_callback(callback, 'ServerId_1')
|
||||||
|
|
||||||
|
This method will raise :exc:`NotImplementedError` if :data:`HAS_PSK` is
|
||||||
|
``False``.
|
||||||
|
|
||||||
.. versionadded:: 3.13
|
.. versionadded:: 3.13
|
||||||
|
|
||||||
.. index:: single: certificates
|
.. index:: single: certificates
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
|
|
||||||
from _ssl import (
|
from _ssl import (
|
||||||
HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
|
HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
|
||||||
HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3
|
HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3, HAS_PSK
|
||||||
)
|
)
|
||||||
from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
|
from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
|
||||||
|
|
||||||
|
|
|
@ -4259,6 +4259,7 @@ def test_session_handling(self):
|
||||||
'Session refers to a different SSLContext.')
|
'Session refers to a different SSLContext.')
|
||||||
|
|
||||||
@requires_tls_version('TLSv1_2')
|
@requires_tls_version('TLSv1_2')
|
||||||
|
@unittest.skipUnless(ssl.HAS_PSK, 'TLS-PSK disabled on this OpenSSL build')
|
||||||
def test_psk(self):
|
def test_psk(self):
|
||||||
psk = bytes.fromhex('deadbeef')
|
psk = bytes.fromhex('deadbeef')
|
||||||
|
|
||||||
|
@ -4326,6 +4327,7 @@ def server_callback(identity):
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
|
|
||||||
@requires_tls_version('TLSv1_3')
|
@requires_tls_version('TLSv1_3')
|
||||||
|
@unittest.skipUnless(ssl.HAS_PSK, 'TLS-PSK disabled on this OpenSSL build')
|
||||||
def test_psk_tls1_3(self):
|
def test_psk_tls1_3(self):
|
||||||
psk = bytes.fromhex('deadbeef')
|
psk = bytes.fromhex('deadbeef')
|
||||||
identity_hint = 'identity-hint'
|
identity_hint = 'identity-hint'
|
||||||
|
|
|
@ -301,8 +301,10 @@ typedef struct {
|
||||||
BIO *keylog_bio;
|
BIO *keylog_bio;
|
||||||
/* Cached module state, also used in SSLSocket and SSLSession code. */
|
/* Cached module state, also used in SSLSocket and SSLSession code. */
|
||||||
_sslmodulestate *state;
|
_sslmodulestate *state;
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
PyObject *psk_client_callback;
|
PyObject *psk_client_callback;
|
||||||
PyObject *psk_server_callback;
|
PyObject *psk_server_callback;
|
||||||
|
#endif
|
||||||
} PySSLContext;
|
} PySSLContext;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -3125,8 +3127,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
||||||
self->alpn_protocols = NULL;
|
self->alpn_protocols = NULL;
|
||||||
self->set_sni_cb = NULL;
|
self->set_sni_cb = NULL;
|
||||||
self->state = get_ssl_state(module);
|
self->state = get_ssl_state(module);
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
self->psk_client_callback = NULL;
|
self->psk_client_callback = NULL;
|
||||||
self->psk_server_callback = NULL;
|
self->psk_server_callback = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Don't check host name by default */
|
/* Don't check host name by default */
|
||||||
if (proto_version == PY_SSL_VERSION_TLS_CLIENT) {
|
if (proto_version == PY_SSL_VERSION_TLS_CLIENT) {
|
||||||
|
@ -3239,8 +3243,10 @@ context_clear(PySSLContext *self)
|
||||||
Py_CLEAR(self->set_sni_cb);
|
Py_CLEAR(self->set_sni_cb);
|
||||||
Py_CLEAR(self->msg_cb);
|
Py_CLEAR(self->msg_cb);
|
||||||
Py_CLEAR(self->keylog_filename);
|
Py_CLEAR(self->keylog_filename);
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
Py_CLEAR(self->psk_client_callback);
|
Py_CLEAR(self->psk_client_callback);
|
||||||
Py_CLEAR(self->psk_server_callback);
|
Py_CLEAR(self->psk_server_callback);
|
||||||
|
#endif
|
||||||
if (self->keylog_bio != NULL) {
|
if (self->keylog_bio != NULL) {
|
||||||
PySSL_BEGIN_ALLOW_THREADS
|
PySSL_BEGIN_ALLOW_THREADS
|
||||||
BIO_free_all(self->keylog_bio);
|
BIO_free_all(self->keylog_bio);
|
||||||
|
@ -4668,6 +4674,7 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
static unsigned int psk_client_callback(SSL *s,
|
static unsigned int psk_client_callback(SSL *s,
|
||||||
const char *hint,
|
const char *hint,
|
||||||
char *identity,
|
char *identity,
|
||||||
|
@ -4735,6 +4742,7 @@ static unsigned int psk_client_callback(SSL *s,
|
||||||
PyGILState_Release(gstate);
|
PyGILState_Release(gstate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_ssl._SSLContext.set_psk_client_callback
|
_ssl._SSLContext.set_psk_client_callback
|
||||||
|
@ -4747,6 +4755,7 @@ _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self,
|
||||||
PyObject *callback)
|
PyObject *callback)
|
||||||
/*[clinic end generated code: output=0aba86f6ed75119e input=7627bae0e5ee7635]*/
|
/*[clinic end generated code: output=0aba86f6ed75119e input=7627bae0e5ee7635]*/
|
||||||
{
|
{
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
if (self->protocol == PY_SSL_VERSION_TLS_SERVER) {
|
if (self->protocol == PY_SSL_VERSION_TLS_SERVER) {
|
||||||
_setSSLError(get_state_ctx(self),
|
_setSSLError(get_state_ctx(self),
|
||||||
"Cannot add PSK client callback to a "
|
"Cannot add PSK client callback to a "
|
||||||
|
@ -4774,8 +4783,14 @@ _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self,
|
||||||
SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback);
|
SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
#else
|
||||||
|
PyErr_SetString(PyExc_NotImplementedError,
|
||||||
|
"TLS-PSK is not supported by your OpenSSL version.");
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
static unsigned int psk_server_callback(SSL *s,
|
static unsigned int psk_server_callback(SSL *s,
|
||||||
const char *identity,
|
const char *identity,
|
||||||
unsigned char *psk,
|
unsigned char *psk,
|
||||||
|
@ -4835,6 +4850,7 @@ static unsigned int psk_server_callback(SSL *s,
|
||||||
PyGILState_Release(gstate);
|
PyGILState_Release(gstate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_ssl._SSLContext.set_psk_server_callback
|
_ssl._SSLContext.set_psk_server_callback
|
||||||
|
@ -4849,6 +4865,7 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self,
|
||||||
const char *identity_hint)
|
const char *identity_hint)
|
||||||
/*[clinic end generated code: output=1f4d6a4e09a92b03 input=65d4b6022aa85ea3]*/
|
/*[clinic end generated code: output=1f4d6a4e09a92b03 input=65d4b6022aa85ea3]*/
|
||||||
{
|
{
|
||||||
|
#ifndef OPENSSL_NO_PSK
|
||||||
if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) {
|
if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) {
|
||||||
_setSSLError(get_state_ctx(self),
|
_setSSLError(get_state_ctx(self),
|
||||||
"Cannot add PSK server callback to a "
|
"Cannot add PSK server callback to a "
|
||||||
|
@ -4882,6 +4899,11 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self,
|
||||||
SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback);
|
SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
#else
|
||||||
|
PyErr_SetString(PyExc_NotImplementedError,
|
||||||
|
"TLS-PSK is not supported by your OpenSSL version.");
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6243,6 +6265,12 @@ sslmodule_init_constants(PyObject *m)
|
||||||
addbool(m, "HAS_TLSv1_3", 0);
|
addbool(m, "HAS_TLSv1_3", 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_PSK
|
||||||
|
addbool(m, "HAS_PSK", 0);
|
||||||
|
#else
|
||||||
|
addbool(m, "HAS_PSK", 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef addbool
|
#undef addbool
|
||||||
#undef ADD_INT_CONST
|
#undef ADD_INT_CONST
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue