Dr Stephen Henson wrote:
> Kaspar Brand wrote:
>> As Joe observed in an earlier message, there are only two places in
>> t1_lib.c:ssl_parse_serverhello_tlsext() which set SSL_AD_DECODE_ERROR,
>> and it seems very likely that the following code is hit:
>>
>>>         if (!s->hit && tlsext_servername == 1)
>>>                 {
>>>                 if (s->tlsext_hostname)
>>>                         {
>>>                         if (s->session->tlsext_hostname == NULL)
>>>                                 {
>>>                                 s->session->tlsext_hostname = 
>>> BUF_strdup(s->tlsext_hostname);
>>>                                 if (!s->session->tlsext_hostname)
>>>                                         {
>>>                                         *al = SSL_AD_UNRECOGNIZED_NAME;
>>>                                         return 0;
>>>                                         }
>>>                                 }
>>>                         else
>>>                                 {
>>>                                 *al = SSL_AD_DECODE_ERROR;
>>>                                 return 0;
>>>                                 }
>>>                         }
>>>                 }
> 
> OK that makes sense. I can now reproduce this with OpenSSL s_server and
> s_client and stateless session resumption. A fix for this would have to be in
> the client code, I'll look into that.
> 

I've looked into this further now. The cause is an interaction between session
tickets and the server name extension.

When a stateless session resumption is attempted OpenSSL sends (as permitted by
RFC5077) an empty session ID. This has the side effect that it is not clear
whether the server has accepted the ticket until later in the handshake whereas
in a stateful resumption this is apparent after received the server hello by
comparing session IDs.

As a result the value of s->hit above cannot be trusted to check for a resumed
session.

I'm looking into the best way to fix this. For now changing the above to:


                         else if (!s->session->tlsext_tick)
                                {
                                *al = SSL_AD_DECODE_ERROR;
                                return 0;
                                }

client side is one way but it doesn't retain all the original logic.

Disabling tickets using SSL_OP_NO_TICKET server side SHOULD work too (does in my
tests) so I've no idea why that wouldn't in the OPs setup unless the patch
doesn't set it in all contexts. Try placing it right after any call to
SSL_CTX_new().

Steve.
-- 
Dr Stephen N. Henson. Senior Technical/Cryptography Advisor,
Open Source Software Institute: www.oss-institute.org
OpenSSL Core team: www.openssl.org

Reply via email to