Visitar URL original
Issue with TLS 1.3 Session Resumption in PyOpenSSL · Issue #1380 · pyca/pyopenssl · GitHub
Skip to content

Issue with TLS 1.3 Session Resumption in PyOpenSSL #1380

Open

Description

@Smuul

Description:

I am encountering an issue when attempting to implement session resumption in TLS 1.3 using PyOpenSSL. I have already tried the implementation suggested in #1291.

Scenario:

Client

self.context = SSL.Context(config.secure_version)
self.context.set_session_cache_mode(SSL.SESS_CACHE_CLIENT)
if session is not None:
             self.conn.set_session(session)

try:
                self.conn.set_connect_state()
                self.conn.do_handshake()
                while self._running:
                    data = self.conn.recv(1)
                    if data:
                            self.session = self.conn.get_session()  
                            break         

Server

self.context = SSL.Context(config.secure_version)
self.context.set_session_cache_mode(SSL.SESS_CACHE_SERVER)
self.context.set_session_id(b'12345678123456781234567812345678')

Observations:

The session resumption works correctly with TLS 1.2:
image

However, the same implementation fails for TLS 1.3. It always creates a new Session Ticket during the second connection attempt:
image

Questions:

What am I doing wrong in my implementation? Is there anything I might be missing to achieve proper session resumption for TLS 1.3?

Any guidance would be greatly appreciated!

Activity

  1. dennisn00 commented on Nov 9, 2024

    @dennisn00

    In TLS1.3, a server may send a NewSessionTicket even on a resumed connection (for example to extend the lifetime of the original session ticket). I am not sure whether pyOpenSSL is doing that on default, but the existence of a NewSessionTicket message itself should not be proof that the session was not resumed.
    You could test manually whether certificates are sent by using set_verify() on the client side:

    def test_verification(a, b, c, d, e):
        print("Certificate is verified")
        return True
    
    self.context.set_verify(SSL.VERIFY_PEER, test_verification)
    

    This should only print on the complete handshake (it will print multiple times though) and not during the resuming handshake.

    Also just looking at the message sizes in your screenshot, it seems like the second ClientHello is a lot bigger, which might be the PSK. You can check in Wireshark whether the second ClientHello includes the pre_shared_key extension

  2. Smuul commented on Nov 12, 2024

    @Smuul
    Author

    I finally managed to get the second ClientHello to use the pre_shared_key extension, and the value of the new session ticket issued during the initial handshake. Here’s how I addressed the problem:

    Added Sleep Delays: I added some sleep intervals in my code where the client and server instances are created. It seems that allowing a little delay between the different stages helped in stabilizing the session ticket process. Without these sleeps, it appears that the client wasn't ready to properly use the received ticket for resumption.

    In addition, i don't use Certificates in my implementation, as i want to use a PSK cipher.
    Thanks a lot for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions