Subject: [alpine-aports] [PATCH] community/erlang: upgrade to 18.3.2

From: Marlus Saraiva <[email-masked]>
Date: Tue, 3 May 2016 00:32:33 +0000

---
 .../erlang/0070-otp-update-version-18.3.2.patch    | 1887 ++++++++++++++++++++
 community/erlang/APKBUILD                          |   14 +-
 2 files changed, 1896 insertions(+), 5 deletions(-)
 create mode 100644 community/erlang/0070-otp-update-version-18.3.2.patch

diff --git a/community/erlang/0070-otp-update-version-18.3.2.patch b/community/erlang/0070-otp-update-version-18.3.2.patch
new file mode 100644
index 0000000..8e38f92
--- /dev/null
+++ b/community/erlang/0070-otp-update-version-18.3.2.patch
@@ -0,0 +1,1887 @@
+--- a/OTP_VERSION
++++ b/OTP_VERSION
+@@ -1 +1 @@
+-18.3
++18.3.2
+--- a/erts/doc/src/notes.xml
++++ b/erts/doc/src/notes.xml
+@@ -32,6 +32,71 @@
+   <p>This document describes the changes made to the ERTS application.</p>
+ 
+ 
++<section><title>Erts 7.3.1</title>
++
++    <section><title>Fixed Bugs and Malfunctions</title>
++      <list>
++        <item>
++          <p>
++	    <c>process_info(Pid, last_calls)</c> did not work for
++	    <c>Pid /= self()</c>.</p>
++          <p>
++	    Own Id: OTP-13418</p>
++        </item>
++        <item>
++          <p>
++	    Make sure to create a crash dump when running out of
++	    memory. This was accidentally removed in the erts-7.3
++	    release.</p>
++          <p>
++	    Own Id: OTP-13419</p>
++        </item>
++        <item>
++          <p>
++	    Schedulers could be woken by a premature timeout on
++	    Linux. This premature wakeup was however harmless.</p>
++          <p>
++	    Own Id: OTP-13420</p>
++        </item>
++        <item>
++          <p>
++	    A process communicating with a port via one of the
++	    <c>erlang:port_*</c> BIFs could potentially end up in an
++	    inconsistent state if the port terminated during the
++	    communication. When this occurred the process could later
++	    block in a <c>receive</c> even though it had messages
++	    matching in its message queue.</p>
++          <p>
++	    This bug was introduced in erts version 5.10 (OTP R16A).</p>
++          <p>
++	    Own Id: OTP-13424 Aux Id: OTP-10336 </p>
++        </item>
++        <item>
++          <p>
++	    The reference count of a process structure could under
++	    rare circumstances be erroneously managed. When this
++	    happened invalid memory accesses occurred.</p>
++          <p>
++	    Own Id: OTP-13446</p>
++        </item>
++        <item>
++          <p>
++	    Fix race between <c>process_flag(trap_exit,true)</c> and
++	    a received exit signal.</p>
++          <p>
++	    A process could terminate due to exit signal even though
++	    <c>process_flag(trap_exit,true)</c> had returned. A very
++	    specific timing between call to <c>process_flag/2</c> and
++	    exit signal from another scheduler was required for this
++	    to happen.</p>
++          <p>
++	    Own Id: OTP-13452</p>
++        </item>
++      </list>
++    </section>
++
++</section>
++
+ <section><title>Erts 7.3</title>
+ 
+     <section><title>Fixed Bugs and Malfunctions</title>
+--- a/erts/emulator/beam/bif.c
++++ b/erts/emulator/beam/bif.c
+@@ -1605,14 +1605,17 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
+ 	*       true. For more info, see implementation of
+ 	*       erts_send_exit_signal().
+ 	*/
++       erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCKS_XSIG_SEND);
+        if (trap_exit)
+ 	   state = erts_smp_atomic32_read_bor_mb(&BIF_P->state,
+ 						 ERTS_PSFLG_TRAP_EXIT);
+        else
+ 	   state = erts_smp_atomic32_read_band_mb(&BIF_P->state,
+ 						  ~ERTS_PSFLG_TRAP_EXIT);
++       erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCKS_XSIG_SEND);
++
+ #ifdef ERTS_SMP
+-       if (ERTS_PROC_PENDING_EXIT(BIF_P)) {
++       if (state & ERTS_PSFLG_PENDING_EXIT) {
+ 	   erts_handle_pending_exit(BIF_P, ERTS_PROC_LOCK_MAIN);
+ 	   ERTS_BIF_EXITED(BIF_P);
+        }
+--- a/erts/emulator/beam/erl_alloc.c
++++ b/erts/emulator/beam/erl_alloc.c
+@@ -1923,7 +1923,7 @@ erts_alc_fatal_error(int error, int func, ErtsAlcType_t n, ...)
+ 	va_start(argp, n);
+ 	size = va_arg(argp, Uint);
+ 	va_end(argp);
+-	erts_exit(1,
++	erts_exit(ERTS_DUMP_EXIT,
+ 		 "%s: Cannot %s %lu bytes of memory (of type \"%s\").\n",
+ 		 allctr_str, op, size, t_str);
+ 	break;
+--- a/erts/emulator/beam/erl_bif_info.c
++++ b/erts/emulator/beam/erl_bif_info.c
+@@ -1534,7 +1534,7 @@ process_info_aux(Process *BIF_P,
+     }
+ 
+     case am_last_calls: {
+-	struct saved_calls *scb = ERTS_PROC_GET_SAVED_CALLS_BUF(BIF_P);
++	struct saved_calls *scb = ERTS_PROC_GET_SAVED_CALLS_BUF(rp);
+ 	if (!scb) {
+ 	    hp = HAlloc(BIF_P, 3);
+ 	    res = am_false;
+--- a/erts/emulator/beam/erl_process.c
++++ b/erts/emulator/beam/erl_process.c
+@@ -9807,12 +9807,14 @@ Process *schedule(Process *p, int calls)
+ 				      | ERTS_PSFLG_PENDING_EXIT
+ 				      | ERTS_PSFLG_ACTIVE_SYS))
+ 			    == ERTS_PSFLG_SUSPENDED)) {
+-			if (state & ERTS_PSFLG_FREE)
+-			    erts_proc_dec_refc(p);
+ 			if (proxy_p) {
+ 			    free_proxy_proc(proxy_p);
+ 			    proxy_p = NULL;
+ 			}
++			else if (state & ERTS_PSFLG_FREE) {
++			    /* free and not queued by proxy */
++			    erts_proc_dec_refc(p);
++			}
+ 			goto pick_next_process;
+ 		    }
+ 		    state = new;
+--- a/erts/emulator/beam/io.c
++++ b/erts/emulator/beam/io.c
+@@ -1529,8 +1529,19 @@ erts_schedule_proc2port_signal(Process *c_p,
+ 	erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
+ 
+     if (sched_res != 0) {
+-	if (refp)
++	if (refp) {
++	    /*
++	     * We need to restore the message queue save
++	     * pointer to the beginning of the message queue
++	     * since the caller now wont wait for a message
++	     * containing the reference created above...
++	     */
++	    ASSERT(c_p);
++	    erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
++	    JOIN_MESSAGE(c_p);
++	    erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
+ 	    *refp = NIL;
++	}
+ 	return ERTS_PORT_OP_DROPPED;
+     }
+     return ERTS_PORT_OP_SCHEDULED;
+--- a/erts/emulator/test/save_calls_SUITE.erl
++++ b/erts/emulator/test/save_calls_SUITE.erl
+@@ -156,8 +156,19 @@ save_calls_1() ->
+ 
+     ?line erlang:process_flag(self(), save_calls, 10),
+     ?line {last_calls, L3} = process_info(self(), last_calls),
++    true = (L3 /= false),
+     ?line L31 = lists:filter(fun is_local_function/1, L3),
+     ?line [] = L31,
++    erlang:process_flag(self(), save_calls, 0),
++
++    %% Also check that it works on another process ...
++    Pid = spawn(fun () -> receive after infinity -> ok end end),
++    erlang:process_flag(Pid, save_calls, 10),
++    {last_calls, L4} = process_info(Pid, last_calls),
++    true = (L4 /= false),
++    L41 = lists:filter(fun is_local_function/1, L4),
++    [] = L41,
++    exit(Pid,kill),
+     ok.
+ 
+ do_bipp() ->
+--- a/erts/lib_src/pthread/ethr_event.c
++++ b/erts/lib_src/pthread/ethr_event.c
+@@ -94,6 +94,9 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout)
+ 	tsp = NULL;
+     }
+     else {
++#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
++	start = ethr_get_monotonic_time();
++#endif
+ 	tsp = &ts;
+ 	time = timeout;
+ 	if (spincount == 0) {
+@@ -102,9 +105,6 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout)
+ 		goto return_event_on;
+ 	    goto set_timeout;
+ 	}
+-#ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME
+-	start = ethr_get_monotonic_time();
+-#endif
+     }
+ 
+     while (1) {
+--- a/erts/vsn.mk
++++ b/erts/vsn.mk
+@@ -18,7 +18,7 @@
+ # %CopyrightEnd%
+ # 
+ 
+-VSN = 7.3
++VSN = 7.3.1
+ 
+ # Port number 4365 in 4.2
+ # Port number 4366 in 4.3
+--- a/lib/inets/doc/src/mod_esi.xml
++++ b/lib/inets/doc/src/mod_esi.xml
+@@ -23,10 +23,6 @@
+     </legalnotice>
+ 
+     <title>mod_esi</title>
+-    <prepared>Joakim Greben&ouml;</prepared>
+-    <docno></docno>
+-    <date>1997-10-14</date>
+-    <rev>2.2</rev>
+     <file>mod_esi.sgml</file>
+   </header>
+   <module>mod_esi</module>
+@@ -39,6 +35,56 @@
+     <marker id="deliver"></marker>
+   </description>
+ 
++ <section>
++    <title>DATA TYPES</title>
++    <p>The following data types are used in the functions for mod_esi:</p>
++
++    <taglist>
++      <tag><c>env() = </c></tag>
++      <item> <p><c>{EnvKey()::atom(), Value::term()}</c></p>
++      </item>
++      
++      <p>Currently supported key value pairs</p>
++      <taglist>		
++	
++	<tag><c>{server_software, string()}</c></tag>
++	<item><p>Indicates the inets version.</p></item>
++	
++	<tag><c>{server_name, string()}</c></tag>
++	<item><p>The local hostname. </p></item>
++
++	<tag><c>{gateway_interface, string()}</c></tag>
++	<item><p>Legacy string used in CGI, just ignore.</p> </item>
++	
++	<tag><c>{server_protocol, string()}</c></tag>
++	<item><p> HTTP version, currently "HTTP/1.1"</p></item>
++	
++	<tag>{server_port, integer()}</tag>
++	<item><p>Servers port number.</p></item>
++	
++	<tag><c>{request_method, "GET | "PUT" | "DELETE | "POST" | "PATCH"}</c></tag>
++	
++	<tag><c>{remote_adress, inet:ip_address()} </c></tag>
++	<item><p>The clients ip address.</p></item>
++
++	<tag><c>{peer_cert, undefined | no_peercert | DER:binary()</c></tag>
++	<item>
++	  <p>For TLS connections where client certificates are used this will
++	  be an ASN.1 DER-encoded X509-certificate as an Erlang binary.
++	  If client certificates are not used the value will be <c>no_peercert</c>,
++	  and if TLS is not used (HTTP or connection is lost due to network failure)
++	  the value will be <c>undefined</c>.
++	</p></item>
++	
++	<tag><c>{script_name, string()}</c></tag>
++	<item><p>Request URI</p></item>
++
++	<tag><c>{http_LowerCaseHTTPHeaderName, string()}</c></tag>
++	<item><p>example: {http_content_type, "text/html"}</p></item>
++      </taglist>
++      
++    </taglist>
++
+   <funcs>
+     <func>
+       <name>deliver(SessionID, Data) -> ok | {error, Reason}</name>
+@@ -63,11 +109,11 @@
+ 	  overhead. Do not assume anything about the data type of 
+ 	  <c>SessionID</c>. <c>SessionID</c> must be the value given 
+ 	  as input to the ESI callback function that you implemented.</p>
+-	</note>
++	  </note>
+       </desc>
+     </func>
+   </funcs>
+-
++  </section>
+   <section>
+     <title>ESI Callback Functions</title>
+   </section>
+@@ -78,9 +124,7 @@
+       to the server process by calling <c>mod_esi:deliver/2</c>.</fsummary>
+       <type>
+         <v>SessionID = term()</v>
+-        <v>Env = [EnvironmentDirectives] ++ ParsedHeader</v>
+-        <v>EnvironmentDirectives = {Key,Value}</v>
+-        <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name</v>
++        <v>Env = env()</v>
+         <v>Input = string()</v>
+       </type>
+       <desc>
+@@ -111,9 +155,7 @@
+       <fsummary>Creates a dynamic web page and returns it as a list. 
+       This function is deprecated and is only kept for backwards compatibility.</fsummary>
+       <type>
+-        <v>Env = [EnvironmentDirectives] ++ ParsedHeader</v>
+-        <v>EnvironmentDirectives = {Key,Value}</v>
+-		  <v>Key = query_string | content_length | server_software | gateway_interface | server_protocol | server_port | request_method | remote_addr | script_name.</v>
++        <v>Env = env()</v>
+         <v>Input = string()</v>
+         <v>Response = string()</v>
+       </type>
+--- a/lib/inets/doc/src/notes.xml
++++ b/lib/inets/doc/src/notes.xml
+@@ -33,7 +33,37 @@
+     <file>notes.xml</file>
+   </header>
+   
+-  <section><title>Inets 6.2</title>
++  <section><title>Inets 6.2.2</title>
++
++    <section><title>Improvements and New Features</title>
++      <list>
++        <item>
++          <p>
++	    Add environment information item peer_cert to mod_esi</p>
++          <p>
++	    Own Id: OTP-13510</p>
++        </item>
++      </list>
++    </section>
++
++</section>
++
++<section><title>Inets 6.2.1</title>
++
++    <section><title>Fixed Bugs and Malfunctions</title>
++      <list>
++        <item>
++          <p>
++	    Mend ipv6_host_with_brackets option in httpc</p>
++          <p>
++	    Own Id: OTP-13417</p>
++        </item>
++      </list>
++    </section>
++
++</section>
++
++<section><title>Inets 6.2</title>
+ 
+     <section><title>Fixed Bugs and Malfunctions</title>
+       <list>
+--- a/lib/inets/src/http_client/httpc.erl
++++ b/lib/inets/src/http_client/httpc.erl
+@@ -556,7 +556,7 @@ handle_request(Method, Url,
+ 
+ 	    Request = #request{from          = Receiver,
+ 			       scheme        = Scheme, 
+-			       address       = {Host, Port},
++			       address       = {host_address(Host, BracketedHost), Port},
+ 			       path          = MaybeEscPath,
+ 			       pquery        = MaybeEscQuery,
+ 			       method        = Method,
+@@ -1268,3 +1268,7 @@ child_name(Pid, [_ | Children]) ->
+ %% d(_, _, _) ->
+ %%     ok.
+ 
++host_address(Host, false) ->
++    Host;
++host_address(Host, true) ->
++    string:strip(string:strip(Host, right, $]), left, $[).
+--- a/lib/inets/src/http_server/httpd_example.erl
++++ b/lib/inets/src/http_server/httpd_example.erl
+@@ -20,7 +20,7 @@
+ %%
+ -module(httpd_example).
+ -export([print/1]).
+--export([get/2, post/2, yahoo/2, test1/2, get_bin/2]).
++-export([get/2, post/2, yahoo/2, test1/2, get_bin/2, peer/2]).
+ 
+ -export([newformat/3]).
+ %% These are used by the inets test-suite
+@@ -94,10 +94,26 @@ default(Env,Input) ->
+    io_lib:format("~p",[httpd:parse_query(Input)]),"\n",
+    footer()].
+ 
++peer(Env, Input) ->
++   Header = 
++     case proplists:get_value(peer_cert, Env) of
++       undefined ->
++   	 header("text/html", "Peer-Cert-Exist:false");
++      _ ->
++         header("text/html", "Peer-Cert-Exist:true")
++     end,
++   [Header,
++   top("Test peer_cert environment option"),
++   "<B>Peer cert:</B> ",
++   io_lib:format("~p",[proplists:get_value(peer_cert, Env)]),"\n",
++   footer()].	   	 
++
+ header() ->
+   header("text/html").
+ header(MimeType) ->
+   "Content-type: " ++ MimeType ++ "\r\n\r\n".
++header(MimeType, Other) ->
++  "Content-type: " ++ MimeType ++ "\r\n" ++ Other ++ "\r\n\r\n".			 
+ 
+ top(Title) ->
+   "<HTML>
+--- a/lib/inets/src/http_server/httpd_script_env.erl
++++ b/lib/inets/src/http_server/httpd_script_env.erl
+@@ -61,6 +61,19 @@ which_port(#mod{config_db = ConfigDb}) ->
+ which_peername(#mod{init_data = #init_data{peername = {_, RemoteAddr}}}) ->
+     RemoteAddr.
+ 
++which_peercert(#mod{socket_type = {Type, _}, socket = Socket}) when Type == essl;
++								    Type == ssl ->
++    case ssl:peercert(Socket) of
++	{ok, Cert} ->
++	    Cert;
++	{error, no_peercert} -> 
++	    no_peercert;
++	_  ->
++	    undefined
++    end;
++which_peercert(_) -> %% Not an ssl connection
++    undefined.
++
+ which_resolve(#mod{init_data = #init_data{resolve = Resolve}}) ->
+     Resolve.
+ 
+@@ -78,6 +91,7 @@ create_basic_elements(esi, ModData) ->
+      {server_port,       which_port(ModData)},
+      {request_method,    which_method(ModData)},
+      {remote_addr,       which_peername(ModData)},
++     {peer_cert,         which_peercert(ModData)},
+      {script_name,       which_request_uri(ModData)}];
+ 
+ create_basic_elements(cgi, ModData) ->
+--- a/lib/inets/src/inets_app/inets.appup.src
++++ b/lib/inets/src/inets_app/inets.appup.src
+@@ -18,10 +18,16 @@
+ %% %CopyrightEnd%
+ {"%VSN%",
+  [
++  {<<"6.2.1">>, [{load_module, httpd_script_env, soft_purge, soft_purge, []}]},
++  {<<"6.2">>,   [{load_module, httpd_script_env, soft_purge, soft_purge, []},
++		 {load_module, httpc, soft_purge, soft_purge, []}]},
+   {<<"6\\..*">>,[{restart_application, inets}]},
+   {<<"5\\..*">>,[{restart_application, inets}]}
+  ],
+  [
++  {<<"6.2.1">>, [{load_module, httpd_script_env, soft_purge, soft_purge, []}]},
++  {<<"6.2">>,   [{load_module, httpd_script_env, soft_purge, soft_purge, []},
++		 {load_module, httpc, soft_purge, soft_purge, []}]},
+   {<<"6\\..*">>,[{restart_application, inets}]},
+   {<<"5\\..*">>,[{restart_application, inets}]}
+  ]
+--- a/lib/inets/test/httpd_SUITE.erl
++++ b/lib/inets/test/httpd_SUITE.erl
+@@ -755,7 +755,11 @@ esi(Config) when is_list(Config) ->
+     %% Check "ErlScriptNoCache" directive (default: false)
+     ok = http_status("GET /cgi-bin/erl/httpd_example:get ",
+ 		     Config, [{statuscode, 200},
+-		      {no_header, "cache-control"}]).
++		      {no_header, "cache-control"}]),
++    ok = http_status("GET /cgi-bin/erl/httpd_example:peer ",
++	  	     Config, [{statuscode, 200},
++	 	      {header, "peer-cert-exist", peer(Config)}]).
++ 
+ %%-------------------------------------------------------------------------
+ mod_esi_chunk_timeout(Config) when is_list(Config) -> 
+     ok = httpd_1_1:mod_esi_chunk_timeout(?config(type, Config), 
+@@ -2065,3 +2069,11 @@ response_default_headers() ->
+      {"X-Frame-Options", "SAMEORIGIN"},
+      %% Override built-in default
+      {"Date", "Override-date"}].
++
++peer(Config) ->
++   case proplists:get_value(type, Config) of
++      ssl ->
++        "true";
++      _ ->
++        "false"
++   end.   
+\ No newline at end of file
+--- a/lib/inets/vsn.mk
++++ b/lib/inets/vsn.mk
+@@ -19,6 +19,6 @@
+ # %CopyrightEnd%
+ 
+ APPLICATION = inets
+-INETS_VSN   = 6.2
++INETS_VSN   = 6.2.2
+ PRE_VSN     =
+ APP_VSN     = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
+--- a/lib/mnesia/doc/src/notes.xml
++++ b/lib/mnesia/doc/src/notes.xml
+@@ -39,7 +39,23 @@
+     thus constitutes one section in this document. The title of each
+     section is the version number of Mnesia.</p>
+ 
+-  <section><title>Mnesia 4.13.3</title>
++  <section><title>Mnesia 4.13.4</title>
++
++    <section><title>Fixed Bugs and Malfunctions</title>
++      <list>
++        <item>
++          <p>
++	    Mnesia transactions could hang while waiting on a
++	    response from a node who had stopped.</p>
++          <p>
++	    Own Id: OTP-13423</p>
++        </item>
++      </list>
++    </section>
++
++</section>
++
++<section><title>Mnesia 4.13.3</title>
+ 
+     <section><title>Fixed Bugs and Malfunctions</title>
+       <list>
+--- a/lib/mnesia/src/mnesia_tm.erl
++++ b/lib/mnesia/src/mnesia_tm.erl
+@@ -1692,13 +1692,10 @@ commit_participant(Coord, Tid, Bin, C0, DiscNs, _RamNs) ->
+ 			    ?eval_debug_fun({?MODULE, commit_participant, undo_prepare},
+ 					    [{tid, Tid}]);
+ 
+-			{'EXIT', _, _} ->
++			{'EXIT', _MnesiaTM, Reason} ->
++			    reply(Coord, {do_abort, Tid, self(), {bad_commit,Reason}}),
+ 			    mnesia_recover:log_decision(D#decision{outcome = aborted}),
+-			    ?eval_debug_fun({?MODULE, commit_participant, exit_log_abort},
+-					    [{tid, Tid}]),
+-			    mnesia_schema:undo_prepare_commit(Tid, C0),
+-			    ?eval_debug_fun({?MODULE, commit_participant, exit_undo_prepare},
+-					    [{tid, Tid}]);
++			    mnesia_schema:undo_prepare_commit(Tid, C0);
+ 
+ 			Msg ->
+ 			    verbose("** ERROR ** commit_participant ~p, got unexpected msg: ~p~n",
+@@ -2210,8 +2207,6 @@ reconfigure_coordinators(N, [{Tid, [Store | _]} | Coordinators]) ->
+ 		true ->
+ 		    send_mnesia_down(Tid, Store, N)
+ 	    end;
+-	aborted ->
+-	    ignore; % avoid spurious mnesia_down messages
+ 	_ ->
+ 	    %% Tell the coordinator about the mnesia_down
+ 	    send_mnesia_down(Tid, Store, N)
+--- a/lib/mnesia/vsn.mk
++++ b/lib/mnesia/vsn.mk
+@@ -1 +1 @@
+-MNESIA_VSN = 4.13.3
++MNESIA_VSN = 4.13.4
+--- a/lib/ssl/doc/src/notes.xml
++++ b/lib/ssl/doc/src/notes.xml
+@@ -28,6 +28,36 @@
+   <p>This document describes the changes made to the SSL application.</p>
+ 
+ 
++<section><title>SSL 7.3.1</title>
++
++    <section><title>Fixed Bugs and Malfunctions</title>
++      <list>
++        <item>
++          <p>
++	    Corrections to cipher suite handling using the 3 and 4
++	    tuple format in addition to commit
++	    89d7e21cf4ae988c57c8ef047bfe85127875c70c</p>
++          <p>
++	    Own Id: OTP-13511</p>
++        </item>
++      </list>
++    </section>
++
++
++    <section><title>Improvements and New Features</title>
++      <list>
++        <item>
++          <p>
++	    Make values for the TLS-1.2 signature_algorithms
++	    extension configurable</p>
++          <p>
++	    Own Id: OTP-13261</p>
++        </item>
++      </list>
++    </section>
++
++</section>
++
+ <section><title>SSL 7.3</title>
+ 
+     <section><title>Fixed Bugs and Malfunctions</title>
+--- a/lib/ssl/doc/src/ssl.xml
++++ b/lib/ssl/doc/src/ssl.xml
+@@ -421,7 +421,6 @@ fun(srp, Username :: string(), UserState :: term()) ->
+ 
+         <warning><p>Using <c>{padding_check, boolean()}</c> makes TLS
+ 	vulnerable to the Poodle attack.</p></warning>
+-
+   </section>
+   
+   <section>
+@@ -522,9 +521,45 @@ fun(srp, Username :: string(), UserState :: term()) ->
+ 	 be supported by the server for the prevention to work.
+ 	</p></warning>
+       </item>
+-    </taglist>
++      <tag><marker id="client_signature_algs"/><c>{signature_algs, [{hash(), ecdsa | rsa | dsa}]}</c></tag>
++	<item>
++	<p>In addition to the algorithms negotiated by the cipher
++	suite used for key exchange, payload encryption, message
++	authentication and pseudo random calculation, the TLS signature
++	algorithm extension <url
++	href="http://www.ietf.org/rfc/rfc5246.txt">Section 7.4.1.4.1 in RFC 5246</url> may be
++	used, from TLS 1.2, to negotiate which signature algorithm to use during the
++	TLS handshake. If no lower TLS versions than 1.2 are supported,
++	the client will send a TLS signature algorithm extension
++	with the algorithms specified by this option.
++	Defaults to
++	
++	<code>[
++%% SHA2
++{sha512, ecdsa},
++{sha512, rsa},
++{sha384, ecdsa},
++{sha384, rsa},
++{sha256, ecdsa},
++{sha256, rsa},
++{sha224, ecdsa},
++{sha224, rsa},
++%% SHA
++{sha, ecdsa},
++{sha, rsa},
++{sha, dsa},
++%% MD5
++{md5, rsa}
++]</code>
++	
++	The algorithms should be in the preferred order.
++	Selected signature algorithm can restrict which hash functions
++	that may be selected.
++	</p>
++	</item>
++      </taglist>
+    </section>
+-
++   
+   <section>
+     <title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title>
+ 
+@@ -651,6 +686,14 @@ fun(srp, Username :: string(), UserState :: term()) ->
+       <item>If true, use the server's preference for cipher selection. If false
+       (the default), use the client's preference.
+       </item>
++      
++      <tag><c>{signature_algs, [{hash(), ecdsa | rsa | dsa}]}</c></tag>
++      <item><p> The algorithms specified by
++      this option will be the ones accepted by the server in a signature algorithm
++      negotiation, introduced in TLS-1.2. The algorithms will also be offered to the client if a
++      client certificate is requested. For more details see the <seealso marker="#client_signature_algs">corresponding client option</seealso>.
++      </p> </item>
++
+     </taglist>
+   </section>
+   
+--- a/lib/ssl/src/dtls_connection.erl
++++ b/lib/ssl/src/dtls_connection.erl
+@@ -196,8 +196,7 @@ hello(start, #state{host = Host, port = Port, role = client,
+     {Record, State} = next_record(State1),
+     next_state(hello, hello, Record, State);
+ 
+-hello(Hello = #client_hello{client_version = ClientVersion,
+-			    extensions = #hello_extensions{hash_signs = HashSigns}},
++hello(Hello = #client_hello{client_version = ClientVersion},
+       State = #state{connection_states = ConnectionStates0,
+ 		     port = Port, session = #session{own_certificate = Cert} = Session0,
+ 		     renegotiation = {Renegotiation, _},
+@@ -209,9 +208,7 @@ hello(Hello = #client_hello{client_version = ClientVersion,
+         {Version, {Type, Session},
+ 	 ConnectionStates,
+ 	 #hello_extensions{ec_point_formats = EcPointFormats,
+-			   elliptic_curves = EllipticCurves} = ServerHelloExt} ->
+-            HashSign = ssl_handshake:select_hashsign(HashSigns, Cert, 
+-						     dtls_v1:corresponding_tls_version(Version)),
++			   elliptic_curves = EllipticCurves} = ServerHelloExt, HashSign} ->
+             ssl_connection:hello({common_client_hello, Type, ServerHelloExt, HashSign},
+ 				 State#state{connection_states  = ConnectionStates,
+ 					     negotiated_version = Version,
+--- a/lib/ssl/src/dtls_handshake.erl
++++ b/lib/ssl/src/dtls_handshake.erl
+@@ -94,7 +94,10 @@ hello(#server_hello{server_version = Version, random = Random,
+ 
+ hello(#client_hello{client_version = ClientVersion}, _Options, {_,_,_,_,ConnectionStates,_}, _Renegotiation) ->      
+     %% Return correct typ to make dialyzer happy until we have time to make the real imp.
+-    {ClientVersion, {new, #session{}}, ConnectionStates, #hello_extensions{}}.
++    HashSigns = tls_v1:default_signature_algs(dtls_v1:corresponding_tls_version(ClientVersion)),
++    {ClientVersion, {new, #session{}}, ConnectionStates, #hello_extensions{}, 
++     %% Placeholder for real hasign handling
++     hd(HashSigns)}.
+ 
+ %% hello(Address, Port,
+ %%       #ssl_tls{epoch = _Epoch, sequence_number = _Seq,
+--- a/lib/ssl/src/ssl.appup.src
++++ b/lib/ssl/src/ssl.appup.src
+@@ -1,9 +1,6 @@
+ %% -*- erlang -*-
+ {"%VSN%",
+  [
+-  {<<"7\\.2">>, [{load_module, tls_connection, soft_purge, soft_purge, []},
+-		 {load_module, ssl_tls_dist_proxy, soft_purge, soft_purge, []}
+-		]},
+   {<<"7\\..*">>, [{restart_application, ssl}]},
+   {<<"6\\..*">>, [{restart_application, ssl}]},
+   {<<"5\\..*">>, [{restart_application, ssl}]},
+@@ -11,9 +8,6 @@
+   {<<"3\\..*">>, [{restart_application, ssl}]}
+  ], 
+  [
+-  {<<"7\\.2">>, [{load_module, tls_connection, soft_purge, soft_purge, []},
+-		 {load_module, ssl_tls_dist_proxy, soft_purge, soft_purge, []}
+-		]},
+   {<<"7\\..*">>, [{restart_application, ssl}]},
+   {<<"6\\..*">>, [{restart_application, ssl}]},
+   {<<"5\\..*">>, [{restart_application, ssl}]},
+--- a/lib/ssl/src/ssl.erl
++++ b/lib/ssl/src/ssl.erl
+@@ -700,6 +700,10 @@ handle_options(Opts0, Role) ->
+ 		    srp_identity = handle_option(srp_identity, Opts, undefined),
+ 		    ciphers    = handle_cipher_option(proplists:get_value(ciphers, Opts, []), 
+ 						      RecordCb:highest_protocol_version(Versions)),
++		    signature_algs = handle_hashsigns_option(proplists:get_value(signature_algs, Opts, 
++									     default_option_role(server, 
++												 tls_v1:default_signature_algs(Versions), Role)),
++							 RecordCb:highest_protocol_version(Versions)), 
+ 		    %% Server side option
+ 		    reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun),
+ 		    reuse_sessions = handle_option(reuse_sessions, Opts, true),
+@@ -749,7 +753,7 @@ handle_options(Opts0, Role) ->
+ 		  alpn_preferred_protocols, next_protocols_advertised,
+ 		  client_preferred_next_protocols, log_alert,
+ 		  server_name_indication, honor_cipher_order, padding_check, crl_check, crl_cache,
+-		  fallback],
++		  fallback, signature_algs],
+ 
+     SockOpts = lists:foldl(fun(Key, PropList) ->
+ 				   proplists:delete(Key, PropList)
+@@ -989,6 +993,18 @@ validate_option(crl_cache, {Cb, {_Handle, Options}} = Value) when is_atom(Cb) an
+ validate_option(Opt, Value) ->
+     throw({error, {options, {Opt, Value}}}).
+ 
++handle_hashsigns_option(Value, {Major, Minor} = Version) when is_list(Value) 
++							      andalso Major >= 3 andalso Minor >= 3->
++    case tls_v1:signature_algs(Version, Value) of
++	[] ->
++	    throw({error, {options, no_supported_algorithms, {signature_algs, Value}}});
++	_ ->	
++	    Value
++    end;
++handle_hashsigns_option(_, {Major, Minor} = Version) when Major >= 3 andalso Minor >= 3->
++    handle_hashsigns_option(tls_v1:default_signature_algs(Version), Version);
++handle_hashsigns_option(_, _Version) ->
++    undefined.
+ 
+ validate_options([]) ->
+ 	[];
+@@ -1089,10 +1105,7 @@ binary_cipher_suites(Version, []) ->
+     %% Defaults to all supported suites that does
+     %% not require explicit configuration
+     ssl_cipher:filter_suites(ssl_cipher:suites(Version));
+-binary_cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility
+-    Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0],
+-    binary_cipher_suites(Version, Ciphers);
+-binary_cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
++binary_cipher_suites(Version, [Tuple|_] = Ciphers0) when is_tuple(Tuple) ->
+     Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
+     binary_cipher_suites(Version, Ciphers);
+ 
+@@ -1285,6 +1298,13 @@ new_ssl_options([{server_name_indication, Value} | Rest], #ssl_options{} = Opts,
+     new_ssl_options(Rest, Opts#ssl_options{server_name_indication = validate_option(server_name_indication, Value)}, RecordCB);
+ new_ssl_options([{honor_cipher_order, Value} | Rest], #ssl_options{} = Opts, RecordCB) -> 
+     new_ssl_options(Rest, Opts#ssl_options{honor_cipher_order = validate_option(honor_cipher_order, Value)}, RecordCB);
++new_ssl_options([{signature_algs, Value} | Rest], #ssl_options{} = Opts, RecordCB) -> 
++    new_ssl_options(Rest, 
++		    Opts#ssl_options{signature_algs = 
++					 handle_hashsigns_option(Value, 
++								 RecordCB:highest_protocol_version())}, 
++		    RecordCB);
++
+ new_ssl_options([{Key, Value} | _Rest], #ssl_options{}, _) -> 
+     throw({error, {options, {Key, Value}}}).
+ 
+--- a/lib/ssl/src/ssl_cipher.erl
++++ b/lib/ssl/src/ssl_cipher.erl
+@@ -43,11 +43,12 @@
+ 
+ -export_type([cipher_suite/0,
+ 	      erl_cipher_suite/0, openssl_cipher_suite/0,
+-	      key_algo/0]).
++	      hash/0, key_algo/0, sign_algo/0]).
+ 
+ -type cipher()            :: null |rc4_128 | idea_cbc | des40_cbc | des_cbc | '3des_ede_cbc' 
+ 			   | aes_128_cbc |  aes_256_cbc | aes_128_gcm | aes_256_gcm | chacha20_poly1305.
+ -type hash()              :: null | sha | md5 | sha224 | sha256 | sha384 | sha512.
++-type sign_algo()         :: rsa | dsa | ecdsa.
+ -type key_algo()          :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss | psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon.
+ -type erl_cipher_suite()  :: {key_algo(), cipher(), hash()} % Pre TLS 1.2 
+ 			     %% TLS 1.2, internally PRE TLS 1.2 will use default_prf
+@@ -841,17 +842,17 @@ suite({rsa_psk, aes_256_cbc,sha}) ->
+ 
+ %%% TLS 1.2 PSK Cipher Suites RFC 5487
+ 
+-suite({psk, aes_128_gcm, null}) ->
++suite({psk, aes_128_gcm, null, sha256}) ->
+     ?TLS_PSK_WITH_AES_128_GCM_SHA256;
+-suite({psk, aes_256_gcm, null}) ->
++suite({psk, aes_256_gcm, null, sha384}) ->
+     ?TLS_PSK_WITH_AES_256_GCM_SHA384;
+-suite({dhe_psk, aes_128_gcm, null}) ->
++suite({dhe_psk, aes_128_gcm, null, sha256}) ->
+     ?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
+-suite({dhe_psk, aes_256_gcm, null}) ->
++suite({dhe_psk, aes_256_gcm, null, sha384}) ->
+     ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
+-suite({rsa_psk, aes_128_gcm, null}) ->
++suite({rsa_psk, aes_128_gcm, null, sha256}) ->
+     ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256;
+-suite({rsa_psk, aes_256_gcm, null}) ->
++suite({rsa_psk, aes_256_gcm, null, sha384}) ->
+     ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384;
+ 
+ suite({psk, aes_128_cbc, sha256}) ->
+@@ -958,74 +959,74 @@ suite({ecdh_anon, aes_256_cbc, sha}) ->
+     ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA;
+ 
+ %%% RFC 5289 EC TLS suites
+-suite({ecdhe_ecdsa, aes_128_cbc, sha256}) ->
++suite({ecdhe_ecdsa, aes_128_cbc, sha256, sha256}) ->
+     ?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
+-suite({ecdhe_ecdsa, aes_256_cbc, sha384}) ->
++suite({ecdhe_ecdsa, aes_256_cbc, sha384, sha384}) ->
+     ?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
+-suite({ecdh_ecdsa, aes_128_cbc, sha256}) ->
++suite({ecdh_ecdsa, aes_128_cbc, sha256, sha256}) ->
+     ?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
+-suite({ecdh_ecdsa, aes_256_cbc, sha384}) ->
++suite({ecdh_ecdsa, aes_256_cbc, sha384, sha384}) ->
+     ?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
+-suite({ecdhe_rsa, aes_128_cbc, sha256}) ->
++suite({ecdhe_rsa, aes_128_cbc, sha256, sha256}) ->
+     ?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
+-suite({ecdhe_rsa, aes_256_cbc, sha384}) ->
++suite({ecdhe_rsa, aes_256_cbc, sha384, sha384}) ->
+     ?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
+-suite({ecdh_rsa, aes_128_cbc, sha256}) ->
++suite({ecdh_rsa, aes_128_cbc, sha256, sha256}) ->
+     ?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
+-suite({ecdh_rsa, aes_256_cbc, sha384}) ->
++suite({ecdh_rsa, aes_256_cbc, sha384, sha384}) ->
+     ?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
+ 
+ %% RFC 5288 AES-GCM Cipher Suites
+-suite({rsa, aes_128_gcm, null}) ->
++suite({rsa, aes_128_gcm, null, sha256}) ->
+     ?TLS_RSA_WITH_AES_128_GCM_SHA256;
+ suite({rsa, aes_256_gcm, null}) ->
+     ?TLS_RSA_WITH_AES_256_GCM_SHA384;
+-suite({dhe_rsa, aes_128_gcm, null}) ->
++suite({dhe_rsa, aes_128_gcm, null, sha384}) ->
+     ?TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
+-suite({dhe_rsa, aes_256_gcm, null}) ->
++suite({dhe_rsa, aes_256_gcm, null, sha256}) ->
+     ?TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
+-suite({dh_rsa, aes_128_gcm, null}) ->
++suite({dh_rsa, aes_128_gcm, null, sha384}) ->
+     ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256;
+-suite({dh_rsa, aes_256_gcm, null}) ->
++suite({dh_rsa, aes_256_gcm, null, sha256}) ->
+     ?TLS_DH_RSA_WITH_AES_256_GCM_SHA384;
+-suite({dhe_dss, aes_128_gcm, null}) ->
++suite({dhe_dss, aes_128_gcm, null, sha384}) ->
+     ?TLS_DHE_DSS_WITH_AES_128_GCM_SHA256;
+-suite({dhe_dss, aes_256_gcm, null}) ->
++suite({dhe_dss, aes_256_gcm, null, sha256}) ->
+     ?TLS_DHE_DSS_WITH_AES_256_GCM_SHA384;
+-suite({dh_dss, aes_128_gcm, null}) ->
++suite({dh_dss, aes_128_gcm, null, sha384}) ->
+     ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256;
+-suite({dh_dss, aes_256_gcm, null}) ->
++suite({dh_dss, aes_256_gcm, null, sha384}) ->
+     ?TLS_DH_DSS_WITH_AES_256_GCM_SHA384;
+-suite({dh_anon, aes_128_gcm, null}) ->
++suite({dh_anon, aes_128_gcm, null, sha256}) ->
+     ?TLS_DH_anon_WITH_AES_128_GCM_SHA256;
+-suite({dh_anon, aes_256_gcm, null}) ->
++suite({dh_anon, aes_256_gcm, null, sha384}) ->
+     ?TLS_DH_anon_WITH_AES_256_GCM_SHA384;
+ 
+ %% RFC 5289 ECC AES-GCM Cipher Suites
+-suite({ecdhe_ecdsa, aes_128_gcm, null}) ->
++suite({ecdhe_ecdsa, aes_128_gcm, null, sha256}) ->
+     ?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+-suite({ecdhe_ecdsa, aes_256_gcm, null}) ->
++suite({ecdhe_ecdsa, aes_256_gcm, null, sha384}) ->
+     ?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+-suite({ecdh_ecdsa, aes_128_gcm, null}) ->
++suite({ecdh_ecdsa, aes_128_gcm, null, sha256}) ->
+     ?TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
+-suite({ecdh_ecdsa, aes_256_gcm, null}) ->
++suite({ecdh_ecdsa, aes_256_gcm, null, sha384}) ->
+     ?TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
+-suite({ecdhe_rsa, aes_128_gcm, null}) ->
++suite({ecdhe_rsa, aes_128_gcm, null, sha256}) ->
+     ?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+-suite({ecdhe_rsa, aes_256_gcm, null}) ->
++suite({ecdhe_rsa, aes_256_gcm, null, sha384}) ->
+     ?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+-suite({ecdh_rsa, aes_128_gcm, null}) ->
++suite({ecdh_rsa, aes_128_gcm, null, sha256}) ->
+     ?TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
+-suite({ecdh_rsa, aes_256_gcm, null}) ->
++suite({ecdh_rsa, aes_256_gcm, null, sha384}) ->
+     ?TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
+ 
+ 
+ %% draft-agl-tls-chacha20poly1305-04 Chacha20/Poly1305 Suites
+-suite({ecdhe_rsa, chacha20_poly1305, null}) ->
++suite({ecdhe_rsa, chacha20_poly1305, null, sha256}) ->
+     ?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+-suite({ecdhe_ecdsa, chacha20_poly1305, null}) ->
++suite({ecdhe_ecdsa, chacha20_poly1305, null, sha256}) ->
+     ?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
+-suite({dhe_rsa, chacha20_poly1305, null}) ->
++suite({dhe_rsa, chacha20_poly1305, null, sha256}) ->
+     ?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256.
+ 
+ %%--------------------------------------------------------------------
+--- a/lib/ssl/src/ssl_connection.erl
++++ b/lib/ssl/src/ssl_connection.erl
+@@ -304,13 +304,9 @@ hello(#hello_request{}, #state{role = client} = State0, Connection) ->
+     {Record, State} = Connection:next_record(State0),
+     Connection:next_state(hello, hello, Record, State);
+ 
+-hello({common_client_hello, Type, ServerHelloExt, NegotiatedHashSign},
++hello({common_client_hello, Type, ServerHelloExt},
+       State, Connection) ->
+-    do_server_hello(Type, ServerHelloExt,
+-		    %% Note NegotiatedHashSign is only negotiated for real if
+-		    %% if TLS version is at least TLS-1.2 
+-		    State#state{hashsign_algorithm = NegotiatedHashSign}, Connection);
+-
++    do_server_hello(Type, ServerHelloExt, State, Connection);
+ hello(timeout, State, _) ->
+     {next_state, hello, State, hibernate};
+ 
+@@ -442,7 +438,8 @@ certify(#server_key_exchange{exchange_keys = Keys},
+        Alg == srp_dss; Alg == srp_rsa; Alg == srp_anon ->
+ 
+     Params = ssl_handshake:decode_server_key(Keys, Alg, Version),
+-    HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, Version),
++    %% Use negotiated value if TLS-1.2 otherwhise return default
++    HashSign = negotiated_hashsign(Params#server_key_params.hashsign, Alg, PubKeyInfo, Version),
+     case is_anonymous(Alg) of
+ 	true ->
+ 	    calculate_secret(Params#server_key_params.params,
+@@ -464,11 +461,18 @@ certify(#server_key_exchange{} = Msg,
+ 
+ certify(#certificate_request{hashsign_algorithms = HashSigns},
+ 	#state{session = #session{own_certificate = Cert},
+-        negotiated_version = Version} = State0, Connection) ->
+-    HashSign = ssl_handshake:select_hashsign(HashSigns, Cert, Version),
+-    {Record, State} = Connection:next_record(State0#state{client_certificate_requested = true}),
+-    Connection:next_state(certify, certify, Record,
+-			  State#state{cert_hashsign_algorithm = HashSign});
++	       key_algorithm = KeyExAlg,
++	       ssl_options = #ssl_options{signature_algs = SupportedHashSigns},
++	       negotiated_version = Version} = State0, Connection) ->
++
++    case ssl_handshake:select_hashsign(HashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
++	#alert {} = Alert ->
++	    Connection:handle_own_alert(Alert, Version, certify, State0);
++	NegotiatedHashSign -> 
++	    {Record, State} = Connection:next_record(State0#state{client_certificate_requested = true}),
++	    Connection:next_state(certify, certify, Record,
++				  State#state{cert_hashsign_algorithm = NegotiatedHashSign})
++    end;
+ 
+ %% PSK and RSA_PSK might bypass the Server-Key-Exchange
+ certify(#server_hello_done{},
+@@ -576,13 +580,15 @@ cipher(#hello_request{}, State0, Connection) ->
+ 
+ cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashSign},
+        #state{role = server,
+-	      public_key_info = {Algo, _, _} =PublicKeyInfo,
++	      key_algorithm = KexAlg,
++	      public_key_info = PublicKeyInfo,
+ 	      negotiated_version = Version,
+ 	      session = #session{master_secret = MasterSecret},
+ 	      tls_handshake_history = Handshake
+ 	     } = State0, Connection) ->
+-
+-    HashSign = ssl_handshake:select_hashsign_algs(CertHashSign, Algo, Version),
++    
++    %% Use negotiated value if TLS-1.2 otherwhise return default
++    HashSign = negotiated_hashsign(CertHashSign, KexAlg, PublicKeyInfo, Version),
+     case ssl_handshake:certificate_verify(Signature, PublicKeyInfo,
+ 					  Version, HashSign, MasterSecret, Handshake) of
+ 	valid ->
+@@ -1448,7 +1454,8 @@ rsa_psk_key_exchange(Version, PskIdentity, PremasterSecret, PublicKeyInfo = {Alg
+ rsa_psk_key_exchange(_, _, _, _) ->
+     throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)).
+ 
+-request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
++request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer, 
++						      signature_algs = SupportedHashSigns},
+ 			   connection_states = ConnectionStates0,
+ 			   cert_db = CertDbHandle,
+ 			   cert_db_ref = CertDbRef,
+@@ -1456,7 +1463,9 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
+     #connection_state{security_parameters =
+ 			  #security_parameters{cipher_suite = CipherSuite}} =
+ 	ssl_record:pending_connection_state(ConnectionStates0, read),
+-    Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version),
++    HashSigns = ssl_handshake:available_signature_algs(SupportedHashSigns, Version, [Version]),
++    Msg = ssl_handshake:certificate_request(CipherSuite, CertDbHandle, CertDbRef, 
++					    HashSigns, Version),
+     State = Connection:send_handshake(Msg, State0),
+     State#state{client_certificate_requested = true};
+ 
+@@ -1881,15 +1890,16 @@ make_premaster_secret({MajVer, MinVer}, rsa) ->
+ make_premaster_secret(_, _) ->
+     undefined.
+ 
+-negotiated_hashsign(undefined, Alg, Version) ->
++negotiated_hashsign(undefined, KexAlg, PubKeyInfo, Version) ->
+     %% Not negotiated choose default 
+-    case is_anonymous(Alg) of
++    case is_anonymous(KexAlg) of
+ 	true ->
+ 	    {null, anon};
+ 	false ->
+-	    ssl_handshake:select_hashsign_algs(Alg, Version)
++	    {PubAlg, _, _} = PubKeyInfo,
++	    ssl_handshake:select_hashsign_algs(undefined, PubAlg, Version)
+     end;
+-negotiated_hashsign(HashSign = {_, _}, _, _) ->
++negotiated_hashsign(HashSign = {_, _}, _, _, _) ->
+     HashSign.
+ 
+ ssl_options_list(SslOptions) ->
+--- a/lib/ssl/src/ssl_handshake.erl
++++ b/lib/ssl/src/ssl_handshake.erl
+@@ -46,7 +46,7 @@
+ 
+ %% Handshake messages
+ -export([hello_request/0, server_hello/4, server_hello_done/0,
+-	 certificate/4, certificate_request/4, key_exchange/3,
++	 certificate/4, certificate_request/5, key_exchange/3,
+ 	 finished/5,  next_protocol/1]).
+ 
+ %% Handle handshake messages
+@@ -64,8 +64,8 @@
+ 	]).
+ 
+ %% Cipher suites handling
+--export([available_suites/2, cipher_suites/2,
+-	 select_session/10, supported_ecc/1]).
++-export([available_suites/2, available_signature_algs/3, cipher_suites/2,
++	 select_session/11, supported_ecc/1]).
+ 
+ %% Extensions handling
+ -export([client_hello_extensions/6,
+@@ -74,8 +74,8 @@
+ 	]).
+ 
+ %% MISC
+--export([select_version/3, prf/5, select_hashsign/3, 
+-	 select_hashsign_algs/2, select_hashsign_algs/3,
++-export([select_version/3, prf/5, select_hashsign/5, 
++	 select_hashsign_algs/3,
+ 	 premaster_secret/2, premaster_secret/3, premaster_secret/4]).
+ 
+ %%====================================================================
+@@ -120,7 +120,8 @@ server_hello(SessionId, Version, ConnectionStates, Extensions) ->
+ server_hello_done() ->
+     #server_hello_done{}.
+ 
+-client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates, Renegotiation) ->
++client_hello_extensions(Host, Version, CipherSuites, 
++			#ssl_options{signature_algs = SupportedHashSigns, versions = AllVersions} = SslOpts, ConnectionStates, Renegotiation) ->
+     {EcPointFormats, EllipticCurves} =
+ 	case advertises_ec_ciphers(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites)) of
+ 	    true ->
+@@ -134,7 +135,7 @@ client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates,
+        renegotiation_info = renegotiation_info(tls_record, client,
+ 					       ConnectionStates, Renegotiation),
+        srp = SRP,
+-       hash_signs = advertised_hash_signs(Version),
++       signature_algs = available_signature_algs(SupportedHashSigns, Version, AllVersions),
+        ec_point_formats = EcPointFormats,
+        elliptic_curves = EllipticCurves,
+        alpn = encode_alpn(SslOpts#ssl_options.alpn_advertised_protocols, Renegotiation),
+@@ -203,14 +204,14 @@ client_certificate_verify(OwnCert, MasterSecret, Version,
+     end.
+ 
+ %%--------------------------------------------------------------------
+--spec certificate_request(ssl_cipher:cipher_suite(), db_handle(), certdb_ref(), ssl_record:ssl_version()) ->
+-    #certificate_request{}.
++-spec certificate_request(ssl_cipher:cipher_suite(), db_handle(), 
++			  certdb_ref(),  #hash_sign_algos{}, ssl_record:ssl_version()) ->
++				 #certificate_request{}.
+ %%
+ %% Description: Creates a certificate_request message, called by the server.
+ %%--------------------------------------------------------------------
+-certificate_request(CipherSuite, CertDbHandle, CertDbRef, Version) ->
++certificate_request(CipherSuite, CertDbHandle, CertDbRef, HashSigns, Version) ->
+     Types = certificate_types(ssl_cipher:suite_definition(CipherSuite), Version),
+-    HashSigns = advertised_hash_signs(Version),
+     Authorities = certificate_authorities(CertDbHandle, CertDbRef),
+     #certificate_request{
+ 		    certificate_types = Types,
+@@ -351,6 +352,9 @@ verify_server_key(#server_key_params{params_bin = EncParams,
+ %%
+ %% Description: Checks that the certificate_verify message is valid.
+ %%--------------------------------------------------------------------
++certificate_verify(_, _, _, undefined, _, _) ->
++    ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
++
+ certificate_verify(Signature, PublicKeyInfo, Version,
+ 		   HashSign = {HashAlgo, _}, MasterSecret, {_, Handshake}) ->
+     Hash = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
+@@ -379,10 +383,11 @@ verify_signature(_Version, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey,
+     end;
+ verify_signature(_Version, Hash, {HashAlgo, dsa}, Signature, {?'id-dsa', PublicKey, PublicKeyParams}) ->
+     public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams});
+-verify_signature(_Version, Hash, {HashAlgo, ecdsa}, Signature,
++verify_signature(_, Hash, {HashAlgo, _SignAlg}, Signature,
+ 		 {?'id-ecPublicKey', PublicKey, PublicKeyParams}) ->
+     public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams}).
+ 
++
+ %%--------------------------------------------------------------------
+ -spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit,
+ 	      verify_peer | verify_none, {fun(), term}, fun(), term(), term(),
+@@ -573,43 +578,46 @@ prf({3,_N}, Secret, Label, Seed, WantedLength) ->
+ 
+ 
+ %%--------------------------------------------------------------------
+--spec select_hashsign(#hash_sign_algos{}| undefined,  undefined | binary(), ssl_record:ssl_version()) ->
+-			      {atom(), atom()} | undefined.
++-spec select_hashsign(#hash_sign_algos{} | undefined,  undefined | binary(), 
++		      atom(), [atom()], ssl_record:ssl_version()) ->
++			     {atom(), atom()} | undefined  | #alert{}.
+ 
+ %%
+-%% Description:
++%% Description: Handles signature_algorithms extension
+ %%--------------------------------------------------------------------
+-select_hashsign(_, undefined, _Version) ->
++select_hashsign(_, undefined, _,  _, _Version) ->
+     {null, anon};
+ %% The signature_algorithms extension was introduced with TLS 1.2. Ignore it if we have
+ %% negotiated a lower version.
+-select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert, {Major, Minor} = Version)
+-  when Major >= 3 andalso Minor >= 3 ->
+-    #'OTPCertificate'{tbsCertificate = TBSCert} =public_key:pkix_decode_cert(Cert, otp),
++select_hashsign(HashSigns, Cert, KeyExAlgo, 
++		undefined, {Major, Minor} = Version)  when Major >= 3 andalso Minor >= 3->
++    select_hashsign(HashSigns, Cert, KeyExAlgo, tls_v1:default_signature_algs(Version), Version);
++select_hashsign(#hash_sign_algos{hash_sign_algos = HashSigns}, Cert, KeyExAlgo, SupportedHashSigns,
++		{Major, Minor}) when Major >= 3 andalso Minor >= 3 ->
++    #'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
+     #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
+-    DefaultHashSign = {_, Sign} = select_hashsign_algs(undefined, Algo, Version),
+-    case lists:filter(fun({sha, dsa}) ->
++    Sign = cert_sign(Algo),
++    case lists:filter(fun({sha, dsa = S}) when S == Sign ->
+ 			      true;
+ 			 ({_, dsa}) ->
+ 			      false;
+-			 ({Hash, S}) when  S == Sign ->
+-			      ssl_cipher:is_acceptable_hash(Hash,
+-							    proplists:get_value(hashs, crypto:supports()));
++			 ({_, _} = Algos) ->
++			      is_acceptable_hash_sign(Algos, Sign, KeyExAlgo, SupportedHashSigns);
+ 			 (_)  ->
+ 			      false
+ 		      end, HashSigns) of
+ 	[] ->
+-	    DefaultHashSign;
+-	[HashSign| _] ->
++	    ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
++	[HashSign | _] ->
+ 	    HashSign
+     end;
+-select_hashsign(_, Cert, Version) ->
++select_hashsign(_, Cert, _, _, Version) ->
+     #'OTPCertificate'{tbsCertificate = TBSCert} = public_key:pkix_decode_cert(Cert, otp),
+     #'OTPSubjectPublicKeyInfo'{algorithm = {_,Algo, _}} = TBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo,
+     select_hashsign_algs(undefined, Algo, Version).
+ 
+ %%--------------------------------------------------------------------
+--spec select_hashsign_algs(#hash_sign_algos{}| undefined, oid(), ssl_record:ssl_version()) ->
++-spec select_hashsign_algs({atom(), atom()}| undefined, oid(), ssl_record:ssl_version()) ->
+ 				  {atom(), atom()}.
+ 
+ %% Description: For TLS 1.2 hash function and signature algorithm pairs can be
+@@ -642,24 +650,6 @@ select_hashsign_algs(undefined, ?rsaEncryption, _) ->
+ select_hashsign_algs(undefined, ?'id-dsa', _) ->
+     {sha, dsa}.
+ 
+--spec select_hashsign_algs(atom(),  ssl_record:ssl_version()) -> {atom(), atom()}.
+-%% Wrap function to keep the knowledge of the default values in
+-%% one place only 
+-select_hashsign_algs(Alg, Version) when (Alg == rsa orelse
+-				    Alg == dhe_rsa orelse
+-				    Alg == dh_rsa orelse
+-				    Alg == ecdhe_rsa orelse
+-				    Alg == ecdh_rsa orelse
+-				    Alg == srp_rsa) ->    
+-    select_hashsign_algs(undefined, ?rsaEncryption, Version);
+-select_hashsign_algs(Alg, Version) when (Alg == dhe_dss orelse
+-				    Alg == dh_dss orelse
+-				    Alg == srp_dss) ->
+-    select_hashsign_algs(undefined, ?'id-dsa', Version);
+-select_hashsign_algs(Alg, Version) when (Alg == ecdhe_ecdsa orelse
+-					 Alg == ecdh_ecdsa) ->
+-    select_hashsign_algs(undefined, ?'id-ecPublicKey', Version).
+-
+ %%--------------------------------------------------------------------
+ -spec master_secret(atom(), ssl_record:ssl_version(), #session{} | binary(), #connection_states{},
+ 		   client | server) -> {binary(), #connection_states{}} | #alert{}.
+@@ -1063,9 +1053,56 @@ available_suites(UserSuites, Version) ->
+ 			    lists:member(Suite, ssl_cipher:all_suites(Version))
+ 		    end, UserSuites).
+ 
+-available_suites(ServerCert, UserSuites, Version, Curve) ->
++available_suites(ServerCert, UserSuites, Version, undefined, Curve) ->
+     ssl_cipher:filter(ServerCert, available_suites(UserSuites, Version))
+-	-- unavailable_ecc_suites(Curve).
++	-- unavailable_ecc_suites(Curve);
++available_suites(ServerCert, UserSuites, Version, HashSigns, Curve) ->
++    Suites = available_suites(ServerCert, UserSuites, Version, undefined, Curve),
++    filter_hashsigns(Suites, [ssl_cipher:suite_definition(Suite) || Suite <- Suites], HashSigns, []).
++filter_hashsigns([], [], _, Acc) ->
++    lists:reverse(Acc);
++filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns,
++		 Acc) when KeyExchange == dhe_ecdsa;
++			   KeyExchange == ecdhe_ecdsa ->
++    do_filter_hashsigns(ecdsa, Suite, Suites, Algos, HashSigns, Acc);
++
++filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns,
++		 Acc) when KeyExchange == rsa;
++			   KeyExchange == dhe_rsa;
++			   KeyExchange == ecdhe_rsa;
++			   KeyExchange == srp_rsa;
++			   KeyExchange == rsa_psk ->
++    do_filter_hashsigns(rsa, Suite, Suites, Algos, HashSigns, Acc);
++filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when 
++      KeyExchange == dhe_dss;
++      KeyExchange == srp_dss ->							       
++    do_filter_hashsigns(dsa, Suite, Suites, Algos, HashSigns, Acc);
++filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when 
++      KeyExchange == dh_dss; 
++      KeyExchange == dh_rsa; 
++      KeyExchange == dh_ecdsa;
++      KeyExchange == ecdh_rsa;    
++      KeyExchange == ecdh_ecdsa ->
++      %%  Fixed DH certificates MAY be signed with any hash/signature
++      %%  algorithm pair appearing in the hash_sign extension.  The names
++    %%  DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA are historical.
++    filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]);
++filter_hashsigns([Suite | Suites], [{KeyExchange,_,_,_} | Algos], HashSigns, Acc) when 
++      KeyExchange == dh_anon;
++      KeyExchange == ecdh_anon;
++      KeyExchange == srp_anon;
++      KeyExchange == psk;
++      KeyExchange == dhe_psk ->
++    %% In this case hashsigns is not used as the kexchange is anonaymous
++    filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]).
++
++do_filter_hashsigns(SignAlgo, Suite, Suites, Algos, HashSigns, Acc) ->
++    case lists:keymember(SignAlgo, 2, HashSigns) of
++	true ->
++	    filter_hashsigns(Suites, Algos, HashSigns, [Suite| Acc]);
++	false ->
++	    filter_hashsigns(Suites, Algos, HashSigns, Acc)
++    end.
+ 
+ unavailable_ecc_suites(no_curve) ->
+     ssl_cipher:ec_keyed_suites();
+@@ -1077,17 +1114,17 @@ cipher_suites(Suites, false) ->
+ cipher_suites(Suites, true) ->
+     Suites.
+ 
+-select_session(SuggestedSessionId, CipherSuites, Compressions, Port, #session{ecc = ECCCurve} = 
++select_session(SuggestedSessionId, CipherSuites, HashSigns, Compressions, Port, #session{ecc = ECCCurve} = 
+ 		   Session, Version,
+-	       #ssl_options{ciphers = UserSuites, honor_cipher_order = HCO} = SslOpts,
++	       #ssl_options{ciphers = UserSuites, honor_cipher_order = HonorCipherOrder} = SslOpts,
+ 	       Cache, CacheCb, Cert) ->
+     {SessionId, Resumed} = ssl_session:server_id(Port, SuggestedSessionId,
+ 						 SslOpts, Cert,
+ 						 Cache, CacheCb),
+     case Resumed of
+         undefined ->
+-	    Suites = available_suites(Cert, UserSuites, Version, ECCCurve),
+-	    CipherSuite = select_cipher_suite(CipherSuites, Suites, HCO),
++	    Suites = available_suites(Cert, UserSuites, Version, HashSigns, ECCCurve),
++	    CipherSuite = select_cipher_suite(CipherSuites, Suites, HonorCipherOrder),
+ 	    Compression = select_compression(Compressions),
+ 	    {new, Session#session{session_id = SessionId,
+ 				  cipher_suite = CipherSuite,
+@@ -1155,7 +1192,7 @@ handle_client_hello_extensions(RecordCB, Random, ClientCipherSuites,
+ 			       #hello_extensions{renegotiation_info = Info,
+ 						 srp = SRP,
+ 						 ec_point_formats = ECCFormat,
+-                         alpn = ALPN,
++						 alpn = ALPN,
+ 						 next_protocol_negotiation = NextProtocolNegotiation}, Version,
+ 			       #ssl_options{secure_renegotiate = SecureRenegotation,
+                                             alpn_preferred_protocols = ALPNPreferredProtocols} = Opts,
+@@ -1324,7 +1361,7 @@ handle_renegotiation_info(_RecordCB, ConnectionStates, SecureRenegotation) ->
+ 
+ hello_extensions_list(#hello_extensions{renegotiation_info = RenegotiationInfo,
+ 					srp = SRP,
+-					hash_signs = HashSigns,
++					signature_algs = HashSigns,
+ 					ec_point_formats = EcPointFormats,
+ 					elliptic_curves = EllipticCurves,
+                                         alpn = ALPN,
+@@ -1799,7 +1836,7 @@ dec_hello_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
+     <<?UINT16(SignAlgoListLen), SignAlgoList/binary>> = ExtData,
+     HashSignAlgos = [{ssl_cipher:hash_algorithm(Hash), ssl_cipher:sign_algorithm(Sign)} ||
+ 			<<?BYTE(Hash), ?BYTE(Sign)>> <= SignAlgoList],
+-    dec_hello_extensions(Rest, Acc#hello_extensions{hash_signs =
++    dec_hello_extensions(Rest, Acc#hello_extensions{signature_algs =
+ 						    #hash_sign_algos{hash_sign_algos = HashSignAlgos}});
+ 
+ dec_hello_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
+@@ -1899,7 +1936,7 @@ from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) ->
+ key_exchange_alg(rsa) ->
+     ?KEY_EXCHANGE_RSA;
+ key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss;
+-			    Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
++			   Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
+     ?KEY_EXCHANGE_DIFFIE_HELLMAN;
+ key_exchange_alg(Alg) when Alg == ecdhe_rsa; Alg == ecdh_rsa;
+ 			   Alg == ecdhe_ecdsa; Alg == ecdh_ecdsa;
+@@ -2008,27 +2045,16 @@ is_member(Suite, SupportedSuites) ->
+ select_compression(_CompressionMetodes) ->
+     ?NULL.
+ 
+--define(TLSEXT_SIGALG_RSA(MD), {MD, rsa}).
+--define(TLSEXT_SIGALG_DSA(MD), {MD, dsa}).
+--define(TLSEXT_SIGALG_ECDSA(MD), {MD, ecdsa}).
+-
+--define(TLSEXT_SIGALG(MD), ?TLSEXT_SIGALG_ECDSA(MD), ?TLSEXT_SIGALG_RSA(MD)).
+-
+-advertised_hash_signs({Major, Minor}) when Major >= 3 andalso Minor >= 3 ->
+-    HashSigns = [?TLSEXT_SIGALG(sha512),
+-		 ?TLSEXT_SIGALG(sha384),
+-		 ?TLSEXT_SIGALG(sha256),
+-		 ?TLSEXT_SIGALG(sha224),
+-		 ?TLSEXT_SIGALG(sha),
+-		 ?TLSEXT_SIGALG_DSA(sha),
+-		 ?TLSEXT_SIGALG_RSA(md5)],
+-    CryptoSupport = crypto:supports(),
+-    HasECC = proplists:get_bool(ecdsa,  proplists:get_value(public_keys, CryptoSupport)),
+-    Hashs = proplists:get_value(hashs, CryptoSupport),
+-    #hash_sign_algos{hash_sign_algos =
+-			 lists:filter(fun({Hash, ecdsa}) -> HasECC andalso proplists:get_bool(Hash, Hashs);
+-					 ({Hash, _}) -> proplists:get_bool(Hash, Hashs) end, HashSigns)};
+-advertised_hash_signs(_) ->
++available_signature_algs(undefined, _, _)  ->
++    undefined;
++available_signature_algs(SupportedHashSigns, {Major, Minor}, AllVersions) when Major >= 3 andalso Minor >= 3 ->
++    case tls_record:lowest_protocol_version(AllVersions) of
++	{3, 3} ->
++	    #hash_sign_algos{hash_sign_algos = SupportedHashSigns};
++	_ ->
++	    undefined
++    end;	
++available_signature_algs(_, _, _) ->
+     undefined.
+ 
+ psk_secret(PSKIdentity, PSKLookup) ->
+@@ -2123,3 +2149,25 @@ distpoints_lookup([DistPoint | Rest], Callback, CRLDbHandle) ->
+ 	CRLs ->
+ 	    [{DistPoint, {CRL, public_key:der_decode('CertificateList', CRL)}} ||  CRL <- CRLs]
+     end.	
++
++cert_sign(?rsaEncryption) ->
++    rsa;
++cert_sign(?'id-ecPublicKey') ->
++    ecdsa;
++cert_sign(?'id-dsa') ->
++    dsa;
++cert_sign(Alg) ->
++    {_, Sign} =public_key:pkix_sign_types(Alg),
++    Sign.
++
++is_acceptable_hash_sign({_, Sign} = Algos, Sign, _, SupportedHashSigns) ->
++    is_acceptable_hash_sign(Algos, SupportedHashSigns);
++is_acceptable_hash_sign(Algos,_, KeyExAlgo, SupportedHashSigns) when KeyExAlgo == dh_ecdsa;
++								     KeyExAlgo == ecdh_rsa;    
++								     KeyExAlgo == ecdh_ecdsa ->
++    is_acceptable_hash_sign(Algos, SupportedHashSigns); 
++is_acceptable_hash_sign(_,_,_,_) ->
++    false.
++is_acceptable_hash_sign(Algos, SupportedHashSigns) ->
++    lists:member(Algos, SupportedHashSigns).
++
+--- a/lib/ssl/src/ssl_handshake.hrl
++++ b/lib/ssl/src/ssl_handshake.hrl
+@@ -95,7 +95,7 @@
+ 
+ -record(hello_extensions, {
+ 	  renegotiation_info,
+-	  hash_signs,          % supported combinations of hashes/signature algos
++	  signature_algs,          % supported combinations of hashes/signature algos
+           alpn,
+ 	  next_protocol_negotiation = undefined, % [binary()]
+ 	  srp,
+--- a/lib/ssl/src/ssl_internal.hrl
++++ b/lib/ssl/src/ssl_internal.hrl
+@@ -135,7 +135,8 @@
+ 	  padding_check = true       :: boolean(),
+ 	  fallback = false           :: boolean(),
+ 	  crl_check                  :: boolean() | peer | best_effort, 
+-	  crl_cache
++	  crl_cache,
++	  signature_algs
+ 	  }).
+ 
+ -record(socket_options,
+--- a/lib/ssl/src/tls_connection.erl
++++ b/lib/ssl/src/tls_connection.erl
+@@ -182,8 +182,7 @@ hello(start, #state{host = Host, port = Port, role = client,
+     next_state(hello, hello, Record, State);
+ 
+ hello(Hello = #client_hello{client_version = ClientVersion,
+-			    extensions = #hello_extensions{hash_signs = HashSigns,
+-							   ec_point_formats = EcPointFormats,
++			    extensions = #hello_extensions{ec_point_formats = EcPointFormats,
+ 							   elliptic_curves = EllipticCurves}},
+       State = #state{connection_states = ConnectionStates0,
+ 		     port = Port, session = #session{own_certificate = Cert} = Session0,
+@@ -191,27 +190,28 @@ hello(Hello = #client_hello{client_version = ClientVersion,
+ 		     session_cache = Cache,
+ 		     session_cache_cb = CacheCb,
+ 		     negotiated_protocol = CurrentProtocol,
++		     key_algorithm = KeyExAlg,
+ 		     ssl_options = SslOpts}) ->
++
+     case tls_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
+-					      ConnectionStates0, Cert}, Renegotiation) of
++					      ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
+         #alert{} = Alert ->
+             handle_own_alert(Alert, ClientVersion, hello, State);
+         {Version, {Type, Session},
+-	 ConnectionStates, Protocol0, ServerHelloExt} ->
+-
++	 ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
+ 	    Protocol = case Protocol0 of
+-		undefined -> CurrentProtocol;
+-		_ -> Protocol0
+-	    end,
+-
+-            HashSign = ssl_handshake:select_hashsign(HashSigns, Cert, Version),
+-            ssl_connection:hello({common_client_hello, Type, ServerHelloExt, HashSign},
++			   undefined -> CurrentProtocol;
++			   _ -> Protocol0
++		       end,
++	    ssl_connection:hello({common_client_hello, Type, ServerHelloExt},
+ 				 State#state{connection_states  = ConnectionStates,
+ 					     negotiated_version = Version,
++					     hashsign_algorithm = HashSign,
+ 					     session = Session,
+ 					     client_ecc = {EllipticCurves, EcPointFormats},
+ 					     negotiated_protocol = Protocol}, ?MODULE)
+     end;
++
+ hello(Hello = #server_hello{},
+       #state{connection_states = ConnectionStates0,
+ 	     negotiated_version = ReqVersion,
+@@ -1069,3 +1069,4 @@ handle_sni_extension(#client_hello{extensions = HelloExtensions}, State0) ->
+     end;
+ handle_sni_extension(_, State0) ->
+     State0.
++
+--- a/lib/ssl/src/tls_handshake.erl
++++ b/lib/ssl/src/tls_handshake.erl
+@@ -56,7 +56,7 @@ client_hello(Host, Port, ConnectionStates,
+     Version = tls_record:highest_protocol_version(Versions),
+     Pending = ssl_record:pending_connection_state(ConnectionStates, read),
+     SecParams = Pending#connection_state.security_parameters,
+-    AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version), 
++    AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version),     
+     Extensions = ssl_handshake:client_hello_extensions(Host, Version, 
+ 						       AvailableCipherSuites,
+ 						       SslOpts, ConnectionStates, Renegotiation),
+@@ -80,13 +80,13 @@ client_hello(Host, Port, ConnectionStates,
+ -spec hello(#server_hello{} | #client_hello{}, #ssl_options{},
+ 	    #connection_states{} | {inet:port_number(), #session{}, db_handle(),
+ 				    atom(), #connection_states{}, 
+-				    binary() | undefined},
++				    binary() | undefined, ssl_cipher:key_algo()},
+ 	    boolean()) ->
+ 		   {tls_record:tls_version(), session_id(), 
+ 		    #connection_states{}, alpn | npn, binary() | undefined}|
+ 		   {tls_record:tls_version(), {resumed | new, #session{}}, 
+ 		    #connection_states{}, binary() | undefined, 
+-		    #hello_extensions{}} |
++		    #hello_extensions{}, {ssl_cipher:hash(), ssl_cipher:sign_algo()} | undefined} |
+ 		   #alert{}.
+ %%
+ %% Description: Handles a recieved hello message
+@@ -149,26 +149,35 @@ get_tls_handshake(Version, Data, Buffer) ->
+ %%% Internal functions
+ %%--------------------------------------------------------------------
+ handle_client_hello(Version, #client_hello{session_id = SugesstedId,
+-				       cipher_suites = CipherSuites,
+-				       compression_methods = Compressions,
+-				       random = Random,
+-				       extensions = #hello_extensions{elliptic_curves = Curves} = HelloExt},
+-		#ssl_options{versions = Versions} = SslOpts,
+-	 {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) ->
++					   cipher_suites = CipherSuites,
++					   compression_methods = Compressions,
++					   random = Random,
++					   extensions = #hello_extensions{elliptic_curves = Curves,
++									  signature_algs = ClientHashSigns} = HelloExt},
++		    #ssl_options{versions = Versions,
++				 signature_algs = SupportedHashSigns} = SslOpts,
++		    {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert, _}, Renegotiation) ->
+     case tls_record:is_acceptable_version(Version, Versions) of
+ 	true ->
++	    AvailableHashSigns = available_signature_algs(ClientHashSigns, SupportedHashSigns, Cert, Version),
+ 	    ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)),
+ 	    {Type, #session{cipher_suite = CipherSuite} = Session1}
+-		= ssl_handshake:select_session(SugesstedId, CipherSuites, Compressions,
++		= ssl_handshake:select_session(SugesstedId, CipherSuites, AvailableHashSigns, Compressions,
+ 					       Port, Session0#session{ecc = ECCCurve}, Version,
+ 					       SslOpts, Cache, CacheCb, Cert),
+ 	    case CipherSuite of 
+ 		no_suite ->
+ 		    ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
+ 		_ ->
+-		    handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt,
+-						   SslOpts, Session1, ConnectionStates0,
+-						   Renegotiation)
++		    {KeyExAlg,_,_,_} = ssl_cipher:suite_definition(CipherSuite),
++		    case ssl_handshake:select_hashsign(ClientHashSigns, Cert, KeyExAlg, SupportedHashSigns, Version) of
++			#alert{} = Alert ->
++			    Alert;
++			HashSign ->
++			    handle_client_hello_extensions(Version, Type, Random, CipherSuites, HelloExt,
++							   SslOpts, Session1, ConnectionStates0,
++							   Renegotiation, HashSign)
++		    end
+ 	    end;
+ 	false ->
+ 	    ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION)
+@@ -245,14 +254,14 @@ enc_handshake(HandshakeMsg, Version) ->
+ 
+ 
+ handle_client_hello_extensions(Version, Type, Random, CipherSuites,
+-			HelloExt, SslOpts, Session0, ConnectionStates0, Renegotiation) ->
++			HelloExt, SslOpts, Session0, ConnectionStates0, Renegotiation, HashSign) ->
+     try ssl_handshake:handle_client_hello_extensions(tls_record, Random, CipherSuites,
+ 						     HelloExt, Version, SslOpts,
+ 						     Session0, ConnectionStates0, Renegotiation) of
+ 	#alert{} = Alert ->
+ 	    Alert;
+ 	{Session, ConnectionStates, Protocol, ServerHelloExt} ->
+-	    {Version, {Type, Session}, ConnectionStates, Protocol, ServerHelloExt}
++	    {Version, {Type, Session}, ConnectionStates, Protocol, ServerHelloExt, HashSign}
+     catch throw:Alert ->
+ 	    Alert
+     end.
+@@ -269,3 +278,12 @@ handle_server_hello_extensions(Version, SessionId, Random, CipherSuite,
+ 	    {Version, SessionId, ConnectionStates, ProtoExt, Protocol}
+     end.
+ 
++available_signature_algs(undefined, SupportedHashSigns, _, {Major, Minor}) when (Major < 3) andalso (Minor < 3) ->
++    SupportedHashSigns;
++available_signature_algs(#hash_sign_algos{hash_sign_algos = ClientHashSigns}, SupportedHashSigns, 
++		     _, {Major, Minor}) when (Major < 3) andalso (Minor < 3) ->
++    ordsets:intersection(ClientHashSigns, SupportedHashSigns);
++available_signature_algs(_, _, _, _) -> 
++    undefined.
++
++
+--- a/lib/ssl/src/tls_v1.erl
++++ b/lib/ssl/src/tls_v1.erl
+@@ -31,7 +31,8 @@
+ 
+ -export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7,
+ 	 setup_keys/8, suites/1, prf/5,
+-	 ecc_curves/1, oid_to_enum/1, enum_to_oid/1]).
++	 ecc_curves/1, oid_to_enum/1, enum_to_oid/1, 
++	 default_signature_algs/1, signature_algs/2]).
+ 
+ %%====================================================================
+ %% Internal application API
+@@ -258,6 +259,54 @@ suites(3) ->
+     ] ++ suites(2).
+ 
+ 
++
++signature_algs({3, 3}, HashSigns) ->
++    CryptoSupports =  crypto:supports(),
++    Hashes = proplists:get_value(hashs, CryptoSupports),
++    PubKeys = proplists:get_value(public_keys, CryptoSupports),
++    Supported = lists:foldl(fun({Hash, dsa = Sign} = Alg, Acc) ->
++				    case proplists:get_bool(dss, PubKeys) 
++					andalso proplists:get_bool(Hash, Hashes)
++					andalso is_pair(Hash, Sign, Hashes)
++				    of
++					true ->
++					    [Alg | Acc];
++					false ->
++					    Acc
++				    end;
++			       ({Hash, Sign} = Alg, Acc) -> 
++				    case proplists:get_bool(Sign, PubKeys) 
++					andalso proplists:get_bool(Hash, Hashes) 
++					andalso is_pair(Hash, Sign, Hashes)
++				    of
++					true ->
++					    [Alg | Acc];
++					false ->
++					    Acc
++				    end
++			    end, [], HashSigns),
++    lists:reverse(Supported).
++
++default_signature_algs({3, 3} = Version) ->
++    Default = [%% SHA2
++	       {sha512, ecdsa},
++	       {sha512, rsa},
++	       {sha384, ecdsa},
++	       {sha384, rsa},
++	       {sha256, ecdsa},
++	       {sha256, rsa},
++	       {sha224, ecdsa},
++	       {sha224, rsa},
++	       %% SHA
++	       {sha, ecdsa},
++	       {sha, rsa},
++	       {sha, dsa},
++	       %% MD5
++	       {md5, rsa}],
++    signature_algs(Version, Default);
++default_signature_algs(_) ->
++    undefined.
++
+ %%--------------------------------------------------------------------
+ %%% Internal functions
+ %%--------------------------------------------------------------------
+@@ -342,6 +391,17 @@ finished_label(client) ->
+ finished_label(server) ->
+     <<"server finished">>.
+ 
++is_pair(sha, dsa, _) ->
++    true;
++is_pair(_, dsa, _) ->
++    false;
++is_pair(Hash, ecdsa, Hashs) ->
++    AtLeastSha = Hashs -- [md2,md4,md5],
++    lists:member(Hash, AtLeastSha);
++is_pair(Hash, rsa, Hashs) ->
++    AtLeastMd5 = Hashs -- [md2,md4],
++    lists:member(Hash, AtLeastMd5).
++
+ %% list ECC curves in prefered order
+ ecc_curves(_Minor) ->
+     TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
+--- a/lib/ssl/test/ssl_basic_SUITE.erl
++++ b/lib/ssl/test/ssl_basic_SUITE.erl
+@@ -58,7 +58,7 @@ all() ->
+ groups() ->
+     [{basic, [], basic_tests()},
+      {options, [], options_tests()},
+-     {'tlsv1.2', [], all_versions_groups()},
++     {'tlsv1.2', [], all_versions_groups() ++ [conf_signature_algs, no_common_signature_algs]},
+      {'tlsv1.1', [], all_versions_groups()},
+      {'tlsv1', [], all_versions_groups() ++ rizzo_tests()},
+      {'sslv3', [], all_versions_groups() ++ rizzo_tests() ++ [ciphersuite_vs_version]},
+@@ -168,6 +168,7 @@ renegotiate_tests() ->
+ 
+ cipher_tests() ->
+     [cipher_suites,
++     cipher_suites_mix,
+      ciphers_rsa_signed_certs,
+      ciphers_rsa_signed_certs_openssl_names,
+      ciphers_dsa_signed_certs,
+@@ -445,7 +446,7 @@ connection_info(Config) when is_list(Config) ->
+ 			   {from, self()}, 
+ 			   {mfa, {?MODULE, connection_info_result, []}},
+ 			   {options, 
+-			    [{ciphers,[{rsa,des_cbc,sha,no_export}]} | 
++			    [{ciphers,[{rsa,des_cbc,sha}]} | 
+ 			     ClientOpts]}]),
+     
+     ct:log("Testcase ~p, Client ~p  Server ~p ~n",
+@@ -911,6 +912,31 @@ cipher_suites(Config) when is_list(Config) ->
+     [_|_] =ssl:cipher_suites(openssl).
+ 
+ %%--------------------------------------------------------------------
++cipher_suites_mix() ->
++    [{doc,"Test to have old and new cipher suites at the same time"}].
++
++cipher_suites_mix(Config) when is_list(Config) -> 
++    CipherSuites = [{ecdh_rsa,aes_128_cbc,sha256,sha256}, {rsa,aes_128_cbc,sha}],
++    ClientOpts = ?config(client_opts, Config),
++    ServerOpts = ?config(server_opts, Config),
++
++    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
++
++    Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
++					{from, self()},
++					{mfa, {ssl_test_lib, send_recv_result_active, []}},
++					{options, ServerOpts}]),
++    Port = ssl_test_lib:inet_port(Server),
++    Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
++					{host, Hostname},
++					{from, self()},
++					{mfa, {ssl_test_lib, send_recv_result_active, []}},
++					{options, [{ciphers, CipherSuites} | ClientOpts]}]),
++
++    ssl_test_lib:check_result(Server, ok, Client, ok),
++    ssl_test_lib:close(Server),
++    ssl_test_lib:close(Client).
++%%--------------------------------------------------------------------
+ socket_options() ->
+     [{doc,"Test API function getopts/2 and setopts/2"}].
+ 
+@@ -2876,7 +2902,61 @@ ciphersuite_vs_version(Config) when is_list(Config) ->
+ 	_ ->
+ 	    ct:fail({unexpected_server_hello, ServerHello})
+     end.
+-										
++			
++%%--------------------------------------------------------------------
++conf_signature_algs() ->
++    [{doc,"Test to set the signature_algs option on both client and server"}].
++conf_signature_algs(Config) when is_list(Config) -> 
++    ClientOpts = ?config(client_opts, Config),
++    ServerOpts = ?config(server_opts, Config),
++    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
++    Server = 
++	ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 
++				   {from, self()}, 
++				   {mfa, {ssl_test_lib, send_recv_result, []}},
++				   {options,  [{active, false}, {signature_algs, [{sha256, rsa}]} | ServerOpts]}]),
++    Port = ssl_test_lib:inet_port(Server),
++    Client = 
++	ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, 
++				   {host, Hostname},
++				   {from, self()}, 
++				   {mfa, {ssl_test_lib, send_recv_result, []}},
++				   {options, [{active, false}, {signature_algs, [{sha256, rsa}]} | ClientOpts]}]),
++    
++    ct:log("Testcase ~p, Client ~p  Server ~p ~n",
++			 [self(), Client, Server]),
++    
++    ssl_test_lib:check_result(Server, ok, Client, ok),
++    
++    ssl_test_lib:close(Server),
++    ssl_test_lib:close(Client).
++
++
++%%--------------------------------------------------------------------
++no_common_signature_algs()  ->
++    [{doc,"Set the signature_algs option so that there client and server does not share any hash sign algorithms"}].
++no_common_signature_algs(Config) when is_list(Config) ->
++    
++    ClientOpts = ?config(client_opts, Config),
++    ServerOpts = ?config(server_opts, Config),
++
++    {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
++
++
++    Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
++					      {from, self()},
++					      {options, [{signature_algs, [{sha256, rsa}]}
++							 | ServerOpts]}]),
++    Port = ssl_test_lib:inet_port(Server),
++    Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
++					      {host, Hostname},
++					      {from, self()}, 
++					      {options, [{signature_algs, [{sha384, rsa}]}
++							 | ClientOpts]}]),
++    
++    ssl_test_lib:check_result(Server, {error, {tls_alert, "insufficient security"}},
++			      Client, {error, {tls_alert, "insufficient security"}}).
++    						
+ %%--------------------------------------------------------------------
+ 
+ dont_crash_on_handshake_garbage() ->
+--- a/lib/ssl/test/ssl_handshake_SUITE.erl
++++ b/lib/ssl/test/ssl_handshake_SUITE.erl
+@@ -166,10 +166,10 @@ ignore_hassign_extension_pre_tls_1_2(Config) ->
+     CertFile = proplists:get_value(certfile, Opts),
+     [{_, Cert, _}] = ssl_test_lib:pem_to_der(CertFile),
+     HashSigns = #hash_sign_algos{hash_sign_algos = [{sha512, rsa}, {sha, dsa}]},
+-    {sha512, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, {3,3}),
++    {sha512, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,3}), {3,3}),
+     %%% Ignore
+-    {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, {3,2}),
+-    {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, {3,0}).
++    {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,2}), {3,2}),
++    {md5sha, rsa} = ssl_handshake:select_hashsign(HashSigns, Cert, ecdhe_rsa, tls_v1:default_signature_algs({3,0}), {3,0}).
+ 
+ is_supported(Hash) ->
+     Algos = crypto:supports(),
+--- a/lib/ssl/test/ssl_test_lib.erl
++++ b/lib/ssl/test/ssl_test_lib.erl
+@@ -905,8 +905,8 @@ anonymous_suites() ->
+ 	 {dh_anon, '3des_ede_cbc', sha},
+ 	 {dh_anon, aes_128_cbc, sha},
+ 	 {dh_anon, aes_256_cbc, sha},
+-	 {dh_anon, aes_128_gcm, null},
+-	 {dh_anon, aes_256_gcm, null},
++	 {dh_anon, aes_128_gcm, null, sha256},
++	 {dh_anon, aes_256_gcm, null, sha384},
+ 	 {ecdh_anon,rc4_128,sha},
+ 	 {ecdh_anon,'3des_ede_cbc',sha},
+ 	 {ecdh_anon,aes_128_cbc,sha},
+@@ -933,12 +933,12 @@ psk_suites() ->
+ 	 {rsa_psk, aes_256_cbc, sha},
+ 	 {rsa_psk, aes_128_cbc, sha256},
+ 	 {rsa_psk, aes_256_cbc, sha384},
+-	 {psk, aes_128_gcm, null},
+-	 {psk, aes_256_gcm, null},
+-	 {dhe_psk, aes_128_gcm, null},
+-	 {dhe_psk, aes_256_gcm, null},
+-	 {rsa_psk, aes_128_gcm, null},
+-	 {rsa_psk, aes_256_gcm, null}],
++	 {psk, aes_128_gcm, null, sha256},
++	 {psk, aes_256_gcm, null, sha384},
++	 {dhe_psk, aes_128_gcm, null, sha256},
++	 {dhe_psk, aes_256_gcm, null, sha384},
++	 {rsa_psk, aes_128_gcm, null, sha256},
++	 {rsa_psk, aes_256_gcm, null, sha384}],
+     ssl_cipher:filter_suites(Suites).
+ 
+ psk_anon_suites() ->
+--- a/lib/ssl/vsn.mk
++++ b/lib/ssl/vsn.mk
+@@ -1 +1 @@
+-SSL_VSN = 7.3
++SSL_VSN = 7.3.1
+--- a/otp_versions.table
++++ b/otp_versions.table
+@@ -1,3 +1,5 @@
++OTP-18.3.2 : inets-6.2.2 ssl-7.3.1 # asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3.1 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 mnesia-4.13.4 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
++OTP-18.3.1 : erts-7.3.1 inets-6.2.1 mnesia-4.13.4 # asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2.1 cosProperty-1.2 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 et-1.5.1 eunit-2.2.13 gs-1.6 hipe-3.15 ic-4.4 jinterface-1.6.1 kernel-4.2 megaco-3.18 observer-2.1.2 odbc-2.11.1 orber-3.8.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1.1 reltool-0.7 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 ssl-7.3 stdlib-2.8 syntax_tools-1.7 test_server-3.10 tools-2.8.3 typer-0.9.10 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 :
+ OTP-18.3 : asn1-4.0.2 common_test-1.12 compiler-6.0.3 cosNotification-1.2.1 cosTime-1.2.1 cosTransactions-1.3.1 crypto-3.6.3 debugger-4.1.2 dialyzer-2.9 diameter-1.11.2 edoc-0.7.18 eldap-1.2.1 erl_docgen-0.4.2 erl_interface-3.8.2 erts-7.3 eunit-2.2.13 hipe-3.15 inets-6.2 kernel-4.2 mnesia-4.13.3 observer-2.1.2 orber-3.8.1 public_key-1.1.1 runtime_tools-1.9.3 sasl-2.7 snmp-5.2.2 ssh-4.2.2 ssl-7.3 stdlib-2.8 test_server-3.10 tools-2.8.3 webtool-0.9.1 wx-1.6.1 xmerl-1.3.10 # cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosProperty-1.2 et-1.5.1 gs-1.6 ic-4.4 jinterface-1.6.1 megaco-3.18 odbc-2.11.1 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 reltool-0.7 syntax_tools-1.7 typer-0.9.10 :
+ OTP-18.2.4 : common_test-1.11.2 # asn1-4.0.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 inets-6.1.1 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2.1 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+ OTP-18.2.3 : inets-6.1.1 # asn1-4.0.1 common_test-1.11.1 compiler-6.0.2 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6.2 debugger-4.1.1 dialyzer-2.8.2 diameter-1.11.1 edoc-0.7.17 eldap-1.2 erl_docgen-0.4.1 erl_interface-3.8.1 erts-7.2.1 et-1.5.1 eunit-2.2.12 gs-1.6 hipe-3.14 ic-4.4 jinterface-1.6.1 kernel-4.1.1 megaco-3.18 mnesia-4.13.2 observer-2.1.1 odbc-2.11.1 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1.1 percept-0.8.11 public_key-1.1 reltool-0.7 runtime_tools-1.9.2 sasl-2.6.1 snmp-5.2.1 ssh-4.2.1 ssl-7.2 stdlib-2.7 syntax_tools-1.7 test_server-3.9.1 tools-2.8.2 typer-0.9.10 webtool-0.9 wx-1.6 xmerl-1.3.9 :
+@@ -14,6 +16,7 @@ OTP-18.0.3 : erts-7.0.3 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 co
+ OTP-18.0.2 : erts-7.0.2 runtime_tools-1.9.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
+ OTP-18.0.1 : erts-7.0.1 # asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 :
+ OTP-18.0 : asn1-4.0 common_test-1.11 compiler-6.0 cosEvent-2.2 cosEventDomain-1.2 cosFileTransfer-1.2 cosNotification-1.2 cosProperty-1.2 cosTime-1.2 cosTransactions-1.3 crypto-3.6 debugger-4.1 dialyzer-2.8 diameter-1.10 edoc-0.7.17 eldap-1.2 erl_docgen-0.4 erl_interface-3.8 erts-7.0 et-1.5.1 eunit-2.2.10 gs-1.6 hipe-3.12 ic-4.4 inets-6.0 jinterface-1.6 kernel-4.0 megaco-3.18 mnesia-4.13 observer-2.1 odbc-2.11 orber-3.8 os_mon-2.4 ose-1.1 otp_mibs-1.1 parsetools-2.1 percept-0.8.11 public_key-1.0 reltool-0.7 runtime_tools-1.9 sasl-2.5 snmp-5.2 ssh-4.0 ssl-7.0 stdlib-2.5 syntax_tools-1.7 test_server-3.9 tools-2.8 typer-0.9.9 webtool-0.9 wx-1.4 xmerl-1.3.8 # :
++OTP-17.5.6.9 : diameter-1.9.2.4 erts-6.4.1.6 ssl-6.0.1.2 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+ OTP-17.5.6.8 : diameter-1.9.2.3 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.5 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+ OTP-17.5.6.7 : diameter-1.9.2.2 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 erts-6.4.1.5 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
+ OTP-17.5.6.6 : erts-6.4.1.5 # asn1-3.0.4 common_test-1.10.1 compiler-5.0.4 cosEvent-2.1.15 cosEventDomain-1.1.14 cosFileTransfer-1.1.16 cosNotification-1.1.21 cosProperty-1.1.17 cosTime-1.1.14 cosTransactions-1.2.14 crypto-3.5 debugger-4.0.3.1 dialyzer-2.7.4 diameter-1.9.2.1 edoc-0.7.16 eldap-1.1.1 erl_docgen-0.3.7 erl_interface-3.7.20 et-1.5 eunit-2.2.9 gs-1.5.16 hipe-3.11.3 ic-4.3.6 inets-5.10.9 jinterface-1.5.12 kernel-3.2.0.1 megaco-3.17.3 mnesia-4.12.5 observer-2.0.4 odbc-2.10.22 orber-3.7.1 os_mon-2.3.1 ose-1.0.2 otp_mibs-1.0.10 parsetools-2.0.12 percept-0.8.10 public_key-0.23 reltool-0.6.6 runtime_tools-1.8.16.1 sasl-2.4.1 snmp-5.1.2 ssh-3.2.4 ssl-6.0.1.1 stdlib-2.4 syntax_tools-1.6.18 test_server-3.8.1 tools-2.7.2 typer-0.9.8 webtool-0.8.10 wx-1.3.3 xmerl-1.3.7 :
diff --git a/community/erlang/APKBUILD b/community/erlang/APKBUILD
index 108b64b..34424f4 100644
--- a/community/erlang/APKBUILD
+++ b/community/erlang/APKBUILD
@@ -2,7 +2,7 @@
 # Maintainer: Marlus Saraiva <[email-masked]>
 
 pkgname=erlang
