@@ -2884,10 +2884,12 @@ decode_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
28842884 ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc )
28852885 when Len + 2 =:= ExtLen ->
28862886 ALPN = # alpn {extension_data = ExtensionData },
2887+ assert_unique_extension (alpn , Acc ),
28872888 decode_extensions (Rest , Version , MessageType , Acc #{alpn => ALPN });
28882889decode_extensions (<<? UINT16 (? NEXTPROTONEG_EXT ), ? UINT16 (Len ),
28892890 ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
28902891 NextP = # next_protocol_negotiation {extension_data = ExtensionData },
2892+ assert_unique_extension (next_protocol_negotiation , Acc ),
28912893 decode_extensions (Rest , Version , MessageType , Acc #{next_protocol_negotiation => NextP });
28922894decode_extensions (<<? UINT16 (? RENEGOTIATION_EXT ), ? UINT16 (Len ),
28932895 Info :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
@@ -2899,6 +2901,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
28992901 <<? BYTE (VerifyLen ), VerifyInfo /binary >> = Info ,
29002902 VerifyInfo
29012903 end ,
2904+ assert_unique_extension (renegotiation_info , Acc ),
29022905 decode_extensions (Rest , Version , MessageType ,
29032906 Acc #{renegotiation_info =>
29042907 # renegotiation_info {renegotiated_connection =
@@ -2907,6 +2910,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
29072910decode_extensions (<<? UINT16 (? SRP_EXT ), ? UINT16 (Len ), ? BYTE (SRPLen ),
29082911 SRP :SRPLen /binary , Rest /binary >>, Version , MessageType , Acc )
29092912 when Len == SRPLen + 1 ->
2913+ assert_unique_extension (srp , Acc ),
29102914 decode_extensions (Rest , Version , MessageType , Acc #{srp => # srp {username = SRP }});
29112915
29122916decode_extensions (<<? UINT16 (? SIGNATURE_ALGORITHMS_EXT ), ? UINT16 (Len ),
@@ -2916,6 +2920,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29162920 <<? UINT16 (SignAlgoListLen ), SignAlgoList /binary >> = ExtData ,
29172921 HashSignAlgos = [{ssl_cipher :hash_algorithm (Hash ), ssl_cipher :sign_algorithm (Sign )} ||
29182922 <<? BYTE (Hash ), ? BYTE (Sign )>> <= SignAlgoList ],
2923+ assert_unique_extension (signature_algs , Acc ),
29192924 decode_extensions (Rest , Version , MessageType ,
29202925 Acc #{signature_algs =>
29212926 # hash_sign_algos {hash_sign_algos =
@@ -2925,6 +2930,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29252930 SignSchemeListLen = Len - 2 ,
29262931 <<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
29272932 HashSigns = decode_sign_alg (Version , SignSchemeList ),
2933+ assert_unique_extension (signature_algs , Acc ),
29282934 decode_extensions (Rest , Version , MessageType ,
29292935 Acc #{signature_algs =>
29302936 # hash_sign_algos {
@@ -2934,6 +2940,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
29342940 SignSchemeListLen = Len - 2 ,
29352941 <<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
29362942 SignSchemes = decode_sign_alg (Version , SignSchemeList ),
2943+ assert_unique_extension (signature_algs , Acc ),
29372944 decode_extensions (Rest , Version , MessageType ,
29382945 Acc #{signature_algs =>
29392946 # signature_algorithms {
@@ -2974,6 +2981,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
29742981 end ,
29752982 SignSchemes = lists :filtermap (Fun , [SignScheme ||
29762983 <<? UINT16 (SignScheme )>> <= SignSchemeList ]),
2984+ assert_unique_extension (signature_algs_cert , Acc ),
29772985 decode_extensions (Rest , Version , MessageType ,
29782986 Acc #{signature_algs_cert =>
29792987 # signature_algorithms_cert {
@@ -2983,6 +2991,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len),
29832991 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
29842992 <<? UINT16 (ProfilesLen ), ProfilesBin :ProfilesLen /binary , ? BYTE (MKILen ), MKI :MKILen /binary >> = ExtData ,
29852993 Profiles = [P || <<P :2 /binary >> <= ProfilesBin ],
2994+ assert_unique_extension (use_srtp , Acc ),
29862995 decode_extensions (Rest , Version , MessageType ,
29872996 Acc #{use_srtp =>
29882997 # use_srtp {
@@ -3003,6 +3012,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30033012 end
30043013 end ,
30053014 EllipticCurves = lists :filtermap (Pick , [ECC || <<ECC :16 >> <= EllipticCurveList ]),
3015+ assert_unique_extension (elliptic_curves , Acc ),
30063016 decode_extensions (Rest , Version , MessageType ,
30073017 Acc #{elliptic_curves =>
30083018 # elliptic_curves {elliptic_curve_list =
@@ -3021,6 +3031,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
30213031 end
30223032 end ,
30233033 SupportedGroups = lists :filtermap (Pick , [Group || <<Group :16 >> <= GroupList ]),
3034+ assert_unique_extension (elliptic_curves , Acc ),
30243035 decode_extensions (Rest , Version , MessageType ,
30253036 Acc #{elliptic_curves =>
30263037 # supported_groups {supported_groups =
@@ -3030,29 +3041,34 @@ decode_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
30303041 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
30313042 <<? BYTE (_ ), ECPointFormatList /binary >> = ExtData ,
30323043 ECPointFormats = binary_to_list (ECPointFormatList ),
3044+ assert_unique_extension (ec_point_formats , Acc ),
30333045 decode_extensions (Rest , Version , MessageType ,
30343046 Acc #{ec_point_formats =>
30353047 # ec_point_formats {ec_point_format_list =
30363048 ECPointFormats }});
30373049
30383050decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
30393051 Rest /binary >>, Version , MessageType , Acc ) when Len == 0 ->
3052+ assert_unique_extension (sni , Acc ),
30403053 decode_extensions (Rest , Version , MessageType ,
30413054 Acc #{sni => # sni {hostname = " " }}); % % Server may send an empty SNI
30423055
30433056decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
30443057 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
30453058 <<? UINT16 (_ ), NameList /binary >> = ExtData ,
3059+ assert_unique_extension (sni , Acc ),
30463060 decode_extensions (Rest , Version , MessageType ,
30473061 Acc #{sni => dec_sni (NameList )});
30483062
30493063decode_extensions (<<? UINT16 (? MAX_FRAGMENT_LENGTH_EXT ), ? UINT16 (1 ), ? BYTE (MaxFragEnum ), Rest /binary >>,
30503064 Version , MessageType , Acc ) ->
30513065 % % RFC 6066 Section 4
3066+ assert_unique_extension (max_frag_enum , Acc ),
30523067 decode_extensions (Rest , Version , MessageType , Acc #{max_frag_enum => # max_frag_enum {enum = MaxFragEnum }});
30533068decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
30543069 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) when Len > 2 ->
30553070 <<? BYTE (_ ),Versions /binary >> = ExtData ,
3071+ assert_unique_extension (client_hello_versions , Acc ),
30563072 decode_extensions (Rest , Version , MessageType ,
30573073 Acc #{client_hello_versions =>
30583074 # client_hello_versions {
@@ -3061,6 +3077,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
30613077decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
30623078 ? UINT16 (SelectedVersion ), Rest /binary >>, Version , MessageType , Acc )
30633079 when Len =:= 2 , SelectedVersion =:= 16#0304 ->
3080+ assert_unique_extension (server_hello_selected_version , Acc ),
30643081 decode_extensions (Rest , Version , MessageType ,
30653082 Acc #{server_hello_selected_version =>
30663083 # server_hello_selected_version {selected_version = ? TLS_1_3 }});
@@ -3069,6 +3086,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30693086 ExtData :Len /binary , Rest /binary >>,
30703087 Version , MessageType = client_hello , Acc ) ->
30713088 <<? UINT16 (_ ),ClientShares /binary >> = ExtData ,
3089+ assert_unique_extension (key_share , Acc ),
30723090 decode_extensions (Rest , Version , MessageType ,
30733091 Acc #{key_share =>
30743092 # key_share_client_hello {
@@ -3078,6 +3096,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30783096 ExtData :Len /binary , Rest /binary >>,
30793097 Version , MessageType = server_hello , Acc ) ->
30803098 <<? UINT16 (Group ),? UINT16 (KeyLen ),KeyExchange :KeyLen /binary >> = ExtData ,
3099+ assert_unique_extension (key_share , Acc ),
30813100 decode_extensions (Rest , Version , MessageType ,
30823101 Acc #{key_share =>
30833102 # key_share_server_hello {
@@ -3098,6 +3117,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30983117decode_extensions (<<? UINT16 (? PSK_KEY_EXCHANGE_MODES_EXT ), ? UINT16 (Len ),
30993118 ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
31003119 <<? BYTE (PLen ),KEModes :PLen /binary >> = ExtData ,
3120+ assert_unique_extension (psk_key_exchange_modes , Acc ),
31013121 decode_extensions (Rest , Version , MessageType ,
31023122 Acc #{psk_key_exchange_modes =>
31033123 # psk_key_exchange_modes {
@@ -3107,17 +3127,18 @@ decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
31073127 ExtData :Len /binary , Rest /binary >>,
31083128 Version , MessageType = client_hello , Acc ) ->
31093129 <<? UINT16 (IdLen ),Identities :IdLen /binary ,? UINT16 (BLen ),Binders :BLen /binary >> = ExtData ,
3130+ assert_unique_extension (pre_shared_key , Acc ),
31103131 decode_extensions (Rest , Version , MessageType ,
31113132 Acc #{pre_shared_key =>
31123133 # pre_shared_key_client_hello {
31133134 offered_psks = # offered_psks {
31143135 identities = decode_psk_identities (Identities ),
31153136 binders = decode_psk_binders (Binders )}}});
3116-
31173137decode_extensions (<<? UINT16 (? PRE_SHARED_KEY_EXT ), ? UINT16 (Len ),
31183138 ExtData :Len /binary , Rest /binary >>,
31193139 Version , MessageType = server_hello , Acc ) ->
31203140 <<? UINT16 (Identity )>> = ExtData ,
3141+ assert_unique_extension (pre_shared_key , Acc ),
31213142 decode_extensions (Rest , Version , MessageType ,
31223143 Acc #{pre_shared_key =>
31233144 # pre_shared_key_server_hello {
@@ -3127,6 +3148,7 @@ decode_extensions(<<?UINT16(?COOKIE_EXT), ?UINT16(Len), ?UINT16(CookieLen),
31273148 Cookie :CookieLen /binary , Rest /binary >>,
31283149 Version , MessageType , Acc )
31293150 when Len == CookieLen + 2 ->
3151+ assert_unique_extension (cookie , Acc ),
31303152 decode_extensions (Rest , Version , MessageType ,
31313153 Acc #{cookie => # cookie {cookie = Cookie }});
31323154
@@ -3137,6 +3159,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31373159 _ExtensionData :Len /binary , Rest /binary >>, Version ,
31383160 MessageType = server_hello , Acc )
31393161 when Len =:= 0 ->
3162+ assert_unique_extension (status_request , Acc ),
31403163 decode_extensions (Rest , Version , MessageType ,
31413164 Acc #{status_request => undefined });
31423165% % RFC8446 4.4.2.1, In TLS1.3, the body of the "status_request" extension
@@ -3149,6 +3172,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31493172 <<? BYTE (? CERTIFICATE_STATUS_TYPE_OCSP ),
31503173 ? UINT24 (OCSPLen ),
31513174 ASN1OCSPResponse :OCSPLen /binary >> ->
3175+ assert_unique_extension (status_request , Acc ),
31523176 decode_extensions (Rest , Version , MessageType ,
31533177 Acc #{status_request => # certificate_status {response = ASN1OCSPResponse }});
31543178 _Other ->
@@ -3157,12 +3181,14 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
31573181
31583182decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (0 ), Rest /binary >>,
31593183 Version , MessageType , Acc ) ->
3184+ assert_unique_extension (early_data , Acc ),
31603185 decode_extensions (Rest , Version , MessageType ,
31613186 Acc #{early_data => # early_data_indication {}});
31623187
31633188decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (4 ), ? UINT32 (MaxSize ),
31643189 Rest /binary >>,
31653190 Version , MessageType , Acc ) ->
3191+ assert_unique_extension (early_data , Acc ),
31663192 decode_extensions (Rest , Version , MessageType ,
31673193 Acc #{early_data =>
31683194 # early_data_indication_nst {indication = MaxSize }});
@@ -3171,6 +3197,7 @@ decode_extensions(<<?UINT16(?CERTIFICATE_AUTHORITIES_EXT), ?UINT16(Len),
31713197 Version , MessageType , Acc ) ->
31723198 CertAutsLen = Len - 2 ,
31733199 <<? UINT16 (CertAutsLen ), EncCertAuts /binary >> = CertAutsExt ,
3200+ assert_unique_extension (certificate_authorities , Acc ),
31743201 decode_extensions (Rest , Version , MessageType ,
31753202 Acc #{certificate_authorities =>
31763203 # certificate_authorities {authorities = decode_cert_auths (EncCertAuts , [])}});
@@ -3182,6 +3209,14 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>
31823209decode_extensions (_ , _ , _ , Acc ) ->
31833210 Acc .
31843211
3212+ assert_unique_extension (Ext , Map ) ->
3213+ case maps :get (Ext , Map , undefined ) of
3214+ undefined ->
3215+ ok ;
3216+ _ ->
3217+ throw (? ALERT_REC (? FATAL , ? ILLEGAL_PARAMETER , {duplicate_extension , Ext }))
3218+ end .
3219+
31853220decode_sign_alg (? TLS_1_2 , SignSchemeList ) ->
31863221 % % Ignore unknown signature algorithms
31873222 Fun = fun (Elem ) ->
0 commit comments