[erlang-questions] SSL handshake failure

Justin Wood <>
Fri Dec 23 15:50:46 CET 2016


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?

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

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/320b7857/attachment.html>


More information about the erlang-questions mailing list