-pkgver=18.3
+pkgver=18.3.2
 _srcver=18.3
 pkgrel=0
 pkgdesc="General-purpose programming language and runtime environment"
@@ -74,7 +74,8 @@ source="http://www.erlang.org/download/otp_src_$_srcver.tar.gz
         0006-Do-not-install-erlang-sources.patch
         0007-Split-off-webtool-dependency-from-tools.patch
         0010-fix-nteventlog-remove.patch
-        0060-set-disksup_posix_only-to-true.patch"
+        0060-set-disksup_posix_only-to-true.patch
+        0070-otp-update-version-18.3.2.patch"
 
 _builddir="$srcdir"/otp_src_$_srcver
 
@@ -217,7 +218,8 @@ f4aa0cc27dc57ea4dcd57191b1948a4d  0005-Do-not-install-nteventlog-and-related-doc
 a8e9e58c2444ac3994a6b418fd387369  0006-Do-not-install-erlang-sources.patch
 b438c37818b5c82443682c3693dd7e53  0007-Split-off-webtool-dependency-from-tools.patch
 0dd300003ff68fc46dc3c839c2541d53  0010-fix-nteventlog-remove.patch
-d17fbaafa9f7820ade09b239c00aede6  0060-set-disksup_posix_only-to-true.patch"
+d17fbaafa9f7820ade09b239c00aede6  0060-set-disksup_posix_only-to-true.patch
+b0d5cf3bac335964a1c8ffd98d9f105d  0070-otp-update-version-18.3.2.patch"
 sha256sums="fdab8129a1cb935db09f1832e3a7d511a4aeb2b9bb3602ca6a7ccb9730d5c9c3  otp_src_18.3.tar.gz
 536e78192f915733cbbb264883af6d9b11c9e70c2c4d3d825b58c4dbec36db86  0001-Do-not-format-man-pages-and-do-not-install-miscellan.patch
 b2e5844215d7f5f5026a77342dd698d16103cc726d23f8265bcc8399d1a82bb9  0002-Remove-rpath.patch
