diff options
Diffstat (limited to 'lib/ssl/src/ssl_handshake.erl')
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 488e4bb72a..07c7f10f2b 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -709,7 +709,13 @@ encode_extensions([#key_share_server_hello{server_share = ServerShare0} | Rest], encode_extensions([#key_share_hello_retry_request{selected_group = Group0} | Rest], Acc) -> Group = tls_v1:group_to_enum(Group0), encode_extensions(Rest, <<?UINT16(?KEY_SHARE_EXT), - ?UINT16(2), ?UINT16(Group), Acc/binary>>). + ?UINT16(2), ?UINT16(Group), Acc/binary>>); +encode_extensions([#psk_key_exchange_modes{ke_modes = KEModes0} | Rest], Acc) -> + KEModes = encode_psk_key_exchange_modes(KEModes0), + KEModesLen = byte_size(KEModes), + ExtLen = KEModesLen + 1, + encode_extensions(Rest, <<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT), + ?UINT16(ExtLen), ?BYTE(KEModesLen), KEModes/binary, Acc/binary>>). encode_client_protocol_negotiation(undefined, _) -> @@ -2093,6 +2099,17 @@ encode_key_share_entry(#key_share_entry{ Len = byte_size(KeyExchange), <<?UINT16((tls_v1:group_to_enum(Group))),?UINT16(Len),KeyExchange/binary>>. +encode_psk_key_exchange_modes(KEModes) -> + encode_psk_key_exchange_modes(lists:reverse(KEModes), <<>>). +%% +encode_psk_key_exchange_modes([], Acc) -> + Acc; +encode_psk_key_exchange_modes([psk_ke|T], Acc) -> + encode_psk_key_exchange_modes(T, <<?BYTE(?PSK_KE),Acc/binary>>); +encode_psk_key_exchange_modes([psk_dhe_ke|T], Acc) -> + encode_psk_key_exchange_modes(T, <<?BYTE(?PSK_DHE_KE),Acc/binary>>). + + hello_extensions_list(HelloExtensions) -> [Ext || {_, Ext} <- maps:to_list(HelloExtensions), Ext =/= undefined]. @@ -2445,6 +2462,13 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len), #key_share_hello_retry_request{ selected_group = tls_v1:enum_to_group(Group)}}); +decode_extensions(<<?UINT16(?PSK_KEY_EXCHANGE_MODES_EXT), ?UINT16(Len), + ExtData:Len/binary, Rest/binary>>, Version, MessageType, Acc) -> + <<?BYTE(PLen),KEModes:PLen/binary>> = ExtData, + decode_extensions(Rest, Version, MessageType, + Acc#{psk_key_exchange_modes => + #psk_key_exchange_modes{ + ke_modes = decode_psk_key_exchange_modes(KEModes)}}); %% Ignore data following the ClientHello (i.e., %% extensions) if not understood. @@ -2504,6 +2528,18 @@ decode_protocols(<<?BYTE(Len), Protocol:Len/binary, Rest/binary>>, Acc) -> decode_protocols(_Bytes, _Acc) -> {error, invalid_protocols}. + +decode_psk_key_exchange_modes(KEModes) -> + decode_psk_key_exchange_modes(KEModes, []). +%% +decode_psk_key_exchange_modes(<<>>, Acc) -> + lists:reverse(Acc); +decode_psk_key_exchange_modes(<<?BYTE(?PSK_KE), Rest/binary>>, Acc) -> + decode_psk_key_exchange_modes(Rest, [psk_ke|Acc]); +decode_psk_key_exchange_modes(<<?BYTE(?PSK_DHE_KE), Rest/binary>>, Acc) -> + decode_psk_key_exchange_modes(Rest, [psk_dhe_ke|Acc]). + + %% encode/decode stream of certificate data to/from list of certificate data certs_to_list(ASN1Certs) -> certs_to_list(ASN1Certs, []). @@ -3042,7 +3078,7 @@ empty_extensions({3,4}, client_hello) -> %% padding => undefined, key_share => undefined, pre_shared_key => undefined, - %% psk_key_exhange_modes => undefined, + psk_key_exchange_modes => undefined, %% early_data => undefined, %% cookie => undefined, client_hello_versions => undefined, |