@@ -2885,10 +2885,12 @@ decode_extensions(<<?UINT16(?ALPN_EXT), ?UINT16(ExtLen), ?UINT16(Len),
2885
2885
ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc )
2886
2886
when Len + 2 =:= ExtLen ->
2887
2887
ALPN = # alpn {extension_data = ExtensionData },
2888
+ assert_unique_extension (alpn , Acc ),
2888
2889
decode_extensions (Rest , Version , MessageType , Acc #{alpn => ALPN });
2889
2890
decode_extensions (<<? UINT16 (? NEXTPROTONEG_EXT ), ? UINT16 (Len ),
2890
2891
ExtensionData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
2891
2892
NextP = # next_protocol_negotiation {extension_data = ExtensionData },
2893
+ assert_unique_extension (next_protocol_negotiation , Acc ),
2892
2894
decode_extensions (Rest , Version , MessageType , Acc #{next_protocol_negotiation => NextP });
2893
2895
decode_extensions (<<? UINT16 (? RENEGOTIATION_EXT ), ? UINT16 (Len ),
2894
2896
Info :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
@@ -2900,6 +2902,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
2900
2902
<<? BYTE (VerifyLen ), VerifyInfo /binary >> = Info ,
2901
2903
VerifyInfo
2902
2904
end ,
2905
+ assert_unique_extension (renegotiation_info , Acc ),
2903
2906
decode_extensions (Rest , Version , MessageType ,
2904
2907
Acc #{renegotiation_info =>
2905
2908
# renegotiation_info {renegotiated_connection =
@@ -2908,6 +2911,7 @@ decode_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len),
2908
2911
decode_extensions (<<? UINT16 (? SRP_EXT ), ? UINT16 (Len ), ? BYTE (SRPLen ),
2909
2912
SRP :SRPLen /binary , Rest /binary >>, Version , MessageType , Acc )
2910
2913
when Len == SRPLen + 1 ->
2914
+ assert_unique_extension (srp , Acc ),
2911
2915
decode_extensions (Rest , Version , MessageType , Acc #{srp => # srp {username = SRP }});
2912
2916
2913
2917
decode_extensions (<<? UINT16 (? SIGNATURE_ALGORITHMS_EXT ), ? UINT16 (Len ),
@@ -2917,6 +2921,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
2917
2921
<<? UINT16 (SignAlgoListLen ), SignAlgoList /binary >> = ExtData ,
2918
2922
HashSignAlgos = [{ssl_cipher :hash_algorithm (Hash ), ssl_cipher :sign_algorithm (Sign )} ||
2919
2923
<<? BYTE (Hash ), ? BYTE (Sign )>> <= SignAlgoList ],
2924
+ assert_unique_extension (signature_algs , Acc ),
2920
2925
decode_extensions (Rest , Version , MessageType ,
2921
2926
Acc #{signature_algs =>
2922
2927
# hash_sign_algos {hash_sign_algos =
@@ -2926,6 +2931,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
2926
2931
SignSchemeListLen = Len - 2 ,
2927
2932
<<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
2928
2933
HashSigns = decode_sign_alg (Version , SignSchemeList ),
2934
+ assert_unique_extension (signature_algs , Acc ),
2929
2935
decode_extensions (Rest , Version , MessageType ,
2930
2936
Acc #{signature_algs =>
2931
2937
# hash_sign_algos {
@@ -2935,6 +2941,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_EXT), ?UINT16(Len),
2935
2941
SignSchemeListLen = Len - 2 ,
2936
2942
<<? UINT16 (SignSchemeListLen ), SignSchemeList /binary >> = ExtData ,
2937
2943
SignSchemes = decode_sign_alg (Version , SignSchemeList ),
2944
+ assert_unique_extension (signature_algs , Acc ),
2938
2945
decode_extensions (Rest , Version , MessageType ,
2939
2946
Acc #{signature_algs =>
2940
2947
# signature_algorithms {
@@ -2954,6 +2961,7 @@ decode_extensions(<<?UINT16(?SIGNATURE_ALGORITHMS_CERT_EXT), ?UINT16(Len),
2954
2961
end ,
2955
2962
SignSchemes = lists :filtermap (Fun , [SignScheme ||
2956
2963
<<? UINT16 (SignScheme )>> <= SignSchemeList ]),
2964
+ assert_unique_extension (signature_algs_cert , Acc ),
2957
2965
decode_extensions (Rest , Version , MessageType ,
2958
2966
Acc #{signature_algs_cert =>
2959
2967
# signature_algorithms_cert {
@@ -2963,6 +2971,7 @@ decode_extensions(<<?UINT16(?USE_SRTP_EXT), ?UINT16(Len),
2963
2971
ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
2964
2972
<<? UINT16 (ProfilesLen ), ProfilesBin :ProfilesLen /binary , ? BYTE (MKILen ), MKI :MKILen /binary >> = ExtData ,
2965
2973
Profiles = [P || <<P :2 /binary >> <= ProfilesBin ],
2974
+ assert_unique_extension (use_srtp , Acc ),
2966
2975
decode_extensions (Rest , Version , MessageType ,
2967
2976
Acc #{use_srtp =>
2968
2977
# use_srtp {
@@ -2983,6 +2992,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
2983
2992
end
2984
2993
end ,
2985
2994
EllipticCurves = lists :filtermap (Pick , [ECC || <<ECC :16 >> <= EllipticCurveList ]),
2995
+ assert_unique_extension (elliptic_curves , Acc ),
2986
2996
decode_extensions (Rest , Version , MessageType ,
2987
2997
Acc #{elliptic_curves =>
2988
2998
# elliptic_curves {elliptic_curve_list =
@@ -3001,6 +3011,7 @@ decode_extensions(<<?UINT16(?ELLIPTIC_CURVES_EXT), ?UINT16(Len),
3001
3011
end
3002
3012
end ,
3003
3013
SupportedGroups = lists :filtermap (Pick , [Group || <<Group :16 >> <= GroupList ]),
3014
+ assert_unique_extension (elliptic_curves , Acc ),
3004
3015
decode_extensions (Rest , Version , MessageType ,
3005
3016
Acc #{elliptic_curves =>
3006
3017
# supported_groups {supported_groups =
@@ -3010,29 +3021,34 @@ decode_extensions(<<?UINT16(?EC_POINT_FORMATS_EXT), ?UINT16(Len),
3010
3021
ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
3011
3022
<<? BYTE (_ ), ECPointFormatList /binary >> = ExtData ,
3012
3023
ECPointFormats = binary_to_list (ECPointFormatList ),
3024
+ assert_unique_extension (ec_point_formats , Acc ),
3013
3025
decode_extensions (Rest , Version , MessageType ,
3014
3026
Acc #{ec_point_formats =>
3015
3027
# ec_point_formats {ec_point_format_list =
3016
3028
ECPointFormats }});
3017
3029
3018
3030
decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
3019
3031
Rest /binary >>, Version , MessageType , Acc ) when Len == 0 ->
3032
+ assert_unique_extension (sni , Acc ),
3020
3033
decode_extensions (Rest , Version , MessageType ,
3021
3034
Acc #{sni => # sni {hostname = " " }}); % % Server may send an empty SNI
3022
3035
3023
3036
decode_extensions (<<? UINT16 (? SNI_EXT ), ? UINT16 (Len ),
3024
3037
ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
3025
3038
<<? UINT16 (_ ), NameList /binary >> = ExtData ,
3039
+ assert_unique_extension (sni , Acc ),
3026
3040
decode_extensions (Rest , Version , MessageType ,
3027
3041
Acc #{sni => dec_sni (NameList )});
3028
3042
3029
3043
decode_extensions (<<? UINT16 (? MAX_FRAGMENT_LENGTH_EXT ), ? UINT16 (1 ), ? BYTE (MaxFragEnum ), Rest /binary >>,
3030
3044
Version , MessageType , Acc ) ->
3031
3045
% % RFC 6066 Section 4
3046
+ assert_unique_extension (max_frag_enum , Acc ),
3032
3047
decode_extensions (Rest , Version , MessageType , Acc #{max_frag_enum => # max_frag_enum {enum = MaxFragEnum }});
3033
3048
decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
3034
3049
ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) when Len > 2 ->
3035
3050
<<? BYTE (_ ),Versions /binary >> = ExtData ,
3051
+ assert_unique_extension (client_hello_versions , Acc ),
3036
3052
decode_extensions (Rest , Version , MessageType ,
3037
3053
Acc #{client_hello_versions =>
3038
3054
# client_hello_versions {
@@ -3041,6 +3057,7 @@ decode_extensions(<<?UINT16(?SUPPORTED_VERSIONS_EXT), ?UINT16(Len),
3041
3057
decode_extensions (<<? UINT16 (? SUPPORTED_VERSIONS_EXT ), ? UINT16 (Len ),
3042
3058
? UINT16 (SelectedVersion ), Rest /binary >>, Version , MessageType , Acc )
3043
3059
when Len =:= 2 , SelectedVersion =:= 16#0304 ->
3060
+ assert_unique_extension (server_hello_selected_version , Acc ),
3044
3061
decode_extensions (Rest , Version , MessageType ,
3045
3062
Acc #{server_hello_selected_version =>
3046
3063
# server_hello_selected_version {selected_version = ? TLS_1_3 }});
@@ -3049,6 +3066,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
3049
3066
ExtData :Len /binary , Rest /binary >>,
3050
3067
Version , MessageType = client_hello , Acc ) ->
3051
3068
<<? UINT16 (_ ),ClientShares /binary >> = ExtData ,
3069
+ assert_unique_extension (key_share , Acc ),
3052
3070
decode_extensions (Rest , Version , MessageType ,
3053
3071
Acc #{key_share =>
3054
3072
# key_share_client_hello {
@@ -3058,6 +3076,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
3058
3076
ExtData :Len /binary , Rest /binary >>,
3059
3077
Version , MessageType = server_hello , Acc ) ->
3060
3078
<<? UINT16 (Group ),? UINT16 (KeyLen ),KeyExchange :KeyLen /binary >> = ExtData ,
3079
+ assert_unique_extension (key_share , Acc ),
3061
3080
decode_extensions (Rest , Version , MessageType ,
3062
3081
Acc #{key_share =>
3063
3082
# key_share_server_hello {
@@ -3078,6 +3097,7 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
3078
3097
decode_extensions (<<? UINT16 (? PSK_KEY_EXCHANGE_MODES_EXT ), ? UINT16 (Len ),
3079
3098
ExtData :Len /binary , Rest /binary >>, Version , MessageType , Acc ) ->
3080
3099
<<? BYTE (PLen ),KEModes :PLen /binary >> = ExtData ,
3100
+ assert_unique_extension (psk_key_exchange_modes , Acc ),
3081
3101
decode_extensions (Rest , Version , MessageType ,
3082
3102
Acc #{psk_key_exchange_modes =>
3083
3103
# psk_key_exchange_modes {
@@ -3087,17 +3107,18 @@ decode_extensions(<<?UINT16(?PRE_SHARED_KEY_EXT), ?UINT16(Len),
3087
3107
ExtData :Len /binary , Rest /binary >>,
3088
3108
Version , MessageType = client_hello , Acc ) ->
3089
3109
<<? UINT16 (IdLen ),Identities :IdLen /binary ,? UINT16 (BLen ),Binders :BLen /binary >> = ExtData ,
3110
+ assert_unique_extension (pre_shared_key , Acc ),
3090
3111
decode_extensions (Rest , Version , MessageType ,
3091
3112
Acc #{pre_shared_key =>
3092
3113
# pre_shared_key_client_hello {
3093
3114
offered_psks = # offered_psks {
3094
3115
identities = decode_psk_identities (Identities ),
3095
3116
binders = decode_psk_binders (Binders )}}});
3096
-
3097
3117
decode_extensions (<<? UINT16 (? PRE_SHARED_KEY_EXT ), ? UINT16 (Len ),
3098
3118
ExtData :Len /binary , Rest /binary >>,
3099
3119
Version , MessageType = server_hello , Acc ) ->
3100
3120
<<? UINT16 (Identity )>> = ExtData ,
3121
+ assert_unique_extension (pre_shared_key , Acc ),
3101
3122
decode_extensions (Rest , Version , MessageType ,
3102
3123
Acc #{pre_shared_key =>
3103
3124
# pre_shared_key_server_hello {
@@ -3107,6 +3128,7 @@ decode_extensions(<<?UINT16(?COOKIE_EXT), ?UINT16(Len), ?UINT16(CookieLen),
3107
3128
Cookie :CookieLen /binary , Rest /binary >>,
3108
3129
Version , MessageType , Acc )
3109
3130
when Len == CookieLen + 2 ->
3131
+ assert_unique_extension (cookie , Acc ),
3110
3132
decode_extensions (Rest , Version , MessageType ,
3111
3133
Acc #{cookie => # cookie {cookie = Cookie }});
3112
3134
@@ -3117,6 +3139,7 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
3117
3139
_ExtensionData :Len /binary , Rest /binary >>, Version ,
3118
3140
MessageType = server_hello , Acc )
3119
3141
when Len =:= 0 ->
3142
+ assert_unique_extension (status_request , Acc ),
3120
3143
decode_extensions (Rest , Version , MessageType ,
3121
3144
Acc #{status_request => undefined });
3122
3145
% % 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),
3129
3152
<<? BYTE (? CERTIFICATE_STATUS_TYPE_OCSP ),
3130
3153
? UINT24 (OCSPLen ),
3131
3154
ASN1OCSPResponse :OCSPLen /binary >> ->
3155
+ assert_unique_extension (status_request , Acc ),
3132
3156
decode_extensions (Rest , Version , MessageType ,
3133
3157
Acc #{status_request => # certificate_status {response = ASN1OCSPResponse }});
3134
3158
_Other ->
@@ -3137,12 +3161,14 @@ decode_extensions(<<?UINT16(?STATUS_REQUEST), ?UINT16(Len),
3137
3161
3138
3162
decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (0 ), Rest /binary >>,
3139
3163
Version , MessageType , Acc ) ->
3164
+ assert_unique_extension (early_data , Acc ),
3140
3165
decode_extensions (Rest , Version , MessageType ,
3141
3166
Acc #{early_data => # early_data_indication {}});
3142
3167
3143
3168
decode_extensions (<<? UINT16 (? EARLY_DATA_EXT ), ? UINT16 (4 ), ? UINT32 (MaxSize ),
3144
3169
Rest /binary >>,
3145
3170
Version , MessageType , Acc ) ->
3171
+ assert_unique_extension (early_data , Acc ),
3146
3172
decode_extensions (Rest , Version , MessageType ,
3147
3173
Acc #{early_data =>
3148
3174
# early_data_indication_nst {indication = MaxSize }});
@@ -3151,6 +3177,7 @@ decode_extensions(<<?UINT16(?CERTIFICATE_AUTHORITIES_EXT), ?UINT16(Len),
3151
3177
Version , MessageType , Acc ) ->
3152
3178
CertAutsLen = Len - 2 ,
3153
3179
<<? UINT16 (CertAutsLen ), EncCertAuts /binary >> = CertAutsExt ,
3180
+ assert_unique_extension (certificate_authorities , Acc ),
3154
3181
decode_extensions (Rest , Version , MessageType ,
3155
3182
Acc #{certificate_authorities =>
3156
3183
# certificate_authorities {authorities = decode_cert_auths (EncCertAuts , [])}});
@@ -3162,6 +3189,14 @@ decode_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len/binary, Rest/binary>>
3162
3189
decode_extensions (_ , _ , _ , Acc ) ->
3163
3190
Acc .
3164
3191
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 , {dublicate_extension , Ext }))
3198
+ end .
3199
+
3165
3200
decode_sign_alg (? TLS_1_2 , SignSchemeList ) ->
3166
3201
% % Ignore unknown signature algorithms
3167
3202
Fun = fun (Elem ) ->
0 commit comments