[erlang-questions] SSL handshake failure

Ingela Andin <>
Fri Dec 23 23:40:13 CET 2016


Hi!

2016-12-23 15:50 GMT+01:00 Justin Wood <>:

> Hi Ingela!
>
> That patch fixed my issue. I appreciate the quick help.
>
> Would you be able to try to explain what the actual bug was here?
>

Well in short the  TLS handshake protocol packets are packed into TLS
record packets that are received on the tcp socket.
Usually TLS handshake packets are relativily small so when reaching the
code of decoding TLS handshake packets
normally there will be atleast one compleate handshake packet. But your
certificate was very big and then
when reaching the code there was no compleate handshake and we need to wait
for more input from the socket.
In the more common case, when a compleate handshake message is assembled,
we want to process it before asking for more data from the socket.


> Also, since I am still new to Erlang, would you be able to say when this
> patch may land in an actual release?
>
>

Well as it is christmas holidays now I would not expect anything until
after Januari 11.  After that it will be merged
to github maint. Then it might be officially patched if deemed importante
enough, and if not it will be released in the next planned
service release. That release will be ,if I remember correctly,  in March.


Regards Ingela Erlang/OTP team - Ericsson AB


Thank you!
>
> On Thu, Dec 22, 2016 at 5:00 PM, Ingela Andin <>
> wrote:
>
>> *Hi!*
>>
>> *Did get the solution slightly wrong  ;) *
>>
>> *Try this instead.*
>>
>> *Regards Ingela *
>>
>> *diff --git a/lib/ssl/src/tls_connection.erl
>> b/lib/ssl/src/tls_connection.erl*
>>
>> *index 32991d3..108bf50 100644*
>>
>> *--- a/lib/ssl/src/tls_connection.erl*
>>
>> *+++ b/lib/ssl/src/tls_connection.erl*
>>
>> @@ -424,18 +424,24 @@ handle_common_event(internal,  #ssl_tls{type =
>> ?HANDSHAKE, fragment = Data},
>>
>>                                       ssl_options = Options} = State0) ->
>>
>>      try
>>
>>         {Packets, Buf} = tls_handshake:get_tls_handshake(Version,Data,Buf0,
>> Options),
>>
>> -       State =
>>
>> +       State1 =
>>
>>             State0#state{protocol_buffers =
>>
>>                              Buffers#protocol_buffers{tls_handshake_buffer
>> = Buf}},
>>
>> -       Events = tls_handshake_events(Packets),
>>
>> -       case StateName of
>>
>> -           connection ->
>>
>> -               ssl_connection:hibernate_after(StateName, State, Events);
>>
>> -           _ ->
>>
>> -               {next_state, StateName, State#state{unprocessed_handshake_events
>> = unprocessed_events(Events)}, Events}
>>
>> -       end
>>
>> +       case Packets of
>>
>> +            [] ->
>>
>> +                {Record, State} = next_record(State1),
>>
>> +                next_event(StateName, Record, State);
>>
>> +            _ ->
>>
>> +                Events = tls_handshake_events(Packets),
>>
>> +                case StateName of
>>
>> +                    connection ->
>>
>> +                        ssl_connection:hibernate_after(StateName,
>> State1, Events);
>>
>> +                    _ ->
>>
>> +                        {next_state, StateName,
>> State1#state{unprocessed_handshake_events = unprocessed_events(Events)},
>> Events}
>>
>> +                end
>>
>> +        end
>>
>>      catch throw:#alert{} = Alert ->
>>
>> -           ssl_connection:handle_own_alert(Alert, Version, StateName,
>> State0)
>>
>> +            ssl_connection:handle_own_alert(Alert, Version, StateName,
>> State0)
>>
>>      end;
>>
>>  %%% TLS record protocol level application data messages
>>
>>  handle_common_event(internal, #ssl_tls{type = ?APPLICATION_DATA,
>> fragment = Data}, StateName, State) ->
>>
>> 2016-12-22 16:44 GMT+01:00 Ingela Andin <>:
>>
>>> Hi!
>>>
>>>
>>> Well maybe I did not understand the problem correctly then, I thought I
>>> had found a potential problem but as I have nothing to test it against.
>>> Can you provide me with a site to test
>>> against or maybe use tracing to  give me more info.  dbg:tracer().
>>> dbg:p(all, [call]).  dbg:tpl(tls_handshake, get_tls_handshake, x).   Could
>>> be a good way to start.rds
>>>
>>>
>>> Regards Ingela
>>>
>>>
>>> 2016-12-22 16:29 GMT+01:00 Justin Wood <>:
>>>
>>>> Thank you for the patch Ingela. Unfortunately it did not fix my issue.
>>>>
>>>> If there is anything else I can provide to help figure this it, just
>>>> let me know.
>>>>
>>>> On Thu, Dec 22, 2016 at 6:56 AM, Ingela Andin <>
>>>> wrote:
>>>>
>>>>> Hi!
>>>>>
>>>>> I think this might be a timing bug. Can you try the following patch?
>>>>>
>>>>> Regards Ingela Erlang/OTP Team - Ericsson AB
>>>>>
>>>>> *diff --git a/lib/ssl/src/tls_connection.erl
>>>>> b/lib/ssl/src/tls_connection.erl*
>>>>>
>>>>> *index 32991d3..e1f8e78 100644*
>>>>>
>>>>> *--- a/lib/ssl/src/tls_connection.erl*
>>>>>
>>>>> *+++ b/lib/ssl/src/tls_connection.erl*
>>>>>
>>>>> @@ -420,6 +420,7 @@ handle_common_event(internal, #alert{} = Alert,
>>>>> StateName,
>>>>>
>>>>>  handle_common_event(internal,  #ssl_tls{type = ?HANDSHAKE, fragment
>>>>> = Data},
>>>>>
>>>>>                     StateName, #state{protocol_buffers =
>>>>>
>>>>>
>>>>> #protocol_buffers{tls_handshake_buffer = Buf0} = Buffers,
>>>>>
>>>>> +                                      unprocessed_handshake_events =
>>>>> NumUnprocessed,
>>>>>
>>>>>                                       negotiated_version = Version,
>>>>>
>>>>>                                       ssl_options = Options} = State0)
>>>>> ->
>>>>>
>>>>>      try
>>>>>
>>>>> @@ -432,7 +433,7 @@ handle_common_event(internal,  #ssl_tls{type =
>>>>> ?HANDSHAKE, fragment = Data},
>>>>>
>>>>>             connection ->
>>>>>
>>>>>                 ssl_connection:hibernate_after(StateName, State,
>>>>> Events);
>>>>>
>>>>>             _ ->
>>>>>
>>>>> -               {next_state, StateName, State#state{unprocessed_handshake_events
>>>>> = unprocessed_events(Events)}, Events}
>>>>>
>>>>> +               {next_state, StateName, State#state{unprocessed_handshake_events
>>>>> = unprocessed_events(Events, NumUnprocessed)}, Events}
>>>>>
>>>>>         end
>>>>>
>>>>>      catch throw:#alert{} = Alert ->
>>>>>
>>>>>             ssl_connection:handle_own_alert(Alert, Version,
>>>>> StateName, State0)
>>>>>
>>>>> @@ -615,8 +616,6 @@ next_event(StateName, Record, State, Actions) ->
>>>>>
>>>>>             {next_state, StateName, State, [{next_event, internal,
>>>>> Alert} | Actions]}
>>>>>
>>>>>      end.
>>>>>
>>>>>
>>>>>
>>>>> -tls_handshake_events([]) ->
>>>>>
>>>>> -    throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
>>>>> malformed_handshake));
>>>>>
>>>>>  tls_handshake_events(Packets) ->
>>>>>
>>>>>      lists:map(fun(Packet) ->
>>>>>
>>>>>                       {next_event, internal, {handshake, Packet}}
>>>>>
>>>>> @@ -727,8 +726,10 @@ gen_info(Event, StateName,
>>>>> #state{negotiated_version = Version} = State) ->
>>>>>
>>>>>
>>>>> malformed_handshake_data),
>>>>>
>>>>>                                             Version, StateName, State)
>>>>>
>>>>>
>>>>>      end.
>>>>>
>>>>> -
>>>>>
>>>>> -unprocessed_events(Events) ->
>>>>>
>>>>> +
>>>>>
>>>>> +unprocessed_events([], Unprocessed) ->
>>>>>
>>>>> +    Unprocessed;
>>>>>
>>>>> +unprocessed_events(Events, _) ->
>>>>>
>>>>>      %% The first handshake event will be processed immediately
>>>>>
>>>>>      %% as it is entered first in the event queue and
>>>>>
>>>>>      %% when it is processed there will be length(Events)-1
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 2016-12-21 14:47 GMT+01:00 Justin Wood <>:
>>>>>
>>>>>> After upgrading to Erlang OTP-19.2 and, in different requests,
>>>>>> specified the version as one of tlsv1, tlsv1.1 or tlsv1.2. Every time I
>>>>>> received the same error.
>>>>>>
>>>>>> I'm not sure if it is helpful at all, but I can replicate this on
>>>>>> Windows, OSX 10.11 (El Capitan) and Ubuntu 14.04. I have not tried on other
>>>>>> platforms.
>>>>>>
>>>>>> Is there any other information that I would be able to give that
>>>>>> would be helpful?
>>>>>>
>>>>>> On Wed, Dec 21, 2016 at 3:38 AM, Technion <>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Justin,
>>>>>>>
>>>>>>>
>>>>>>> Is this earlier discussion relevant:
>>>>>>>
>>>>>>>
>>>>>>> http://erlang.org/pipermail/erlang-questions/2016-November/0
>>>>>>> 90780.html
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ------------------------------
>>>>>>> *From:*  <
>>>>>>> > on behalf of Justin Wood <
>>>>>>> >
>>>>>>> *Sent:* Wednesday, 21 December 2016 11:56 AM
>>>>>>> *To:* 
>>>>>>> *Subject:* [erlang-questions] SSL handshake failure
>>>>>>>
>>>>>>> Hi there,
>>>>>>>
>>>>>>> I am attempting to use the ssl module in order to get a socket to a
>>>>>>> remote server (MongoDB). I am using the following line of code (OTP 19)
>>>>>>>
>>>>>>> ssl:connect("my-server.net", 27017, [binary, {active, false},
>>>>>>> {packet, raw}], 5000).
>>>>>>>
>>>>>>> Whenever I use this, I get the following:
>>>>>>>
>>>>>>> =ERROR REPORT==== 20-Dec-2016::19:13:13 ===
>>>>>>> SSL: certify: tls_connection.erl:603:Fatal error: handshake failure
>>>>>>> - malformed_handshake
>>>>>>> {error,{tls_alert,"handshake failure"}}
>>>>>>>
>>>>>>> Which lead me to look into erlang:get_stacktrace/0
>>>>>>>
>>>>>>> erlang:get_stacktrace().
>>>>>>> [{tls_connection,start_fsm,8,
>>>>>>>                  [{file,"tls_connection.erl"},{line,79}]},
>>>>>>>  {ssl_connection,connect,8,
>>>>>>>                  [{file,"ssl_connection.erl"},{line,84}]},
>>>>>>>  {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
>>>>>>>  {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
>>>>>>>  {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
>>>>>>>  {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]
>>>>>>>
>>>>>>> My problem is that the certificate that the server is using should
>>>>>>> be legitimate. I can connect, without error, using other clients and
>>>>>>> languages.
>>>>>>>
>>>>>>> I took a look through Wireshark in order to try and figure out what
>>>>>>> is going on and this is what I see.
>>>>>>>
>>>>>>> * The Client says hello and presents a list of cipher suites.
>>>>>>> * The Server says hello and says that it wants to use
>>>>>>> TLS_RSA_WITH_AES_256_GCM_SHA384 (This cipher is in the list that
>>>>>>> the client sends)
>>>>>>> * The Server sends the Client the certificates it is using (these
>>>>>>> both appear to be signed by DigiCert).
>>>>>>> * The Server sends an encrypted handshake message.
>>>>>>> * The Client responds with a Fatal Alert stating a Handshake Failure.
>>>>>>> * The Server sends another encrypted handshake message.
>>>>>>>
>>>>>>> I have verified that ssl:connect/4 is working fine as I can connect
>>>>>>> to a number of different miscellaneous services (including a number of
>>>>>>> other MongoDB instances).
>>>>>>>
>>>>>>> I was wondering if there is anything else I can do to try and figure
>>>>>>> out why erlang does not allow this connection.
>>>>>>>
>>>>>>> Justin
>>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> erlang-questions mailing list
>>>>>> 
>>>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20161223/31939b68/attachment.html>


More information about the erlang-questions mailing list