@@ -227,7 +229,8 @@ b2e5844215d7f5f5026a77342dd698d16103cc726d23f8265bcc8399d1a82bb9  0002-Remove-rp
 fcf2c37b3eaddd3e1bea2880c1b80f010623743ab2f43e144e0ecc7be874d4ff  0006-Do-not-install-erlang-sources.patch
 9704a53bc4bd6f5624f9ce3f201128204011f4579f19b547df74d92ae22777cf  0007-Split-off-webtool-dependency-from-tools.patch
 019c62ea3fee60068caa8c3152d7f96e76591fc5dc096abfcea48ec1593eb758  0010-fix-nteventlog-remove.patch
-3ffda0b3acbde755b496c1a974c20e1ca580432c403944c1c16836f48e248429  0060-set-disksup_posix_only-to-true.patch"
+3ffda0b3acbde755b496c1a974c20e1ca580432c403944c1c16836f48e248429  0060-set-disksup_posix_only-to-true.patch
+ec32540b798d2b3a7b8271cf95c63423dda864b24c8765368835295bf4575c61  0070-otp-update-version-18.3.2.patch"
 sha512sums="f4a69bb14743d9f913d7060cfb6426f7c54693d07ed439506ede5160a0ba5a79a81cf08a56aaa02c68b3377cd22fed66a0fbeb216378330d7ad5c6348ed82014  otp_src_18.3.tar.gz
 172f9b0f61748bf2f04737df0451bcc9c0812db0f365f0ef7c7c244fceb991987f79a5274eea578a89cc7d077f84645d1395d9dbcbf14010268b896a080c2ccf  0001-Do-not-format-man-pages-and-do-not-install-miscellan.patch
 97c40c185b71b23ffcb924639af390b9a0be897070e396a9413e193e6d43048dfe3b86bcd0c5598b81a66ce1349de9e09f5228a452b51b6612cd947bbafb6377  0002-Remove-rpath.patch
