Skip to content

Commit ad6c893

Browse files
committed
Fix TLS-PSK for TLS 1.3
SSL_CTX_set_session_id_context() is a server-side only operation. Using this the client-side is causing authentication errors
1 parent 79f9d24 commit ad6c893

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

Doc/library/ssl.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,6 +2003,12 @@ to speed up repeated connections from the same clients.
20032003

20042004
Setting ``callback`` to :const:`None` removes any existing callback.
20052005

2006+
.. note::
2007+
When using TLS 1.3:
2008+
2009+
- the ``hint`` parameter is always :const:`None`.
2010+
- the OpenSSL implementation requires client-identity to be a non-empty string.
2011+
20062012
Example usage::
20072013

20082014
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
@@ -2041,6 +2047,9 @@ to speed up repeated connections from the same clients.
20412047

20422048
The parameter ``identity_hint`` is an optional identity hint sent to the client.
20432049

2050+
.. note::
2051+
When using TLS 1.3 the ``identity_hint`` parameter is not sent to the client.
2052+
20442053
Example usage::
20452054

20462055
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)

Lib/test/test_ssl.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4252,6 +4252,22 @@ def server_callback(identity):
42524252
with client_context.wrap_socket(socket.socket()) as s:
42534253
s.connect((HOST, server.port))
42544254

4255+
# works with TLS 1.3, although identity_hint is not sent to client
4256+
client_context.maximum_version = ssl.TLSVersion.TLSv1_3
4257+
client_context.minimum_version = ssl.TLSVersion.TLSv1_3
4258+
server_context.maximum_version = ssl.TLSVersion.TLSv1_3
4259+
server_context.minimum_version = ssl.TLSVersion.TLSv1_3
4260+
4261+
def client_callback(hint):
4262+
self.assertIsNone(hint)
4263+
return client_identity, psk
4264+
4265+
client_context.set_psk_client_callback(client_callback)
4266+
server = ThreadedEchoServer(context=server_context)
4267+
with server:
4268+
with client_context.wrap_socket(socket.socket()) as s:
4269+
s.connect((HOST, server.port))
4270+
42554271
# adding client callback to server or vice versa raises an exception
42564272
with self.assertRaisesRegex(ssl.SSLError, 'Cannot add PSK server callback'):
42574273
client_context.set_psk_server_callback(server_callback, identity_hint)

Modules/_ssl.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,10 +3171,14 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
31713171
usage for no cost at all. */
31723172
SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS);
31733173

3174+
/* Setting the session id context is a server-side only operation.
3175+
* It can cause unexpected behaviour on client-side connections. */
3176+
if (proto_version == PY_SSL_VERSION_TLS_SERVER) {
31743177
#define SID_CTX "Python"
3175-
SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX,
3176-
sizeof(SID_CTX));
3178+
SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX,
3179+
sizeof(SID_CTX));
31773180
#undef SID_CTX
3181+
}
31783182

31793183
params = SSL_CTX_get0_param(self->ctx);
31803184
/* Improve trust chain building when cross-signed intermediate

0 commit comments

Comments
 (0)