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-behaviour(ct_suite). 26 27-include_lib("common_test/include/ct.hrl"). 28-include_lib("public_key/include/public_key.hrl"). 29 30 31%% Common test 32-export([all/0, 33 groups/0, 34 init_per_suite/1, 35 init_per_group/2, 36 init_per_testcase/2, 37 end_per_suite/1, 38 end_per_group/2, 39 end_per_testcase/2 40 ]). 41 42%% Test cases 43-export([ecc_default_order/1, 44 ecc_default_order_custom_curves/1, 45 ecc_client_order/1, 46 ecc_client_order_custom_curves/1, 47 ecc_unknown_curve/1, 48 client_ecdh_rsa_server_ecdhe_ecdsa_server_custom/1, 49 client_ecdh_rsa_server_ecdhe_rsa_server_custom/1, 50 client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom/1, 51 client_ecdhe_rsa_server_ecdhe_rsa_server_custom/1, 52 client_ecdhe_rsa_server_ecdh_rsa_server_custom/1, 53 client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom/1, 54 client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom/1, 55 client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom/1, 56 client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom/1, 57 client_ecdsa_server_ecdsa_with_raw_key/1, 58 mix_sign/1 59 ]). 60 61%%-------------------------------------------------------------------- 62%% Common Test interface functions ----------------------------------- 63%%-------------------------------------------------------------------- 64 65all() -> 66 [ 67 {group, 'tlsv1.2'}, 68 {group, 'tlsv1.1'}, 69 {group, 'tlsv1'}, 70 {group, 'dtlsv1.2'}, 71 {group, 'dtlsv1'} 72 ]. 73 74groups() -> 75 [ 76 {'tlsv1.2', [], [mix_sign | test_cases()]}, 77 {'tlsv1.1', [], test_cases()}, 78 {'tlsv1', [], test_cases()}, 79 {'dtlsv1.2', [], [mix_sign | test_cases()]}, 80 {'dtlsv1', [], test_cases()} 81 ]. 82 83test_cases()-> 84 misc() ++ ecc_negotiation(). 85 86misc()-> 87 [client_ecdsa_server_ecdsa_with_raw_key]. 88 89ecc_negotiation() -> 90 [ecc_default_order, 91 ecc_default_order_custom_curves, 92 ecc_client_order, 93 ecc_client_order_custom_curves, 94 ecc_unknown_curve, 95 client_ecdh_rsa_server_ecdhe_ecdsa_server_custom, 96 client_ecdh_rsa_server_ecdhe_rsa_server_custom, 97 client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom, 98 client_ecdhe_rsa_server_ecdhe_rsa_server_custom, 99 client_ecdhe_rsa_server_ecdh_rsa_server_custom, 100 client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom, 101 client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom, 102 client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom, 103 client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom 104 ]. 105 106%%-------------------------------------------------------------------- 107init_per_suite(Config0) -> 108 end_per_suite(Config0), 109 try crypto:start() of 110 ok -> 111 case ssl_test_lib:sufficient_crypto_support(cipher_ec) of 112 true -> 113 Config0; 114 false -> 115 {skip, "Crypto does not support ECC"} 116 end 117 catch _:_ -> 118 {skip, "Crypto did not start"} 119 end. 120 121end_per_suite(_Config) -> 122 application:stop(ssl), 123 application:stop(crypto). 124 125%%-------------------------------------------------------------------- 126init_per_group(GroupName, Config) -> 127 case ssl_test_lib:is_protocol_version(GroupName) of 128 true -> 129 ct:log("Ciphers: ~p~n ", [ssl:cipher_suites(default, GroupName)]), 130 ssl_test_lib:init_per_group(GroupName, 131 [{client_type, erlang}, 132 {server_type, erlang}, 133 {version, GroupName} | Config]); 134 false -> 135 Config 136 end. 137 138end_per_group(GroupName, Config) -> 139 ssl_test_lib:end_per_group(GroupName, Config). 140 141%%-------------------------------------------------------------------- 142 143init_per_testcase(TestCase, Config) -> 144 ssl_test_lib:ct_log_supported_protocol_versions(Config), 145 Version = proplists:get_value(version, Config), 146 ct:log("Ciphers: ~p~n ", [ssl:cipher_suites(default, Version)]), 147 end_per_testcase(TestCase, Config), 148 ssl:start(), 149 ct:timetrap({seconds, 15}), 150 Config. 151 152end_per_testcase(_TestCase, Config) -> 153 application:stop(ssl), 154 Config. 155 156%%-------------------------------------------------------------------- 157%% Test Cases -------------------------------------------------------- 158%%-------------------------------------------------------------------- 159%% Test diffrent certificate chain types, note that it is the servers 160%% chain that affect what cipher suite that will be choosen 161 162client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) -> 163 Default = ssl_test_lib:default_cert_chain_conf(), 164 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 165 {client_chain, Default}] 166 , ecdhe_ecdsa, ecdhe_ecdsa, Config), 167 COpts = ssl_test_lib:ssl_options(COpts0, Config), 168 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 169 ServerKeyFile = proplists:get_value(keyfile, SOpts), 170 {ok, PemBin} = file:read_file(ServerKeyFile), 171 PemEntries = public_key:pem_decode(PemBin), 172 {'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries), 173 ServerKey = {'ECPrivateKey', Key}, 174 SType = proplists:get_value(server_type, Config), 175 CType = proplists:get_value(client_type, Config), 176 {Server, Port} = ssl_test_lib:start_server_with_raw_key(SType, 177 [{key, ServerKey} | proplists:delete(keyfile, SOpts)], 178 Config), 179 Client = ssl_test_lib:start_client(CType, Port, COpts, Config), 180 ssl_test_lib:gen_check_result(Server, SType, Client, CType), 181 ssl_test_lib:stop(Server, Client). 182 183ecc_default_order(Config) -> 184 Default = ssl_test_lib:default_cert_chain_conf(), 185 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 186 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 187 {client_chain, Default}], 188 ecdhe_ecdsa, ecdhe_ecdsa, 189 Config, DefaultCurve), 190 COpts = ssl_test_lib:ssl_options(COpts0, Config), 191 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 192 ECCOpts = [], 193 case ssl_test_lib:supported_eccs([{eccs, [DefaultCurve]}]) of 194 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 195 false -> {skip, "unsupported named curves"} 196 end. 197 198ecc_default_order_custom_curves(Config) -> 199 Default = ssl_test_lib:default_cert_chain_conf(), 200 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 201 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 202 {client_chain, Default}], 203 ecdhe_ecdsa, ecdhe_ecdsa, 204 Config, DefaultCurve), 205 COpts = ssl_test_lib:ssl_options(COpts0, Config), 206 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 207 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 208 case ssl_test_lib:supported_eccs(ECCOpts) of 209 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 210 false -> {skip, "unsupported named curves"} 211 end. 212 213ecc_client_order(Config) -> 214 Default = ssl_test_lib:default_cert_chain_conf(), 215 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 216 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 217 {client_chain, Default}], 218 ecdhe_ecdsa, ecdhe_ecdsa, 219 Config, DefaultCurve), 220 COpts = ssl_test_lib:ssl_options(COpts0, Config), 221 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 222 ECCOpts = [{honor_ecc_order, false}], 223 case ssl_test_lib:supported_eccs([{eccs, [DefaultCurve]}]) of 224 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 225 false -> {skip, "unsupported named curves"} 226 end. 227 228ecc_client_order_custom_curves(Config) -> 229 Default = ssl_test_lib:default_cert_chain_conf(), 230 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 231 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 232 {client_chain, Default}], 233 ecdhe_ecdsa, ecdhe_ecdsa, 234 Config, DefaultCurve), 235 COpts = ssl_test_lib:ssl_options(COpts0, Config), 236 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 237 ECCOpts = [{honor_ecc_order, false}, {eccs, [secp256r1, DefaultCurve]}], 238 case ssl_test_lib:supported_eccs(ECCOpts) of 239 true -> ssl_test_lib:ecc_test(DefaultCurve, COpts, SOpts, [], ECCOpts, Config); 240 false -> {skip, "unsupported named curves"} 241 end. 242 243ecc_unknown_curve(Config) -> 244 Default = ssl_test_lib:default_cert_chain_conf(), 245 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 246 {client_chain, Default}], 247 ecdhe_ecdsa, ecdhe_ecdsa, Config), 248 COpts = ssl_test_lib:ssl_options(COpts0, Config), 249 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 250 ECCOpts = [{eccs, ['123_fake_curve']}], 251 ssl_test_lib:ecc_test_error(COpts, SOpts, [], ECCOpts, Config). 252 253client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) -> 254 Default = ssl_test_lib:default_cert_chain_conf(), 255 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 256 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 257 {client_chain, Default}], 258 ecdh_rsa, ecdhe_ecdsa, Config), 259 COpts = ssl_test_lib:ssl_options(COpts0, Config), 260 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 261 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 262 case ssl_test_lib:supported_eccs(ECCOpts) of 263 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 264 false -> {skip, "unsupported named curves"} 265 end. 266 267client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) -> 268 Default = ssl_test_lib:default_cert_chain_conf(), 269 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 270 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 271 {client_chain, Default}], 272 ecdh_rsa, ecdhe_rsa, Config), 273 COpts = ssl_test_lib:ssl_options(COpts0, Config), 274 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 275 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 276 277 case ssl_test_lib:supported_eccs(ECCOpts) of 278 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 279 false -> {skip, "unsupported named curves"} 280 end. 281 282client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) -> 283 Default = ssl_test_lib:default_cert_chain_conf(), 284 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 285 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 286 {client_chain, Default}], 287 ecdhe_rsa, ecdhe_ecdsa, Config), 288 COpts = ssl_test_lib:ssl_options(COpts0, Config), 289 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 290 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 291 case ssl_test_lib:supported_eccs(ECCOpts) of 292 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 293 false -> {skip, "unsupported named curves"} 294 end. 295 296client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) -> 297 Default = ssl_test_lib:default_cert_chain_conf(), 298 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 299 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 300 {client_chain, Default}], 301 ecdhe_rsa, ecdhe_rsa, Config), 302 303 COpts = ssl_test_lib:ssl_options(COpts0, Config), 304 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 305 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 306 case ssl_test_lib:supported_eccs(ECCOpts) of 307 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 308 false -> {skip, "unsupported named curves"} 309 end. 310client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) -> 311 Default = ssl_test_lib:default_cert_chain_conf(), 312 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 313 Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]), 314 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, [[], [], [{extensions, Ext}]]}, 315 {client_chain, Default}], 316 ecdhe_rsa, ecdh_rsa, Config), 317 318 COpts = ssl_test_lib:ssl_options(COpts0, Config), 319 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 320 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 321 Expected = secp256r1, %% The certificate curve 322 323 case ssl_test_lib:supported_eccs(ECCOpts) of 324 true -> ssl_test_lib:ecc_test(Expected, COpts, SOpts, [], ECCOpts, Config); 325 false -> {skip, "unsupported named curves"} 326 end. 327 328client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) -> 329 Default = ssl_test_lib:default_cert_chain_conf(), 330 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 331 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 332 {client_chain, Default}], 333 ecdhe_ecdsa, ecdhe_ecdsa, Config), 334 COpts = ssl_test_lib:ssl_options(COpts0, Config), 335 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 336 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 337 case ssl_test_lib:supported_eccs(ECCOpts) of 338 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 339 false -> {skip, "unsupported named curves"} 340 end. 341 342client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) -> 343 Default = ssl_test_lib:default_cert_chain_conf(), 344 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 345 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 346 {client_chain, Default}], 347 ecdhe_ecdsa, ecdhe_rsa, Config), 348 COpts = ssl_test_lib:ssl_options(COpts0, Config), 349 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 350 ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, DefaultCurve]}], 351 case ssl_test_lib:supported_eccs(ECCOpts) of 352 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config); 353 false -> {skip, "unsupported named curves"} 354 end. 355 356client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) -> 357 Default = ssl_test_lib:default_cert_chain_conf(), 358 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 359 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 360 {client_chain, Default}], 361 ecdhe_ecdsa, ecdhe_ecdsa, Config), 362 COpts = ssl_test_lib:ssl_options(COpts0, Config), 363 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 364 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 365 case ssl_test_lib:supported_eccs(ECCOpts) of 366 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config); 367 false -> {skip, "unsupported named curves"} 368 end. 369 370client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom(Config) -> 371 Default = ssl_test_lib:default_cert_chain_conf(), 372 DefaultCurve = pubkey_cert_records:namedCurves(hd(tls_v1:ecc_curves(1))), 373 {COpts0, SOpts0} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default}, 374 {client_chain, Default}], 375 ecdhe_rsa, ecdhe_ecdsa, Config), 376 COpts = ssl_test_lib:ssl_options(COpts0, Config), 377 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 378 ECCOpts = [{eccs, [secp256r1, DefaultCurve]}], 379 case ssl_test_lib:supported_eccs(ECCOpts) of 380 true -> ssl_test_lib:ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config); 381 false -> {skip, "unsupported named curves"} 382 end. 383 384mix_sign(Config) -> 385 mix_sign_rsa_peer(Config), 386 mix_sign_ecdsa_peer(Config). 387 388mix_sign_ecdsa_peer(Config) -> 389 {COpts0, SOpts0} = ssl_test_lib:make_mix_cert([{mix, peer_ecc} |Config]), 390 COpts = ssl_test_lib:ssl_options(COpts0, Config), 391 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 392 ECDHE_ECDSA = 393 ssl:filter_cipher_suites(ssl:cipher_suites(default, 'tlsv1.2'), 394 [{key_exchange, fun(ecdhe_ecdsa) -> true; (_) -> false end}]), 395 ssl_test_lib:basic_test(COpts, [{ciphers, ECDHE_ECDSA} | SOpts], Config). 396 397 398mix_sign_rsa_peer(Config) -> 399 {COpts0, SOpts0} = ssl_test_lib:make_mix_cert([{mix, peer_rsa} |Config]), 400 COpts = ssl_test_lib:ssl_options(COpts0, Config), 401 SOpts = ssl_test_lib:ssl_options(SOpts0, Config), 402 ECDHE_RSA = 403 ssl:filter_cipher_suites(ssl:cipher_suites(default, 'tlsv1.2'), 404 [{key_exchange, fun(ecdhe_rsa) -> true; (_) -> false end}]), 405 ssl_test_lib:basic_test(COpts, [{ciphers, ECDHE_RSA} | SOpts], Config). 406 407