Mbed TLS is now part of TrustedFirmware.org.

server ssl session resume / SNI


Jul 29, 2017 12:05
ioio

Hello I have a tier client that connects to my ssl server , my server hosts virtual servers, identified using SNI. it does the following :

- client connects to the server for "server1.hostname"
- server accept the connection, sends the server1 certificate and provides the client with the ssl session id
- then client tries to connect to my server again, for "server2.hostname". as the client is a bit stupid and since the ip of server1 and server2 are the same. it opens the connection, providing SNI "server2.hostname" but also sending the first connection session id
- "unfortunately", the server sends the server2 certificate (normall) but also resumes the session "a session has been resumed (..\..\library\ssl_srv.c:2359)", so my stupid tier client keeps the context of the first connection and keep the first connection certificate and closes the connection.

is this a normal server behaviour ? since we use another server name, shoudln't the server it refuse to resume the session ? or is it required for the server to maintain a session cache for each virtual host ?

thank you

 
Jul 29, 2017 13:04
ioio

It seems that there currently would be no way to filter the ssl session cache by sni host name (unless each connection would have a copy of the cache in p_cache, configured by the sni callback, but that would be very ugly)

may i propose this evolution ? in ssl_srv, line 2285, the code is

   /*
     * Resume is 0  by default, see ssl_handshake_init().
     * It may be already set to 1 by ssl_parse_session_ticket_ext().
     * If not, try looking up session ID in our cache.
     */
    if( ssl->handshake->resume == 0 &&
#if defined(MBEDTLS_SSL_RENEGOTIATION)
        ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
#endif
        ssl->session_negotiate->id_len != 0 &&
        ssl->conf->f_get_cache != NULL &&
        ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
    {
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
        ssl->handshake->resume = 1;
    }

may it become :

   /*
     * Resume is 0  by default, see ssl_handshake_init().
     * It may be already set to 1 by ssl_parse_session_ticket_ext().
     * If not, try looking up session ID in our cache.
     */
    if( ssl->handshake->resume == 0 &&
#if defined(MBEDTLS_SSL_RENEGOTIATION)
        ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
#endif
        ssl->session_negotiate->id_len != 0 &&
        ssl->conf->f_get_cache != NULL &&
        ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ,ssl->conf->p_sni) == 0 )
    {
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
        ssl->handshake->resume = 1;
    }

the same would ally to f_set_cache call, and of course the get_cache / set cache prototype would then need to have a third parameter const char* hostname.

would it be possible ? thank you

 
Jul 30, 2017 08:43
Ron Eldor

Hi ioio,
Thank you for your question.
If the client is trying to connect to "server2.hostname", it is basically trying to connect to a new server, so I would expect it to use a different session id.
Having said that, as an open source project, we encourage contributions from the community. Please submit a Pull Request with your suggested change, with your justifications for this enhancement, and we will look into it.
Thank you for your cooperation!
Regards,
mbed TLS Team member
Ron

 
Jul 30, 2017 08:57
ioio

Hi Ron, totatly agree that the client shouldn't try to request that session id, but since i can't change the client... I'll make a pull request, thank you !

 
Jul 30, 2017 14:46
ioio

I tried to actually implement it , and i missunderstood the code p_sni is not the actual sni information, but the user pointer passed to the sni callback, the hostname doesn't seems to be stored . seems the fix i proposed is not right and. which doesn't solve the problem...

 
Jul 30, 2017 20:17
ioio

Passing the handshake certificate allows to do the job properly

ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->handshake->key_cert->cert, ssl->session_negotiate ) == 0 )

and

if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->handshake->key_cert->cert, ssl->session ) != 0 )

i'll try to make the pull request, but i 'm not used to git ...

the change is very simple, but i am not used to the different implication of setting or not the preprocessor definitions. but I guess you will review the change ?

 
Aug 9, 2017 09:27
ioio

Hi Ron, I was wondering is there is some more actions required from my side for this or if the pull request is enough and it is now up to the reviewers ? thank you

 
Aug 9, 2017 10:30
Ron Eldor

Hi ioio,
It is better you also add tests for this feature.
It would also be appreciated if you modify the Changelog accordingly
After that, it is up to the reviewers
Regards,
mbed TLS Team member
Ron