diff options
author | Jack Lloyd <lloyd@randombit.net> | 2015-12-20 13:51:28 -0500 |
---|---|---|
committer | Jack Lloyd <lloyd@randombit.net> | 2015-12-20 13:51:28 -0500 |
commit | 22d05ebfdbb409530fb20133cf150fb4c419faac (patch) | |
tree | 33498ae9e833f11cf2c27d15cbfe2ff502143ccd /src | |
parent | 1752f0d522eef9a4a703fccf702b4b026c1c1d01 (diff) |
Add --data-dir option to test command
Understand using '-' on the command line to mean stdin
Fix last few unit tests that wanted to write to the filesystem; removes
outdata directory.
Diffstat (limited to 'src')
34 files changed, 224 insertions, 240 deletions
diff --git a/src/cli/cli.h b/src/cli/cli.h index d079afbc5..fdc83e97b 100644 --- a/src/cli/cli.h +++ b/src/cli/cli.h @@ -157,6 +157,7 @@ class Command } } + bool seen_stdin_flag = false; size_t arg_i = 0; for(auto&& arg : m_spec_args) { @@ -171,6 +172,13 @@ class Command m_user_args.insert(std::make_pair(arg, args[arg_i])); + if(args[arg_i] == "-") + { + if(seen_stdin_flag) + throw CLI_Usage_Error("Cannot specifiy '-' (stdin) more than once"); + seen_stdin_flag = true; + } + ++arg_i; } @@ -235,6 +243,8 @@ class Command return "Usage: " + m_spec; } + const std::string& cmd_spec() const { return m_spec; } + std::string cmd_name() const { return m_spec.substr(0, m_spec.find(' ')); @@ -403,9 +413,21 @@ class Command std::function<void (uint8_t[], size_t)> consumer_fn, size_t buf_size = 0) const { - // Any need to support non-binary files here? - std::ifstream in(input_file, std::ios::binary); + if(input_file == "-") + { + do_read_file(std::cin, consumer_fn, buf_size); + } + else + { + std::ifstream in(input_file, std::ios::binary); + do_read_file(in, consumer_fn, buf_size); + } + } + void do_read_file(std::istream& in, + std::function<void (uint8_t[], size_t)> consumer_fn, + size_t buf_size = 0) const + { // Avoid an infinite loop on --buf-size=0 std::vector<uint8_t> buf(buf_size == 0 ? 4096 : buf_size); diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 6dab50932..0a09bacc3 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -28,78 +28,25 @@ namespace { -using Botan_Tests::Test; - -std::unique_ptr<Botan::RandomNumberGenerator> -setup_tests(std::ostream& out, size_t threads, - size_t soak_level, - bool log_success, - std::string drbg_seed) - { - out << "Testing " << Botan::version_string() << "\n"; - out << "Starting tests"; - - if(threads > 1) - out << " threads:" << threads; - - out << " soak level:" << soak_level; - - std::unique_ptr<Botan::RandomNumberGenerator> rng; - -#if defined(BOTAN_HAS_HMAC_DRBG) - if(drbg_seed == "") - { - const uint64_t ts = Test::timestamp(); - std::vector<uint8_t> ts8(8); - Botan::store_be(ts, ts8.data()); - drbg_seed = Botan::hex_encode(ts8); - } - - out << " rng:HMAC_DRBG with seed '" << drbg_seed << "'"; - rng.reset(new Botan::Serialized_RNG(new Botan::HMAC_DRBG("HMAC(SHA-384)"))); - const std::vector<uint8_t> seed = Botan::hex_decode(drbg_seed); - rng->add_entropy(seed.data(), seed.size()); - -#else - - if(drbg_seed != "") - throw Botan_Tests::Test_Error("HMAC_DRBG disabled in build, cannot specify DRBG seed"); - -#if defined(BOTAN_HAS_SYSTEM_RNG) - out << " rng:system"; - rng.reset(new Botan::System_RNG); -#else - // AutoSeeded_RNG always available - out << " rng:autoseeded"; - rng.reset(new Botan::Serialized_RNG(new Botan::AutoSeeded_RNG)); -#endif - -#endif - - out << std::endl; - - Botan_Tests::Test::setup_tests(soak_level, log_success, rng.get()); - - return rng; - } - class Test_Runner : public Botan_CLI::Command { public: - Test_Runner() : Command("test --threads=0 --soak=5 --drbg-seed= --log-success *suites") {} + Test_Runner() : Command("test --threads=0 --soak=5 --drbg-seed= --data-dir= --log-success *suites") {} std::string help_text() const override { std::ostringstream err; - err << "Usage: botan-test [--drbg-seed=] [--threads=N] [--log-success] " - << "suite suite ...\n\n" - << "Available suites\n" + const std::string& spec = cmd_spec(); + + err << "Usage: botan-test" + << spec.substr(spec.find_first_of(' '), std::string::npos) + << "\n\nAvailable test suites\n" << "----------------\n"; size_t line_len = 0; - for(auto&& test : Test::registered_tests()) + for(auto&& test : Botan_Tests::Test::registered_tests()) { err << test << " "; line_len += test.size() + 1; @@ -122,9 +69,10 @@ class Test_Runner : public Botan_CLI::Command void go() override { const size_t threads = get_arg_sz("threads"); - const size_t soak = get_arg_sz("soak"); + const size_t soak_level = get_arg_sz("soak"); const std::string drbg_seed = get_arg("drbg-seed"); bool log_success = flag_set("log-success"); + const std::string data_dir = get_arg_or("data-dir", "src/tests/data"); std::vector<std::string> req = get_arg_list("suites"); @@ -148,31 +96,72 @@ class Test_Runner : public Botan_CLI::Command req.insert(req.end(), all_others.begin(), all_others.end()); } - std::unique_ptr<Botan::RandomNumberGenerator> rng = - setup_tests(std::cout, threads, soak, log_success, drbg_seed); + output() << "Testing " << Botan::version_string() << "\n"; + output() << "Starting tests"; + + if(threads > 1) + output() << " threads:" << threads; + + output() << " soak level:" << soak_level; + + std::unique_ptr<Botan::RandomNumberGenerator> rng; + +#if defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_64) + std::vector<uint8_t> seed = Botan::hex_decode(drbg_seed); + if(seed.empty()) + { + const uint64_t ts = Botan_Tests::Test::timestamp(); + seed.resize(8); + Botan::store_be(ts, seed.data()); + } + + output() << " rng:HMAC_DRBG with seed '" << Botan::hex_encode(seed) << "'"; + rng.reset(new Botan::Serialized_RNG(new Botan::HMAC_DRBG("HMAC(SHA-384)"))); + rng->add_entropy(seed.data(), seed.size()); + +#else + + if(drbg_seed != "") + throw Botan_Tests::Test_Error("HMAC_DRBG disabled in build, cannot specify DRBG seed"); - size_t failed = run_tests(req, std::cout, threads); +#if defined(BOTAN_HAS_SYSTEM_RNG) + output() << " rng:system"; + rng.reset(new Botan::System_RNG); +#else + // AutoSeeded_RNG always available + output() << " rng:autoseeded"; + rng.reset(new Botan::Serialized_RNG(new Botan::AutoSeeded_RNG)); +#endif + +#endif + + output() << "\n"; + + Botan_Tests::Test::setup_tests(soak_level, log_success, data_dir, rng.get()); + + const size_t failed = run_tests(req, output(), threads); // Throw so main returns an error if(failed) throw Botan_Tests::Test_Error("Test suite failure"); } + private: - std::string report_out(const std::vector<Test::Result>& results, + std::string report_out(const std::vector<Botan_Tests::Test::Result>& results, size_t& tests_failed, size_t& tests_ran) { std::ostringstream out; - std::map<std::string, Test::Result> combined; + std::map<std::string, Botan_Tests::Test::Result> combined; for(auto&& result : results) { const std::string who = result.who(); auto i = combined.find(who); if(i == combined.end()) { - combined[who] = Test::Result(who); + combined[who] = Botan_Tests::Test::Result(who); i = combined.find(who); } @@ -200,7 +189,7 @@ class Test_Runner : public Botan_CLI::Command { for(auto&& test_name : tests_to_run) { - std::vector<Test::Result> results = Test::run_test(test_name, false); + const auto results = Botan_Tests::Test::run_test(test_name, false); out << report_out(results, tests_failed, tests_ran) << std::flush; } } @@ -216,13 +205,14 @@ class Test_Runner : public Botan_CLI::Command (50-100% speedup) and provides a proof of concept for parallel testing. */ - typedef std::future<std::vector<Test::Result>> FutureResults; + typedef std::future<std::vector<Botan_Tests::Test::Result>> FutureResults; std::deque<FutureResults> fut_results; for(auto&& test_name : tests_to_run) { - fut_results.push_back(std::async(std::launch::async, - [test_name]() { return Test::run_test(test_name, false); })); + auto run_it = [test_name] { + return Botan_Tests::Test::run_test(test_name, false); }; + fut_results.push_back(std::async(std::launch::async, run_it)); while(fut_results.size() > threads) { diff --git a/src/tests/outdata/.gitkeep b/src/tests/outdata/.gitkeep deleted file mode 100644 index e69de29bb..000000000 --- a/src/tests/outdata/.gitkeep +++ /dev/null diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp index a9545a736..5d7e1094e 100644 --- a/src/tests/test_aead.cpp +++ b/src/tests/test_aead.cpp @@ -20,7 +20,7 @@ class AEAD_Tests : public Text_Based_Test { public: AEAD_Tests() : - Text_Based_Test(Test::data_dir("aead"), {"Key", "Nonce", "In", "Out"}, {"AD"}) + Text_Based_Test("aead", {"Key", "Nonce", "In", "Out"}, {"AD"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index 96ec035fe..5eaa0d0f1 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -147,7 +147,7 @@ BOTAN_REGISTER_TEST("bigint_unit", BigInt_Unit_Tests); class BigInt_KAT_Tests : public Text_Based_Test { public: - BigInt_KAT_Tests() : Text_Based_Test(Test::data_file("bigint.vec"), + BigInt_KAT_Tests() : Text_Based_Test("bigint.vec", std::vector<std::string>{"Output"}, {"In1","In2","Input","Shift","Modulus","Value","Base","Exponent","IsPrime"}) {} diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp index 7831b99a3..75a460bc7 100644 --- a/src/tests/test_block.cpp +++ b/src/tests/test_block.cpp @@ -12,7 +12,7 @@ namespace Botan_Tests { class Block_Cipher_Tests : public Text_Based_Test { public: - Block_Cipher_Tests() : Text_Based_Test(Test::data_dir("block"), {"Key", "In", "Out"}) {} + Block_Cipher_Tests() : Text_Based_Test("block", {"Key", "In", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { diff --git a/src/tests/test_c25519.cpp b/src/tests/test_c25519.cpp index db2a94e37..c04902674 100644 --- a/src/tests/test_c25519.cpp +++ b/src/tests/test_c25519.cpp @@ -20,7 +20,7 @@ class Curve25519_Sclarmult_Tests : public Text_Based_Test { public: Curve25519_Sclarmult_Tests() : Text_Based_Test( - Test::data_file("pubkey/c25519_scalar.vec"), + "pubkey/c25519_scalar.vec", {"Secret","Basepoint","Out"}) {} diff --git a/src/tests/test_dh.cpp b/src/tests/test_dh.cpp index 362ffcf24..643206031 100644 --- a/src/tests/test_dh.cpp +++ b/src/tests/test_dh.cpp @@ -23,7 +23,7 @@ class Diffie_Hellman_KAT_Tests : public PK_Key_Agreement_Test public: Diffie_Hellman_KAT_Tests() : PK_Key_Agreement_Test( "Diffie-Hellman", - Test::data_file("pubkey/dh.vec"), + "pubkey/dh.vec", {"P", "G", "X", "Y", "Msg", "OutLen", "K"}, {"KDF"}) {} diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp index 78b34d21b..1c7327ab4 100644 --- a/src/tests/test_dlies.cpp +++ b/src/tests/test_dlies.cpp @@ -23,7 +23,7 @@ class DLIES_KAT_Tests : public Text_Based_Test { public: DLIES_KAT_Tests() : Text_Based_Test( - Test::data_file("pubkey/dlies.vec"), + "pubkey/dlies.vec", {"P", "G", "X1", "X2", "Msg", "Ciphertext"}) {} diff --git a/src/tests/test_dsa.cpp b/src/tests/test_dsa.cpp index 71d581474..f9444412d 100644 --- a/src/tests/test_dsa.cpp +++ b/src/tests/test_dsa.cpp @@ -22,7 +22,7 @@ class DSA_KAT_Tests : public PK_Signature_Generation_Test public: DSA_KAT_Tests() : PK_Signature_Generation_Test( "DSA", - Test::data_file("pubkey/dsa.vec"), + "pubkey/dsa.vec", {"P", "Q", "G", "X", "Hash", "Msg", "Signature"}) {} diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp index 818fc4460..a19b64f03 100644 --- a/src/tests/test_ecc_pointmul.cpp +++ b/src/tests/test_ecc_pointmul.cpp @@ -22,7 +22,7 @@ class ECC_Pointmult_Tests : public Text_Based_Test { public: ECC_Pointmult_Tests() : Text_Based_Test( - Test::data_file("pubkey/ecc.vec"), + "pubkey/ecc.vec", {"Group", "m", "X", "Y"}) {} diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index e18038676..7140dcbe7 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -23,7 +23,7 @@ class ECDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test public: ECDSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( "ECDSA", - Test::data_file("pubkey/ecdsa.vec"), + "pubkey/ecdsa.vec", {"Group", "X", "Hash", "Msg", "Signature"}) {} diff --git a/src/tests/test_elg.cpp b/src/tests/test_elg.cpp index 1dfbdf92f..31f8439f6 100644 --- a/src/tests/test_elg.cpp +++ b/src/tests/test_elg.cpp @@ -22,7 +22,7 @@ class ElGamal_KAT_Tests : public PK_Encryption_Decryption_Test public: ElGamal_KAT_Tests() : PK_Encryption_Decryption_Test( "ElGamal", - Test::data_file("pubkey/elgamal.vec"), + "pubkey/elgamal.vec", {"P", "G", "X", "Msg", "Nonce", "Ciphertext"}, {"Padding"}) {} diff --git a/src/tests/test_fuzzer.cpp b/src/tests/test_fuzzer.cpp index 91d301826..eba49a1ae 100644 --- a/src/tests/test_fuzzer.cpp +++ b/src/tests/test_fuzzer.cpp @@ -41,7 +41,7 @@ class Fuzzer_Input_Tests : public Test try { - files = Botan::get_files_recursive(Test::data_dir("fuzz/x509")); + files = Botan::get_files_recursive(Test::data_dir() + "/fuzz/x509"); } catch(Botan::No_Filesystem_Access) { diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp index a80cd666c..4daa7189e 100644 --- a/src/tests/test_gost_3410.cpp +++ b/src/tests/test_gost_3410.cpp @@ -23,7 +23,7 @@ class GOST_3410_2001_Verification_Tests : public PK_Signature_Verification_Test public: GOST_3410_2001_Verification_Tests() : PK_Signature_Verification_Test( "GOST 34.10-2001", - Test::data_file("pubkey/gost_3410.vec"), + "pubkey/gost_3410.vec", {"Group", "Pubkey", "Hash", "Msg", "Signature"}) {} diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp index bdfe70a6a..be7156411 100644 --- a/src/tests/test_hash.cpp +++ b/src/tests/test_hash.cpp @@ -15,7 +15,7 @@ namespace { class Hash_Function_Tests : public Text_Based_Test { public: - Hash_Function_Tests() : Text_Based_Test(Test::data_dir("hash"), {"In", "Out"}) {} + Hash_Function_Tests() : Text_Based_Test("hash", {"In", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { diff --git a/src/tests/test_kdf.cpp b/src/tests/test_kdf.cpp index ccf742edd..e1bd0305c 100644 --- a/src/tests/test_kdf.cpp +++ b/src/tests/test_kdf.cpp @@ -18,7 +18,7 @@ namespace { class KDF_KAT_Tests : public Text_Based_Test { public: - KDF_KAT_Tests() : Text_Based_Test(Test::data_dir("kdf"), + KDF_KAT_Tests() : Text_Based_Test("kdf", {"OutputLen", "Salt", "Secret", "Output"}, {"IKM","XTS"}) {} diff --git a/src/tests/test_keywrap.cpp b/src/tests/test_keywrap.cpp index 01ada5509..f000a8be7 100644 --- a/src/tests/test_keywrap.cpp +++ b/src/tests/test_keywrap.cpp @@ -20,7 +20,7 @@ namespace { class RFC3394_Keywrap_Tests : public Text_Based_Test { public: - RFC3394_Keywrap_Tests() : Text_Based_Test(Test::data_file("rfc3394.vec"), + RFC3394_Keywrap_Tests() : Text_Based_Test("rfc3394.vec", {"Key", "KEK", "Output"}) {} diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp index e7341f443..8bc58e0e1 100644 --- a/src/tests/test_mac.cpp +++ b/src/tests/test_mac.cpp @@ -20,7 +20,7 @@ class Message_Auth_Tests : public Text_Based_Test { public: Message_Auth_Tests() : - Text_Based_Test(Test::data_dir("mac"), {"Key", "In", "Out"}) {} + Text_Based_Test("mac", {"Key", "In", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp index 88379f2ea..d3c646504 100644 --- a/src/tests/test_mceliece.cpp +++ b/src/tests/test_mceliece.cpp @@ -51,7 +51,7 @@ class McEliece_Keygen_Encrypt_Test : public Text_Based_Test public: McEliece_Keygen_Encrypt_Test() : Text_Based_Test("McEliece", - Test::data_file("pubkey/mce.vec"), + "pubkey/mce.vec", {"McElieceSeed", "KeyN","KeyT","PublicKeyFingerprint", "PrivateKeyFingerprint", "EncryptPRNGSeed", "SharedKey", "Ciphertext" }) diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp index cc1645e92..7b6344975 100644 --- a/src/tests/test_modes.cpp +++ b/src/tests/test_modes.cpp @@ -18,7 +18,7 @@ class Cipher_Mode_Tests : public Text_Based_Test { public: Cipher_Mode_Tests() : - Text_Based_Test(Test::data_dir("modes"), {"Key", "Nonce", "In", "Out"}) + Text_Based_Test("modes", {"Key", "Nonce", "In", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override diff --git a/src/tests/test_nr.cpp b/src/tests/test_nr.cpp index 856954cd2..bd1d67d4f 100644 --- a/src/tests/test_nr.cpp +++ b/src/tests/test_nr.cpp @@ -22,7 +22,7 @@ class NR_KAT_Tests : public PK_Signature_Generation_Test public: NR_KAT_Tests() : PK_Signature_Generation_Test( "Nyberg-Rueppel", - Test::data_file("pubkey/nr.vec"), + "pubkey/nr.vec", {"P", "Q", "G", "X", "Hash", "Nonce", "Msg", "Signature"}) {} diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp index 314fa31df..5c45acb0c 100644 --- a/src/tests/test_ocb.cpp +++ b/src/tests/test_ocb.cpp @@ -20,7 +20,7 @@ namespace { class OCB_Long_KAT_Tests : public Text_Based_Test { public: - OCB_Long_KAT_Tests() : Text_Based_Test(Test::data_file("ocb_long.vec"), + OCB_Long_KAT_Tests() : Text_Based_Test("ocb_long.vec", {"Keylen", "Taglen", "Output"}) {} Test::Result run_one_test(const std::string&, const VarMap& vars) diff --git a/src/tests/test_passhash.cpp b/src/tests/test_passhash.cpp index 8cbad507e..b8d8bea47 100644 --- a/src/tests/test_passhash.cpp +++ b/src/tests/test_passhash.cpp @@ -22,7 +22,7 @@ namespace { class Bcrypt_Tests : public Text_Based_Test { public: - Bcrypt_Tests() : Text_Based_Test(Test::data_file("bcrypt.vec"), {"Password","Passhash"}) {} + Bcrypt_Tests() : Text_Based_Test("bcrypt.vec", {"Password","Passhash"}) {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -56,7 +56,7 @@ BOTAN_REGISTER_TEST("bcrypt", Bcrypt_Tests); class Passhash9_Tests : public Text_Based_Test { public: - Passhash9_Tests() : Text_Based_Test(Test::data_file("passhash9.vec"), {"Password","Passhash"}) {} + Passhash9_Tests() : Text_Based_Test("passhash9.vec", {"Password","Passhash"}) {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp index 0e5d9fe68..a6b673199 100644 --- a/src/tests/test_pbkdf.cpp +++ b/src/tests/test_pbkdf.cpp @@ -18,7 +18,7 @@ namespace { class PBKDF_KAT_Tests : public Text_Based_Test { public: - PBKDF_KAT_Tests() : Text_Based_Test(Test::data_dir("pbkdf"), + PBKDF_KAT_Tests() : Text_Based_Test("pbkdf", {"OutputLen", "Iterations", "Salt", "Passphrase", "Output"}) {} diff --git a/src/tests/test_rfc6979.cpp b/src/tests/test_rfc6979.cpp index 59d44f5b9..0ebb4c86d 100644 --- a/src/tests/test_rfc6979.cpp +++ b/src/tests/test_rfc6979.cpp @@ -20,7 +20,7 @@ namespace { class RFC6979_KAT_Tests : public Text_Based_Test { public: - RFC6979_KAT_Tests() : Text_Based_Test(Test::data_file("rfc6979.vec"), + RFC6979_KAT_Tests() : Text_Based_Test("rfc6979.vec", {"Q", "X", "H", "K"}) {} Test::Result run_one_test(const std::string& hash, const VarMap& vars) diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp index 626fe85b5..a5dbbc8e1 100644 --- a/src/tests/test_rng.cpp +++ b/src/tests/test_rng.cpp @@ -58,7 +58,7 @@ Botan::RandomNumberGenerator* get_rng(const std::string& algo_str, const std::ve class X931_RNG_Tests : public Text_Based_Test { public: - X931_RNG_Tests() : Text_Based_Test(Test::data_file("x931.vec"), {"IKM", "L", "Out"}) {} + X931_RNG_Tests() : Text_Based_Test("x931.vec", {"IKM", "L", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { @@ -88,7 +88,7 @@ BOTAN_REGISTER_TEST("x931_rng", X931_RNG_Tests); class HMAC_DRBG_Tests : public Text_Based_Test { public: - HMAC_DRBG_Tests() : Text_Based_Test(Test::data_file("hmac_drbg.vec"), + HMAC_DRBG_Tests() : Text_Based_Test("hmac_drbg.vec", {"EntropyInput", "EntropyInputReseed", "Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp index 5a9a14945..2720ae49a 100644 --- a/src/tests/test_rsa.cpp +++ b/src/tests/test_rsa.cpp @@ -22,7 +22,7 @@ class RSA_ES_KAT_Tests : public PK_Encryption_Decryption_Test public: RSA_ES_KAT_Tests() : PK_Encryption_Decryption_Test( "RSA", - Test::data_file("pubkey/rsaes.vec"), + "pubkey/rsaes.vec", {"E", "P", "Q", "Msg", "Ciphertext"}, {"Padding", "Nonce"}) {} @@ -43,7 +43,7 @@ class RSA_Signature_KAT_Tests : public PK_Signature_Generation_Test public: RSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( "RSA", - Test::data_file("pubkey/rsa_sig.vec"), + "pubkey/rsa_sig.vec", {"E", "P", "Q", "Msg", "Signature"}, {"Padding", "Nonce"}) {} @@ -66,7 +66,7 @@ class RSA_Signature_Verify_Tests : public PK_Signature_Verification_Test public: RSA_Signature_Verify_Tests() : PK_Signature_Verification_Test( "RSA", - Test::data_file("pubkey/rsa_verify.vec"), + "pubkey/rsa_verify.vec", {"E", "N", "Msg", "Signature"}, {"Padding"}) {} diff --git a/src/tests/test_rw.cpp b/src/tests/test_rw.cpp index 47cb11706..bee9dfff0 100644 --- a/src/tests/test_rw.cpp +++ b/src/tests/test_rw.cpp @@ -23,7 +23,7 @@ class RW_KAT_Tests : public PK_Signature_Generation_Test public: RW_KAT_Tests() : PK_Signature_Generation_Test( "Rabin-Williams", - Test::data_file("pubkey/rw_sig.vec"), + "pubkey/rw_sig.vec", {"E", "P", "Q", "Msg", "Signature"}, {"Padding"}) {} @@ -47,7 +47,7 @@ class RW_Verify_Tests : public PK_Signature_Verification_Test public: RW_Verify_Tests() : PK_Signature_Verification_Test( "Rabin-Williams", - Test::data_file("pubkey/rw_verify.vec"), + "pubkey/rw_verify.vec", {"E", "N", "Msg", "Signature"}) {} diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp index fb38ad677..232fdcdd9 100644 --- a/src/tests/test_stream.cpp +++ b/src/tests/test_stream.cpp @@ -17,7 +17,7 @@ namespace Botan_Tests { class Stream_Cipher_Tests : public Text_Based_Test { public: - Stream_Cipher_Tests(): Text_Based_Test(Test::data_dir("stream"), + Stream_Cipher_Tests(): Text_Based_Test("stream", {"Key", "In", "Out"}, {"Nonce"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp index f6611b3ae..16b1848ef 100644 --- a/src/tests/test_utils.cpp +++ b/src/tests/test_utils.cpp @@ -21,8 +21,8 @@ namespace { class Utility_Function_Tests : public Text_Based_Test { public: - Utility_Function_Tests() : Text_Based_Test(Test::data_file("util.vec"), - {"In1","In2","Out"}) + Utility_Function_Tests() : Text_Based_Test("util.vec", + {"In1","In2","Out"}) {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override @@ -177,7 +177,7 @@ BOTAN_REGISTER_TEST("util", Utility_Function_Tests); class Date_Format_Tests : public Text_Based_Test { public: - Date_Format_Tests() : Text_Based_Test(Test::data_file("dates.vec"), + Date_Format_Tests() : Text_Based_Test("dates.vec", std::vector<std::string>{"Date"}) {} @@ -248,7 +248,7 @@ BOTAN_REGISTER_TEST("util_dates", Date_Format_Tests); class Base64_Tests : public Text_Based_Test { public: - Base64_Tests() : Text_Based_Test(Test::data_file("base64.vec"), + Base64_Tests() : Text_Based_Test("base64.vec", std::vector<std::string>({"Base64"}), {"Binary"}) {} diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 35a1e01dc..b0292926e 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -15,9 +15,6 @@ namespace Botan_Tests { -#define TEST_DATA_DIR "src/tests/data" -#define TEST_OUTDATA_DIR "src/tests/outdata" - Test::Registration::Registration(const std::string& name, Test* test) { if(Test::global_registry().count(name) == 0) @@ -420,32 +417,19 @@ std::vector<Test::Result> Test::run_test(const std::string& test_name, bool fail return results; } -//static -std::string Test::data_dir(const std::string& what) - { - return std::string(TEST_DATA_DIR) + "/" + what; - } - -//static -std::string Test::data_file(const std::string& what) - { - return std::string(TEST_DATA_DIR) + "/" + what; - } - -//static -std::string Test::full_path_for_output_file(const std::string& base) - { - return std::string(TEST_OUTDATA_DIR) + "/" + base; - } - // static member variables of Test Botan::RandomNumberGenerator* Test::m_test_rng = nullptr; +std::string Test::m_data_dir; size_t Test::m_soak_level = 0; bool Test::m_log_success = false; //static -void Test::setup_tests(size_t soak, bool log_success, Botan::RandomNumberGenerator* rng) +void Test::setup_tests(size_t soak, + bool log_success, + const std::string& data_dir, + Botan::RandomNumberGenerator* rng) { + m_data_dir = data_dir; m_soak_level = soak; m_log_success = log_success; m_test_rng = rng; @@ -458,6 +442,18 @@ size_t Test::soak_level() } //static +std::string Test::data_file(const std::string& what) + { + return Test::data_dir() + "/" + what; + } + +//static +const std::string& Test::data_dir() + { + return m_data_dir; + } + +//static bool Test::log_success() { return m_log_success; @@ -604,16 +600,17 @@ std::string Text_Based_Test::get_next_line() { if(m_first) { - if(m_data_src.find(".vec") != std::string::npos) + const std::string full_path = Test::data_dir() + "/" + m_data_src; + if(full_path.find(".vec") != std::string::npos) { - m_srcs.push_back(m_data_src); + m_srcs.push_back(full_path); } else { - const auto fs = Botan::get_files_recursive(m_data_src); + const auto fs = Botan::get_files_recursive(full_path); m_srcs.assign(fs.begin(), fs.end()); if(m_srcs.empty()) - throw Test_Error("Error reading test data dir " + m_data_src); + throw Test_Error("Error reading test data dir " + full_path); } m_first = false; diff --git a/src/tests/tests.h b/src/tests/tests.h index 74b6de08e..c38145504 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -273,9 +273,7 @@ class Test static Test* get_test(const std::string& test_name); - static std::string data_dir(const std::string& what); static std::string data_file(const std::string& what); - static std::string full_path_for_output_file(const std::string& base); template<typename Alloc> static std::vector<uint8_t, Alloc> @@ -302,16 +300,22 @@ class Test return r; } - static void setup_tests(size_t soak, bool log_succcss, Botan::RandomNumberGenerator* rng); + static void setup_tests(size_t soak, + bool log_succcss, + const std::string& data_dir, + Botan::RandomNumberGenerator* rng); static size_t soak_level(); static bool log_success(); + static const std::string& data_dir(); + static Botan::RandomNumberGenerator& rng(); static std::string random_password(); static uint64_t timestamp(); // nanoseconds arbitrary epoch private: + static std::string m_data_dir; static Botan::RandomNumberGenerator* m_test_rng; static size_t m_soak_level; static bool m_log_success; diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index 169819e32..66c2610f8 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -3,7 +3,7 @@ * * (C) 2007 Falko Strenzke * 2007 Manuel Hartl -* 2008 Jack Lloyd +* 2008,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -19,10 +19,6 @@ #include <botan/pkcs8.h> #endif -#if defined(BOTAN_HAS_RSA) - #include <botan/rsa.h> -#endif - #if defined(BOTAN_HAS_X509_CERTIFICATES) #include <botan/x509cert.h> #endif @@ -129,10 +125,11 @@ Test::Result test_decode_ver_link_SHA1() Test::Result test_sign_then_ver() { + Test::Result result("ECDSA Unit"); + Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); Botan::ECDSA_PrivateKey ecdsa(Test::rng(), dom_pars); - Test::Result result("ECDSA Unit"); Botan::PK_Signer signer(ecdsa, "EMSA1(SHA-1)"); auto msg = Botan::hex_decode("12345678901234567890abcdef12"); @@ -189,7 +186,7 @@ Test::Result test_ec_sign() result.test_eq("invalid ECDSA signature invalid", verifier.check_signature(sig), false); } - catch (std::exception& e) + catch(std::exception& e) { result.test_failure("test_ec_sign", e.what()); } @@ -197,54 +194,45 @@ Test::Result test_ec_sign() return result; } -Test::Result test_create_pkcs8() +Test::Result test_ecdsa_create_save_load() { Test::Result result("ECDSA Unit"); + std::string ecc_private_key_pem; + const std::vector<byte> msg = Botan::hex_decode("12345678901234567890abcdef12"); + std::vector<byte> msg_signature; + try { -#if defined(BOTAN_HAS_RSA) - Botan::RSA_PrivateKey rsa_key(Test::rng(), 1024); - - std::ofstream rsa_priv_key(Test::full_path_for_output_file("rsa_private.pkcs8.pem")); - rsa_priv_key << Botan::PKCS8::PEM_encode(rsa_key); -#endif - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); Botan::ECDSA_PrivateKey key(Test::rng(), dom_pars); - // later used by other tests :( - std::ofstream priv_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem")); - priv_key << Botan::PKCS8::PEM_encode(key); + Botan::PK_Signer signer(key, "EMSA1(SHA-1)"); + msg_signature = signer.sign_message(msg, Test::rng()); + + ecc_private_key_pem = Botan::PKCS8::PEM_encode(key); } - catch (std::exception& e) + catch(std::exception& e) { result.test_failure("create_pkcs8", e.what()); } + Botan::DataSource_Memory pem_src(ecc_private_key_pem); + std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(pem_src, Test::rng())); + Botan::ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key.get()); + result.confirm("the loaded key could be converted into an ECDSA_PrivateKey", loaded_ec_key); + + Botan::PK_Verifier verifier(*loaded_ec_key, "EMSA1(SHA-1)"); + + result.confirm("generated signature valid", verifier.verify_message(msg, msg_signature)); + return result; } -Test::Result test_create_and_verify() +Test::Result test_unusual_curve() { Test::Result result("ECDSA Unit"); - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); - Botan::ECDSA_PrivateKey key(Test::rng(), dom_pars); - std::ofstream priv_key(Test::full_path_for_output_file("dompar_private.pkcs8.pem")); - priv_key << Botan::PKCS8::PEM_encode(key); - - std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem"), Test::rng())); - Botan::ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key.get()); - result.confirm("the loaded key could not be converted into an ECDSA_PrivateKey", loaded_ec_key); - -#if defined(BOTAN_HAS_RSA) - std::unique_ptr<Botan::Private_Key> loaded_key_1(Botan::PKCS8::load_key(Test::full_path_for_output_file("rsa_private.pkcs8.pem"), Test::rng())); - Botan::ECDSA_PrivateKey* loaded_rsa_key = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key_1.get()); - result.test_eq("loaded key type corrected", loaded_key_1->algo_name(), "RSA"); - result.confirm("RSA key cannot be casted to ECDSA", !loaded_rsa_key); -#endif - //calc a curve which is not in the registry const std::string G_secp_comp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; const Botan::BigInt bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); @@ -258,17 +246,59 @@ Test::Result test_create_and_verify() if(!result.confirm("point is on curve", p_G.on_the_curve())) return result; - Botan::ECDSA_PrivateKey key_odd_oid(Test::rng(), dom_params); - std::string key_odd_oid_str = Botan::PKCS8::PEM_encode(key_odd_oid); + Botan::ECDSA_PrivateKey key_odd_curve(Test::rng(), dom_params); + std::string key_odd_curve_str = Botan::PKCS8::PEM_encode(key_odd_curve); - Botan::DataSource_Memory key_data_src(key_odd_oid_str); - std::unique_ptr<Botan::Private_Key> loaded_key2(Botan::PKCS8::load_key(key_data_src, Test::rng())); + Botan::DataSource_Memory key_data_src(key_odd_curve_str); + std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(key_data_src, Test::rng())); result.confirm("reloaded key", loaded_key.get()); return result; } +Test::Result test_read_pkcs8() + { + Test::Result result("ECDSA Unit"); + + const std::vector<byte> msg = Botan::hex_decode("12345678901234567890abcdef12"); + + try + { + std::unique_ptr<Botan::Private_Key> loaded_key_nodp(Botan::PKCS8::load_key(Test::data_file("ecc/nodompar_private.pkcs8.pem"), Test::rng())); + // anew in each test with unregistered domain-parameters + Botan::ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key_nodp.get()); + result.confirm("key loaded", ecdsa_nodp); + + Botan::PK_Signer signer(*ecdsa_nodp, "EMSA1(SHA-1)"); + Botan::PK_Verifier verifier(*ecdsa_nodp, "EMSA1(SHA-1)"); + + std::vector<byte> signature_nodp = signer.sign_message(msg, Test::rng()); + + result.confirm("signature valid", verifier.verify_message(msg, signature_nodp)); + + try + { + std::unique_ptr<Botan::Private_Key> loaded_key_withdp( + Botan::PKCS8::load_key(Test::data_file("ecc/withdompar_private.pkcs8.pem"), Test::rng())); + + result.test_failure("loaded key with unknown OID"); + } + catch(std::exception& e) + { + result.test_note("rejected key with unknown OID"); + } + } + catch(std::exception& e) + { + result.test_failure("read_pkcs8", e.what()); + } + + return result; + } + + + Test::Result test_curve_registry() { const std::vector<std::string> oids = { @@ -324,65 +354,6 @@ Test::Result test_curve_registry() return result; } -Test::Result test_read_pkcs8() - { - Test::Result result("ECDSA Unit"); - - const std::vector<byte> msg = Botan::hex_decode("12345678901234567890abcdef12"); - - try - { - std::unique_ptr<Botan::Private_Key> loaded_key(Botan::PKCS8::load_key(Test::full_path_for_output_file("wo_dompar_private.pkcs8.pem"), Test::rng())); - Botan::ECDSA_PrivateKey* ecdsa = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key.get()); - result.confirm("key loaded", ecdsa); - - Botan::PK_Signer signer(*ecdsa, "EMSA1(SHA-1)"); - - std::vector<byte> sig = signer.sign_message(msg, Test::rng()); - - Botan::PK_Verifier verifier(*ecdsa, "EMSA1(SHA-1)"); - - result.confirm("generated signature valid", verifier.verify_message(msg, sig)); - } - catch (std::exception& e) - { - result.test_failure("read_pkcs8", e.what()); - } - - try - { - std::unique_ptr<Botan::Private_Key> loaded_key_nodp(Botan::PKCS8::load_key(Test::data_file("ecc/nodompar_private.pkcs8.pem"), Test::rng())); - // anew in each test with unregistered domain-parameters - Botan::ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<Botan::ECDSA_PrivateKey*>(loaded_key_nodp.get()); - result.confirm("key loaded", ecdsa_nodp); - - Botan::PK_Signer signer(*ecdsa_nodp, "EMSA1(SHA-1)"); - Botan::PK_Verifier verifier(*ecdsa_nodp, "EMSA1(SHA-1)"); - - std::vector<byte> signature_nodp = signer.sign_message(msg, Test::rng()); - - result.confirm("signature valid", verifier.verify_message(msg, signature_nodp)); - - try - { - std::unique_ptr<Botan::Private_Key> loaded_key_withdp( - Botan::PKCS8::load_key(Test::data_file("ecc/withdompar_private.pkcs8.pem"), Test::rng())); - - result.test_failure("loaded key with unknown OID"); - } - catch (std::exception& e) - { - result.test_note("rejected key with unknown OID"); - } - } - catch (std::exception& e) - { - result.test_failure("read_pkcs8", e.what()); - } - - return result; - } - Test::Result test_ecc_key_with_rfc5915_extensions() { Test::Result result("ECDSA Unit"); @@ -419,10 +390,10 @@ class ECDSA_Unit_Tests : public Test #endif results.push_back(test_sign_then_ver()); results.push_back(test_ec_sign()); - results.push_back(test_create_pkcs8()); - results.push_back(test_create_and_verify()); - results.push_back(test_curve_registry()); results.push_back(test_read_pkcs8()); + results.push_back(test_ecdsa_create_save_load()); + results.push_back(test_unusual_curve()); + results.push_back(test_curve_registry()); results.push_back(test_ecc_key_with_rfc5915_extensions()); return results; } |