@@ -237,4 +240,5 @@ b174e3c9103aa26e3b4993ae77b849a55f733e6f8e5dd7bb641a8548aea7fcc91b99d772c91ff886
 ef9045ec689e2a6517dba7626c1225a9a265f14675d704effd324529c3d5128260ba64cebfd41185364d2c5ac9a644ccc7088d0031c14c6ff74cd60f3c5bff1f  0006-Do-not-install-erlang-sources.patch
 d65fcfc3a9441941c6292c33d354964a82da11cc7a411dd0440719e490075ed588c1e70690e80650561749010d737394567f12ff73bd460f0d00c792c77cfae3  0007-Split-off-webtool-dependency-from-tools.patch
 b7387f92f8c27a0565c7885bba4b357183c62d422616e073bc5ffad338a0e22cb5165dcb3b95bf0b920ba00831599f2216027883f4be255aa6f6150b68b7a37c  0010-fix-nteventlog-remove.patch
-f3c50f8610e08173c365a575737079b0259db6fc0dfa5b1be63c281b52358bbce9e2595132a8f6a06772785d7d38d108f8da8515e2f7706cd03b6585aab4d071  0060-set-disksup_posix_only-to-true.patch"
+f3c50f8610e08173c365a575737079b0259db6fc0dfa5b1be63c281b52358bbce9e2595132a8f6a06772785d7d38d108f8da8515e2f7706cd03b6585aab4d071  0060-set-disksup_posix_only-to-true.patch
+e472bdb4b322d66b9c0ad9627abc469b8c648145ffad1dd7f645b38b2fad43492f475d2fd4d0bab159be6110db5043bb6d792d72e8276b3c3869be46129c6616  0070-otp-update-version-18.3.2.patch"
-- 
2.8.0

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---