1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2007-2020. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% 22 23-module(ssl_ECC_SUITE). 24 25%% Note: This directive should only be used in test suites. 26-compile(export_all). 27 28-include_lib("common_test/include/ct.hrl"). 29-include_lib("public_key/include/public_key.hrl"). 30 31%%-------------------------------------------------------------------- 32%% Common Test interface functions ----------------------------------- 33%%-------------------------------------------------------------------- 34 35all() -> 36 [ 37 {group, 'tlsv1.2'}, 38 {group, 'tlsv1.1'}, 39 {group, 'tlsv1'}, 40 {group, 'dtlsv1.2'}, 41 {group, 'dtlsv1'} 42 ]. 43 44groups() -> 45 [ 46 {'tlsv1.2', [], [mix_sign | test_cases()]}, 47 {'tlsv1.1', [], test_cases()}, 48 {'tlsv1', [], test_cases()}, 49 {'dtlsv1.2', [], [mix_sign | test_cases()]}, 50 {'dtlsv1', [], test_cases()} 51 ]. 52 53test_cases()-> 54 misc() ++ ecc_negotiation(). 55 56misc()-> 57 [client_ecdsa_server_ecdsa_with_raw_key]. 58 59ecc_negotiation() -> 60 [ecc_default_order, 61 ecc_default_order_custom_curves, 62 ecc_client_order, 63 ecc_client_order_custom_curves, 64 ecc_unknown_curve, 65 client_ecdh_rsa_server_ecdhe_ecdsa_server_custom, 66 client_ecdh_rsa_server_ecdhe_rsa_server_custom, 67 client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom, 68 client_ecdhe_rsa_server_ecdhe_rsa_server_custom, 69 client_ecdhe_rsa_server_ecdh_rsa_server_custom, 70 client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom, 71 client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom, 72 client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom, 73 client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom 74 ]. 75 76%%-------------------------------------------------------------------- 77init_per_suite(Config0) -> 78 end_per_suite(Config0), 79 try crypto:start() of 80 ok -> 81 case ssl_test_lib:sufficient_crypto_support(cipher_ec) of 82 true -> 83 Config0; 84 false -> 85 {skip, "Crypto does not support ECC"} 86 end 87 catch _:_ -> 88 {skip, "Crypto did not start"} 89 end. 90 91end_per_suite(_Config) -> 92 application:stop(ssl), 93 application:stop(crypto). 94 95%%-------------------------------------------------------------------- 96init_per_group(GroupName, Config) -> 97 case ssl_test_lib:is_tls_version(GroupName) of 98 true -> 99 [{tls_version, GroupName}, 100 {server_type, erlang}, 101 {client_type, erlang} | ssl_test_lib:init_tls_version(GroupName, Config)]; 102 _ -> 103 Config 104 end. 105 106end_per_group(GroupName, Config0) -> 107 case ssl_test_lib:is_tls_version(GroupName) of 108 true -> 109 Config = ssl_test_lib:clean_tls_version(Config0), 110 proplists:delete(tls_version, Config); 111 false -> 112 Config0 113 end. 114 115%%-------------------------------------------------------------------- 116 117init_per_testcase(TestCase, Config) -> 118 ssl_test_lib:ct_log_supported_protocol_versions(Config), 119 ct:log("Ciphers: ~p~n ", [ ssl:cipher_suites()]), 120 end_per_testcase(TestCase, Config), 121 ssl:start(), 122 ct:timetrap({seconds, 15}), 123 Config. 124 125end_per_testcase(_TestCase, Config) -> 126 application:stop(ssl), 127 Config. 128 129%%-------------------------------------------------------------------- 130%% Test Cases -------------------------------------------------------- 131%%-------------------------------------------------------------------- 132%% Test diffrent certificate chain types, note that it is the servers 133%% chain that affect what cipher suit that will be choosen 134 135client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) -> 136 Default = ssl_test_lib:default_cert_chain_conf(), 137 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 138 {client_chain, Default}] 139 , ecdhe_ecdsa, ecdhe_ecdsa, Config), 140 COpts = ssl_test_lib:ssl_options(COpts0, Config), 141 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 142 ServerKeyFile = proplists:get_value(keyfile, SOpts), 143 {ok, PemBin} = file:read_file(ServerKeyFile), 144 PemEntries = public_key:pem_decode(PemBin), 145 {'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries), 146 ServerKey = {'ECPrivateKey', Key}, 147 SType = proplists:get_value(server_type, Config), 148 CType = proplists:get_value(client_type, Config), 149 {Server, Port} = ssl_test_lib:start_server_with_raw_key(SType, 150 [{key, ServerKey} | proplists:delete(keyfile, SOpts)], 151 Config), 152 Client = ssl_test_lib:start_client(CType, Port, COpts, Config), 153 ssl_test_lib:gen_check_result(Server, SType, Client, CType), 154 ssl_test_lib:stop(Server, Client). 155 156ecc_default_order(Config) -> 157 Default = ssl_test_lib:default_cert_chain_conf(), 158 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 159 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 160 {client_chain, Default}], 161 ecdhe_ecdsa, ecdhe_ecdsa, 162 Config, DefaultCurve), 163 COpts = ssl_test_lib:ssl_options(COpts0, Config), 164 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 165 ECCOpts = [], 166 case ssl_test_lib:supported_eccs([{eccs, [DefaultCurve]}]) of 167 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 168 false -> {skip, "unsupported named curves"} 169 end. 170 171ecc_default_order_custom_curves(Config) -> 172 Default = ssl_test_lib:default_cert_chain_conf(), 173 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 174 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 175 {client_chain, Default}], 176 ecdhe_ecdsa, ecdhe_ecdsa, 177 Config, DefaultCurve), 178 COpts = ssl_test_lib:ssl_options(COpts0, Config), 179 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 180 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 181 case ssl_test_lib:supported_eccs(ECCOpts) of 182 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 183 false -> {skip, "unsupported named curves"} 184 end. 185 186ecc_client_order(Config) -> 187 Default = ssl_test_lib:default_cert_chain_conf(), 188 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 189 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 190 {client_chain, Default}], 191 ecdhe_ecdsa, ecdhe_ecdsa, 192 Config, DefaultCurve), 193 COpts = ssl_test_lib:ssl_options(COpts0, Config), 194 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 195 ECCOpts = [{honor_ecc_order, false}], 196 case ssl_test_lib:supported_eccs([{eccs, [DefaultCurve]}]) of 197 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 198 false -> {skip, "unsupported named curves"} 199 end. 200 201ecc_client_order_custom_curves(Config) -> 202 Default = ssl_test_lib:default_cert_chain_conf(), 203 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 204 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 205 {client_chain, Default}], 206 ecdhe_ecdsa, ecdhe_ecdsa, 207 Config, DefaultCurve), 208 COpts = ssl_test_lib:ssl_options(COpts0, Config), 209 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 210 ECCOpts = [{honor_ecc_order, false}, {eccs, [secp256r1, DefaultCurve]}], 211 case ssl_test_lib:supported_eccs(ECCOpts) of 212 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 213 false -> {skip, "unsupported named curves"} 214 end. 215 216ecc_unknown_curve(Config) -> 217 Default = ssl_test_lib:default_cert_chain_conf(), 218 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 219 {client_chain, Default}], 220 ecdhe_ecdsa, ecdhe_ecdsa, Config), 221 COpts = ssl_test_lib:ssl_options(COpts0, Config), 222 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 223 ECCOpts = [{eccs, ['123_fake_curve']}], 224 ssl_test_lib:ecc_test_error(COpts, SOpts, [], ECCOpts, Config). 225 226client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) -> 227 Default = ssl_test_lib:default_cert_chain_conf(), 228 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 229 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 230 {client_chain, Default}], 231 ecdh_rsa, ecdhe_ecdsa, Config), 232 COpts = ssl_test_lib:ssl_options(COpts0, Config), 233 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 234 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 235 case ssl_test_lib:supported_eccs(ECCOpts) of 236 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 237 false -> {skip, "unsupported named curves"} 238 end. 239 240client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) -> 241 Default = ssl_test_lib:default_cert_chain_conf(), 242 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 243 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 244 {client_chain, Default}], 245 ecdh_rsa, ecdhe_rsa, Config), 246 COpts = ssl_test_lib:ssl_options(COpts0, Config), 247 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 248 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 249 250 case ssl_test_lib:supported_eccs(ECCOpts) of 251 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 252 false -> {skip, "unsupported named curves"} 253 end. 254 255client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) -> 256 Default = ssl_test_lib:default_cert_chain_conf(), 257 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 258 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 259 {client_chain, Default}], 260 ecdhe_rsa, ecdhe_ecdsa, Config), 261 COpts = ssl_test_lib:ssl_options(COpts0, Config), 262 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 263 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 264 case ssl_test_lib:supported_eccs(ECCOpts) of 265 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 266 false -> {skip, "unsupported named curves"} 267 end. 268 269client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) -> 270 Default = ssl_test_lib:default_cert_chain_conf(), 271 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 272 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 273 {client_chain, Default}], 274 ecdhe_rsa, ecdhe_rsa, Config), 275 276 COpts = ssl_test_lib:ssl_options(COpts0, Config), 277 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 278 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 279 case ssl_test_lib:supported_eccs(ECCOpts) of 280 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 281 false -> {skip, "unsupported named curves"} 282 end. 283client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) -> 284 Default = ssl_test_lib:default_cert_chain_conf(), 285 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 286 Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]), 287 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, [[], [], [{extensions, Ext}]]}, 288 {client_chain, Default}], 289 ecdhe_rsa, ecdh_rsa, Config), 290 291 COpts = ssl_test_lib:ssl_options(COpts0, Config), 292 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 293 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 294 Expected = secp256r1, %% The certificate curve 295 296 case ssl_test_lib:supported_eccs(ECCOpts) of 297 true -> ssl_test_lib:ecc_test(Expected, COpts, SOpts, [], ECCOpts, Config); 298 false -> {skip, "unsupported named curves"} 299 end. 300 301client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) -> 302 Default = ssl_test_lib:default_cert_chain_conf(), 303 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 304 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 305 {client_chain, Default}], 306 ecdhe_ecdsa, ecdhe_ecdsa, Config), 307 COpts = ssl_test_lib:ssl_options(COpts0, Config), 308 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 309 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 310 case ssl_test_lib:supported_eccs(ECCOpts) of 311 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 312 false -> {skip, "unsupported named curves"} 313 end. 314 315client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) -> 316 Default = ssl_test_lib:default_cert_chain_conf(), 317 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 318 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 319 {client_chain, Default}], 320 ecdhe_ecdsa, ecdhe_rsa, Config), 321 COpts = ssl_test_lib:ssl_options(COpts0, Config), 322 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 323 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 324 case ssl_test_lib:supported_eccs(ECCOpts) of 325 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 326 false -> {skip, "unsupported named curves"} 327 end. 328 329client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) -> 330 Default = ssl_test_lib:default_cert_chain_conf(), 331 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 332 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 333 {client_chain, Default}], 334 ecdhe_ecdsa, ecdhe_ecdsa, Config), 335 COpts = ssl_test_lib:ssl_options(COpts0, Config), 336 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 337 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 338 case ssl_test_lib:supported_eccs(ECCOpts) of 339 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config); 340 false -> {skip, "unsupported named curves"} 341 end. 342 343client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom(Config) -> 344 Default = ssl_test_lib:default_cert_chain_conf(), 345 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 346 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 347 {client_chain, Default}], 348 ecdhe_rsa, ecdhe_ecdsa, Config), 349 COpts = ssl_test_lib:ssl_options(COpts0, Config), 350 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 351 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 352 case ssl_test_lib:supported_eccs(ECCOpts) of 353 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config); 354 false -> {skip, "unsupported named curves"} 355 end. 356 357mix_sign(Config) -> 358 mix_sign_rsa_peer(Config), 359 mix_sign_ecdsa_peer(Config). 360 361mix_sign_ecdsa_peer(Config) -> 362 {COpts0, SOpts0} = ssl_test_lib:make_mix_cert([{mix, peer_ecc} |Config]), 363 COpts = ssl_test_lib:ssl_options(COpts0, Config), 364 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 365 ECDHE_ECDSA = 366 ssl:filter_cipher_suites(ssl:cipher_suites(default, 'tlsv1.2'), 367 [{key_exchange, fun(ecdhe_ecdsa) -> true; (_) -> false end}]), 368 ssl_test_lib:basic_test(COpts, [{ciphers, ECDHE_ECDSA} | SOpts], Config). 369 370 371mix_sign_rsa_peer(Config) -> 372 {COpts0, SOpts0} = ssl_test_lib:make_mix_cert([{mix, peer_rsa} |Config]), 373 COpts = ssl_test_lib:ssl_options(COpts0, Config), 374 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 375 ECDHE_RSA = 376 ssl:filter_cipher_suites(ssl:cipher_suites(default, 'tlsv1.2'), 377 [{key_exchange, fun(ecdhe_rsa) -> true; (_) -> false end}]), 378 ssl_test_lib:basic_test(COpts, [{ciphers, ECDHE_RSA} | SOpts], Config). 379 380