@@ -2885,10 +2885,12 @@ decode_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
28852885 ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc )
28862886 when Len + 2 =:= ExtLen ->
28872887 ALPN = # alpn {extension_data = ExtensionData },
2888+ assert_unique_extension (alpn , Acc ),
28882889 decode_extensions (Rest , Version , MessageType , Acc #{alpn => ALPN });
28892890decode_extensions (<<? UINT16 (? NEXTPROTONEG_EXT ), ? UINT16 (Len ),
28902891 ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
28912892 NextP = # next_protocol_negotiation {extension_data = ExtensionData },
2893+ assert_unique_extension (next_protocol_negotiation , Acc ),
28922894 decode_extensions (Rest , Version , MessageType , Acc #{next_protocol_negotiation => NextP });
28932895decode_extensions (<<? UINT16 (? RENEGOTIATION_EXT ), ? UINT16 (Len ),
28942896 Info :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
@@ -2900,6 +2902,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29002902 <<? BYTE (VerifyLen ), VerifyInfo /binary >> = Info ,
29012903 VerifyInfo
29022904 end ,
2905+ assert_unique_extension (renegotiation_info , Acc ),
29032906 decode_extensions (Rest , Version , MessageType ,
29042907 Acc #{renegotiation_info =>
29052908 # renegotiation_info {renegotiated_connection =
@@ -2908,6 +2911,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29082911decode_extensions (<<? UINT16 (? SRP_EXT ), ? UINT16 (Len ), ? BYTE (SRPLen ),
29092912 SRP :SRPLen /binary , Rest /binary >>, Version , MessageType , Acc )
29102913 when Len == SRPLen + 1 ->
2914+ assert_unique_extension (srp , Acc ),
29112915 decode_extensions (Rest , Version , MessageType , Acc #{srp => # srp {username = SRP }});
29122916
29132917decode_extensions (<<? UINT16 (? SIGNATURE_ALGORITHMS_EXT ), ? UINT16 (Len ),
@@ -2917,6 +2921,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29172921 <<? UINT16 (SignAlgoListLen ), SignAlgoList /binary >> = ExtData ,
29182922 HashSignAlgos = [{ssl_cipher :hash_algorithm (Hash ), ssl_cipher :sign_algorithm (Sign )} ||
29192923 <<? BYTE (Hash ), ? BYTE (Sign )>> <= SignAlgoList ],
2924+ assert_unique_extension (signature_algs , Acc ),
29202925 decode_extensions (Rest , Version , MessageType ,
29212926 Acc #{signature_algs =>
29222927 # hash_sign_algos {hash_sign_algos =
@@ -2926,6 +2931,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29262931 SignSchemeListLen = Len - 2 ,
29272932 <<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
29282933 HashSigns = decode_sign_alg (Version , SignSchemeList ),
2934+ assert_unique_extension (signature_algs , Acc ),
29292935 decode_extensions (Rest , Version , MessageType ,
29302936 Acc #{signature_algs =>
29312937 # hash_sign_algos {
@@ -2935,6 +2941,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29352941 SignSchemeListLen = Len - 2 ,
29362942 <<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
29372943 SignSchemes = decode_sign_alg (Version , SignSchemeList ),
2944+ assert_unique_extension (signature_algs , Acc ),
29382945 decode_extensions (Rest , Version , MessageType ,
29392946 Acc #{signature_algs =>
29402947 # signature_algorithms {
@@ -2954,6 +2961,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
29542961 end ,
29552962 SignSchemes = lists :filtermap (Fun , [SignScheme ||
29562963 <<? UINT16 (SignScheme )>> <= SignSchemeList ]),
2964+ assert_unique_extension (signature_algs_cert , Acc ),
29572965 decode_extensions (Rest , Version , MessageType ,
29582966 Acc #{signature_algs_cert =>
29592967 # signature_algorithms_cert {
@@ -2963,6 +2971,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len),
29632971 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
29642972 <<? UINT16 (ProfilesLen ), ProfilesBin :ProfilesLen /binary , ? BYTE (MKILen ), MKI :MKILen /binary >> = ExtData ,
29652973 Profiles = [P || <<P :2 /binary >> <= ProfilesBin ],
2974+ assert_unique_extension (use_srtp , Acc ),
29662975 decode_extensions (Rest , Version , MessageType ,
29672976 Acc #{use_srtp =>
29682977 # use_srtp {
@@ -2983,6 +2992,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
29832992 end
29842993 end ,
29852994 EllipticCurves = lists :filtermap (Pick , [ECC || <<ECC :16 >> <= EllipticCurveList ]),
2995+ assert_unique_extension (elliptic_curves , Acc ),
29862996 decode_extensions (Rest , Version , MessageType ,
29872997 Acc #{elliptic_curves =>
29882998 # elliptic_curves {elliptic_curve_list =
@@ -3001,6 +3011,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30013011 end
30023012 end ,
30033013 SupportedGroups = lists :filtermap (Pick , [Group || <<Group :16 >> <= GroupList ]),
3014+ assert_unique_extension (elliptic_curves , Acc ),
30043015 decode_extensions (Rest , Version , MessageType ,
30053016 Acc #{elliptic_curves =>
30063017 # supported_groups {supported_groups =
@@ -3010,29 +3021,34 @@ decode_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
30103021 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
30113022 <<? BYTE (_ ), ECPointFormatList /binary >> = ExtData ,
30123023 ECPointFormats = binary_to_list (ECPointFormatList ),
3024+ assert_unique_extension (ec_point_formats , Acc ),
30133025 decode_extensions (Rest , Version , MessageType ,
30143026 Acc #{ec_point_formats =>
30153027 # ec_point_formats {ec_point_format_list =
30163028 ECPointFormats }});
30173029
30183030decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
30193031 Rest /binary >>, Version , MessageType , Acc ) when Len == 0 ->
3032+ assert_unique_extension (sni , Acc ),
30203033 decode_extensions (Rest , Version , MessageType ,
30213034 Acc #{sni => # sni {hostname = " " }}); % % Server may send an empty SNI
30223035
30233036decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
30243037 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
30253038 <<? UINT16 (_ ), NameList /binary >> = ExtData ,
3039+ assert_unique_extension (sni , Acc ),
30263040 decode_extensions (Rest , Version , MessageType ,
30273041 Acc #{sni => dec_sni (NameList )});
30283042
30293043decode_extensions (<<? UINT16 (? MAX_FRAGMENT_LENGTH_EXT ), ? UINT16 (1 ), ? BYTE (MaxFragEnum ), Rest /binary >>,
30303044 Version , MessageType , Acc ) ->
30313045 % % RFC 6066 Section 4
3046+ assert_unique_extension (max_frag_enum , Acc ),
30323047 decode_extensions (Rest , Version , MessageType , Acc #{max_frag_enum => # max_frag_enum {enum = MaxFragEnum }});
30333048decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
30343049 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) when Len > 2 ->
30353050 <<? BYTE (_ ),Versions /binary >> = ExtData ,
3051+ assert_unique_extension (client_hello_versions , Acc ),
30363052 decode_extensions (Rest , Version , MessageType ,
30373053 Acc #{client_hello_versions =>
30383054 # client_hello_versions {
@@ -3041,6 +3057,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30413057decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
30423058 ? UINT16 (SelectedVersion ), Rest /binary >>, Version , MessageType , Acc )
30433059 when Len =:= 2 , SelectedVersion =:= 16#0304 ->
3060+ assert_unique_extension (server_hello_selected_version , Acc ),
30443061 decode_extensions (Rest , Version , MessageType ,
30453062 Acc #{server_hello_selected_version =>
30463063 # server_hello_selected_version {selected_version = ? TLS_1_3 }});
@@ -3049,6 +3066,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30493066 ExtData :Len /binary , Rest /binary >>,
30503067 Version , MessageType = client_hello , Acc ) ->
30513068 <<? UINT16 (_ ),ClientShares /binary >> = ExtData ,
3069+ assert_unique_extension (key_share , Acc ),
30523070 decode_extensions (Rest , Version , MessageType ,
30533071 Acc #{key_share =>
30543072 # key_share_client_hello {
@@ -3058,6 +3076,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30583076 ExtData :Len /binary , Rest /binary >>,
30593077 Version , MessageType = server_hello , Acc ) ->
30603078 <<? UINT16 (Group ),? UINT16 (KeyLen ),KeyExchange :KeyLen /binary >> = ExtData ,
3079+ assert_unique_extension (key_share , Acc ),
30613080 decode_extensions (Rest , Version , MessageType ,
30623081 Acc #{key_share =>
30633082 # key_share_server_hello {
@@ -3078,6 +3097,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30783097decode_extensions (<<? UINT16 (? PSK_KEY_EXCHANGE_MODES_EXT ), ? UINT16 (Len ),
30793098 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
30803099 <<? BYTE (PLen ),KEModes :PLen /binary >> = ExtData ,
3100+ assert_unique_extension (psk_key_exchange_modes , Acc ),
30813101 decode_extensions (Rest , Version , MessageType ,
30823102 Acc #{psk_key_exchange_modes =>
30833103 # psk_key_exchange_modes {
@@ -3087,17 +3107,18 @@ decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
30873107 ExtData :Len /binary , Rest /binary >>,
30883108 Version , MessageType = client_hello , Acc ) ->
30893109 <<? UINT16 (IdLen ),Identities :IdLen /binary ,? UINT16 (BLen ),Binders :BLen /binary >> = ExtData ,
3110+ assert_unique_extension (pre_shared_key , Acc ),
30903111 decode_extensions (Rest , Version , MessageType ,
30913112 Acc #{pre_shared_key =>
30923113 # pre_shared_key_client_hello {
30933114 offered_psks = # offered_psks {
30943115 identities = decode_psk_identities (Identities ),
30953116 binders = decode_psk_binders (Binders )}}});
3096-
30973117decode_extensions (<<? UINT16 (? PRE_SHARED_KEY_EXT ), ? UINT16 (Len ),
30983118 ExtData :Len /binary , Rest /binary >>,
30993119 Version , MessageType = server_hello , Acc ) ->
31003120 <<? UINT16 (Identity )>> = ExtData ,
3121+ assert_unique_extension (pre_shared_key , Acc ),
31013122 decode_extensions (Rest , Version , MessageType ,
31023123 Acc #{pre_shared_key =>
31033124 # pre_shared_key_server_hello {
@@ -3107,6 +3128,7 @@ decode_extensions(<<?UINT16(?COOKIE_EXT), ?UINT16(Len), ?UINT16(CookieLen),
31073128 Cookie :CookieLen /binary , Rest /binary >>,
31083129 Version , MessageType , Acc )
31093130 when Len == CookieLen + 2 ->
3131+ assert_unique_extension (cookie , Acc ),
31103132 decode_extensions (Rest , Version , MessageType ,
31113133 Acc #{cookie => # cookie {cookie = Cookie }});
31123134
@@ -3117,6 +3139,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31173139 _ExtensionData :Len /binary , Rest /binary >>, Version ,
31183140 MessageType = server_hello , Acc )
31193141 when Len =:= 0 ->
3142+ assert_unique_extension (status_request , Acc ),
31203143 decode_extensions (Rest , Version , MessageType ,
31213144 Acc #{status_request => undefined });
31223145% % RFC8446 4.4.2.1, In TLS1.3, the body of the "status_request" extension
@@ -3129,6 +3152,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31293152 <<? BYTE (? CERTIFICATE_STATUS_TYPE_OCSP ),
31303153 ? UINT24 (OCSPLen ),
31313154 ASN1OCSPResponse :OCSPLen /binary >> ->
3155+ assert_unique_extension (status_request , Acc ),
31323156 decode_extensions (Rest , Version , MessageType ,
31333157 Acc #{status_request => # certificate_status {response = ASN1OCSPResponse }});
31343158 _Other ->
@@ -3137,12 +3161,14 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31373161
31383162decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (0 ), Rest /binary >>,
31393163 Version , MessageType , Acc ) ->
3164+ assert_unique_extension (early_data , Acc ),
31403165 decode_extensions (Rest , Version , MessageType ,
31413166 Acc #{early_data => # early_data_indication {}});
31423167
31433168decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (4 ), ? UINT32 (MaxSize ),
31443169 Rest /binary >>,
31453170 Version , MessageType , Acc ) ->
3171+ assert_unique_extension (early_data , Acc ),
31463172 decode_extensions (Rest , Version , MessageType ,
31473173 Acc #{early_data =>
31483174 # early_data_indication_nst {indication = MaxSize }});
@@ -3151,6 +3177,7 @@ decode_extensions(<<?UINT16(?CERTIFICATE_AUTHORITIES_EXT), ?UINT16(Len),
31513177 Version , MessageType , Acc ) ->
31523178 CertAutsLen = Len - 2 ,
31533179 <<? UINT16 (CertAutsLen ), EncCertAuts /binary >> = CertAutsExt ,
3180+ assert_unique_extension (certificate_authorities , Acc ),
31543181 decode_extensions (Rest , Version , MessageType ,
31553182 Acc #{certificate_authorities =>
31563183 # certificate_authorities {authorities = decode_cert_auths (EncCertAuts , [])}});
@@ -3162,6 +3189,14 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>
31623189decode_extensions (_ , _ , _ , Acc ) ->
31633190 Acc .
31643191
3192+ assert_unique_extension (Ext , Map ) ->
3193+ case maps :get (Ext , Map , undefined ) of
3194+ undefined ->
3195+ ok ;
3196+ _ ->
3197+ throw (? ALERT_REC (? FATAL , ? ILLEGAL_PARAMETER , {duplicate_extension , Ext }))
3198+ end .
3199+
31653200decode_sign_alg (? TLS_1_2 , SignSchemeList ) ->
31663201 % % Ignore unknown signature algorithms
31673202 Fun = fun (Elem ) ->
0 commit comments