1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2008-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-module(public_key_SUITE). 23 24-include_lib("common_test/include/ct.hrl"). 25-include_lib("public_key/include/public_key.hrl"). 26 27-export([ 28 suite/0, 29 all/0, 30 groups/0, 31 init_per_suite/1, 32 end_per_suite/1, 33 init_per_group/2, 34 end_per_group/2, 35 init_per_testcase/2, 36 init_common_per_testcase/1, 37 end_per_testcase/2, 38 app/0, 39 app/1, 40 appup/0, 41 appup/1, 42 dsa_pem/0, 43 dsa_pem/1, 44 dsa_priv_pkcs8/0, 45 dsa_priv_pkcs8/1, 46 rsa_pem/0, 47 rsa_pem/1, 48 rsa_pss_pss_pem/0, 49 rsa_pss_pss_pem/1, 50 rsa_priv_pkcs8/0, 51 rsa_priv_pkcs8/1, 52 ec_pem/0, 53 ec_pem/1, 54 ec_pem2/0, 55 ec_pem2/1, 56 ec_priv_pkcs8/0, 57 ec_priv_pkcs8/1, 58 eddsa_priv_pkcs8/0, 59 eddsa_priv_pkcs8/1, 60 eddsa_priv_rfc5958/0, 61 eddsa_priv_rfc5958/1, 62 init_ec_pem_encode_generated/1, 63 ec_pem_encode_generated/0, 64 ec_pem_encode_generated/1, 65 encrypted_pem/0, 66 encrypted_pem/1, 67 dh_pem/0, 68 dh_pem/1, 69 pkcs10_pem/0, 70 pkcs10_pem/1, 71 pkcs7_pem/0, 72 pkcs7_pem/1, 73 cert_pem/0, 74 cert_pem/1, 75 encrypt_decrypt/0, 76 encrypt_decrypt/1, 77 rsa_sign_verify/0, 78 rsa_sign_verify/1, 79 rsa_pss_sign_verify/0, 80 rsa_pss_sign_verify/1, 81 dsa_sign_verify/0, 82 dsa_sign_verify/1, 83 pkix/0, 84 pkix/1, 85 pkix_countryname/0, 86 pkix_countryname/1, 87 pkix_emailaddress/0, 88 pkix_emailaddress/1, 89 pkix_path_validation/0, 90 pkix_path_validation/1, 91 pkix_path_validation_root_expired/0, 92 pkix_path_validation_root_expired/1, 93 pkix_verify_hostname_cn/1, 94 pkix_verify_hostname_subjAltName/1, 95 pkix_verify_hostname_options/1, 96 pkix_verify_hostname_subjAltName_IP/1, 97 pkix_iso_rsa_oid/0, 98 pkix_iso_rsa_oid/1, 99 pkix_iso_dsa_oid/0, 100 pkix_iso_dsa_oid/1, 101 pkix_dsa_sha2_oid/0, 102 pkix_dsa_sha2_oid/1, 103 pkix_crl/0, 104 pkix_crl/1, 105 general_name/0, 106 general_name/1, 107 pkix_hash_type/0, 108 pkix_hash_type/1, 109 pkix_test_data_all_default/0, 110 pkix_test_data_all_default/1, 111 pkix_test_data/0, 112 pkix_test_data/1, 113 short_cert_issuer_hash/0, 114 short_cert_issuer_hash/1, 115 short_crl_issuer_hash/0, 116 short_crl_issuer_hash/1, 117 gen_ec_param_prime_field/0, 118 gen_ec_param_prime_field/1, 119 gen_ec_param_char_2_field/0, 120 gen_ec_param_char_2_field/1 121 ]). 122 123-define(TIMEOUT, 120000). % 2 min 124 125 126%%-------------------------------------------------------------------- 127%% Common Test interface functions ----------------------------------- 128%%-------------------------------------------------------------------- 129 130suite() -> 131 []. 132 133all() -> 134 [app, 135 appup, 136 {group, pem_decode_encode}, 137 encrypt_decrypt, 138 {group, sign_verify}, 139 pkix, 140 pkix_countryname, 141 pkix_emailaddress, 142 pkix_path_validation, 143 pkix_path_validation_root_expired, 144 pkix_iso_rsa_oid, 145 pkix_iso_dsa_oid, 146 pkix_dsa_sha2_oid, 147 pkix_crl, 148 pkix_hash_type, 149 general_name, 150 pkix_verify_hostname_cn, 151 pkix_verify_hostname_subjAltName, 152 pkix_verify_hostname_subjAltName_IP, 153 pkix_verify_hostname_options, 154 pkix_test_data_all_default, 155 pkix_test_data, 156 short_cert_issuer_hash, 157 short_crl_issuer_hash 158 ]. 159 160groups() -> 161 [{pem_decode_encode, [], [dsa_pem, rsa_pem, rsa_pss_pss_pem, ec_pem, encrypted_pem, 162 dh_pem, cert_pem, pkcs7_pem, pkcs10_pem, ec_pem2, 163 rsa_priv_pkcs8, dsa_priv_pkcs8, ec_priv_pkcs8, 164 eddsa_priv_pkcs8, eddsa_priv_rfc5958, 165 ec_pem_encode_generated, 166 gen_ec_param_prime_field, gen_ec_param_char_2_field 167 ]}, 168 {sign_verify, [], [rsa_sign_verify, rsa_pss_sign_verify, dsa_sign_verify]} 169 ]. 170%%------------------------------------------------------------------- 171init_per_suite(Config) -> 172 application:stop(crypto), 173 try crypto:start() of 174 ok -> 175 application:start(asn1), 176 Config 177 catch _:_ -> 178 {skip, "Crypto did not start"} 179 end. 180 181end_per_suite(_Config) -> 182 application:stop(asn1), 183 application:stop(crypto). 184 185%%------------------------------------------------------------------- 186init_per_group(_GroupName, Config) -> 187 Config. 188 189end_per_group(_GroupName, Config) -> 190 Config. 191%%------------------------------------------------------------------- 192 193init_per_testcase(pkix_test_data_all_default, Config) -> 194 case crypto:ec_curves() of 195 [] -> 196 {skip, missing_ecc_support}; 197 _ -> 198 init_common_per_testcase(Config) 199 end; 200 201init_per_testcase(gen_ec_param_prime_field=TC, Config) -> 202 init_per_testcase_gen_ec_param(TC, secp521r1, Config); 203 204init_per_testcase(gen_ec_param_char_2_field=TC, Config) -> 205 init_per_testcase_gen_ec_param(TC, sect571r1, Config); 206 207init_per_testcase(rsa_pss_sign_verify, Config) -> 208 Supports = crypto:supports(), 209 RSAOpts = proplists:get_value(rsa_opts, Supports), 210 211 case lists:member(rsa_pkcs1_pss_padding, RSAOpts) 212 andalso lists:member(rsa_pss_saltlen, RSAOpts) 213 andalso lists:member(rsa_mgf1_md, RSAOpts) of 214 true -> 215 Config; 216 false -> 217 {skip, not_supported_by_crypto} 218 end; 219init_per_testcase(TestCase, Config) -> 220 case TestCase of 221 ec_pem_encode_generated -> 222 init_ec_pem_encode_generated(Config); 223 _ -> init_common_per_testcase(Config) 224 end. 225 226init_common_per_testcase(Config0) -> 227 Config = lists:keydelete(watchdog, 1, Config0), 228 Dog = ct:timetrap(?TIMEOUT), 229 [{watchdog, Dog} | Config]. 230 231 232end_per_testcase(_TestCase, _Config) -> 233 ok. 234 235%%-------------------------------------------------------------------- 236%% Test Cases -------------------------------------------------------- 237%%-------------------------------------------------------------------- 238 239app() -> 240 [{doc, "Test that the public_key app file is ok"}]. 241app(Config) when is_list(Config) -> 242 ok = test_server:app_test(public_key). 243 244%%-------------------------------------------------------------------- 245 246appup() -> 247 [{doc, "Test that the public_key appup file is ok"}]. 248appup(Config) when is_list(Config) -> 249 ok = test_server:appup_test(public_key). 250 251%%-------------------------------------------------------------------- 252 253dsa_pem() -> 254 [{doc, "DSA PEM-file decode/encode"}]. 255dsa_pem(Config) when is_list(Config) -> 256 Datadir = proplists:get_value(data_dir, Config), 257 258 [{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] = 259 erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")), 260 261 DSAKey = public_key:der_decode('DSAPrivateKey', DerDSAKey), 262 263 DSAKey = public_key:pem_entry_decode(Entry0), 264 265 {ok, DSAPubPem} = file:read_file(filename:join(Datadir, "dsa_pub.pem")), 266 [{'SubjectPublicKeyInfo', _, _} = PubEntry0] = 267 public_key:pem_decode(DSAPubPem), 268 DSAPubKey = public_key:pem_entry_decode(PubEntry0), 269 true = check_entry_type(DSAPubKey, 'DSAPublicKey'), 270 PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', DSAPubKey), 271 DSAPubPemNoEndNewLines = strip_superfluous_newlines(DSAPubPem), 272 DSAPubPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry0])). 273 274dsa_priv_pkcs8() -> 275 [{doc, "DSA PKCS8 private key decode/encode"}]. 276dsa_priv_pkcs8(Config) when is_list(Config) -> 277 Datadir = proplists:get_value(data_dir, Config), 278 {ok, DsaPem} = file:read_file(filename:join(Datadir, "dsa_key_pkcs8.pem")), 279 [{'PrivateKeyInfo', DerDSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(DsaPem), 280 DSAKey = public_key:der_decode('PrivateKeyInfo', DerDSAKey), 281 DSAKey = public_key:pem_entry_decode(Entry0), 282 true = check_entry_type(DSAKey, 'DSAPrivateKey'), 283 PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', DSAKey), 284 DSAPemNoEndNewLines = strip_superfluous_newlines(DsaPem), 285 DSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 286 287%%-------------------------------------------------------------------- 288 289rsa_pem() -> 290 [{doc, "RSA PEM-file decode/encode"}]. 291rsa_pem(Config) when is_list(Config) -> 292 Datadir = proplists:get_value(data_dir, Config), 293 [{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry0 ] = 294 erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")), 295 296 RSAKey0 = public_key:der_decode('RSAPrivateKey', DerRSAKey), 297 298 RSAKey0 = public_key:pem_entry_decode(Entry0), 299 300 [{'RSAPrivateKey', _, {_,_}} = Entry1] = 301 erl_make_certs:pem_to_der(filename:join(Datadir, "rsa.pem")), 302 303 true = check_entry_type(public_key:pem_entry_decode(Entry1, "abcd1234"), 304 'RSAPrivateKey'), 305 306 {ok, RSAPubPem} = file:read_file(filename:join(Datadir, "rsa_pub.pem")), 307 [{'SubjectPublicKeyInfo', _, _} = PubEntry0] = 308 public_key:pem_decode(RSAPubPem), 309 RSAPubKey = public_key:pem_entry_decode(PubEntry0), 310 true = check_entry_type(RSAPubKey, 'RSAPublicKey'), 311 PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey), 312 RSAPubPemNoEndNewLines = strip_superfluous_newlines(RSAPubPem), 313 RSAPubPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry0])), 314 315 {ok, RSARawPem} = file:read_file(filename:join(Datadir, "rsa_pub_key.pem")), 316 [{'RSAPublicKey', _, _} = PubEntry1] = 317 public_key:pem_decode(RSARawPem), 318 RSAPubKey = public_key:pem_entry_decode(PubEntry1), 319 RSARawPemNoEndNewLines = strip_superfluous_newlines(RSARawPem), 320 RSARawPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry1])). 321 322rsa_pss_pss_pem() -> 323 [{doc, "RSA PKCS8 RSASSA-PSS private key decode/encode"}]. 324rsa_pss_pss_pem(Config) when is_list(Config) -> 325 Datadir = proplists:get_value(data_dir, Config), 326 {ok, RsaPem} = file:read_file(filename:join(Datadir, "rsa_pss_pss_key.pem")), 327 [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(RsaPem), 328 {RSAKey, Parms} = public_key:der_decode('PrivateKeyInfo', DerRSAKey), 329 {RSAKey, Parms} = public_key:pem_entry_decode(Entry0), 330 true = check_entry_type(RSAKey, 'RSAPrivateKey'), 331 PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', {RSAKey, Parms}), 332 RSAPemNoEndNewLines = strip_superfluous_newlines(RsaPem), 333 RSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 334 335rsa_priv_pkcs8() -> 336 [{doc, "RSA PKCS8 private key decode/encode"}]. 337rsa_priv_pkcs8(Config) when is_list(Config) -> 338 Datadir = proplists:get_value(data_dir, Config), 339 {ok, RsaPem} = file:read_file(filename:join(Datadir, "rsa_key_pkcs8.pem")), 340 [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(RsaPem), 341 RSAKey = public_key:der_decode('PrivateKeyInfo', DerRSAKey), 342 RSAKey = public_key:pem_entry_decode(Entry0), 343 true = check_entry_type(RSAKey, 'RSAPrivateKey'), 344 PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', RSAKey), 345 RSAPemNoEndNewLines = strip_superfluous_newlines(RsaPem), 346 RSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 347 348%%-------------------------------------------------------------------- 349 350ec_pem() -> 351 [{doc, "EC key PEM-file decode/encode"}]. 352ec_pem(Config) when is_list(Config) -> 353 Datadir = proplists:get_value(data_dir, Config), 354 {ok, ECPubPem} = file:read_file(filename:join(Datadir, "ec_pubkey.pem")), 355 [{'SubjectPublicKeyInfo', _, _} = PubEntry0] = 356 public_key:pem_decode(ECPubPem), 357 ECPubKey = public_key:pem_entry_decode(PubEntry0), 358 true = check_entry_type(ECPubKey, 'ECPoint'), 359 PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', ECPubKey), 360 ECPubPemNoEndNewLines = strip_superfluous_newlines(ECPubPem), 361 ECPubPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry0])), 362 363 {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key.pem")), 364 [{'EcpkParameters', _, not_encrypted} = Entry1, 365 {'ECPrivateKey', _, not_encrypted} = Entry2] = public_key:pem_decode(ECPrivPem), 366 367 ECParams = public_key:pem_entry_decode(Entry1), 368 true = check_entry_type(ECParams, 'EcpkParameters'), 369 ECPrivKey = public_key:pem_entry_decode(Entry2), 370 true = check_entry_type(ECPrivKey, 'ECPrivateKey'), 371 true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'), 372 ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), 373 ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])). 374 375ec_pem2() -> 376 [{doc, "EC key w/explicit params PEM-file decode/encode"}]. 377ec_pem2(Config) when is_list(Config) -> 378 Datadir = proplists:get_value(data_dir, Config), 379 380 %% Load key with explicit curve parameters. Generated with... 381 %% openssl ecparam -name secp521r1 -genkey -param_enc explicit -out ec_key2.pem 382 {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key2.pem")), 383 [{'EcpkParameters', _, not_encrypted} = Entry1, 384 {'ECPrivateKey', _, not_encrypted} = Entry2] = public_key:pem_decode(ECPrivPem), 385 386 ECParams = public_key:pem_entry_decode(Entry1), 387 true = check_entry_type(ECParams, 'EcpkParameters'), 388 ECPrivKey = public_key:pem_entry_decode(Entry2), 389 true = check_entry_type(ECPrivKey, 'ECPrivateKey'), 390 true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'), 391 ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), 392 ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])). 393 394ec_priv_pkcs8() -> 395 [{doc, "EC PKCS8 private key decode/encode"}]. 396ec_priv_pkcs8(Config) when is_list(Config) -> 397 Datadir = proplists:get_value(data_dir, Config), 398 {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key_pkcs8.pem")), 399 [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), 400 ECPrivKey = public_key:pem_entry_decode(PKCS8Key), 401 true = check_entry_type(ECPrivKey, 'ECPrivateKey'), 402 true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'), 403 PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', ECPrivKey), 404 ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), 405 ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 406 407eddsa_priv_pkcs8() -> 408 [{doc, "EDDSA PKCS8 private key decode/encode"}]. 409eddsa_priv_pkcs8(Config) when is_list(Config) -> 410 Datadir = proplists:get_value(data_dir, Config), 411 {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "eddsa_key_pkcs8.pem")), 412 [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), 413 ECPrivKey = public_key:pem_entry_decode(PKCS8Key), 414 true = check_entry_type(ECPrivKey, 'ECPrivateKey'), 415 true = ECPrivKey#'ECPrivateKey'.parameters == {namedCurve, ?'id-Ed25519'}, 416 true = size(ECPrivKey#'ECPrivateKey'.privateKey) == 32, 417 PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', ECPrivKey), 418 ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), 419 ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 420 421eddsa_priv_rfc5958() -> 422 [{doc, "EDDSA PKCS8 private key decode/encode"}]. 423eddsa_priv_rfc5958(Config) when is_list(Config) -> 424 Datadir = proplists:get_value(data_dir, Config), 425 {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "eddsa_key_rfc5958.pem")), 426 [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), 427 ECPrivKey = public_key:pem_entry_decode(PKCS8Key), 428 true = check_entry_type(ECPrivKey, 'ECPrivateKey'), 429 true = ECPrivKey#'ECPrivateKey'.parameters == {namedCurve, ?'id-Ed25519'}, 430 true = size(ECPrivKey#'ECPrivateKey'.privateKey) == 32, 431 PrivEntry0 = public_key:pem_entry_encode('OneAsymmetricKey', ECPrivKey), 432 ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), 433 ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). 434 435init_ec_pem_encode_generated(Config) -> 436 case catch true = lists:member('secp384r1', crypto:ec_curves()) of 437 {'EXIT', _} -> {skip, {'secp384r1', not_supported}}; 438 _ -> init_common_per_testcase(Config) 439 end. 440 441ec_pem_encode_generated() -> 442 [{doc, "PEM-encode generated EC key"}]. 443ec_pem_encode_generated(_Config) -> 444 445 Key1 = public_key:generate_key({namedCurve, 'secp384r1'}), 446 public_key:pem_entry_encode('ECPrivateKey', Key1), 447 448 Key2 = public_key:generate_key({namedCurve, ?'secp384r1'}), 449 public_key:pem_entry_encode('ECPrivateKey', Key2). 450 451 452%%-------------------------------------------------------------------- 453 454encrypted_pem() -> 455 [{doc, "Encrypted PEM-file decode/encode"}]. 456encrypted_pem(Config) when is_list(Config) -> 457 Datadir = proplists:get_value(data_dir, Config), 458 459 [{'RSAPrivateKey', DerRSAKey, not_encrypted}] = 460 erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")), 461 462 RSAKey = public_key:der_decode('RSAPrivateKey', DerRSAKey), 463 464 Salt0 = crypto:strong_rand_bytes(8), 465 Entry0 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey, 466 {{"DES-EDE3-CBC", Salt0}, "1234abcd"}), 467 RSAKey = public_key:pem_entry_decode(Entry0,"1234abcd"), 468 Des3KeyFile = filename:join(Datadir, "des3_client_key.pem"), 469 erl_make_certs:der_to_pem(Des3KeyFile, [Entry0]), 470 [{'RSAPrivateKey', _, {"DES-EDE3-CBC", Salt0}}] = 471 erl_make_certs:pem_to_der(Des3KeyFile), 472 473 Salt1 = crypto:strong_rand_bytes(8), 474 Entry1 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey, 475 {{"DES-CBC", Salt1}, "4567efgh"}), 476 DesKeyFile = filename:join(Datadir, "des_client_key.pem"), 477 erl_make_certs:der_to_pem(DesKeyFile, [Entry1]), 478 [{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry2] = 479 erl_make_certs:pem_to_der(DesKeyFile), 480 {ok, Pem} = file:read_file(DesKeyFile), 481 check_encapsulated_header(Pem), 482 true = check_entry_type(public_key:pem_entry_decode(Entry2, "4567efgh"), 483 'RSAPrivateKey'). 484 485%%-------------------------------------------------------------------- 486 487dh_pem() -> 488 [{doc, "DH parametrs PEM-file decode/encode"}]. 489dh_pem(Config) when is_list(Config) -> 490 Datadir = proplists:get_value(data_dir, Config), 491 [{'DHParameter', _DerDH, not_encrypted} = Entry] = 492 erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")), 493 asn1_encode_decode(Entry). 494 495%%-------------------------------------------------------------------- 496 497pkcs10_pem() -> 498 [{doc, "PKCS-10 PEM-file decode/encode"}]. 499pkcs10_pem(Config) when is_list(Config) -> 500 Datadir = proplists:get_value(data_dir, Config), 501 [{'CertificationRequest', _DerPKCS10, not_encrypted} = Entry] = 502 erl_make_certs:pem_to_der(filename:join(Datadir, "req.pem")), 503 asn1_encode_decode(Entry). 504%%-------------------------------------------------------------------- 505pkcs7_pem() -> 506 [{doc, "PKCS-7 PEM-file decode/encode"}]. 507pkcs7_pem(Config) when is_list(Config) -> 508 Datadir = proplists:get_value(data_dir, Config), 509 [{'ContentInfo', _, not_encrypted} = Entry0] = 510 erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_cert.pem")), 511 [{'ContentInfo', _, not_encrypted} = Entry1] = 512 erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_ext.pem")), 513 asn1_encode_decode(Entry0), 514 asn1_encode_decode(Entry1). 515 516%%-------------------------------------------------------------------- 517cert_pem() -> 518 [{doc, "Certificate PEM-file decode/encode"}]. 519cert_pem(Config) when is_list(Config) -> 520 Datadir = proplists:get_value(data_dir, Config), 521 522 [{'Certificate', _, not_encrypted} = Entry0] = 523 erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")), 524 525 asn1_encode_decode(Entry0), 526 527 [{'Certificate', _, not_encrypted} = Entry1, 528 {'Certificate', _, not_encrypted} = Entry2] = 529 erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")), 530 531 asn1_encode_decode(Entry1), 532 asn1_encode_decode(Entry2). 533 534%%-------------------------------------------------------------------- 535encrypt_decrypt() -> 536 [{doc, "Test public_key:encrypt_private and public_key:decrypt_public"}]. 537encrypt_decrypt(Config) when is_list(Config) -> 538 {PrivateKey, _DerKey} = erl_make_certs:gen_rsa(64), 539 #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = PrivateKey, 540 PublicKey = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, 541 Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), 542 RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), 543 Msg = public_key:decrypt_public(RsaEncrypted, PublicKey), 544 RsaEncrypted2 = public_key:encrypt_public(Msg, PublicKey), 545 Msg = public_key:decrypt_private(RsaEncrypted2, PrivateKey), 546 ok. 547 548%%-------------------------------------------------------------------- 549rsa_sign_verify() -> 550 [{doc, "Checks that we can sign and verify rsa signatures."}]. 551rsa_sign_verify(Config) when is_list(Config) -> 552 Ca = {_, CaKey} = erl_make_certs:make_cert([]), 553 {Cert1, _} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]), 554 PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = 555 public_key:pem_entry_decode(CaKey), 556 PublicRSA = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, 557 true = public_key:pkix_verify(Cert1, PublicRSA), 558 559 Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), 560 RSASign = public_key:sign(Msg, sha, PrivateRSA), 561 true = public_key:verify(Msg, sha, RSASign, PublicRSA), 562 false = public_key:verify(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA), 563 false = public_key:verify(Msg, sha, <<1:8, RSASign/binary>>, PublicRSA), 564 565 RSASign1 = public_key:sign(Msg, md5, PrivateRSA), 566 true = public_key:verify(Msg, md5, RSASign1, PublicRSA). 567 568%%-------------------------------------------------------------------- 569rsa_pss_sign_verify() -> 570 [{doc, "Checks that we can sign and verify rsa pss signatures."}]. 571rsa_pss_sign_verify(Config) when is_list(Config) -> 572 CertChainConf = #{server_chain => 573 #{root => [], 574 intermediates => [], 575 peer => []}, 576 client_chain => 577 #{root => [{key, {hardcode_rsa_key(1), pss_params(sha256)}}], 578 intermediates => [], 579 peer => []}}, 580 #{client_config := ClientConf} = public_key:pkix_test_data(CertChainConf), 581 Cert = proplists:get_value(cert, ClientConf), 582 {#'RSAPrivateKey'{modulus=Mod, publicExponent=Exp}, Parms} = {hardcode_rsa_key(1), pss_params(sha256)}, 583 584 true = public_key:pkix_verify(Cert, {#'RSAPublicKey'{modulus=Mod, publicExponent=Exp}, Parms}). 585 586%%-------------------------------------------------------------------- 587 588dsa_sign_verify() -> 589 [{doc, "Checks that we can sign and verify dsa signatures."}]. 590dsa_sign_verify(Config) when is_list(Config) -> 591 Ca = erl_make_certs:make_cert([]), 592 CertInfo = {_,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]), 593 {Cert2,_CertKey} = erl_make_certs:make_cert([{issuer, CertInfo}]), 594 595 #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X} = 596 public_key:pem_entry_decode(CertKey1), 597 true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}), 598 599 Datadir = proplists:get_value(data_dir, Config), 600 [DsaKey = {'DSAPrivateKey', _, _}] = 601 erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")), 602 DSAPrivateKey = public_key:pem_entry_decode(DsaKey), 603 #'DSAPrivateKey'{p=P1, q=Q1, g=G1, y=Y1, x=_X1} = DSAPrivateKey, 604 605 Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), 606 DSASign = public_key:sign(Msg, sha, DSAPrivateKey), 607 DSAPublicKey = Y1, 608 DSAParams = #'Dss-Parms'{p=P1, q=Q1, g=G1}, 609 true = public_key:verify(Msg, sha, DSASign, {DSAPublicKey, DSAParams}), 610 false = public_key:verify(<<1:8, Msg/binary>>, sha, DSASign, 611 {DSAPublicKey, DSAParams}), 612 false = public_key:verify(Msg, sha, <<1:8, DSASign/binary>>, 613 {DSAPublicKey, DSAParams}), 614 615 Digest = crypto:hash(sha,Msg), 616 DigestSign = public_key:sign(Digest, none, DSAPrivateKey), 617 true = public_key:verify(Digest, none, DigestSign, {DSAPublicKey, DSAParams}), 618 <<_:8, RestDigest/binary>> = Digest, 619 false = public_key:verify(<<1:8, RestDigest/binary>>, none, DigestSign, 620 {DSAPublicKey, DSAParams}), 621 false = public_key:verify(Digest, none, <<1:8, DigestSign/binary>>, 622 {DSAPublicKey, DSAParams}). 623 624%%-------------------------------------------------------------------- 625pkix() -> 626 [{doc, "Misc pkix tests not covered elsewhere"}]. 627pkix(Config) when is_list(Config) -> 628 Datadir = proplists:get_value(data_dir, Config), 629 Certs0 = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")), 630 Certs1 = erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")), 631 TestTransform = fun({'Certificate', CertDer, not_encrypted}) -> 632 PlainCert = public_key:pkix_decode_cert(CertDer, plain), 633 OtpCert = public_key:pkix_decode_cert(CertDer, otp), 634 CertDer = 635 public_key:pkix_encode('OTPCertificate', OtpCert, otp), 636 CertDer = 637 public_key:pkix_encode('Certificate', PlainCert, plain), 638 OTPTBS = OtpCert#'OTPCertificate'.tbsCertificate, 639 OTPSubj = OTPTBS#'OTPTBSCertificate'.subject, 640 DNEncoded = public_key:pkix_encode('Name', OTPSubj, otp), 641 PlainTBS = PlainCert#'Certificate'.tbsCertificate, 642 Subj2 = PlainTBS#'TBSCertificate'.subject, 643 DNEncoded = public_key:pkix_encode('Name', Subj2, plain), 644 645 false = public_key:pkix_is_fixed_dh_cert(CertDer) 646 end, 647 [TestTransform(Cert) || Cert <- Certs0 ++ Certs1], 648 649 Root = element(2, hd(Certs0)), 650 Peer = element(2, hd(Certs1)), 651 652 true = public_key:pkix_is_self_signed(Root), 653 false = public_key:pkix_is_self_signed(Peer), 654 655 CaIds = [element(2, public_key:pkix_issuer_id(Cert, self)) || 656 {'Certificate', Cert, _} <- Certs0], 657 {ok, IssuerId} = 658 public_key:pkix_issuer_id(Peer, other), 659 660 {ok, Id} = public_key:pkix_issuer_id(Root, self), 661 Id = public_key:pkix_subject_id(Root), 662 663 true = lists:member(IssuerId, CaIds), 664 665 %% Should be normalized allready 666 TestStr = {rdnSequence, 667 [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"ERLANGCA"}}], 668 [{'AttributeTypeAndValue', {2,5,4,3},{printableString," erlang ca "}}]]}, 669 VerifyStr = {rdnSequence, 670 [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}], 671 [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}]]}, 672 VerifyStr = public_key:pkix_normalize_name(TestStr). 673 674 675%%-------------------------------------------------------------------- 676pkix_countryname() -> 677 [{doc, "Test workaround for certs that code x509countryname as utf8"}]. 678pkix_countryname(Config) when is_list(Config) -> 679 Cert = incorrect_countryname_pkix_cert(), 680 OTPCert = public_key:pkix_decode_cert(Cert, otp), 681 TBSCert = OTPCert#'OTPCertificate'.tbsCertificate, 682 Issuer = TBSCert#'OTPTBSCertificate'.issuer, 683 Subj = TBSCert#'OTPTBSCertificate'.subject, 684 check_countryname(Issuer), 685 check_countryname(Subj). 686 687%%-------------------------------------------------------------------- 688pkix_emailaddress() -> 689 [{doc, "Test workaround for certs that code emailAddress as utf8"}]. 690pkix_emailaddress(Config) when is_list(Config) -> 691 Cert = incorrect_emailaddress_pkix_cert(), 692 OTPCert = public_key:pkix_decode_cert(Cert, otp), 693 TBSCert = OTPCert#'OTPCertificate'.tbsCertificate, 694 Issuer = TBSCert#'OTPTBSCertificate'.issuer, 695 Subj = TBSCert#'OTPTBSCertificate'.subject, 696 check_emailaddress(Issuer), 697 check_emailaddress(Subj). 698 699%%-------------------------------------------------------------------- 700pkix_path_validation() -> 701 [{doc, "Test PKIX path validation"}]. 702pkix_path_validation(Config) when is_list(Config) -> 703 CaK = {Trusted,_} = 704 erl_make_certs:make_cert([{key, dsa}, 705 {subject, [ 706 {name, "Public Key"}, 707 {?'id-at-name', {printableString, "public_key"}}, 708 {?'id-at-pseudonym', {printableString, "pubkey"}}, 709 {city, "Stockholm"}, 710 {country, "SE"}, 711 {org, "erlang"}, 712 {org_unit, "testing dep"} 713 ]} 714 ]), 715 ok = erl_make_certs:write_pem("./", "public_key_cacert", CaK), 716 717 CertK1 = {Cert1, _} = erl_make_certs:make_cert([{issuer, CaK}]), 718 CertK2 = {Cert2,_} = erl_make_certs:make_cert([{issuer, CertK1}, 719 {digest, md5}, {extensions, false}]), 720 ok = erl_make_certs:write_pem("./", "public_key_cert", CertK2), 721 722 {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1], []), 723 724 {error, {bad_cert,invalid_issuer}} = 725 public_key:pkix_path_validation(Trusted, [Cert2], []), 726 727 {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1, Cert2], []), 728 {error, issuer_not_found} = public_key:pkix_issuer_id(Cert2, other), 729 730 CertK3 = {Cert3,_} = erl_make_certs:make_cert([{issuer, CertK1}, 731 {extensions, [{basic_constraints, false}]}]), 732 {Cert4,_} = erl_make_certs:make_cert([{issuer, CertK3}, {extensions, [{key_usage, undefined}]}]), 733 734 {error, {bad_cert,missing_basic_constraint}} = 735 public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], []), 736 737 VerifyFunAndState0 = {fun(_,{bad_cert, missing_basic_constraint}, UserState) -> 738 {valid, UserState}; 739 (_,{bad_cert, _} = Reason, _) -> 740 {fail, Reason}; 741 (_,{extension, _}, UserState) -> 742 {unknown, UserState}; 743 (_, valid, UserState) -> 744 {valid, UserState}; 745 (_, valid_peer, UserState) -> 746 {valid, UserState} 747 end, []}, 748 {ok, _} = 749 public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], 750 [{verify_fun, VerifyFunAndState0}]), 751 752 {error, {bad_cert, unknown_ca}} = 753 public_key:pkix_path_validation(unknown_ca, [Cert1, Cert3, Cert4], []), 754 755 VerifyFunAndState1 = 756 {fun(_,{bad_cert, unknown_ca}, UserState) -> 757 {valid, UserState}; 758 (_,{bad_cert, _} = Reason, _) -> 759 {fail, Reason}; 760 (_,{extension, _}, UserState) -> 761 {unknown, UserState}; 762 (_, valid, UserState) -> 763 {valid, UserState} 764 end, []}, 765 766 {ok, _} = 767 public_key:pkix_path_validation(unknown_ca, [Cert1], [{verify_fun, 768 VerifyFunAndState1}]), 769 770 VerifyFunAndState2 = 771 {fun(_, {bad_cert, selfsigned_peer}, _UserState) -> 772 {fail, custom_reason}; 773 (_,{extension, _}, UserState) -> 774 {unknown, UserState}; 775 (_, valid, UserState) -> 776 {valid, UserState} 777 end, []}, 778 779 {error, custom_reason} = 780 public_key:pkix_path_validation(selfsigned_peer, [Trusted], [{verify_fun, 781 VerifyFunAndState2}]), 782 % check RSASSA-PSS key 783 % RsaPssKey = {public_key:generate_key({rsa, 1024, 65537}), pss_params(sha256)}, 784 RsaPssKey = {hardcode_rsa_key(1), pss_params(sha256)}, 785 786 CaKPSS = {TrustedPSSCert,_} = erl_make_certs:make_cert([{key, RsaPssKey}, 787 {subject, [ 788 {name, "RSASSA-PSS Public Key"}, 789 {?'id-at-name', {printableString, "public_key"}}, 790 {?'id-at-pseudonym', {printableString, "pubkey"}}, 791 {city, "Stockholm"}, 792 {country, "SE"}, 793 {org, "erlang"}, 794 {org_unit, "testing dep"} 795 ]} 796 ]), 797 ChainPSSCert = {CertPSS, _} = erl_make_certs:make_cert([{issuer, {TrustedPSSCert,RsaPssKey}}]), 798 {ok, _} = public_key:pkix_path_validation(TrustedPSSCert, [CertPSS], []). 799 800pkix_path_validation_root_expired() -> 801 [{doc, "Test root expiration so that it does not fall between chairs"}]. 802pkix_path_validation_root_expired(Config) when is_list(Config) -> 803 {Year, Month, Day} = date(), 804 SRoot = public_key:pkix_test_root_cert("OTP test server ROOT", [{validity, {{Year-2, Month, Day}, 805 {Year-1, Month, Day}}}]), 806 #{server_config := Conf} = public_key:pkix_test_data(#{server_chain => #{root => SRoot, 807 intermediates => [], 808 peer => []}, 809 client_chain => #{root => [], 810 intermediates => [], 811 peer => []}}), 812 [ICA, Root] = proplists:get_value(cacerts, Conf), 813 true = public_key:pkix_is_self_signed(Root), 814 Peer = proplists:get_value(cert, Conf), 815 {error, {bad_cert, cert_expired}} = public_key:pkix_path_validation(Root, [ICA, Peer], []). 816 817%%-------------------------------------------------------------------- 818%% To generate the PEM file contents: 819%% 820%% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -subj '/C=SE/CN=example.com/CN=*.foo.example.com/CN=a*b.bar.example.com/O=erlang.org' > public_key_SUITE_data/pkix_verify_hostname_cn.pem 821%% 822%% Note that the same pem-file is used in pkix_verify_hostname_options/1 823%% 824%% Subject: C=SE, CN=example.com, CN=*.foo.example.com, CN=a*b.bar.example.com, O=erlang.org 825%% extensions = no subjAltName 826 827pkix_verify_hostname_cn(Config) -> 828 DataDir = proplists:get_value(data_dir, Config), 829 {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_cn.pem")), 830 Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp), 831 832 %% Check that 1) only CNs are checked, 833 %% 2) an empty label does not match a wildcard and 834 %% 3) a wildcard does not match more than one label 835 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"erlang.org"}, 836 {dns_id,"foo.EXAMPLE.com"}, 837 {dns_id,"b.a.foo.EXAMPLE.com"}]), 838 839 %% Check that a hostname is extracted from a https-uri and used for checking: 840 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"HTTPS://EXAMPLE.com"}]), 841 842 %% Check wildcard matching one label: 843 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"a.foo.EXAMPLE.com"}]), 844 845 %% Check wildcard with surrounding chars matches one label: 846 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"accb.bar.EXAMPLE.com"}]), 847 848 %% Check that a wildcard with surrounding chars matches an empty string: 849 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://ab.bar.EXAMPLE.com"}]). 850 851%%-------------------------------------------------------------------- 852%% To generate the PEM file contents: 853%% 854%% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -extensions SAN -config public_key_SUITE_data/verify_hostname.conf 2>/dev/null > public_key_SUITE_data/pkix_verify_hostname_subjAltName.pem 855%% 856%% Subject: C=SE, CN=example.com 857%% Subject Alternative Name: DNS:kb.example.org, DNS:*.example.org, URI:http://www.example.org, URI:https://wws.example.org 858 859pkix_verify_hostname_subjAltName(Config) -> 860 DataDir = proplists:get_value(data_dir, Config), 861 {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_subjAltName.pem")), 862 Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp), 863 864 %% Check that neither a uri nor dns hostname matches a CN if subjAltName is present: 865 false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://example.com"}, 866 {dns_id,"example.com"}]), 867 868 %% Check that a uri_id matches a URI subjAltName: 869 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://wws.example.org"}]), 870 871 %% Check that a dns_id does not match a URI subjAltName: 872 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"www.example.org"}, 873 {dns_id,"wws.example.org"}]), 874 875 %% Check that a dns_id matches a DNS subjAltName: 876 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"kb.example.org"}]), 877 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"KB.EXAMPLE.ORG"}]), 878 879 %% Check that a dns_id does not match a DNS subjAltName wiht wildcard 880 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"other.example.org"}]), 881 882 %% Check that a dns_id does match a DNS subjAltName wiht wildcard with matchfun 883 MatchFun = {match_fun, public_key:pkix_verify_hostname_match_fun(https)}, 884 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"other.example.org"}], [MatchFun]), 885 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"OTHER.EXAMPLE.ORG"}], [MatchFun]), 886 887 %% Check that a uri_id does not match a DNS subjAltName wiht wildcard 888 false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://other.example.org"}]), 889 false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://OTHER.EXAMPLE.ORG"}]), 890 891 %% Check that a dns_id does match a DNS subjAltName wiht wildcard with matchfun 892 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://other.example.org"}], [MatchFun]), 893 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://OTHER.EXAMPLE.ORG"}], [MatchFun]), 894 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://OTHER.example.org"}], [MatchFun]), 895 896 ok. 897 898%%-------------------------------------------------------------------- 899%% Uses the pem-file for pkix_verify_hostname_cn 900%% Subject: C=SE, CN=example.com, CN=*.foo.example.com, CN=a*b.bar.example.com, O=erlang.org 901pkix_verify_hostname_options(Config) -> 902 DataDir = proplists:get_value(data_dir, Config), 903 {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_cn.pem")), 904 Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp), 905 906 %% Check that the fail_callback is called and is presented the correct certificate: 907 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"erlang.org"}], 908 [{fail_callback, 909 fun(#'OTPCertificate'{}=C) when C==Cert -> 910 true; % To test the return value matters 911 (#'OTPCertificate'{}=C) -> 912 ct:log("~p:~p: Wrong cert:~n~p~nExpect~n~p", 913 [?MODULE, ?LINE, C, Cert]), 914 ct:fail("Wrong cert, see log"); 915 (C) -> 916 ct:log("~p:~p: Bad cert: ~p",[?MODULE,?LINE,C]), 917 ct:fail("Bad cert, see log") 918 end}]), 919 920 %% Check the callback for user-provided match functions: 921 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"very.wrong.domain"}], 922 [{match_fun, 923 fun("very.wrong.domain", {cn,"example.com"}) -> 924 true; 925 (_, _) -> 926 false 927 end}]), 928 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"not.example.com"}], 929 [{match_fun, fun(_, _) -> default end}]), 930 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}], 931 [{match_fun, fun(_, _) -> default end}]), 932 933 %% Check the callback for user-provided fqdn extraction: 934 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}], 935 [{fqdn_fun, 936 fun({uri_id, "some://very.wrong.domain"}) -> 937 "example.com"; 938 (_) -> 939 "" 940 end}]), 941 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://example.com"}], 942 [{fqdn_fun, fun(_) -> default end}]), 943 false = public_key:pkix_verify_hostname(Cert, [{uri_id,"some://very.wrong.domain"}]), 944 945 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}]), 946 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"abb.bar.example.com"}]), 947 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"example.com"}, 948 {dns_id,"abb.bar.example.com"}], 949 [{fqdn_fun,fun(_)->undefined end}]). 950 951 952%%-------------------------------------------------------------------- 953%% To generate the PEM file contents: 954%% 955%% openssl req -x509 -nodes -newkey rsa:1024 -keyout /dev/null -extensions SAN -config public_key_SUITE_data/verify_hostname_ip.conf 2>/dev/null > public_key_SUITE_data/pkix_verify_hostname_subjAltName_IP.pem 956%% 957%% Subject: C=SE, CN=example.com 958%% Subject Alternative Name: DNS:1.2.3.4, DNS: abcd:ef::1, IP:10.67.16.75, URI:https://10.11.12.13 959 960pkix_verify_hostname_subjAltName_IP(Config) -> 961 DataDir = proplists:get_value(data_dir, Config), 962 {ok,Bin} = file:read_file(filename:join(DataDir,"pkix_verify_hostname_subjAltName_IP.pem")), 963 Cert = public_key:pkix_decode_cert(element(2,hd(public_key:pem_decode(Bin))), otp), 964 965 %% Print the tests that a matchfun has to handle 966 catch public_key:pkix_verify_hostname(Cert, [{some_tag,"some.domain"}, 967 {ip, {10,67,16,75}} 968 ], 969 [{match_fun, 970 fun(Ref,Pres) -> 971 ct:pal("~p:~p:~nRef : ~p~nPres: ~p",[?MODULE,?LINE,Ref,Pres]), 972 false 973 end}]), 974 975 false = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://1.2.3.4"}]), 976 true = public_key:pkix_verify_hostname(Cert, [{uri_id,"https://10.11.12.13"}]), 977 true = public_key:pkix_verify_hostname(Cert, [{dns_id,"1.2.3.4"}]), 978 true = public_key:pkix_verify_hostname(Cert, [{dns_id,<<"1.2.3.4">>}]), 979 false = public_key:pkix_verify_hostname(Cert, [{dns_id,"10.67.16.75"}]), 980 true = public_key:pkix_verify_hostname(Cert, [{ip, "aBcD:ef:0::0:1"}]), 981 true = public_key:pkix_verify_hostname(Cert, [{ip, {16#abcd,16#ef,0,0,0,0,0,1}}]), 982 true = public_key:pkix_verify_hostname(Cert, [{ip, "10.67.16.75"}]), 983 true = public_key:pkix_verify_hostname(Cert, [{ip, <<"10.67.16.75">>}]), 984 true = public_key:pkix_verify_hostname(Cert, [{ip, {10,67,16,75}}]), 985 false = public_key:pkix_verify_hostname(Cert, [{ip, {1,2,3,4}}]), 986 false = public_key:pkix_verify_hostname(Cert, [{ip, {10,11,12,13}}]). 987%%-------------------------------------------------------------------- 988pkix_iso_rsa_oid() -> 989 [{doc, "Test workaround for supporting certs that use ISO oids" 990 " 1.3.14.3.2.29 instead of PKIX/PKCS oid"}]. 991pkix_iso_rsa_oid(Config) when is_list(Config) -> 992 Datadir = proplists:get_value(data_dir, Config), 993 {ok, PemCert} = file:read_file(filename:join(Datadir, "rsa_ISO.pem")), 994 [{_, Cert, _}] = public_key:pem_decode(PemCert), 995 OTPCert = public_key:pkix_decode_cert(Cert, otp), 996 SigAlg = OTPCert#'OTPCertificate'.signatureAlgorithm, 997 {_, rsa} = public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm). 998 999%%-------------------------------------------------------------------- 1000pkix_iso_dsa_oid() -> 1001 [{doc, "Test workaround for supporting certs that use ISO oids" 1002 "1.3.14.3.2.27 instead of PKIX/PKCS oid"}]. 1003pkix_iso_dsa_oid(Config) when is_list(Config) -> 1004 Datadir = proplists:get_value(data_dir, Config), 1005 {ok, PemCert} = file:read_file(filename:join(Datadir, "dsa_ISO.pem")), 1006 [{_, Cert, _}] = public_key:pem_decode(PemCert), 1007 OTPCert = public_key:pkix_decode_cert(Cert, otp), 1008 SigAlg = OTPCert#'OTPCertificate'.signatureAlgorithm, 1009 {_, dsa} = public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm). 1010 1011%%-------------------------------------------------------------------- 1012pkix_dsa_sha2_oid() -> 1013 [{doc, "Test support dsa_sha2 oid"}]. 1014pkix_dsa_sha2_oid(Config) when is_list(Config) -> 1015 {sha224, dsa} = public_key:pkix_sign_types(?'id-dsa-with-sha224'), 1016 {sha256, dsa} = public_key:pkix_sign_types(?'id-dsa-with-sha256'). 1017 1018%%-------------------------------------------------------------------- 1019 1020pkix_crl() -> 1021 [{doc, "test pkix_crl_* functions"}]. 1022 1023pkix_crl(Config) when is_list(Config) -> 1024 Datadir = proplists:get_value(data_dir, Config), 1025 {ok, PemCRL} = file:read_file(filename:join(Datadir, "idp_crl.pem")), 1026 [{_, CRL, _}] = public_key:pem_decode(PemCRL), 1027 1028 {ok, IDPPemCert} = file:read_file(filename:join(Datadir, "idp_cert.pem")), 1029 [{_, IDPCert, _}] = public_key:pem_decode(IDPPemCert), 1030 1031 {ok, SignPemCert} = file:read_file(filename:join(Datadir, "crl_signer.pem")), 1032 [{_, SignCert, _}] = public_key:pem_decode(SignPemCert), 1033 1034 OTPIDPCert = public_key:pkix_decode_cert(IDPCert, otp), 1035 OTPSignCert = public_key:pkix_decode_cert(SignCert, otp), 1036 ERLCRL = public_key:der_decode('CertificateList',CRL), 1037 1038 {rdnSequence,_} = public_key:pkix_crl_issuer(CRL), 1039 {rdnSequence,_} = public_key:pkix_crl_issuer(ERLCRL), 1040 1041 true = public_key:pkix_crl_verify(CRL, SignCert), 1042 true = public_key:pkix_crl_verify(ERLCRL, OTPSignCert), 1043 1044 [#'DistributionPoint'{}|_] = public_key:pkix_dist_points(IDPCert), 1045 [#'DistributionPoint'{}|_] = public_key:pkix_dist_points(OTPIDPCert), 1046 1047 #'DistributionPoint'{cRLIssuer = asn1_NOVALUE, 1048 reasons = asn1_NOVALUE, 1049 distributionPoint = Point} = public_key:pkix_dist_point(IDPCert), 1050 #'DistributionPoint'{cRLIssuer = asn1_NOVALUE, 1051 reasons = asn1_NOVALUE, 1052 distributionPoint = Point} = public_key:pkix_dist_point(OTPIDPCert). 1053 1054general_name() -> 1055 [{doc, "Test that decoding of general name filed may have other values" 1056 " than {rdnSequence, Seq}"}]. 1057 1058general_name(Config) when is_list(Config) -> 1059 DummyRfc822Name = "CN=CNDummy, OU=OUDummy, O=ODummy, C=SE", 1060 {ok, {1, DummyRfc822Name}} = 1061 pubkey_cert:cert_auth_key_id( 1062 #'AuthorityKeyIdentifier'{authorityCertIssuer = 1063 [{rfc822Name, DummyRfc822Name}], 1064 authorityCertSerialNumber = 1065 1}). 1066 1067%%-------------------------------------------------------------------- 1068 1069pkix_hash_type() -> 1070 [{doc, "Test API function pkix_hash_type/1"}]. 1071 1072pkix_hash_type(Config) when is_list(Config) -> 1073 sha = public_key:pkix_hash_type(?'id-sha1'), 1074 sha512 = public_key:pkix_hash_type(?'id-sha512'), 1075 sha384 = public_key:pkix_hash_type(?'id-sha384'), 1076 sha256 = public_key:pkix_hash_type(?'id-sha256'), 1077 sha224 = public_key:pkix_hash_type('id-sha224'), 1078 md5 = public_key:pkix_hash_type('id-md5'). 1079 1080 1081%%-------------------------------------------------------------------- 1082 1083pkix_test_data_all_default() -> 1084 [{doc, "Test API function pkix_test_data/1"}]. 1085 1086pkix_test_data_all_default(Config) when is_list(Config) -> 1087 #{server_config := ServerConf0, 1088 client_config := ClientConf0} = public_key:pkix_test_data(#{server_chain => 1089 #{root => [], 1090 intermediates => [[]], 1091 peer => []}, 1092 client_chain => 1093 #{root => [], 1094 intermediates => [[]], 1095 peer => []}}), 1096 check_conf_member(ServerConf0, [key, cert, cacerts]), 1097 check_conf_member(ClientConf0, [key, cert, cacerts]), 1098 1099 3 = length(proplists:get_value(cacerts, ServerConf0)), 1100 3 = length(proplists:get_value(cacerts, ServerConf0)), 1101 1102 #{server_config := ServerConf1, 1103 client_config := ClientConf1} = public_key:pkix_test_data(#{server_chain => 1104 #{root => [], 1105 peer => []}, 1106 client_chain => 1107 #{root => [], 1108 peer => []}}), 1109 2 = length(proplists:get_value(cacerts, ServerConf1)), 1110 2 = length(proplists:get_value(cacerts, ServerConf1)), 1111 1112 check_conf_member(ServerConf1, [key, cert, cacerts]), 1113 check_conf_member(ClientConf1, [key, cert, cacerts]). 1114 1115 1116pkix_test_data() -> 1117 [{doc, "Test API function pkix_test_data/1"}]. 1118 1119pkix_test_data(Config) when is_list(Config) -> 1120 {Year, Month, Day} = date(), 1121 Keygen = 1122 case crypto:ec_curves() of 1123 [] -> 1124 {rsa, 2048, 17}; 1125 [Curve |_] -> 1126 Oid = pubkey_cert_records:namedCurves(Curve), 1127 {namedCurve, Oid} 1128 end, 1129 #{server_config := ServerConf0, 1130 client_config := ClientConf0} = 1131 public_key:pkix_test_data(#{server_chain => 1132 #{root => [], 1133 intermediates => [], 1134 peer => [{key, hardcode_rsa_key(1)}]}, 1135 client_chain => 1136 #{root => [{validity, {{Year-2, Month, Day}, 1137 {Year-1, Month, Day}}}], 1138 intermediates => 1139 [[{extensions, [#'Extension'{extnID = ?'id-ce-basicConstraints', 1140 extnValue = #'BasicConstraints'{cA=true, 1141 pathLenConstraint = 1}, 1142 critical = true}]}]], 1143 peer => [{key, Keygen}, {digest, sha1}]}}), 1144 check_conf_member(ServerConf0, [key, cert, cacerts]), 1145 check_conf_member(ClientConf0, [key, cert, cacerts]). 1146 1147 1148 1149check_conf_member(_, []) -> 1150 true; 1151check_conf_member(Conf, [Member | Rest]) -> 1152 case lists:keymember(Member, 1, Conf) of 1153 true -> 1154 check_conf_member(Conf, Rest); 1155 false -> 1156 ct:fail({misssing_conf, Member}) 1157 end. 1158 1159%%-------------------------------------------------------------------- 1160short_cert_issuer_hash() -> 1161 [{doc, "Test OpenSSL-style hash for certificate issuer"}]. 1162 1163short_cert_issuer_hash(Config) when is_list(Config) -> 1164 Datadir = ?config(data_dir, Config), 1165 [{'Certificate', CertDER, _}] = 1166 erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")), 1167 1168 %% This hash value was obtained by running: 1169 %% openssl x509 -in client_cert.pem -issuer_hash -noout 1170 CertIssuerHash = "d4c8d7e5", 1171 1172 #'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{issuer = Issuer}} = 1173 public_key:pkix_decode_cert(CertDER, otp), 1174 1175 CertIssuerHash = public_key:short_name_hash(Issuer). 1176 1177%%-------------------------------------------------------------------- 1178short_crl_issuer_hash() -> 1179 [{doc, "Test OpenSSL-style hash for CRL issuer"}]. 1180 1181short_crl_issuer_hash(Config) when is_list(Config) -> 1182 Datadir = ?config(data_dir, Config), 1183 [{'CertificateList', CrlDER, _}] = 1184 erl_make_certs:pem_to_der(filename:join(Datadir, "idp_crl.pem")), 1185 1186 %% This hash value was obtained by running: 1187 %% openssl crl -in idp_crl.pem -hash -noout 1188 CrlIssuerHash = "d6134ed3", 1189 1190 Issuer = public_key:pkix_crl_issuer(CrlDER), 1191 1192 CrlIssuerHash = public_key:short_name_hash(Issuer). 1193 1194%%-------------------------------------------------------------------- 1195gen_ec_param_prime_field() -> 1196 [{doc, "Generate key with EC prime_field parameters"}]. 1197gen_ec_param_prime_field(Config) when is_list(Config) -> 1198 Datadir = proplists:get_value(data_dir, Config), 1199 do_gen_ec_param(filename:join(Datadir, "ec_key_param0.pem")). 1200 1201%%-------------------------------------------------------------------- 1202gen_ec_param_char_2_field() -> 1203 [{doc, "Generate key with EC characteristic_two_field parameters"}]. 1204gen_ec_param_char_2_field(Config) when is_list(Config) -> 1205 Datadir = proplists:get_value(data_dir, Config), 1206 do_gen_ec_param(filename:join(Datadir, "ec_key_param1.pem")). 1207 1208%%-------------------------------------------------------------------- 1209%% Internal functions ------------------------------------------------ 1210%%-------------------------------------------------------------------- 1211asn1_encode_decode({Asn1Type, Der, not_encrypted} = Entry) -> 1212 Decoded = public_key:der_decode(Asn1Type, Der), 1213 Decoded = public_key:pem_entry_decode(Entry), 1214 Entry = public_key:pem_entry_encode(Asn1Type, Decoded), 1215 ok. 1216 1217check_countryname({rdnSequence,DirName}) -> 1218 do_check_countryname(DirName). 1219do_check_countryname([]) -> 1220 ok; 1221do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName', 1222 value = "US"}|_]) -> 1223 ok; 1224do_check_countryname([#'AttributeTypeAndValue'{type = ?'id-at-countryName', 1225 value = Value}|_]) -> 1226 ct:fail({incorrect_country_name, Value}); 1227do_check_countryname([_| Rest]) -> 1228 do_check_countryname(Rest). 1229 1230check_emailaddress({rdnSequence,DirName}) -> 1231 do_check_emailaddress(DirName). 1232do_check_emailaddress([]) -> 1233 ok; 1234do_check_emailaddress([#'AttributeTypeAndValue'{type = ?'id-emailAddress', 1235 value = "invalid@email.com"}|_]) -> 1236 ok; 1237do_check_emailaddress([#'AttributeTypeAndValue'{type = ?'id-emailAddress', 1238 value = Value}|_]) -> 1239 ct:fail({incorrect_email_address, Value}); 1240do_check_emailaddress([_| Rest]) -> 1241 do_check_emailaddress(Rest). 1242 1243check_entry_type(#'DSAPrivateKey'{}, 'DSAPrivateKey') -> 1244 true; 1245check_entry_type(#'RSAPrivateKey'{}, 'RSAPrivateKey') -> 1246 true; 1247check_entry_type(#'RSAPublicKey'{}, 'RSAPublicKey') -> 1248 true; 1249check_entry_type({_Int, #'Dss-Parms'{}}, 'DSAPublicKey') when is_integer(_Int) -> 1250 true; 1251check_entry_type(#'DHParameter'{}, 'DHParameter') -> 1252 true; 1253check_entry_type(#'Certificate'{}, 'Certificate') -> 1254 true; 1255check_entry_type({#'ECPoint'{}, _}, 'ECPoint') -> 1256 true; 1257check_entry_type(#'ECPrivateKey'{}, 'ECPrivateKey') -> 1258 true; 1259check_entry_type({namedCurve, _}, 'EcpkParameters') -> 1260 true; 1261check_entry_type({ecParameters, #'ECParameters'{}}, 'EcpkParameters') -> 1262 true; 1263check_entry_type(_,_) -> 1264 false. 1265 1266check_encapsulated_header(Pem) when is_binary(Pem)-> 1267 check_encapsulated_header( binary:split(Pem, <<"\n">>, [global])); 1268check_encapsulated_header([<<"DEK-Info: DES-CBC,FB7577791A9056A1">>, <<>> | _]) -> 1269 true; 1270check_encapsulated_header([ _ | Rest]) -> 1271 check_encapsulated_header(Rest); 1272check_encapsulated_header([]) -> 1273 false. 1274 1275strip_superfluous_newlines(Bin) -> 1276 Str = string:strip(binary_to_list(Bin), right, 10), 1277 re:replace(Str,"\n\n","\n", [{return,list}, global]). 1278 1279do_gen_ec_param(File) -> 1280 {ok, KeyPem} = file:read_file(File), 1281 Entries = public_key:pem_decode(KeyPem), 1282 [ParamInfo] = [Entry || Entry={'EcpkParameters', _, not_encrypted} <- Entries], 1283 {ecParameters, Params} = public_key:pem_entry_decode(ParamInfo), 1284 Key = public_key:generate_key(Params), 1285 case check_entry_type(Key, 'ECPrivateKey') of 1286 true -> 1287 ok; 1288 false -> 1289 ct:fail({key_gen_fail, File}) 1290 end. 1291 1292init_per_testcase_gen_ec_param(_TC, Curve, Config) -> 1293 case crypto:ec_curves() of 1294 [] -> 1295 {skip, missing_ec_support}; 1296 Curves -> 1297 case lists:member(Curve, Curves) 1298 andalso crypto_supported_curve(Curve, Curves) 1299 of 1300 true -> 1301 init_common_per_testcase(Config); 1302 false -> 1303 {skip, {missing_ec_support, Curve}} 1304 end 1305 end. 1306 1307 1308crypto_supported_curve(Curve, _Curves) -> 1309 try crypto:generate_key(ecdh, Curve) of 1310 {error,_} -> false; % Just in case crypto is changed in the future... 1311 _-> true 1312 catch 1313 _:_-> false 1314 end. 1315 1316incorrect_countryname_pkix_cert() -> 1317 <<48,130,5,186,48,130,4,162,160,3,2,1,2,2,7,7,250,61,63,6,140,137,48,13,6,9,42, 134,72,134,247,13,1,1,5,5,0,48,129,220,49,11,48,9,6,3,85,4,6,19,2,85,83,49, 16,48,14,6,3,85,4,8,19,7,65,114,105,122,111,110,97,49,19,48,17,6,3,85,4,7,19, 10,83,99,111,116,116,115,100,97,108,101,49,37,48,35,6,3,85,4,10,19,28,83,116, 97,114,102,105,101,108,100,32,84,101,99,104,110,111,108,111,103,105,101,115, 44,32,73,110,99,46,49,57,48,55,6,3,85,4,11,19,48,104,116,116,112,58,47,47,99, 101,114,116,105,102,105,99,97,116,101,115,46,115,116,97,114,102,105,101,108, 100,116,101,99,104,46,99,111,109,47,114,101,112,111,115,105,116,111,114,121, 49,49,48,47,6,3,85,4,3,19,40,83,116,97,114,102,105,101,108,100,32,83,101,99, 117,114,101,32,67,101,114,116,105,102,105,99,97,116,105,111,110,32,65,117, 116,104,111,114,105,116,121,49,17,48,15,6,3,85,4,5,19,8,49,48,54,56,56,52,51, 53,48,30,23,13,49,48,49,48,50,51,48,49,51,50,48,53,90,23,13,49,50,49,48,50, 51,48,49,51,50,48,53,90,48,122,49,11,48,9,6,3,85,4,6,12,2,85,83,49,11,48,9,6, 3,85,4,8,12,2,65,90,49,19,48,17,6,3,85,4,7,12,10,83,99,111,116,116,115,100, 97,108,101,49,38,48,36,6,3,85,4,10,12,29,83,112,101,99,105,97,108,32,68,111, 109,97,105,110,32,83,101,114,118,105,99,101,115,44,32,73,110,99,46,49,33,48, 31,6,3,85,4,3,12,24,42,46,108,111,103,105,110,46,115,101,99,117,114,101,115, 101,114,118,101,114,46,110,101,116,48,130,1,34,48,13,6,9,42,134,72,134,247, 13,1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,185,136,240,80,141,36,124, 245,182,130,73,19,188,74,166,117,72,228,185,209,43,129,244,40,44,193,231,11, 209,12,234,88,43,142,1,162,48,122,17,95,230,105,171,131,12,147,46,204,36,80, 250,171,33,253,35,62,83,22,71,212,186,141,14,198,89,89,121,204,224,122,246, 127,110,188,229,162,67,95,6,74,231,127,99,131,7,240,85,102,203,251,50,58,58, 104,245,103,181,183,134,32,203,121,232,54,32,188,139,136,112,166,126,14,91, 223,153,172,164,14,61,38,163,208,215,186,210,136,213,143,70,147,173,109,217, 250,169,108,31,211,104,238,103,93,182,59,165,43,196,189,218,241,30,148,240, 109,90,69,176,194,52,116,173,151,135,239,10,209,179,129,192,102,75,11,25,168, 223,32,174,84,223,134,70,167,55,172,143,27,130,123,226,226,7,34,142,166,39, 48,246,96,231,150,84,220,106,133,193,55,95,159,227,24,249,64,36,1,142,171,16, 202,55,126,7,156,15,194,22,116,53,113,174,104,239,203,120,45,131,57,87,84, 163,184,27,83,57,199,91,200,34,43,98,61,180,144,76,65,170,177,2,3,1,0,1,163, 130,1,224,48,130,1,220,48,15,6,3,85,29,19,1,1,255,4,5,48,3,1,1,0,48,29,6,3, 85,29,37,4,22,48,20,6,8,43,6,1,5,5,7,3,1,6,8,43,6,1,5,5,7,3,2,48,14,6,3,85, 29,15,1,1,255,4,4,3,2,5,160,48,56,6,3,85,29,31,4,49,48,47,48,45,160,43,160, 41,134,39,104,116,116,112,58,47,47,99,114,108,46,115,116,97,114,102,105,101, 108,100,116,101,99,104,46,99,111,109,47,115,102,115,50,45,48,46,99,114,108, 48,83,6,3,85,29,32,4,76,48,74,48,72,6,11,96,134,72,1,134,253,110,1,7,23,2,48, 57,48,55,6,8,43,6,1,5,5,7,2,1,22,43,104,116,116,112,115,58,47,47,99,101,114, 116,115,46,115,116,97,114,102,105,101,108,100,116,101,99,104,46,99,111,109, 47,114,101,112,111,115,105,116,111,114,121,47,48,129,141,6,8,43,6,1,5,5,7,1, 1,4,129,128,48,126,48,42,6,8,43,6,1,5,5,7,48,1,134,30,104,116,116,112,58,47, 47,111,99,115,112,46,115,116,97,114,102,105,101,108,100,116,101,99,104,46,99, 111,109,47,48,80,6,8,43,6,1,5,5,7,48,2,134,68,104,116,116,112,58,47,47,99, 101,114,116,105,102,105,99,97,116,101,115,46,115,116,97,114,102,105,101,108, 100,116,101,99,104,46,99,111,109,47,114,101,112,111,115,105,116,111,114,121, 47,115,102,95,105,110,116,101,114,109,101,100,105,97,116,101,46,99,114,116, 48,31,6,3,85,29,35,4,24,48,22,128,20,73,75,82,39,209,27,188,242,161,33,106, 98,123,81,66,122,138,215,213,86,48,59,6,3,85,29,17,4,52,48,50,130,24,42,46, 108,111,103,105,110,46,115,101,99,117,114,101,115,101,114,118,101,114,46,110, 101,116,130,22,108,111,103,105,110,46,115,101,99,117,114,101,115,101,114,118, 101,114,46,110,101,116,48,29,6,3,85,29,14,4,22,4,20,138,233,191,208,157,203, 249,85,242,239,20,195,48,10,148,49,144,101,255,116,48,13,6,9,42,134,72,134, 247,13,1,1,5,5,0,3,130,1,1,0,82,31,121,162,49,50,143,26,167,202,143,61,71, 189,201,199,57,81,122,116,90,192,88,24,102,194,174,48,157,74,27,87,210,223, 253,93,3,91,150,109,120,1,110,27,11,200,198,141,222,246,14,200,71,105,41,138, 13,114,122,106,63,17,197,181,234,121,61,89,74,65,41,231,248,219,129,83,176, 219,55,107,55,211,112,98,38,49,69,77,96,221,108,123,152,12,210,159,157,141, 43,226,55,187,129,3,82,49,136,66,81,196,91,234,196,10,82,48,6,80,163,83,71, 127,102,177,93,209,129,26,104,2,84,24,255,248,161,3,244,169,234,92,122,110, 43,4,17,113,185,235,108,219,210,236,132,216,177,227,17,169,58,162,159,182, 162,93,160,229,200,9,163,229,110,121,240,168,232,14,91,214,188,196,109,210, 164,222,0,109,139,132,113,91,16,118,173,178,176,80,132,34,41,199,51,206,250, 224,132,60,115,192,94,107,163,219,212,226,225,65,169,148,108,213,46,174,173, 103,110,189,229,166,149,254,31,51,44,144,108,187,182,11,251,201,206,86,138, 208,59,51,86,132,235,81,225,88,34,190,8,184>>. 1318 1319incorrect_emailaddress_pkix_cert() -> 1320 <<48,130,3,74,48,130,2,50,2,9,0,133,49,203,25,198,156,252,230,48,13,6,9,42,134, 72,134,247,13,1,1,5,5,0,48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17, 6,3,85,4,8,12,10,83,111,109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10, 12,24,73,110,116,101,114,110,101,116,32,87,105,100,103,105,116,115,32,80,116, 121,32,76,116,100,49,32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110, 118,97,108,105,100,64,101,109,97,105,108,46,99,111,109,48,30,23,13,49,51,49, 49,48,55,50,48,53,54,49,56,90,23,13,49,52,49,49,48,55,50,48,53,54,49,56,90, 48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17,6,3,85,4,8,12,10,83,111, 109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10,12,24,73,110,116,101, 114,110,101,116,32,87,105,100,103,105,116,115,32,80,116,121,32,76,116,100,49, 32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110,118,97,108,105,100,64, 101,109,97,105,108,46,99,111,109,48,130,1,34,48,13,6,9,42,134,72,134,247,13, 1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,190,243,49,213,219,60,232,105, 1,127,126,9,130,15,60,190,78,100,148,235,246,223,21,91,238,200,251,84,55,212, 78,32,120,61,85,172,0,144,248,5,165,29,143,79,64,178,51,153,203,76,115,238, 192,49,173,37,121,203,89,62,157,13,181,166,30,112,154,40,202,140,104,211,157, 73,244,9,78,236,70,153,195,158,233,141,42,238,2,143,160,225,249,27,30,140, 151,176,43,211,87,114,164,108,69,47,39,195,123,185,179,219,28,218,122,53,83, 77,48,81,184,14,91,243,12,62,146,86,210,248,228,171,146,225,87,51,146,155, 116,112,238,212,36,111,58,41,67,27,6,61,61,3,84,150,126,214,121,57,38,12,87, 121,67,244,37,45,145,234,131,115,134,58,194,5,36,166,52,59,229,32,47,152,80, 237,190,58,182,248,98,7,165,198,211,5,31,231,152,116,31,108,71,218,64,188, 178,143,27,167,79,15,112,196,103,116,212,65,197,94,37,4,132,103,91,217,73, 223,207,185,7,153,221,240,232,31,44,102,108,82,83,56,242,210,214,74,71,246, 177,217,148,227,220,230,4,176,226,74,194,37,2,3,1,0,1,48,13,6,9,42,134,72, 134,247,13,1,1,5,5,0,3,130,1,1,0,89,247,141,154,173,123,123,203,143,85,28,79, 73,37,164,6,17,89,171,224,149,22,134,17,198,146,158,192,241,41,253,58,230, 133,71,189,43,66,123,88,15,242,119,227,249,99,137,61,200,54,161,0,177,167, 169,114,80,148,90,22,97,78,162,181,75,93,209,116,245,46,81,232,64,157,93,136, 52,57,229,113,197,218,113,93,42,161,213,104,205,137,30,144,183,58,10,98,47, 227,177,96,40,233,98,150,209,217,68,22,221,133,27,161,152,237,46,36,179,59, 172,97,134,194,205,101,137,71,192,57,153,20,114,27,173,233,166,45,56,0,61, 205,45,202,139,7,132,103,248,193,157,184,123,43,62,172,236,110,49,62,209,78, 249,83,219,133,1,213,143,73,174,16,113,143,189,41,84,60,128,222,30,177,104, 134,220,52,239,171,76,59,176,36,113,176,214,118,16,44,235,21,167,199,216,200, 76,219,142,248,13,70,145,205,216,230,226,148,97,223,216,179,68,209,222,63, 140,137,24,164,192,149,194,79,119,247,75,159,49,116,70,241,70,116,11,40,119, 176,157,36,160,102,140,255,34,248,25,231,136,59>>. 1321 1322hardcode_rsa_key(1) -> 1323 #'RSAPrivateKey'{ 1324 version = 'two-prime', 1325 modulus = 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669, 1326 publicExponent = 17, 1327 privateExponent = 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657, 1328 prime1 = 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197, 1329 prime2 = 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577, 1330 exponent1 = 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609, 1331 exponent2 = 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993, 1332 coefficient = 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441, 1333 otherPrimeInfos = asn1_NOVALUE}; 1334 1335hardcode_rsa_key(2) -> 1336 #'RSAPrivateKey'{ 1337 version = 'two-prime', 1338 modulus = 21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777, 1339 publicExponent = 17, 1340 privateExponent = 18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773, 1341 prime1 = 146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419, 1342 prime2 = 145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083, 1343 exponent1 = 51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677, 1344 exponent2 = 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029, 1345 coefficient = 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540, 1346 otherPrimeInfos = asn1_NOVALUE}; 1347hardcode_rsa_key(3) -> 1348 #'RSAPrivateKey'{ 1349 version = 'two-prime', 1350 modulus = 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429, 1351 publicExponent = 17, 1352 privateExponent = 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265, 1353 prime1 = 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823, 1354 prime2 =146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523, 1355 exponent1 = 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349, 1356 exponent2 = 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609, 1357 coefficient = 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612, 1358 otherPrimeInfos = asn1_NOVALUE}; 1359hardcode_rsa_key(4) -> 1360 #'RSAPrivateKey'{ 1361 version ='two-prime', 1362 modulus = 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389, 1363 publicExponent = 17, 1364 privateExponent = 26933870828264240605980991639786903194205240075898493207372837775011576208154148256741268036255908348187001210401018346586267012540419880263858569570986761169933338532757527109161473558558433313931326474042230460969355628442100895016122589386862163232450330461545076609969553227901257730132640573174013751883368376011370428995523268034111482031427024082719896108094847702954695363285832195666458915142143884210891427766607838346722974883433132513540317964796373298134261669479023445911856492129270184781873446960437310543998533283339488055776892320162032014809906169940882070478200435536171854883284366514852906334641, 1365 prime1 = 177342190816702392178883147766999616783253285436834252111702533617098994535049411784501174309695427674025956656849179054202187436663487378682303508229883753383891163725167367039879190685255046547908384208614573353917213168937832054054779266431207529839577747601879940934691505396807977946728204814969824442867, 1366 prime2 = 161367340863680900415977542864139121629424927689088951345472941851682581254789586032968359551717004797621579428672968948552429138154521719743297455351687337112710712475376510559020211584326773715482918387500187602625572442687231345855402020688502483137168684570635690059254866684191216155909970061793538842967, 1367 exponent1 = 62591361464718491357252875682470452982324688977706206627659717747211409835899792394529826226951327414362102349476180842659595565881230839534930649963488383547255704844176717778780890830090016428673547367746320007264898765507470136725216211681602657590439205035957626212244060728285168687080542875871702744541, 1368 exponent2 = 28476589564178982426348978152495139111074987239250991413906989738532220221433456358759122273832412611344984605059935696803369847909621479954699550944415412431654831613301737157474154985469430655673456186029444871051571607533040825739188591886206320553618003159523945304574388238386685203984112363845918619347, 1369 coefficient = 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012, 1370 otherPrimeInfos = asn1_NOVALUE}. 1371 1372pss_params(sha256) -> 1373 #'RSASSA-PSS-params'{ 1374 hashAlgorithm = #'HashAlgorithm'{algorithm = ?'id-sha256'}, 1375 maskGenAlgorithm = #'MaskGenAlgorithm'{algorithm = ?'id-mgf1', 1376 parameters = #'HashAlgorithm'{algorithm = ?'id-sha256'} 1377 }, 1378 saltLength = 32, 1379 trailerField = 1}. 1380 1381