Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-63284: Add support for TLS-PSK (pre-shared key) to the ssl module #103181

Merged
merged 22 commits into from Nov 27, 2023

Conversation

grantramsay
Copy link
Contributor

@grantramsay grantramsay commented Apr 2, 2023

Add support for TLS-PSK (pre-shared key) to the ssl module (plus documentation and unit-tests).

The referenced issue (#63284) is ~10 years old, but the information is still valid.

I've tested this by:

  • connecting python TLS-PSK client/server (as in the unit-tests)
  • connecting to openssl s_client/s_server from python:
    • openssl s_server -accept localhost:12345 -psk deadbeef -cipher PSK -verify_return_error -nocert
    • openssl s_client -connect localhost:12345 -psk deadbeef -cipher PSK -verify_return_error

Things I'm still uncertain on:

  • It's not yet working with TLS 1.3 (I'm currently looking into this). [Fixed]
  • Do I need to call PyErr_WriteUnraisable() if there's a python exception during a C callback? [Fixed]

This is my first python contribution.
I have probably got a few things wrong, but I'm happy to fix them up.

Thanks!

@cpython-cla-bot
Copy link

cpython-cla-bot bot commented Apr 2, 2023

All commit authors signed the Contributor License Agreement.
CLA signed

@arhadthedev arhadthedev added stdlib Python modules in the Lib dir topic-SSL labels Apr 2, 2023
@grantramsay grantramsay force-pushed the fix-issue-63284 branch 2 times, most recently from 7fab649 to ad6c893 Compare April 3, 2023 04:04
@grantramsay
Copy link
Contributor Author

I figured out why it wasn't working with TLS 1.3.

The error on the client-side is:

ssl.SSLError: [SSL: ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT] attempt to reuse session in different context (_ssl.c:996)

When initialising the SSLContext there is a call to SSL_CTX_set_session_id_context():

#define SID_CTX "Python"
    SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX,
                                   sizeof(SID_CTX));
#undef SID_CTX

The openssl man pages state this is a "server side only" operation:
https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_session_id_context.html

SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)

The session id context becomes part of the session. The session id context is set by the SSL/TLS server. The SSL_CTX_set_session_id_context() and SSL_set_session_id_context() functions are therefore only useful on the server side.

Calling this on a client-side socket seems to result in unexpected behavior, where the client thinks it's trying to resume a non-existent session.

It looks like others have run into the same issue: maovidal/paho_sslpsk2_demo#2 (comment)

Disabling the call to SSL_CTX_set_session_id_context() for client-side SSLContext creation fixes it.
I've added another commit with this fix

@arhadthedev
Copy link
Member

@jackjansen, @dstufft, @alex (as ssl module experts)

SSL_CTX_set_session_id_context() is a server-side only operation.
Using this on the client-side is causing authentication errors
@grantramsay
Copy link
Contributor Author

Modified the documentation for TLS 1.3.
I initially assumed it was a quirk of the OpenSSL TLS 1.3 implementation that meant "client-identity" had to be a non-empty string.

However this ticket explains that it is a change in TLS 1.3: openssl/openssl#8894 (comment)

TLSv1.3 explicitly states that an identity must be at least 1 byte long. But in TLSv1.2 an identity was allowed to have a zero length.

@grantramsay
Copy link
Contributor Author

Hey just giving this a bump

@terryjreedy terryjreedy requested review from dstufft and tiran May 30, 2023 15:04
Modules/_ssl.c Outdated Show resolved Hide resolved
Modules/_ssl.c Outdated Show resolved Hide resolved
Doc/library/ssl.rst Show resolved Hide resolved
@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Doc/library/ssl.rst Outdated Show resolved Hide resolved
@gpshead gpshead self-assigned this May 30, 2023
@gpshead gpshead added the type-feature A feature request or enhancement label May 30, 2023
RFC4279 states these are UTF-8.
Add unit test using non-ASCII chars
The PR has missed the 3.12 merge window
@grantramsay
Copy link
Contributor Author

I have made the requested changes; please review again

@grantramsay
Copy link
Contributor Author

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@gpshead: please review the changes made to this pull request.

@bruno-at-bareos
Copy link

@gpshead is there anything that still need to be done to see this PR moving forward?

@grantramsay
Copy link
Contributor Author

Hi @gpshead, it has been a while but I'm still interested in getting this merged.
Do you have any further review comments/suggestions?

I have made the requested changes; please review again

@doronz88
Copy link

I'm also very interested in this feature. Feel free to tag me if you need any help

Modules/_ssl.c Outdated Show resolved Hide resolved
@gpshead
Copy link
Member

gpshead commented Nov 27, 2023

Thanks for the contributon!

FWIW the timestamp on the NEWS.d/next/ filename is irrelevant, it is only being used as a uniqueness collision avoidance mechanism. All of those get merged into one file during releases.

@gpshead gpshead merged commit e954ac7 into python:main Nov 27, 2023
31 of 32 checks passed
@grantramsay
Copy link
Contributor Author

Awesome!! Thanks for taking the time to review!

aisk pushed a commit to aisk/cpython that referenced this pull request Feb 11, 2024
…odule (python#103181)

Add support for TLS-PSK (pre-shared key) to the ssl module.

---------

Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-SSL type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants