pyopenssl icon indicating copy to clipboard operation
pyopenssl copied to clipboard

Is there a way to get the session_id from the pyopenssl

Open ratnapolepalli opened this issue 1 year ago • 9 comments

I see there is a method for set_session_id , but could not find get_session_id. I could not find the way to get the session Id. I also found set_session and get_session , but could not find the get_session_id.

Could anyone help on this , how to fix this issue

ratnapolepalli avatar Aug 21 '23 11:08 ratnapolepalli

any luck?

vkosuri avatar Oct 20 '23 12:10 vkosuri

I am also looking into this in order to implement the security check for an FTPS data connection.

For the OpenSSL API I found SSL_SESSION_get_id

I can see that pypopenssl access is done via from cryptography.hazmat.bindings.openssl.binding import Binding

And I can see that SSL_SESSION_get_id is defined in cryptography

https://github.com/reaperhulk/cryptography/blob/f69f27b1dd20ad2d24f48053a72545527e808104/src/_cffi_src/openssl/ssl.py#L303

I am not very familiar with cffi ... so I am not sure how this is exposed.

Hope it helps

adiroiban avatar Oct 25 '23 18:10 adiroiban

We no longer bind SSL_SESSION_get_id, but we can re-add the binding if it makes sense for pyOpenSSL. @adiroiban are you interested in doing PRs on both sides? It would look roughly like:

  • Add binding back to cryptography
  • Submit PR to pyOpenSSL. The CI will fail except on cryptographyMain, but that's okay
  • Release new cryptography
  • Update PR with new minimum version of cryptography, review, merge
  • Release new pyOpenSSL with the feature.

reaperhulk avatar Oct 25 '23 18:10 reaperhulk

I can give it a try. I tried to read the cryptography code for the binding ... but at a first look, I could't find the place where the binding is made... maybe this was moved to rust.


I don't realy need the actual session ID value. I only want to make sure that 2 independent TCP connections have the same session ID :)

There is this function SSL.Connection.master_key()

I guess that if 2 connections have the same peer certificate and the same encryption key, they might also share the same session.


But for the future, I think is best for FTPS applications to use the session_id() rather than handle the encryption key... and accidentlly leaking in some logs.

adiroiban avatar Oct 25 '23 19:10 adiroiban

I have continue working on this.

On client-side for TLS 1.2 it looks like SSL.Connection.get_session() and SSL.Connection.set_session() are enought to implement client-side TLS session resumption.

Now, the actual session ID is still usefull on the client side to validate wheter the sessions was resumed for not.

The client can set a session ID, but the server can decide not to reuse it.


For TLS 1.3 it looks like we also need SSL_CTX_sess_set_new_cb

From SSL_get1_session docs

Calling these functions on the client side in TLSv1.3 before the session has been established will still return an SSL_SESSION object but that object cannot be used for resuming the session.

For session resumption, there is also the SSL_SESSION_is_resumable


I guess we should start by looking into the API required to implement session resumption for server-side and client-side on pyopenssl for TLS 1.2 and TLS 1.3


For the client side with TLS 1.3, SSL.Connection.get_session() returns a resumable session, if I set the context to context.set_session_cache_mode(SSL.SESS_CACHE_OFF)

Setting the cache to SESS_CACHE_CLIENT returns a session that can only be used to resume one.

I will do more testing and more code and docs reading :)

adiroiban avatar Oct 26 '23 01:10 adiroiban

It looks like SSL_SESSION_get_id was removed here (https://github.com/pyca/cryptography/pull/8340 ) and I think the removal was released in 40.0.0


I think that the critical API that should be available in cryptography and pyOpenSSL is SSL_session_reused

I started a ticket here https://github.com/pyca/cryptography/issues/9969


I still need to do more reading about SSL_SESSION_get_id and TLS 1.3 as in TLS 1.3 there are session tickets instead of session IDs.

adiroiban avatar Dec 07 '23 02:12 adiroiban

Cryptography PR at https://github.com/pyca/cryptography/pull/9978

It doesn't add SSL_SESSION_get_id

It adds SSL_session_reused which can be used to check if the previously set session was reused.


We can also have SSL_SESSION_get_id exposes, but I think that it would help to know the use case for this API.

When a session is resued, the client-side will have the same ID...but the server side has different ID, even when reused.

adiroiban avatar Dec 09 '23 16:12 adiroiban

When a session is resued, the client-side will have the same ID...but the server side has different ID, even when reused.

I'm just curious to know, is this behaviour the same as earlier?

vkosuri avatar Dec 11 '23 07:12 vkosuri

Hi

I'm just curious to know, is this behaviour the same as earlier?

This is only on TLS 1.3

You can try with pip install cryptography==39.0.2 as this verion has the missing API.

In my tests, on TLS 1.3 SSL_session_reused returns 1 (was reused) while SSL_SESSION_get_id were different... but maybe there was an error in my process.

I am trying to get SSL_session_reused as I think this is the API


I have create a PR for SSL_session_reused here, but I'm not sure how to write the automated tests.

All ok for TLS 1.2 but for TLS 1.3 the automated tests are failing.

I did some manual tests with curl and it looked fine.

https://github.com/pyca/pyopenssl/pull/1276

If you have time, maybe you can give it a try.


For which protocol do you need SSL_SESSION_get_id ?

For HTTPS you might not need it on TLS1.3 - https://timtaubert.de/blog/2017/02/the-future-of-session-resumption/


I need this API to implement an FTPS server and client.

adiroiban avatar Dec 11 '23 08:12 adiroiban