From 83f9c5c032cc502df38b52d8a5b0389657b37801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= Date: Wed, 17 Jul 2019 16:40:04 +0200 Subject: ssl: Implement psk_key_exchange_modes extension Implement encode/decode of psk_key_exchange_modes. --- lib/ssl/src/ssl_handshake.erl | 40 +++++++++++++++++++++++++++++++++++++-- lib/ssl/src/tls_handshake_1_3.hrl | 36 +++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 14 deletions(-) (limited to 'lib') 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(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, <>). encode_client_protocol_negotiation(undefined, _) -> @@ -2093,6 +2099,17 @@ encode_key_share_entry(#key_share_entry{ Len = byte_size(KeyExchange), <>. +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, <>); +encode_psk_key_exchange_modes([psk_dhe_ke|T], Acc) -> + encode_psk_key_exchange_modes(T, <>). + + hello_extensions_list(HelloExtensions) -> [Ext || {_, Ext} <- maps:to_list(HelloExtensions), Ext =/= undefined]. @@ -2445,6 +2462,13 @@ decode_extensions(<>, Version, MessageType, Acc) -> + <> = 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(<>, 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(<>, Acc) -> + decode_psk_key_exchange_modes(Rest, [psk_ke|Acc]); +decode_psk_key_exchange_modes(<>, 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, diff --git a/lib/ssl/src/tls_handshake_1_3.hrl b/lib/ssl/src/tls_handshake_1_3.hrl index 7ae1b93e1c..78756c69db 100644 --- a/lib/ssl/src/tls_handshake_1_3.hrl +++ b/lib/ssl/src/tls_handshake_1_3.hrl @@ -74,29 +74,41 @@ y % opaque Y[coordinate_length]; }). +%% RFC 8446 4.2.9. Pre-Shared Key Exchange Modes + +%% enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode; -define(PSK_KE, 0). -define(PSK_DHE_KE, 1). --record(psk_keyexchange_modes, { +-record(psk_key_exchange_modes, { ke_modes % ke_modes<1..255> }). + +%% RFC 8446 4.2.10. Early Data Indication -record(empty, { }). -record(early_data_indication, { indication % uint32 max_early_data_size (new_session_ticket) | %% #empty{} (client_hello, encrypted_extensions) }). --record(psk_identity, { - identity, % opaque identity<1..2^16-1> - obfuscated_ticket_age % uint32 - }). --record(offered_psks, { - psk_identity, %identities<7..2^16-1>; - psk_binder_entry %binders<33..2^16-1>, opaque PskBinderEntry<32..255> - }). --record(pre_shared_keyextension,{ - extension %OfferedPsks (client_hello) | uint16 selected_identity (server_hello) - }). + +%% RFC 8446 4.2.11. Pre-Shared Key Extension +-record(psk_identity, + { + identity, % opaque identity<1..2^16-1> + obfuscated_ticket_age % uint32 + }). + +-record(offered_psks, + { + identities, % PskIdentity identities<7..2^16-1>; + binders % PskBinderEntry binders<33..2^16-1>; opaque PskBinderEntry<32..255> + }). + +-record(pre_shared_key, + { + data % OfferedPsks (client_hello) | uint16 selected_identity (server_hello) + }). %% RFC 8446 B.3.1.2. -record(cookie, { -- cgit v1.2.3