[erlang-bugs] SSL 3.11.1 : Certificate-based authentication fails with Firefox

Ingela Anderton Andin <>
Wed Jun 2 17:51:48 CEST 2010


Hi !

Thank you for reporting this bug. I have created a fix could you please 
try it out.

git  fetch git://github.com/IngelaAndin/otp.git 
ia/ssl_many_handshake_packages_at_once

Regards Ingela Erlang/OTP team, Ericsson AB

Paul Guyot wrote:
> Hello,
>
> Certificate-based authentication fails with Firefox (on MacOS X), while the same setup succeeds with Safari, Chrome and curl (which probably use OpenSSL). The server is a very simple erlang SSL server that verifies the peer certificate :
>
> ssl:ssl_accept(ClientTransportSocket, [{ssl_imp, new}, {active, false}, {fail_if_no_peer_cert, true}, {verify, verify_peer}, {cacertfile, ?ALL_CERTIFICATES}, {certfile, ?SERVER_CERT_FILE}, {keyfile, ?SERVER_KEY_FILE}, {validate_extensions_fun, fun validate_extensions/4}, {verify_fun, fun(ErrorList) -> case ErrorList of [] -> true; _ -> io:format("ErrorList is ~p~n", [ErrorList]), false end end}], infinity)
>
> The bug seems to be in next_state/3, for the handshake case, around line 1766 of ssl_connection.erl (from the dev branch on github).
>
>    	{Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0, KeyAlg,Version),
>    	Start = {next_state, StateName, State0#state{tls_handshake_buffer = Buf}},
> 	lists:foldl(Handle, Start, Packets)
>
> Handlers (invoked from Handle) can call next_record to get the next packet. For example, handle_peer_cert/3 (line 1148), is as follows :
>
> handle_peer_cert(PeerCert, PublicKeyInfo, 
> 		 #state{session = Session} = State0) ->
>     State1 = State0#state{session = 
> 			 Session#session{peer_certificate = PeerCert},
> 			 public_key_info = PublicKeyInfo},
>     {Record, State} = next_record(State1),
>     next_state(certify, Record, State).
>
> next_record/1 will then attempt to get the next record, ignoring Packets list:
>
> next_record(#state{tls_cipher_texts = [], socket = Socket} = State) ->
>     inet:setopts(Socket, [{active,once}]),
>     {no_record, State};
> next_record(#state{tls_cipher_texts = [CT | Rest], 
> 		   connection_states = ConnStates0} = State) ->
>     case ssl_record:decode_cipher_text(CT, ConnStates0) of
> 	{Plain, ConnStates} ->		      
> 	    {Plain, State#state{tls_cipher_texts = Rest, connection_states = ConnStates}};
> 	#alert{} = Alert ->
> 	    {Alert, State}
>     end.
>
> If the client sends a single packet in the handshake buffer (i.e. lists:foldl only runs once), everything is fine. The handler will call next_record that will either serve the packet from tls_cipher_texts or handshake with the transport layer with {active, once}.
>
> If the client sends more than one packet in the handshake buffer (Data + Buf0 above), and more data to the socket that can get returned by next_record, events end up being processed in wrong order.
>
> This is typically what happens with Firefox.
>
> Packets is composed of three elements :
>
> [{{certificate, [<<48,130,5,6,48,...>>]}, <<11, ...>>},
>  {{client_key_exchange, {client_diffie_hellman_public, <<...>>}}, <<16,...>>},
>  {{certificate_verify, <<120, ...>>}, <<15,...>>}]
>
> While at the same time, a record is present in tls_cipher_texts.
>
> Eventually, the process fails with a function_clause error because the state isn't what is expected (in this very case, there is no cipher_state defined here since no client_key_exchange packet was processed):
>
> ** Reason for termination = 
> ** {function_clause,[{ssl_cipher,block_decipher,
>                                  [#Fun<ssl_cipher.3.32442245>,undefined,20,
>                                   <<120,5,167,147,201,226,3,57,134,28,129,147,
>                                     41,178,143,254,181,2,49,7,140,13,191,3,135,
>                                     237,179,175,167,41,239,235,34,22,61,214,
>                                     228,77,124,198,115,53,25,153,151,63,51,197>>,
>                                   {3,1}]},
>                      {ssl_record,decipher,2},
>                      {ssl_record,decode_cipher_text,2},
>                      {ssl_connection,next_record,1},
>                      {ssl_connection,next_state,3},
>                      {lists,foldl,3},				<--- this is the lists:foldl above
>                      {ssl_connection,next_state,3},
>                      {gen_fsm,handle_msg,7}]}
>
> Paul
>
>
> ________________________________________________________________
> erlang-bugs (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:
>
>
>   



More information about the erlang-bugs mailing list