diff options
Diffstat (limited to 'src')
93 files changed, 2895 insertions, 1907 deletions
diff --git a/src/cli/asn1.cpp b/src/cli/asn1.cpp index b877a24a1..f24e2c316 100644 --- a/src/cli/asn1.cpp +++ b/src/cli/asn1.cpp @@ -47,7 +47,9 @@ std::string url_encode(const std::vector<uint8_t>& in) { const int c = in[i]; if(::isprint(c)) + { out << static_cast<char>(c); + } else { out << "%" << std::hex << static_cast<int>(c) << std::dec; @@ -56,14 +58,16 @@ std::string url_encode(const std::vector<uint8_t>& in) } if(unprintable >= in.size() / 4) + { return Botan::hex_encode(in); + } return out.str(); } void emit(const std::string& type, size_t level, size_t length, const std::string& value = "") { - const size_t LIMIT = 4*1024; + const size_t LIMIT = 4 * 1024; const size_t BIN_LIMIT = 1024; std::ostringstream out; @@ -72,23 +76,35 @@ void emit(const std::string& type, size_t level, size_t length, const std::strin << ", l=" << std::setw(4) << length << ": "; for(size_t i = INITIAL_LEVEL; i != level; ++i) + { out << ' '; + } out << type; bool should_skip = false; if(value.length() > LIMIT) + { should_skip = true; + } if((type == "OCTET STRING" || type == "BIT STRING") && value.length() > BIN_LIMIT) + { should_skip = true; + } if(value != "" && !should_skip) { - if(out.tellp() % 2 == 0) out << ' '; + if(out.tellp() % 2 == 0) + { + out << ' '; + } - while(out.tellp() < 50) out << ' '; + while(out.tellp() < 50) + { + out << ' '; + } out << value; } @@ -177,12 +193,12 @@ void decode(Botan::BER_Decoder& decoder, size_t level) if(type_tag == Botan::SEQUENCE) { emit("SEQUENCE", level, length); - decode(cons_info, level+1); + decode(cons_info, level + 1); } else if(type_tag == Botan::SET) { emit("SET", level, length); - decode(cons_info, level+1); + decode(cons_info, level + 1); } else { @@ -193,15 +209,21 @@ void decode(Botan::BER_Decoder& decoder, size_t level) name = "cons [" + std::to_string(type_tag) + "]"; if(class_tag & Botan::APPLICATION) + { name += " appl"; + } if(class_tag & Botan::CONTEXT_SPECIFIC) + { name += " context"; + } } else + { name = type_name(type_tag) + " (cons)"; + } emit(name, level, length); - decode(cons_info, level+1); + decode(cons_info, level + 1); } } else if((class_tag & Botan::APPLICATION) || (class_tag & Botan::CONTEXT_SPECIFIC)) @@ -217,12 +239,10 @@ void decode(Botan::BER_Decoder& decoder, size_t level) } catch(...) { - emit("[" + std::to_string(type_tag) + "]", level, length, - url_encode(bits)); + emit("[" + std::to_string(type_tag) + "]", level, length, url_encode(bits)); } #else - emit("[" + std::to_string(type_tag) + "]", level, length, - url_encode(bits)); + emit("[" + std::to_string(type_tag) + "]", level, length, url_encode(bits)); #endif } else if(type_tag == Botan::OBJECT_ID) @@ -232,7 +252,9 @@ void decode(Botan::BER_Decoder& decoder, size_t level) std::string out = Botan::OIDS::lookup(oid); if(out != oid.as_string()) + { out += " [" + oid.as_string() + "]"; + } emit(type_name(type_tag), level, length, out); } @@ -241,21 +263,31 @@ void decode(Botan::BER_Decoder& decoder, size_t level) Botan::BigInt number; if(type_tag == Botan::INTEGER) + { data.decode(number); + } else if(type_tag == Botan::ENUMERATED) + { data.decode(number, Botan::ENUMERATED, class_tag); + } std::vector<uint8_t> rep; /* If it's small, it's probably a number, not a hash */ if(number.bits() <= 20) + { rep = Botan::BigInt::encode(number, Botan::BigInt::Decimal); + } else + { rep = Botan::BigInt::encode(number, Botan::BigInt::Hexadecimal); + } std::string str; for(size_t i = 0; i != rep.size(); ++i) + { str += static_cast<char>(rep[i]); + } emit(type_name(type_tag), level, length, str); } @@ -263,8 +295,7 @@ void decode(Botan::BER_Decoder& decoder, size_t level) { bool boolean; data.decode(boolean); - emit(type_name(type_tag), - level, length, (boolean ? "true" : "false")); + emit(type_name(type_tag), level, length, (boolean ? "true" : "false")); } else if(type_tag == Botan::NULL_TAG) { @@ -282,8 +313,7 @@ void decode(Botan::BER_Decoder& decoder, size_t level) } catch(...) { - emit(type_name(type_tag), level, length, - url_encode(decoded_bits)); + emit(type_name(type_tag), level, length, url_encode(decoded_bits)); } } else if(type_tag == Botan::BIT_STRING) @@ -294,19 +324,23 @@ void decode(Botan::BER_Decoder& decoder, size_t level) std::vector<bool> bit_set; for(size_t i = 0; i != decoded_bits.size(); ++i) + { for(size_t j = 0; j != 8; ++j) { - const bool bit = static_cast<bool>((decoded_bits[decoded_bits.size()-i-1] >> (7-j)) & 1); + const bool bit = static_cast<bool>((decoded_bits[decoded_bits.size() - i - 1] >> (7 - j)) & 1); bit_set.push_back(bit); } + } std::string bit_str; for(size_t i = 0; i != bit_set.size(); ++i) { - bool the_bit = bit_set[bit_set.size()-i-1]; + bool the_bit = bit_set[bit_set.size() - i - 1]; if(!the_bit && bit_str.size() == 0) + { continue; + } bit_str += (the_bit ? "1" : "0"); } diff --git a/src/cli/cc_enc.cpp b/src/cli/cc_enc.cpp index 9a3256417..ec160c3ce 100644 --- a/src/cli/cc_enc.cpp +++ b/src/cli/cc_enc.cpp @@ -28,7 +28,9 @@ uint8_t luhn_checksum(uint64_t cc_number) { digit *= 2; if(digit > 9) + { digit -= 9; + } } sum += digit; @@ -75,11 +77,15 @@ uint64_t encrypt_cc_number(uint64_t cc_number, const Botan::BigInt c = Botan::FPE::fe1_encrypt(n, cc_ranked, key, tweak); if(c.bits() > 50) + { throw Botan::Internal_Error("FPE produced a number too large"); + } uint64_t enc_cc = 0; for(size_t i = 0; i != 7; ++i) - enc_cc = (enc_cc << 8) | c.byte_at(6-i); + { + enc_cc = (enc_cc << 8) | c.byte_at(6 - i); + } return cc_derank(enc_cc); } @@ -94,11 +100,15 @@ uint64_t decrypt_cc_number(uint64_t enc_cc, const Botan::BigInt c = Botan::FPE::fe1_decrypt(n, cc_ranked, key, tweak); if(c.bits() > 50) + { throw CLI_Error("FPE produced a number too large"); + } uint64_t dec_cc = 0; for(size_t i = 0; i != 7; ++i) - dec_cc = (dec_cc << 8) | c.byte_at(6-i); + { + dec_cc = (dec_cc << 8) | c.byte_at(6 - i); + } return cc_derank(dec_cc); } @@ -117,12 +127,11 @@ class CC_Encrypt final : public Command std::unique_ptr<Botan::PBKDF> pbkdf(Botan::PBKDF::create("PBKDF2(SHA-256)")); if(!pbkdf) + { throw CLI_Error_Unsupported("PBKDF", "PBKDF2(SHA-256)"); + } - Botan::secure_vector<uint8_t> key = - pbkdf->pbkdf_iterations(32, pass, - tweak.data(), tweak.size(), - 100000); + Botan::secure_vector<uint8_t> key = pbkdf->pbkdf_iterations(32, pass, tweak.data(), tweak.size(), 100000); output() << encrypt_cc_number(cc_number, key, tweak) << "\n"; } @@ -143,12 +152,11 @@ class CC_Decrypt final : public Command std::unique_ptr<Botan::PBKDF> pbkdf(Botan::PBKDF::create("PBKDF2(SHA-256)")); if(!pbkdf) + { throw CLI_Error_Unsupported("PBKDF", "PBKDF2(SHA-256)"); + } - Botan::secure_vector<uint8_t> key = - pbkdf->pbkdf_iterations(32, pass, - tweak.data(), tweak.size(), - 100000); + Botan::secure_vector<uint8_t> key = pbkdf->pbkdf_iterations(32, pass, tweak.data(), tweak.size(), 100000); output() << decrypt_cc_number(cc_number, key, tweak) << "\n"; } diff --git a/src/cli/cli.h b/src/cli/cli.h index c3dc8d849..a5150d6d7 100644 --- a/src/cli/cli.h +++ b/src/cli/cli.h @@ -12,11 +12,11 @@ #include <botan/rng.h> #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> + #include <botan/system_rng.h> #endif #include <fstream> @@ -56,15 +56,15 @@ class CLI_Error_Unsupported : public CLI_Error { public: CLI_Error_Unsupported(const std::string& what, - const std::string& who) : - CLI_Error(what + " with '" + who + "' unsupported or not available") {} + const std::string& who) + : CLI_Error(what + " with '" + who + "' unsupported or not available") {} }; struct CLI_Error_Invalid_Spec : public CLI_Error { public: - explicit CLI_Error_Invalid_Spec(const std::string& spec) : - CLI_Error("Invalid command spec '" + spec + "'") {} + explicit CLI_Error_Invalid_Spec(const std::string& spec) + : CLI_Error("Invalid command spec '" + spec + "'") {} }; class Command @@ -124,7 +124,7 @@ class Command parse_spec(); std::vector<std::string> args; - for(auto&& param : params) + for(auto const& param : params) { if(param.find("--") == 0) { @@ -138,12 +138,15 @@ class Command if(m_spec_flags.count(opt_name) == 0) { if(m_spec_opts.count(opt_name)) + { throw CLI_Usage_Error("Invalid usage of option --" + opt_name + " without value"); + } else + { throw CLI_Usage_Error("Unknown flag --" + opt_name); + } } - m_user_flags.insert(opt_name); } else @@ -168,7 +171,7 @@ class Command bool seen_stdin_flag = false; size_t arg_i = 0; - for(auto&& arg : m_spec_args) + for(auto const& arg : m_spec_args) { if(arg_i >= args.size()) { @@ -184,7 +187,9 @@ class Command if(args[arg_i] == "-") { if(seen_stdin_flag) + { throw CLI_Usage_Error("Cannot specifiy '-' (stdin) more than once"); + } seen_stdin_flag = true; } @@ -194,7 +199,9 @@ class Command if(m_spec_rest.empty()) { if(arg_i != args.size()) + { throw CLI_Usage_Error("Too many arguments"); + } } else { @@ -218,7 +225,7 @@ class Command } // Now insert any defaults for options not supplied by the user - for(auto&& opt : m_spec_opts) + for(auto const& opt : m_spec_opts) { if(m_user_args.count(opt.first) == 0) { @@ -252,7 +259,10 @@ class Command return "Usage: " + m_spec; } - const std::string& cmd_spec() const { return m_spec; } + const std::string& cmd_spec() const + { + return m_spec; + } std::string cmd_name() const { @@ -266,14 +276,18 @@ class Command const std::vector<std::string> parts = Botan::split_on(m_spec, ' '); if(parts.size() == 0) + { throw CLI_Error_Invalid_Spec(m_spec); + } for(size_t i = 1; i != parts.size(); ++i) { const std::string s = parts[i]; if(s.empty()) // ?!? (shouldn't happen) + { throw CLI_Error_Invalid_Spec(m_spec); + } if(s.size() > 2 && s[0] == '-' && s[1] == '-') { @@ -287,8 +301,7 @@ class Command } else { - m_spec_opts.insert(std::make_pair(s.substr(2, eq - 2), - s.substr(eq + 1, std::string::npos))); + m_spec_opts.insert(std::make_pair(s.substr(2, eq - 2), s.substr(eq + 1, std::string::npos))); } } else if(s[0] == '*') @@ -307,7 +320,9 @@ class Command { // named argument if(!m_spec_rest.empty()) // rest arg wasn't last + { throw CLI_Error("Invalid command spec " + m_spec); + } m_spec_args.push_back(s); } @@ -318,13 +333,12 @@ class Command m_spec_opts.insert(std::make_pair("output", "")); m_spec_opts.insert(std::make_pair("error-output", "")); - m_spec_opts.insert(std::make_pair("rng-type", #if defined(BOTAN_HAS_SYSTEM_RNG) - "system" + const auto availableRng = "system"; #else - "auto" + const auto availableRng = "auto"; #endif - )); + m_spec_opts.insert(std::make_pair("rng-type", availableRng)); } /* @@ -335,14 +349,18 @@ class Command std::ostream& output() { if(m_output_stream.get()) + { return *m_output_stream; + } return std::cout; } std::ostream& error_output() { if(m_error_output_stream.get()) + { return *m_error_output_stream; + } return std::cerr; } @@ -397,7 +415,9 @@ class Command std::vector<std::string> get_arg_list(const std::string& what) const { if(what != m_spec_rest) + { throw CLI_Error("Unexpected list name '" + what + "'"); + } return m_user_rest; } @@ -409,7 +429,9 @@ class Command { std::vector<uint8_t> buf; auto insert_fn = [&](const uint8_t b[], size_t l) - { buf.insert(buf.end(), b, b + l); }; + { + buf.insert(buf.end(), b, b + l); + }; this->read_file(input_file, insert_fn); return buf; } @@ -418,7 +440,9 @@ class Command { std::string str; auto insert_fn = [&](const uint8_t b[], size_t l) - { str.append(reinterpret_cast<const char*>(b), l); }; + { + str.append(reinterpret_cast<const char*>(b), l); + }; this->read_file(input_file, insert_fn); return str; } @@ -438,7 +462,9 @@ class Command { std::ifstream in(input_file, std::ios::binary); if(!in) + { throw CLI_IO_Error("reading file", input_file); + } do_read_file(in, consumer_fn, buf_size); } } @@ -557,8 +583,8 @@ class Command }; }; -#define BOTAN_REGISTER_COMMAND(name, CLI_Class) \ - namespace { Botan_CLI::Command::Registration \ +#define BOTAN_REGISTER_COMMAND(name, CLI_Class) \ + namespace { Botan_CLI::Command::Registration \ reg_cmd_ ## CLI_Class(name, []() -> Botan_CLI::Command* { return new CLI_Class; }); } \ BOTAN_FORCE_SEMICOLON diff --git a/src/cli/compress.cpp b/src/cli/compress.cpp index d5b2c4736..6ee6398ee 100644 --- a/src/cli/compress.cpp +++ b/src/cli/compress.cpp @@ -7,7 +7,7 @@ #include "cli.h" #if defined(BOTAN_HAS_COMPRESSION) - #include <botan/compression.h> + #include <botan/compression.h> #endif namespace Botan_CLI { @@ -19,15 +19,15 @@ class Compress final : public Command public: Compress() : Command("compress --type=gzip --level=6 --buf-size=8192 file") {} - std::string output_filename(const std::string& input_fsname, - const std::string& comp_type) + std::string output_filename(const std::string& input_fsname, const std::string& comp_type) { - const std::map<std::string, std::string> suffixes = { - { "zlib", "zlib" }, - { "gzip", "gz" }, - { "bzip2", "bz2" }, - { "lzma", "xz" }, - }; + const std::map<std::string, std::string> suffixes = + { + { "zlib", "zlib" }, + { "gzip", "gz" }, + { "bzip2", "bz2" }, + { "lzma", "xz" }, + }; auto suffix_info = suffixes.find(comp_type); if(suffixes.count(comp_type) == 0) @@ -103,10 +103,12 @@ class Decompress final : public Command { auto last_dot = in_file.find_last_of('.'); if(last_dot == std::string::npos || last_dot == 0) + { throw CLI_Error("No extension detected in filename '" + in_file + "'"); + } out_file = in_file.substr(0, last_dot); - suffix = in_file.substr(last_dot+1, std::string::npos); + suffix = in_file.substr(last_dot + 1, std::string::npos); } void go() override @@ -119,18 +121,24 @@ class Decompress final : public Command std::ifstream in(in_file); if(!in.good()) + { throw CLI_IO_Error("reading", in_file); + } std::unique_ptr<Botan::Decompression_Algorithm> decompress; decompress.reset(Botan::make_decompressor(suffix)); if(!decompress) + { throw CLI_Error_Unsupported("Decompression", suffix); + } std::ofstream out(out_file); if(!out.good()) + { throw CLI_IO_Error("writing", out_file); + } Botan::secure_vector<uint8_t> buf; diff --git a/src/cli/credentials.h b/src/cli/credentials.h index 71acdc83d..99733e42b 100644 --- a/src/cli/credentials.h +++ b/src/cli/credentials.h @@ -18,8 +18,12 @@ inline bool value_exists(const std::vector<std::string>& vec, const std::string& val) { for(size_t i = 0; i != vec.size(); ++i) + { if(vec[i] == val) + { return true; + } + } return false; } @@ -64,7 +68,7 @@ class Basic_Credentials_Manager : public Botan::Credentials_Manager // TODO: make path configurable const std::vector<std::string> paths = { "/etc/ssl/certs", "/usr/share/ca-certificates" }; - for(auto&& path : paths) + for(auto const& path : paths) { std::shared_ptr<Botan::Certificate_Store> cs(new Botan::Certificate_Store_In_Memory(path)); m_certstores.push_back(cs); @@ -84,10 +88,14 @@ class Basic_Credentials_Manager : public Botan::Credentials_Manager // don't ask for client certs if(type == "tls-server") + { return v; + } - for(auto&& cs : m_certstores) + for(auto const& cs : m_certstores) + { v.push_back(cs.get()); + } return v; } @@ -99,13 +107,17 @@ class Basic_Credentials_Manager : public Botan::Credentials_Manager { BOTAN_UNUSED(type); - for(auto&& i : m_creds) + for(auto const& i : m_creds) { if(std::find(algos.begin(), algos.end(), i.key->algo_name()) == algos.end()) + { continue; + } if(hostname != "" && !i.certs[0].matches_dns_name(hostname)) + { continue; + } return i.certs; } @@ -117,10 +129,12 @@ class Basic_Credentials_Manager : public Botan::Credentials_Manager const std::string& /*type*/, const std::string& /*context*/) override { - for(auto&& i : m_creds) + for(auto const& i : m_creds) { if(cert == i.certs[0]) + { return i.key.get(); + } } return nullptr; @@ -129,8 +143,8 @@ class Basic_Credentials_Manager : public Botan::Credentials_Manager private: struct Certificate_Info { - std::vector<Botan::X509_Certificate> certs; - std::shared_ptr<Botan::Private_Key> key; + std::vector<Botan::X509_Certificate> certs; + std::shared_ptr<Botan::Private_Key> key; }; std::vector<Certificate_Info> m_creds; diff --git a/src/cli/main.cpp b/src/cli/main.cpp index f63de8fa2..5fbaf085e 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -36,9 +36,7 @@ std::string main_help() int main(int argc, char* argv[]) { - std::cerr << Botan::runtime_version_check(BOTAN_VERSION_MAJOR, - BOTAN_VERSION_MINOR, - BOTAN_VERSION_PATCH); + std::cerr << Botan::runtime_version_check(BOTAN_VERSION_MAJOR, BOTAN_VERSION_MINOR, BOTAN_VERSION_PATCH); const std::string cmd_name = (argc <= 1) ? "help" : argv[1]; diff --git a/src/cli/math.cpp b/src/cli/math.cpp index 4ed58b9f0..ee1c2b1a9 100644 --- a/src/cli/math.cpp +++ b/src/cli/math.cpp @@ -68,9 +68,7 @@ class Factor final : public Command std::sort(factors.begin(), factors.end()); output() << n << ": "; - std::copy(factors.begin(), - factors.end(), - std::ostream_iterator<Botan::BigInt>(output(), " ")); + std::copy(factors.begin(), factors.end(), std::ostream_iterator<Botan::BigInt>(output(), " ")); output() << std::endl; } @@ -92,11 +90,15 @@ class Factor final : public Command Botan::BigInt a_factor = 0; while(a_factor == 0) + { a_factor = rho(n, rng); + } std::vector<Botan::BigInt> rho_factored = factorize(a_factor, rng); for(size_t j = 0; j != rho_factored.size(); j++) + { factors.push_back(rho_factored[j]); + } n /= a_factor; } @@ -111,7 +113,7 @@ class Factor final : public Command */ Botan::BigInt rho(const Botan::BigInt& n, Botan::RandomNumberGenerator& rng) { - Botan::BigInt x = Botan::BigInt::random_integer(rng, 0, n-1); + Botan::BigInt x = Botan::BigInt::random_integer(rng, 0, n - 1); Botan::BigInt y = x; Botan::BigInt d = 0; @@ -123,18 +125,22 @@ class Factor final : public Command i++; if(i == 0) // overflow, bail out + { break; + } x = mod_n.multiply((x + 1), x); d = Botan::gcd(y - x, n); if(d != 1 && d != n) + { return d; + } if(i == k) { y = x; - k = 2*k; + k = 2 * k; } } return 0; @@ -155,7 +161,9 @@ class Factor final : public Command { uint16_t prime = Botan::PRIMES[j]; if(n < prime) + { break; + } Botan::BigInt x = Botan::gcd(n, prime); diff --git a/src/cli/pubkey.cpp b/src/cli/pubkey.cpp index aac493a0e..25f3e2ed5 100644 --- a/src/cli/pubkey.cpp +++ b/src/cli/pubkey.cpp @@ -17,11 +17,11 @@ #include <botan/pubkey.h> #if defined(BOTAN_HAS_DL_GROUP) - #include <botan/dl_group.h> + #include <botan/dl_group.h> #endif #if defined(BOTAN_HAS_ECC_GROUP) - #include <botan/ec_group.h> + #include <botan/ec_group.h> #endif namespace Botan_CLI { @@ -37,7 +37,7 @@ class PK_Keygen final : public Command const std::string params = get_arg("params"); std::unique_ptr<Botan::Private_Key> - key(Botan::create_private_key(algo, rng(), params)); + key(Botan::create_private_key(algo, rng(), params)); if(!key) { @@ -82,11 +82,17 @@ namespace { std::string algo_default_emsa(const std::string& key) { if(key == "RSA") - return "EMSA4"; // PSS + { + return "EMSA4"; + } // PSS else if(key == "ECDSA" || key == "DSA") + { return "EMSA1"; + } else + { return "EMSA1"; + } } } @@ -98,20 +104,27 @@ class PK_Sign final : public Command void go() override { - std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), - rng(), - get_arg("passphrase"))); + std::unique_ptr<Botan::Private_Key> key( + Botan::PKCS8::load_key( + get_arg("key"), + rng(), + get_arg("passphrase"))); if(!key) + { throw CLI_Error("Unable to load private key"); + } const std::string sig_padding = get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")"; Botan::PK_Signer signer(*key, rng(), sig_padding); - this->read_file(get_arg("file"), - [&signer](const uint8_t b[], size_t l) { signer.update(b, l); }); + auto onData = [&signer](const uint8_t b[], size_t l) + { + signer.update(b, l); + }; + this->read_file(get_arg("file"), onData); output() << Botan::base64_encode(signer.signature(rng())) << "\n"; } @@ -128,14 +141,19 @@ class PK_Verify final : public Command { std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(get_arg("pubkey"))); if(!key) + { throw CLI_Error("Unable to load public key"); + } const std::string sig_padding = get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")"; Botan::PK_Verifier verifier(*key, sig_padding); - this->read_file(get_arg("file"), - [&verifier](const uint8_t b[], size_t l) { verifier.update(b, l); }); + auto onData = [&verifier](const uint8_t b[], size_t l) + { + verifier.update(b, l); + }; + this->read_file(get_arg("file"), onData); const Botan::secure_vector<uint8_t> signature = Botan::base64_decode(this->slurp_file_as_str(get_arg("signature"))); @@ -227,7 +245,9 @@ class Gen_DL_Group final : public Command output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42); } else + { throw CLI_Usage_Error("Invalid DL type '" + type + "'"); + } } }; @@ -243,9 +263,10 @@ class PKCS8_Tool final : public Command void go() override { std::unique_ptr<Botan::Private_Key> key( - Botan::PKCS8::load_key(get_arg("key"), - rng(), - get_arg("pass-in"))); + Botan::PKCS8::load_key( + get_arg("key"), + rng(), + get_arg("pass-in"))); const std::chrono::milliseconds pbe_millis(get_arg_sz("pbe-millis")); const std::string pbe = get_arg("pbe"); diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index 2bffc736e..cf048e0d2 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -26,91 +26,91 @@ //#define INCLUDE_SIMD_PERF #if defined(BOTAN_HAS_SIMD_32) && defined(INCLUDE_SIMD_PERF) - #include <botan/internal/simd_32.h> + #include <botan/internal/simd_32.h> #endif #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> + #include <botan/system_rng.h> #endif #if defined(BOTAN_HAS_HMAC_DRBG) - #include <botan/hmac_drbg.h> + #include <botan/hmac_drbg.h> #endif #if defined(BOTAN_HAS_HMAC_RNG) - #include <botan/hmac_rng.h> + #include <botan/hmac_rng.h> #endif #if defined(BOTAN_HAS_RDRAND_RNG) - #include <botan/rdrand_rng.h> + #include <botan/rdrand_rng.h> #endif #if defined(BOTAN_HAS_FPE_FE1) - #include <botan/fpe_fe1.h> + #include <botan/fpe_fe1.h> #endif #if defined(BOTAN_HAS_COMPRESSION) - #include <botan/compression.h> + #include <botan/compression.h> #endif #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - #include <botan/pkcs8.h> - #include <botan/pubkey.h> - #include <botan/x509_key.h> - #include <botan/workfactor.h> + #include <botan/pkcs8.h> + #include <botan/pubkey.h> + #include <botan/x509_key.h> + #include <botan/workfactor.h> #endif #if defined(BOTAN_HAS_NUMBERTHEORY) - #include <botan/numthry.h> + #include <botan/numthry.h> #endif #if defined(BOTAN_HAS_RSA) - #include <botan/rsa.h> + #include <botan/rsa.h> #endif #if defined(BOTAN_HAS_ECC_GROUP) - #include <botan/ec_group.h> + #include <botan/ec_group.h> #endif #if defined(BOTAN_HAS_ECDSA) - #include <botan/ecdsa.h> + #include <botan/ecdsa.h> #endif #if defined(BOTAN_HAS_ECKCDSA) - #include <botan/eckcdsa.h> + #include <botan/eckcdsa.h> #endif #if defined(BOTAN_HAS_ECGDSA) - #include <botan/ecgdsa.h> + #include <botan/ecgdsa.h> #endif #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include <botan/dh.h> + #include <botan/dh.h> #endif #if defined(BOTAN_HAS_CURVE_25519) - #include <botan/curve25519.h> + #include <botan/curve25519.h> #endif #if defined(BOTAN_HAS_ECDH) - #include <botan/ecdh.h> + #include <botan/ecdh.h> #endif #if defined(BOTAN_HAS_MCELIECE) - #include <botan/mceliece.h> + #include <botan/mceliece.h> #endif #if defined(BOTAN_HAS_XMSS) - #include <botan/xmss.h> + #include <botan/xmss.h> #endif #if defined(BOTAN_HAS_NEWHOPE) && defined(BOTAN_HAS_CHACHA) - #include <botan/newhope.h> - #include <botan/chacha.h> + #include <botan/newhope.h> + #include <botan/chacha.h> #endif namespace Botan_CLI { @@ -123,17 +123,16 @@ class Timer Timer(const std::string& name, uint64_t event_mult = 1, const std::string& doing = "", - const std::string& provider = "") : - m_name(name + (provider.empty() ? provider : " [" + provider + "]")), - m_doing(doing), - m_event_mult(event_mult) - {} + const std::string& provider = "") + : m_name(name + (provider.empty() ? provider : " [" + provider + "]")) + , m_doing(doing) + , m_event_mult(event_mult) {} Timer(const std::string& name, const std::string& provider, const std::string& doing, - uint64_t event_mult = 1) : - Timer(name, event_mult, doing, provider) {} + uint64_t event_mult = 1) + : Timer(name, event_mult, doing, provider) {} static uint64_t get_system_timestamp_ns() { @@ -197,8 +196,15 @@ class Timer struct Timer_Scope { public: - explicit Timer_Scope(Timer& timer) : m_timer(timer) { m_timer.start(); } - ~Timer_Scope() { m_timer.stop(); } + explicit Timer_Scope(Timer& timer) + : m_timer(timer) + { + m_timer.start(); + } + ~Timer_Scope() + { + m_timer.stop(); + } private: Timer& m_timer; }; @@ -219,17 +225,41 @@ class Timer } } - uint64_t value() const { return m_time_used; } - double seconds() const { return milliseconds() / 1000.0; } - double milliseconds() const { return value() / 1000000.0; } + uint64_t value() const + { + return m_time_used; + } + double seconds() const + { + return milliseconds() / 1000.0; + } + double milliseconds() const + { + return value() / 1000000.0; + } - double ms_per_event() const { return milliseconds() / events(); } + double ms_per_event() const + { + return milliseconds() / events(); + } - uint64_t cycles_consumed() const { return m_cpu_cycles_used; } + uint64_t cycles_consumed() const + { + return m_cpu_cycles_used; + } - uint64_t events() const { return m_event_count * m_event_mult; } - const std::string& get_name() const { return m_name; } - const std::string& doing() const { return m_doing; } + uint64_t events() const + { + return m_event_count * m_event_mult; + } + const std::string& get_name() const + { + return m_name; + } + const std::string& doing() const + { + return m_doing; + } static std::string result_string_bps(const Timer& t); static std::string result_string_ops(const Timer& t); @@ -244,7 +274,7 @@ class Timer std::string Timer::result_string_bps(const Timer& timer) { - const size_t MiB = 1024*1024; + const size_t MiB = 1024 * 1024; const double MiB_total = static_cast<double>(timer.events()) / MiB; const double MiB_per_sec = MiB_total / timer.seconds(); @@ -253,10 +283,11 @@ std::string Timer::result_string_bps(const Timer& timer) oss << timer.get_name(); if(!timer.doing().empty()) + { oss << " " << timer.doing(); + } - oss << " " << std::fixed << std::setprecision(3) - << MiB_per_sec << " MiB/sec"; + oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec"; if(timer.cycles_consumed() != 0) { @@ -309,7 +340,8 @@ std::vector<std::string> default_benchmark_list() points of the most interesting or widely used algorithms. */ - return { + return + { /* Block ciphers */ "AES-128", "AES-192", @@ -382,7 +414,8 @@ std::vector<std::string> default_benchmark_list() class Speed final : public Command { public: - Speed() : Command("speed --msec=300 --provider= --buf-size=4096 *algos") {} + Speed() + : Command("speed --msec=300 --provider= --buf-size=4096 *algos") {} void go() override { @@ -393,7 +426,9 @@ class Speed final : public Command std::vector<std::string> algos = get_arg_list("algos"); const bool using_defaults = (algos.empty()); if(using_defaults) + { algos = default_benchmark_list(); + } for(auto algo : algos) { @@ -592,7 +627,7 @@ class Speed final : public Command size_t buf_size, bench_fn<T> bench_one) { - for(auto&& prov : T::providers(algo)) + for(auto const& prov : T::providers(algo)) { if(provider.empty() || provider == prov) { @@ -618,19 +653,20 @@ class Speed final : public Command Timer ks_timer(cipher.name(), provider, "key schedule"); const Botan::SymmetricKey key(rng(), cipher.maximum_keylength()); - ks_timer.run([&] { cipher.set_key(key); }); + ks_timer.run([&]() { cipher.set_key(key); }); - encrypt_timer.run_until_elapsed(runtime, [&] { cipher.encrypt(buffer); }); + encrypt_timer.run_until_elapsed(runtime, [&]() { cipher.encrypt(buffer); }); output() << Timer::result_string_bps(encrypt_timer); - decrypt_timer.run_until_elapsed(runtime, [&] { cipher.decrypt(buffer); }); + decrypt_timer.run_until_elapsed(runtime, [&]() { cipher.decrypt(buffer); }); output() << Timer::result_string_bps(decrypt_timer); } - void bench_stream_cipher(Botan::StreamCipher& cipher, - const std::string& provider, - const std::chrono::milliseconds runtime, - size_t buf_size) + void bench_stream_cipher( + Botan::StreamCipher& cipher, + const std::string& provider, + const std::chrono::milliseconds runtime, + size_t buf_size) { Botan::secure_vector<uint8_t> buffer = rng().random_vec(buf_size); @@ -647,28 +683,30 @@ class Speed final : public Command while(encrypt_timer.under(runtime)) { - encrypt_timer.run([&] { cipher.encipher(buffer); }); + encrypt_timer.run([&]() { cipher.encipher(buffer); }); } output() << Timer::result_string_bps(encrypt_timer); } - void bench_hash(Botan::HashFunction& hash, - const std::string& provider, - const std::chrono::milliseconds runtime, - size_t buf_size) + void bench_hash( + Botan::HashFunction& hash, + const std::string& provider, + const std::chrono::milliseconds runtime, + size_t buf_size) { Botan::secure_vector<uint8_t> buffer = rng().random_vec(buf_size); Timer timer(hash.name(), provider, "hash", buffer.size()); - timer.run_until_elapsed(runtime, [&] { hash.update(buffer); }); + timer.run_until_elapsed(runtime, [&]() { hash.update(buffer); }); output() << Timer::result_string_bps(timer); } - void bench_mac(Botan::MessageAuthenticationCode& mac, - const std::string& provider, - const std::chrono::milliseconds runtime, - size_t buf_size) + void bench_mac( + Botan::MessageAuthenticationCode& mac, + const std::string& provider, + const std::chrono::milliseconds runtime, + size_t buf_size) { Botan::secure_vector<uint8_t> buffer = rng().random_vec(buf_size); @@ -676,14 +714,15 @@ class Speed final : public Command mac.set_key(key); Timer timer(mac.name(), provider, "mac", buffer.size()); - timer.run_until_elapsed(runtime, [&] { mac.update(buffer); }); + timer.run_until_elapsed(runtime, [&]() { mac.update(buffer); }); output() << Timer::result_string_bps(timer); } - void bench_cipher_mode(Botan::Cipher_Mode& enc, - Botan::Cipher_Mode& dec, - const std::chrono::milliseconds runtime, - size_t buf_size) + void bench_cipher_mode( + Botan::Cipher_Mode& enc, + Botan::Cipher_Mode& dec, + const std::chrono::milliseconds runtime, + size_t buf_size) { Botan::secure_vector<uint8_t> buffer = rng().random_vec(buf_size); @@ -694,22 +733,24 @@ class Speed final : public Command const Botan::SymmetricKey key(rng(), enc.key_spec().maximum_keylength()); - ks_timer.run([&] { enc.set_key(key); }); - ks_timer.run([&] { dec.set_key(key); }); + ks_timer.run([&]() { enc.set_key(key); }); + ks_timer.run([&]() { dec.set_key(key); }); Botan::secure_vector<uint8_t> iv = rng().random_vec(enc.default_nonce_length()); while(encrypt_timer.under(runtime) && decrypt_timer.under(runtime)) { // Must run in this order, or AEADs will reject the ciphertext - iv_timer.run([&] { enc.start(iv); }); - encrypt_timer.run([&] { enc.finish(buffer); }); + iv_timer.run([&]() { enc.start(iv); }); + encrypt_timer.run([&]() { enc.finish(buffer); }); - iv_timer.run([&] { dec.start(iv); }); - decrypt_timer.run([&] { dec.finish(buffer); }); + iv_timer.run([&]() { dec.start(iv); }); + decrypt_timer.run([&]() { dec.finish(buffer); }); if(iv.size() > 0) + { iv[0] += 1; + } } output() << Timer::result_string_ops(ks_timer); @@ -718,10 +759,11 @@ class Speed final : public Command output() << Timer::result_string_bps(decrypt_timer); } - void bench_rng(Botan::RandomNumberGenerator& rng, - const std::string& rng_name, - const std::chrono::milliseconds runtime, - size_t buf_size) + void bench_rng( + Botan::RandomNumberGenerator& rng, + const std::string& rng_name, + const std::chrono::milliseconds runtime, + size_t buf_size) { Botan::secure_vector<uint8_t> buffer(buf_size); @@ -730,7 +772,7 @@ class Speed final : public Command #endif Timer timer(rng_name, "", "generate", buffer.size()); - timer.run_until_elapsed(runtime, [&] { rng.randomize(buffer.data(), buffer.size()); }); + timer.run_until_elapsed(runtime, [&]() { rng.randomize(buffer.data(), buffer.size()); }); output() << Timer::result_string_bps(timer); } @@ -750,7 +792,7 @@ class Speed final : public Command Timer sub_op("SIMD_4x32", SIMD_par, "sub"); Timer xor_op("SIMD_4x32", SIMD_par, "xor"); Timer bswap_op("SIMD_4x32", SIMD_par, "bswap"); - Timer transpose_op("SIMD_4x32", SIMD_par/4, "transpose4"); + Timer transpose_op("SIMD_4x32", SIMD_par / 4, "transpose4"); std::chrono::milliseconds msec_part = msec / 5; @@ -761,7 +803,8 @@ class Speed final : public Command { total_time.start(); - load_le_op.run([&] { + load_le_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { // Test that unaligned loads work ok @@ -769,42 +812,48 @@ class Speed final : public Command } }); - load_be_op.run([&] { + load_be_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { simd[i].load_be(rnd + i); } }); - add_op.run([&] { + add_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { - simd[i] += simd[(i+8) % SIMD_par]; + simd[i] += simd[(i + 8) % SIMD_par]; } }); - xor_op.run([&] { + xor_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { - simd[i] ^= simd[(i+8) % SIMD_par]; + simd[i] ^= simd[(i + 8) % SIMD_par]; } }); - transpose_op.run([&] { + transpose_op.run([&]() + { for(size_t i = 0; i != SIMD_par; i += 4) { - Botan::SIMD_4x32::transpose(simd[i], simd[i+1], simd[i+2], simd[i+3]); + Botan::SIMD_4x32::transpose(simd[i], simd[i + 1], simd[i + 2], simd[i + 3]); } }); - sub_op.run([&] { + sub_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { - simd[i] -= simd[(i+8) % SIMD_par]; + simd[i] -= simd[(i + 8) % SIMD_par]; } }); - bswap_op.run([&] { + bswap_op.run([&]() + { for(size_t i = 0; i != SIMD_par; ++i) { simd[i] = simd[i].bswap(); @@ -834,7 +883,7 @@ class Speed final : public Command Botan_Tests::SeedCapturing_RNG rng; Timer timer(src, "", "bytes"); - timer.run([&] { entropy_bits = srcs.poll_just(rng, src); }); + timer.run([&]() { entropy_bits = srcs.poll_just(rng, src); }); #if defined(BOTAN_HAS_COMPRESSION) std::unique_ptr<Botan::Compression_Algorithm> comp(Botan::make_compressor("zlib")); @@ -866,11 +915,12 @@ class Speed final : public Command #if defined(BOTAN_HAS_ECC_GROUP) void bench_ecc_mult(const std::chrono::milliseconds runtime) { - const std::vector<std::string> groups = { + const std::vector<std::string> groups = + { "secp256r1", "brainpool256r1", "secp384r1", "brainpool384r1", "secp521r1", "brainpool512r1" - }; + }; for(std::string group_name : groups) { @@ -888,7 +938,7 @@ class Speed final : public Command const Botan::PointGFp r1 = mult_timer.run([&]() { return base_point * scalar; }); const Botan::PointGFp r2 = blinded_mult_timer.run( - [&]() { return scalar_mult.blinded_multiply(scalar, rng()); }); + [&]() { return scalar_mult.blinded_multiply(scalar, rng()); }); BOTAN_ASSERT_EQUAL(r1, r2, "Same point computed by both methods"); } @@ -913,8 +963,8 @@ class Speed final : public Command const Botan::secure_vector<uint8_t> os_cmp = Botan::EC2OSP(p, Botan::PointGFp::COMPRESSED); const Botan::secure_vector<uint8_t> os_uncmp = Botan::EC2OSP(p, Botan::PointGFp::UNCOMPRESSED); - uncmp_timer.run([&] { OS2ECP(os_uncmp, curve); }); - cmp_timer.run([&] { OS2ECP(os_cmp, curve); }); + uncmp_timer.run([&]() { OS2ECP(os_uncmp, curve); }); + cmp_timer.run([&]() { OS2ECP(os_cmp, curve); }); } output() << Timer::result_string_ops(uncmp_timer); @@ -978,8 +1028,8 @@ class Speed final : public Command while(f_timer.under(runtime)) { - e_timer.run([&] { Botan::power_mod(group.get_g(), random_e, group.get_p()); }); - f_timer.run([&] { Botan::power_mod(group.get_g(), random_f, group.get_p()); }); + e_timer.run([&]() { Botan::power_mod(group.get_g(), random_e, group.get_p()); }); + f_timer.run([&]() { Botan::power_mod(group.get_g(), random_f, group.get_p()); }); } output() << Timer::result_string_ops(e_timer); @@ -1006,19 +1056,23 @@ class Speed final : public Command { const Botan::BigInt x(rng(), p.bits() - 1); - const Botan::BigInt x_inv1 = invmod_timer.run([&]{ + const Botan::BigInt x_inv1 = invmod_timer.run([&] + { return Botan::inverse_mod(x + p, p); }); - const Botan::BigInt x_inv2 = monty_timer.run([&]{ + const Botan::BigInt x_inv2 = monty_timer.run([&] + { return Botan::normalized_montgomery_inverse(x, p); }); - const Botan::BigInt x_inv3 = ct_invmod_timer.run([&]{ + const Botan::BigInt x_inv3 = ct_invmod_timer.run([&] + { return Botan::ct_inverse_mod_odd_modulus(x, p); }); - const Botan::BigInt x_inv4 = powm_timer.run([&]{ + const Botan::BigInt x_inv4 = powm_timer.run([&] + { return powm_p(x); }); @@ -1044,12 +1098,15 @@ class Speed final : public Command while(genprime_timer.under(runtime) && is_prime_timer.under(runtime)) { - const Botan::BigInt p = genprime_timer.run([&] { - return Botan::random_prime(rng(), bits, coprime); }); + const Botan::BigInt p = genprime_timer.run([&] + { + return Botan::random_prime(rng(), bits, coprime); + }); - const bool ok = is_prime_timer.run([&] { + const bool ok = is_prime_timer.run([&] + { return Botan::is_prime(p, rng(), 64, true); - }); + }); if(!ok) { @@ -1060,7 +1117,7 @@ class Speed final : public Command // Now test p+2, p+4, ... which may or may not be prime for(size_t i = 2; i != 64; i += 2) { - is_prime_timer.run([&] { Botan::is_prime(p, rng(), 64, true); }); + is_prime_timer.run([&]() { Botan::is_prime(p, rng(), 64, true); }); } } @@ -1071,11 +1128,12 @@ class Speed final : public Command #endif #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - void bench_pk_enc(const Botan::Private_Key& key, - const std::string& nm, - const std::string& provider, - const std::string& padding, - std::chrono::milliseconds msec) + void bench_pk_enc( + const Botan::Private_Key& key, + const std::string& nm, + const std::string& provider, + const std::string& padding, + std::chrono::milliseconds msec) { std::vector<uint8_t> plaintext, ciphertext; @@ -1091,12 +1149,12 @@ class Speed final : public Command if(ciphertext.empty() || enc_timer.under(msec)) { plaintext = unlock(rng().random_vec(enc.maximum_input_size())); - ciphertext = enc_timer.run([&] { return enc.encrypt(plaintext, rng()); }); + ciphertext = enc_timer.run([&]() { return enc.encrypt(plaintext, rng()); }); } if(dec_timer.under(msec)) { - auto dec_pt = dec_timer.run([&] { return dec.decrypt(ciphertext); }); + auto dec_pt = dec_timer.run([&]() { return dec.decrypt(ciphertext); }); if(dec_pt != plaintext) // sanity check { @@ -1126,8 +1184,8 @@ class Speed final : public Command while(ka_timer.under(msec)) { - Botan::SymmetricKey symkey1 = ka_timer.run([&] { return ka1.derive_key(32, ka2_pub); }); - Botan::SymmetricKey symkey2 = ka_timer.run([&] { return ka2.derive_key(32, ka1_pub); }); + Botan::SymmetricKey symkey1 = ka_timer.run([&]() { return ka1.derive_key(32, ka2_pub); }); + Botan::SymmetricKey symkey2 = ka_timer.run([&]() { return ka2.derive_key(32, ka1_pub); }); if(symkey1 != symkey1) { @@ -1197,7 +1255,7 @@ class Speed final : public Command */ message = unlock(rng().random_vec(48)); - signature = sig_timer.run([&] { return sig.sign_message(message, rng()); }); + signature = sig_timer.run([&]() { return sig.sign_message(message, rng()); }); bad_signature = signature; bad_signature[rng().next_byte() % bad_signature.size()] ^= rng().next_nonzero_byte(); @@ -1205,16 +1263,20 @@ class Speed final : public Command if(ver_timer.under(msec)) { - const bool verified = ver_timer.run([&] { - return ver.verify_message(message, signature); }); + const bool verified = ver_timer.run([&] + { + return ver.verify_message(message, signature); + }); if(!verified) { error_output() << "Correct signature rejected in PK signature bench\n"; } - const bool verified_bad = ver_timer.run([&] { - return ver.verify_message(message, bad_signature); }); + const bool verified_bad = ver_timer.run([&] + { + return ver.verify_message(message, bad_signature); + }); if(verified_bad) { @@ -1238,7 +1300,8 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { return new Botan::RSA_PrivateKey(rng(), keylen); })); @@ -1264,7 +1327,8 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { return new Botan::ECDSA_PrivateKey(rng(), Botan::EC_Group(grp)); })); @@ -1276,7 +1340,7 @@ class Speed final : public Command #if defined(BOTAN_HAS_ECKCDSA) void bench_eckcdsa(const std::string& provider, - std::chrono::milliseconds msec) + std::chrono::milliseconds msec) { for(std::string grp : { "secp256r1", "secp384r1", "secp521r1" }) { @@ -1284,7 +1348,8 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { return new Botan::ECKCDSA_PrivateKey(rng(), Botan::EC_Group(grp)); })); @@ -1296,7 +1361,7 @@ class Speed final : public Command #if defined(BOTAN_HAS_ECGDSA) void bench_ecgdsa(const std::string& provider, - std::chrono::milliseconds msec) + std::chrono::milliseconds msec) { for(std::string grp : { "secp256r1", "secp384r1", "secp521r1" }) { @@ -1304,7 +1369,8 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { return new Botan::ECGDSA_PrivateKey(rng(), Botan::EC_Group(grp)); })); @@ -1325,10 +1391,12 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] + { return new Botan::DH_PrivateKey(rng(), Botan::DL_Group(grp)); })); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] + { return new Botan::DH_PrivateKey(rng(), Botan::DL_Group(grp)); })); @@ -1348,10 +1416,12 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] + { return new Botan::ECDH_PrivateKey(rng(), Botan::EC_Group(grp)); })); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] + { return new Botan::ECDH_PrivateKey(rng(), Botan::EC_Group(grp)); })); @@ -1369,10 +1439,12 @@ class Speed final : public Command Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key1(keygen_timer.run([&] + { return new Botan::Curve25519_PrivateKey(rng()); })); - std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] { + std::unique_ptr<Botan::PK_Key_Agreement_Key> key2(keygen_timer.run([&] + { return new Botan::Curve25519_PrivateKey(rng()); })); @@ -1394,13 +1466,14 @@ class Speed final : public Command SL=256 n=6624 t=115 - 942 KB pubkey 2184 KB privkey */ - const std::vector<std::pair<size_t, size_t>> mce_params = { - { 2480, 45 }, - { 2960, 57 }, - { 3408, 67 }, - { 4624, 95 }, - { 6624, 115 } - }; + const std::vector<std::pair<size_t, size_t>> mce_params = + { + { 2480, 45 }, + { 2960, 57 }, + { 3408, 67 }, + { 4624, 95 }, + { 6624, 115 } + }; for(auto params : mce_params) { @@ -1413,12 +1486,13 @@ class Speed final : public Command } const std::string nm = "McEliece-" + std::to_string(n) + "," + std::to_string(t) + - " (WF=" + std::to_string(Botan::mceliece_work_factor(n, t)) + ")"; + " (WF=" + std::to_string(Botan::mceliece_work_factor(n, t)) + ")"; Timer keygen_timer(nm, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { - return new Botan::McEliece_PrivateKey(rng(), n, t); + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { + return new Botan::McEliece_PrivateKey(rng(), n, t); })); output() << Timer::result_string_ops(keygen_timer); @@ -1428,24 +1502,26 @@ class Speed final : public Command #endif #if defined(BOTAN_HAS_XMSS) - void bench_xmss(const std::string& provider, - std::chrono::milliseconds msec) + void bench_xmss(const std::string& provider, + std::chrono::milliseconds msec) { // H16 and H20 signatures take an hour or more to generate - std::vector<std::string> xmss_params{ + std::vector<std::string> xmss_params + { "XMSS_SHA2-256_W16_H10", "XMSS_SHA2-512_W16_H10", "XMSS_SHAKE128_W16_H10", "XMSS_SHAKE256_W16_H10", - }; + }; for(std::string params : xmss_params) { Timer keygen_timer(params, provider, "keygen"); - std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] { + std::unique_ptr<Botan::Private_Key> key(keygen_timer.run([&] + { return new Botan::XMSS_PrivateKey(Botan::XMSS_Parameters::xmss_id_from_string(params), rng()); - })); + })); output() << Timer::result_string_ops(keygen_timer); bench_pk_sig(*key, params, provider, "", msec); @@ -1467,8 +1543,14 @@ class Speed final : public Command class ChaCha20_RNG : public Botan::RandomNumberGenerator { public: - std::string name() const override { return "ChaCha20_RNG"; } - void clear() override { /* ignored */ } + std::string name() const override + { + return "ChaCha20_RNG"; + } + void clear() override + { + /* ignored */ + } void randomize(uint8_t out[], size_t len) override { @@ -1476,9 +1558,15 @@ class Speed final : public Command m_chacha.cipher1(out, len); } - bool is_seeded() const override { return true; } + bool is_seeded() const override + { + return true; + } - void add_entropy(const uint8_t[], size_t) override { /* ignored */ } + void add_entropy(const uint8_t[], size_t) override + { + /* ignored */ + } ChaCha20_RNG(const Botan::secure_vector<uint8_t>& seed) { diff --git a/src/cli/timing_tests.cpp b/src/cli/timing_tests.cpp index 3adda8482..6ffbbddc2 100644 --- a/src/cli/timing_tests.cpp +++ b/src/cli/timing_tests.cpp @@ -23,27 +23,27 @@ #include <botan/internal/os_utils.h> #if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> + #include <botan/system_rng.h> #endif #if defined(BOTAN_HAS_AUTO_SEEDED_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_EME_RAW) - #include <botan/pubkey.h> - #include <botan/rsa.h> + #include <botan/pubkey.h> + #include <botan/rsa.h> #endif #if defined(BOTAN_HAS_TLS_CBC) - #include <botan/internal/tls_cbc.h> - #include <botan/tls_exceptn.h> + #include <botan/internal/tls_cbc.h> + #include <botan/tls_exceptn.h> #endif #if defined(BOTAN_HAS_ECDSA) - #include <botan/ecdsa.h> - #include <botan/reducer.h> - #include <botan/numthry.h> + #include <botan/ecdsa.h> + #include <botan/reducer.h> + #include <botan/numthry.h> #endif namespace Botan_CLI { @@ -56,10 +56,10 @@ class Timing_Test Timing_Test() = default; virtual ~Timing_Test() = default; - std::vector<std::vector<ticks>> - execute_evaluation(const std::vector<std::string>& inputs, - size_t warmup_runs, - size_t measurement_runs); + std::vector<std::vector<ticks>> execute_evaluation( + const std::vector<std::string>& inputs, + size_t warmup_runs, + size_t measurement_runs); virtual std::vector<uint8_t> prepare_input(std::string input) = 0; @@ -92,13 +92,11 @@ class Timing_Test class Bleichenbacker_Timing_Test : public Timing_Test { public: - Bleichenbacker_Timing_Test(size_t keysize) : - m_privkey(Timing_Test::timing_test_rng(), keysize), - m_pubkey(m_privkey), - m_enc(m_pubkey, Timing_Test::timing_test_rng(), "Raw"), - m_dec(m_privkey, Timing_Test::timing_test_rng(), "PKCS1v15") - { - } + Bleichenbacker_Timing_Test(size_t keysize) + : m_privkey(Timing_Test::timing_test_rng(), keysize) + , m_pubkey(m_privkey) + , m_enc(m_pubkey, Timing_Test::timing_test_rng(), "Raw") + , m_dec(m_privkey, Timing_Test::timing_test_rng(), "PKCS1v15") {} std::vector<uint8_t> prepare_input(std::string input) override { @@ -138,12 +136,11 @@ class Bleichenbacker_Timing_Test : public Timing_Test class Manger_Timing_Test : public Timing_Test { public: - Manger_Timing_Test(size_t keysize) : - m_privkey(Timing_Test::timing_test_rng(), keysize), - m_pubkey(m_privkey), - m_enc(m_pubkey, Timing_Test::timing_test_rng(), m_encrypt_padding), - m_dec(m_privkey, Timing_Test::timing_test_rng(), m_decrypt_padding) - {} + Manger_Timing_Test(size_t keysize) + : m_privkey(Timing_Test::timing_test_rng(), keysize) + , m_pubkey(m_privkey) + , m_enc(m_pubkey, Timing_Test::timing_test_rng(), m_encrypt_padding) + , m_dec(m_privkey, Timing_Test::timing_test_rng(), m_decrypt_padding) {} std::vector<uint8_t> prepare_input(std::string input) override { @@ -159,7 +156,7 @@ class Manger_Timing_Test : public Timing_Test { m_dec.decrypt(input.data(), m_ctext_length); } - catch (Botan::Decoding_Error e) + catch(Botan::Decoding_Error e) { } ticks end = get_ticks(); @@ -187,12 +184,10 @@ class Manger_Timing_Test : public Timing_Test class Lucky13_Timing_Test : public Timing_Test { public: - Lucky13_Timing_Test(const std::string& mac_name, - size_t mac_keylen) : - m_mac_algo(mac_name), - m_mac_keylen (mac_keylen), - m_dec("AES-128", 16, m_mac_algo, m_mac_keylen, true, false) - {} + Lucky13_Timing_Test(const std::string& mac_name, size_t mac_keylen) + : m_mac_algo(mac_name) + , m_mac_keylen(mac_keylen) + , m_dec("AES-128", 16, m_mac_algo, m_mac_keylen, true, false) {} std::vector<uint8_t> prepare_input(std::string input) override; ticks measure_critical_function(std::vector<uint8_t> input) override; @@ -261,14 +256,12 @@ class ECDSA_Timing_Test : public Timing_Test const Botan::Modular_Reducer m_mod_order; }; -ECDSA_Timing_Test::ECDSA_Timing_Test(std::string ecgroup) : - m_privkey(Timing_Test::timing_test_rng(), Botan::EC_Group(ecgroup)), - m_order(m_privkey.domain().get_order()), - m_base_point(m_privkey.domain().get_base_point(), m_order), - m_x(m_privkey.private_value()), - m_mod_order(m_order) - { - } +ECDSA_Timing_Test::ECDSA_Timing_Test(std::string ecgroup) + : m_privkey(Timing_Test::timing_test_rng(), Botan::EC_Group(ecgroup)) + , m_order(m_privkey.domain().get_order()) + , m_base_point(m_privkey.domain().get_base_point(), m_order) + , m_x(m_privkey.private_value()) + , m_mod_order(m_order) {} std::vector<uint8_t> ECDSA_Timing_Test::prepare_input(std::string input) { @@ -295,20 +288,28 @@ ticks ECDSA_Timing_Test::measure_critical_function(std::vector<uint8_t> input) #endif -std::vector<std::vector<ticks>> Timing_Test::execute_evaluation(const std::vector<std::string>& raw_inputs, size_t warmup_runs, size_t measurement_runs) +std::vector<std::vector<ticks>> Timing_Test::execute_evaluation( + const std::vector<std::string>& raw_inputs, + size_t warmup_runs, size_t measurement_runs) { std::vector<std::vector<ticks>> all_results(raw_inputs.size()); std::vector<std::vector<uint8_t>> inputs(raw_inputs.size()); - for(size_t i = 0; i != all_results.size(); ++i) - all_results[i].reserve(measurement_runs); + for(auto& result : all_results) + { + result.reserve(measurement_runs); + } for(size_t i = 0; i != inputs.size(); ++i) + { inputs[i] = prepare_input(raw_inputs[i]); + } // arbitrary upper bounds of 1 and 10 million resp if(warmup_runs > 1000000 || measurement_runs > 100000000) + { throw CLI_Error("Requested execution counts too large, rejecting"); + } size_t total_runs = 0; while(total_runs < (warmup_runs + measurement_runs)) @@ -325,7 +326,9 @@ std::vector<std::vector<ticks>> Timing_Test::execute_evaluation(const std::vecto if(total_runs >= warmup_runs) { for(size_t i = 0; i != results.size(); ++i) + { all_results[i].push_back(results[i]); + } } } @@ -335,8 +338,9 @@ std::vector<std::vector<ticks>> Timing_Test::execute_evaluation(const std::vecto class Timing_Test_Command : public Command { public: - Timing_Test_Command() : Command("timing_test test_type --test-data-file= --test-data-dir=src/tests/data/timing --warmup-runs=1000 --measurement-runs=10000") - {} + Timing_Test_Command() + : Command("timing_test test_type --test-data-file= --test-data-dir=src/tests/data/timing " + "--warmup-runs=1000 --measurement-runs=10000") {} virtual void go() override { @@ -364,19 +368,20 @@ class Timing_Test_Command : public Command { std::ifstream infile(filename); if(infile.good() == false) + { throw CLI_Error("Error reading test data from '" + filename + "'"); + } std::string line; - while (std::getline(infile, line)) + while(std::getline(infile, line)) { - if (line.size() > 0 && line.at(0) != '#') + if(line.size() > 0 && line.at(0) != '#') { lines.push_back(line); } } } - std::vector<std::vector<ticks>> results = - test->execute_evaluation(lines, warmup_runs, measurement_runs); + std::vector<std::vector<ticks>> results = test->execute_evaluation(lines, warmup_runs, measurement_runs); size_t unique_id = 0; std::ostringstream oss; @@ -406,7 +411,7 @@ class Timing_Test_Command : public Command "lucky13sec4sha1 " + "lucky13sec4sha256 " + "lucky13sec4sha384 " - ); + ); } }; diff --git a/src/cli/tls_client.cpp b/src/cli/tls_client.cpp index 3cba471f0..642e60373 100644 --- a/src/cli/tls_client.cpp +++ b/src/cli/tls_client.cpp @@ -15,7 +15,7 @@ #include <botan/hex.h> #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) -#include <botan/tls_session_manager_sqlite.h> + #include <botan/tls_session_manager_sqlite.h> #endif #include <string> @@ -32,7 +32,7 @@ #include <fcntl.h> #if !defined(MSG_NOSIGNAL) - #define MSG_NOSIGNAL 0 + #define MSG_NOSIGNAL 0 #endif #include "credentials.h" @@ -42,9 +42,10 @@ namespace Botan_CLI { class TLS_Client final : public Command, public Botan::TLS::Callbacks { public: - TLS_Client() : Command("tls_client host --port=443 --print-certs --policy= " - "--tls1.0 --tls1.1 --tls1.2 " - "--session-db= --session-db-pass= --next-protocols= --type=tcp") {} + TLS_Client() + : Command("tls_client host --port=443 --print-certs --policy= " + "--tls1.0 --tls1.1 --tls1.2 " + "--session-db= --session-db-pass= --next-protocols= --type=tcp") {} void go() override { @@ -97,7 +98,9 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks const std::string next_protos = get_arg("next-protocols"); if(transport != "tcp" && transport != "udp") + { throw CLI_Usage_Error("Invalid transport type '" + transport + "' for TLS"); + } const bool use_tcp = (transport == "tcp"); @@ -121,20 +124,15 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks struct sockaddr_storage addrbuf; std::string hostname; if(!host.empty() && - inet_pton(AF_INET, host.c_str(), &addrbuf) != 1 && - inet_pton(AF_INET6, host.c_str(), &addrbuf) != 1) + inet_pton(AF_INET, host.c_str(), &addrbuf) != 1 && + inet_pton(AF_INET6, host.c_str(), &addrbuf) != 1) { hostname = host; } - Botan::TLS::Client client(*this, - *session_mgr, - creds, - *policy, - rng(), + Botan::TLS::Client client(*this, *session_mgr, creds, *policy, rng(), Botan::TLS::Server_Information(hostname, port), - version, - protocols_to_offer); + version, protocols_to_offer); bool first_active = true; @@ -151,7 +149,9 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks { std::string app = client.application_protocol(); if(app != "") + { output() << "Server choose protocol: " << client.application_protocol() << "\n"; + } first_active = false; } } @@ -162,7 +162,7 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks if(FD_ISSET(m_sockfd, &readfds)) { - uint8_t buf[4*1024] = { 0 }; + uint8_t buf[4 * 1024] = { 0 }; ssize_t got = ::read(m_sockfd, buf, sizeof(buf)); @@ -213,7 +213,9 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks } } else + { client.send(buf, got); + } } if(client.timeout_check()) @@ -231,7 +233,7 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks addrinfo hints = {}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = tcp ? SOCK_STREAM : SOCK_DGRAM; - addrinfo *res, *rp = nullptr; + addrinfo* res, *rp = nullptr; if(::getaddrinfo(host.c_str(), std::to_string(port).c_str(), &hints, &res) != 0) { @@ -277,22 +279,25 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks const Botan::TLS::Policy& policy) override { if(cert_chain.empty()) + { throw std::invalid_argument("Certificate chain was empty"); + } - Botan::Path_Validation_Restrictions restrictions(policy.require_cert_revocation_info(), - policy.minimum_signature_strength()); + Botan::Path_Validation_Restrictions restrictions( + policy.require_cert_revocation_info(), + policy.minimum_signature_strength()); auto ocsp_timeout = std::chrono::milliseconds(1000); - Botan::Path_Validation_Result result = - Botan::x509_path_validate(cert_chain, - restrictions, - trusted_roots, - hostname, - usage, - std::chrono::system_clock::now(), - ocsp_timeout, - ocsp); + Botan::Path_Validation_Result result = Botan::x509_path_validate( + cert_chain, + restrictions, + trusted_roots, + hostname, + usage, + std::chrono::system_clock::now(), + ocsp_timeout, + ocsp); std::cout << "Certificate validation status: " << result.result_string() << "\n"; if(result.successful_validation()) @@ -300,20 +305,26 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks auto status = result.all_statuses(); if(status.size() > 0 && status[0].count(Botan::Certificate_Status_Code::OCSP_RESPONSE_GOOD)) + { std::cout << "Valid OCSP response for this server\n"; + } } } bool tls_session_established(const Botan::TLS::Session& session) override { output() << "Handshake complete, " << session.version().to_string() - << " using " << session.ciphersuite().to_string() << "\n"; + << " using " << session.ciphersuite().to_string() << "\n"; if(!session.session_id().empty()) + { output() << "Session ID " << Botan::hex_encode(session.session_id()) << "\n"; + } if(!session.session_ticket().empty()) + { output() << "Session ticket " << Botan::hex_encode(session.session_ticket()) << "\n"; + } if(flag_set("print-certs")) { @@ -321,7 +332,7 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks for(size_t i = 0; i != certs.size(); ++i) { - output() << "Certificate " << i+1 << "/" << certs.size() << "\n"; + output() << "Certificate " << i + 1 << "/" << certs.size() << "\n"; output() << certs[i].to_string(); output() << certs[i].PEM_encode(); } @@ -335,7 +346,9 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks int r = send(sockfd, buf, length, MSG_NOSIGNAL); if(r == -1) + { throw CLI_Error("Socket write failed errno=" + std::to_string(errno)); + } } void tls_emit_data(const uint8_t buf[], size_t length) override @@ -349,9 +362,13 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks if(sent == -1) { if(errno == EINTR) + { sent = 0; + } else + { throw CLI_Error("Socket write failed errno=" + std::to_string(errno)); + } } offset += sent; @@ -367,11 +384,13 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks void tls_record_received(uint64_t /*seq_no*/, const uint8_t buf[], size_t buf_size) override { for(size_t i = 0; i != buf_size; ++i) + { output() << buf[i]; + } } - private: - int m_sockfd = -1; + private: + int m_sockfd = -1; }; BOTAN_REGISTER_COMMAND("tls_client", TLS_Client); diff --git a/src/cli/tls_proxy.cpp b/src/cli/tls_proxy.cpp index 5140654de..25ffabdb8 100644 --- a/src/cli/tls_proxy.cpp +++ b/src/cli/tls_proxy.cpp @@ -28,7 +28,7 @@ #include <botan/hex.h> #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) - #include <botan/tls_session_manager_sqlite.h> + #include <botan/tls_session_manager_sqlite.h> #endif #include "credentials.h" @@ -67,28 +67,31 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio typedef boost::shared_ptr<tls_proxy_session> pointer; - static pointer create(boost::asio::io_service& io, - Botan::TLS::Session_Manager& session_manager, - Botan::Credentials_Manager& credentials, - Botan::TLS::Policy& policy, - tcp::resolver::iterator endpoints) + static pointer create( + boost::asio::io_service& io, + Botan::TLS::Session_Manager& session_manager, + Botan::Credentials_Manager& credentials, + Botan::TLS::Policy& policy, + tcp::resolver::iterator endpoints) { return pointer( - new tls_proxy_session( - io, - session_manager, - credentials, - policy, - endpoints) - ); + new tls_proxy_session( + io, + session_manager, + credentials, + policy, + endpoints) + ); } - tcp::socket& client_socket() { return m_client_socket; } + tcp::socket& client_socket() + { + return m_client_socket; + } void start() { m_c2p.resize(readbuf_size); - client_read(boost::system::error_code(), 0); // start read loop } @@ -103,22 +106,21 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio } private: - tls_proxy_session(boost::asio::io_service& io, - Botan::TLS::Session_Manager& session_manager, - Botan::Credentials_Manager& credentials, - Botan::TLS::Policy& policy, - tcp::resolver::iterator endpoints) : - m_strand(io), - m_server_endpoints(endpoints), - m_client_socket(io), - m_server_socket(io), - m_tls(*this, - session_manager, - credentials, - policy, - m_rng) - { - } + tls_proxy_session( + boost::asio::io_service& io, + Botan::TLS::Session_Manager& session_manager, + Botan::Credentials_Manager& credentials, + Botan::TLS::Policy& policy, + tcp::resolver::iterator endpoints) + : m_strand(io) + , m_server_endpoints(endpoints) + , m_client_socket(io) + , m_server_socket(io) + , m_tls(*this, + session_manager, + credentials, + policy, + m_rng) {} void client_read(const boost::system::error_code& error, size_t bytes_transferred) @@ -133,7 +135,9 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio try { if(!m_tls.is_active()) + { log_binary_message("From client", &m_c2p[0], bytes_transferred); + } m_tls.received_data(&m_c2p[0], bytes_transferred); } catch(Botan::Exception& e) @@ -145,9 +149,11 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio m_client_socket.async_read_some( boost::asio::buffer(&m_c2p[0], m_c2p.size()), - m_strand.wrap(boost::bind(&tls_proxy_session::client_read, shared_from_this(), - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred))); + m_strand.wrap( + boost::bind( + &tls_proxy_session::client_read, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); } void handle_client_write_completion(const boost::system::error_code& error) @@ -190,7 +196,9 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio void tls_emit_data(const uint8_t buf[], size_t buf_len) override { if(buf_len > 0) + { m_p2c_pending.insert(m_p2c_pending.end(), buf, buf + buf_len); + } // no write now active and we still have output pending if(m_p2c.empty() && !m_p2c_pending.empty()) @@ -202,17 +210,20 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio boost::asio::async_write( m_client_socket, boost::asio::buffer(&m_p2c[0], m_p2c.size()), - m_strand.wrap(boost::bind( - &tls_proxy_session::handle_client_write_completion, - shared_from_this(), - boost::asio::placeholders::error))); + m_strand.wrap( + boost::bind( + &tls_proxy_session::handle_client_write_completion, + shared_from_this(), + boost::asio::placeholders::error))); } } void proxy_write_to_server(const uint8_t buf[], size_t buf_len) { if(buf_len > 0) + { m_p2s_pending.insert(m_p2s_pending.end(), buf, buf + buf_len); + } // no write now active and we still have output pending if(m_p2s.empty() && !m_p2s_pending.empty()) @@ -224,10 +235,11 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio boost::asio::async_write( m_server_socket, boost::asio::buffer(&m_p2s[0], m_p2s.size()), - m_strand.wrap(boost::bind( - &tls_proxy_session::handle_server_write_completion, - shared_from_this(), - boost::asio::placeholders::error))); + m_strand.wrap( + boost::bind( + &tls_proxy_session::handle_server_write_completion, + shared_from_this(), + boost::asio::placeholders::error))); } } @@ -261,9 +273,10 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio m_server_socket.async_read_some( boost::asio::buffer(&m_s2p[0], m_s2p.size()), - m_strand.wrap(boost::bind(&tls_proxy_session::server_read, shared_from_this(), - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred))); + m_strand.wrap( + boost::bind(&tls_proxy_session::server_read, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); } bool tls_session_established(const Botan::TLS::Session& session) override @@ -273,20 +286,21 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio m_hostname = session.server_info().hostname(); if(m_hostname != "") + { std::cout << "Client requested hostname '" << m_hostname << "'" << std::endl; + } - async_connect(m_server_socket, m_server_endpoints, - [this](boost::system::error_code ec, tcp::resolver::iterator endpoint) - { - if(ec) - { - log_error("Server connection", ec); - return; - } - - server_read(boost::system::error_code(), 0); // start read loop - proxy_write_to_server(nullptr, 0); - }); + auto onConnect = [this](boost::system::error_code ec, tcp::resolver::iterator endpoint) + { + if(ec) + { + log_error("Server connection", ec); + return; + } + server_read(boost::system::error_code(), 0); // start read loop + proxy_write_to_server(nullptr, 0); + }; + async_connect(m_server_socket, m_server_endpoints, onConnect); return true; } @@ -298,7 +312,9 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio return; } else + { std::cout << "Alert " << alert.type_string() << std::endl; + } } boost::asio::io_service::strand m_strand; @@ -326,16 +342,17 @@ class tls_proxy_server public: typedef tls_proxy_session session; - tls_proxy_server(boost::asio::io_service& io, unsigned short port, - tcp::resolver::iterator endpoints, - Botan::Credentials_Manager& creds, - Botan::TLS::Policy& policy, - Botan::TLS::Session_Manager& session_mgr) : - m_acceptor(io, tcp::endpoint(tcp::v4(), port)), - m_server_endpoints(endpoints), - m_creds(creds), - m_policy(policy), - m_session_manager(session_mgr) + tls_proxy_server( + boost::asio::io_service& io, unsigned short port, + tcp::resolver::iterator endpoints, + Botan::Credentials_Manager& creds, + Botan::TLS::Policy& policy, + Botan::TLS::Session_Manager& session_mgr) + : m_acceptor(io, tcp::endpoint(tcp::v4(), port)) + , m_server_endpoints(endpoints) + , m_creds(creds) + , m_policy(policy) + , m_session_manager(session_mgr) { session::pointer new_session = make_session(); @@ -345,29 +362,26 @@ class tls_proxy_server &tls_proxy_server::handle_accept, this, new_session, - boost::asio::placeholders::error) - ); + boost::asio::placeholders::error)); } private: session::pointer make_session() { return session::create( - m_acceptor.get_io_service(), - m_session_manager, - m_creds, - m_policy, - m_server_endpoints - ); + m_acceptor.get_io_service(), + m_session_manager, + m_creds, + m_policy, + m_server_endpoints); } void handle_accept(session::pointer new_session, const boost::system::error_code& error) { - if (!error) + if(!error) { new_session->start(); - new_session = make_session(); m_acceptor.async_accept( @@ -376,8 +390,7 @@ class tls_proxy_server &tls_proxy_server::handle_accept, this, new_session, - boost::asio::placeholders::error) - ); + boost::asio::placeholders::error)); } } @@ -395,7 +408,7 @@ class TLS_Proxy final : public Command { public: TLS_Proxy() : Command("tls_proxy listen_port target_host target_port server_cert server_key " - "--threads=0 --session-db= --session-db-pass=") {} + "--threads=0 --session-db= --session-db-pass=") {} void go() override { @@ -439,12 +452,16 @@ class TLS_Proxy final : public Command // run forever... first thread is main calling io.run below for(size_t i = 2; i <= num_threads; ++i) + { threads.push_back(std::make_shared<std::thread>([&io]() { io.run(); })); + } io.run(); - for (size_t i = 0; i < threads.size(); ++i) + for(size_t i = 0; i < threads.size(); ++i) + { threads[i]->join(); + } } }; diff --git a/src/cli/tls_server.cpp b/src/cli/tls_server.cpp index b1a5b0ec6..41e131dce 100644 --- a/src/cli/tls_server.cpp +++ b/src/cli/tls_server.cpp @@ -25,7 +25,7 @@ #include <fcntl.h> #if !defined(MSG_NOSIGNAL) - #define MSG_NOSIGNAL 0 + #define MSG_NOSIGNAL 0 #endif namespace Botan_CLI { @@ -43,7 +43,9 @@ class TLS_Server final : public Command const std::string transport = get_arg("type"); if(transport != "tcp" && transport != "udp") + { throw CLI_Usage_Error("Invalid transport type '" + transport + "' for TLS"); + } const bool is_tcp = (transport == "tcp"); @@ -70,11 +72,14 @@ class TLS_Server final : public Command Basic_Credentials_Manager creds(rng(), server_crt, server_key); - auto protocol_chooser = [](const std::vector<std::string>& protocols) -> std::string { + auto protocol_chooser = [](const std::vector<std::string>& protocols) -> std::string + { for(size_t i = 0; i != protocols.size(); ++i) + { std::cout << "Client offered protocol " << i << " = " << protocols[i] << std::endl; + } return "echo/1.0"; // too bad - }; + }; output() << "Listening for new connections on " << transport << " port " << port << std::endl; @@ -85,62 +90,67 @@ class TLS_Server final : public Command int fd; if(is_tcp) + { fd = ::accept(server_fd, nullptr, nullptr); + } else { struct sockaddr_in from; socklen_t from_len = sizeof(sockaddr_in); - if(::recvfrom(server_fd, nullptr, 0, MSG_PEEK, - reinterpret_cast<struct sockaddr*>(&from), &from_len) != 0) + if(::recvfrom(server_fd, nullptr, 0, MSG_PEEK, reinterpret_cast<struct sockaddr*>(&from), &from_len) != 0) + { throw CLI_Error("Could not peek next packet"); + } if(::connect(server_fd, reinterpret_cast<struct sockaddr*>(&from), from_len) != 0) + { throw CLI_Error("Could not connect UDP socket"); - + } fd = server_fd; } using namespace std::placeholders; auto socket_write = is_tcp ? std::bind(&stream_socket_write, fd, _1, _2) : - std::bind(&dgram_socket_write, fd, _1, _2); + std::bind(&dgram_socket_write, fd, _1, _2); std::string s; std::list<std::string> pending_output; auto proc_fn = [&](const uint8_t input[], size_t input_len) { - for(size_t i = 0; i != input_len; ++i) + for(size_t i = 0; i != input_len; ++i) + { + const char c = static_cast<char>(input[i]); + s += c; + if(c == '\n') { - const char c = static_cast<char>(input[i]); - s += c; - if(c == '\n') - { - pending_output.push_back(s); - s.clear(); - } + pending_output.push_back(s); + s.clear(); } + } }; - Botan::TLS::Server server(socket_write, - proc_fn, - std::bind(&TLS_Server::alert_received, this, _1, _2, _3), - std::bind(&TLS_Server::handshake_complete, this, _1), - session_manager, - creds, - *policy, - rng(), - protocol_chooser, - !is_tcp); + Botan::TLS::Server server( + socket_write, + proc_fn, + std::bind(&TLS_Server::alert_received, this, _1, _2, _3), + std::bind(&TLS_Server::handshake_complete, this, _1), + session_manager, + creds, + *policy, + rng(), + protocol_chooser, + !is_tcp); try { while(!server.is_closed()) { - try + try { - uint8_t buf[4*1024] = { 0 }; + uint8_t buf[4 * 1024] = { 0 }; ssize_t got = ::read(fd, buf, sizeof(buf)); if(got == -1) @@ -164,10 +174,12 @@ class TLS_Server final : public Command server.send(output); if(output == "quit\n") + { server.close(); + } } } - catch(std::exception& e) + catch(std::exception& e) { std::cout << "Connection1 problem: " << e.what() << std::endl; if(is_tcp) @@ -183,7 +195,9 @@ class TLS_Server final : public Command } if(is_tcp) + { ::close(fd); + } } } private: @@ -193,7 +207,9 @@ class TLS_Server final : public Command int fd = ::socket(PF_INET, type, 0); if(fd == -1) + { throw CLI_Error("Unable to acquire socket"); + } sockaddr_in socket_info; ::memset(&socket_info, 0, sizeof(socket_info)); @@ -217,7 +233,6 @@ class TLS_Server final : public Command throw CLI_Error("listen failed"); } } - return fd; } @@ -227,10 +242,14 @@ class TLS_Server final : public Command << " using " << session.ciphersuite().to_string() << std::endl; if(!session.session_id().empty()) + { std::cout << "Session ID " << Botan::hex_encode(session.session_id()) << std::endl; + } if(!session.session_ticket().empty()) + { std::cout << "Session ticket " << Botan::hex_encode(session.session_ticket()) << std::endl; + } return true; } @@ -240,9 +259,13 @@ class TLS_Server final : public Command ssize_t sent = ::send(sockfd, buf, length, MSG_NOSIGNAL); if(sent == -1) + { std::cout << "Error writing to socket - " << strerror(errno) << std::endl; + } else if(sent != static_cast<ssize_t>(length)) + { std::cout << "Packet of length " << length << " truncated to " << sent << std::endl; + } } static void stream_socket_write(int sockfd, const uint8_t buf[], size_t length) @@ -254,9 +277,13 @@ class TLS_Server final : public Command if(sent == -1) { if(errno == EINTR) + { sent = 0; + } else + { throw CLI_Error("Socket write failed"); + } } buf += sent; diff --git a/src/cli/tls_utils.cpp b/src/cli/tls_utils.cpp index ef590ff3f..b24af1656 100644 --- a/src/cli/tls_utils.cpp +++ b/src/cli/tls_utils.cpp @@ -18,7 +18,8 @@ class TLS_All_Policy : public Botan::TLS::Policy public: std::vector<std::string> allowed_ciphers() const override { - return std::vector<std::string>{ + return std::vector<std::string> + { "ChaCha20Poly1305", "AES-256/OCB(12)", "AES-128/OCB(12)", @@ -41,8 +42,7 @@ class TLS_All_Policy : public Botan::TLS::Policy std::vector<std::string> allowed_key_exchange_methods() const override { - return { "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK", - "CECPQ1", "ECDH", "DH", "RSA" }; + return { "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK", "CECPQ1", "ECDH", "DH", "RSA" }; } std::vector<std::string> allowed_signature_methods() const override @@ -54,22 +54,35 @@ class TLS_All_Policy : public Botan::TLS::Policy class TLS_Ciphersuites final : public Command { public: - TLS_Ciphersuites() : Command("tls_ciphers --policy=default --version=tls1.2") {} + TLS_Ciphersuites() + : Command("tls_ciphers --policy=default --version=tls1.2") {} static Botan::TLS::Protocol_Version::Version_Code tls_version_from_str(const std::string& str) { if(str == "tls1.2" || str == "TLS1.2" || str == "TLS-1.2") + { return Botan::TLS::Protocol_Version::TLS_V12; + } else if(str == "tls1.1" || str == "TLS1.1" || str == "TLS-1.1") + { return Botan::TLS::Protocol_Version::TLS_V11; + } else if(str == "tls1.0" || str == "TLS1.1" || str == "TLS-1.1") + { return Botan::TLS::Protocol_Version::TLS_V10; + } if(str == "dtls1.2" || str == "DTLS1.2" || str == "DTLS-1.2") + { return Botan::TLS::Protocol_Version::DTLS_V12; + } else if(str == "dtls1.0" || str == "DTLS1.0" || str == "DTLS-1.0") + { return Botan::TLS::Protocol_Version::DTLS_V10; + } else + { throw CLI_Error("Unknown TLS version '" + str + "'"); + } } void go() override @@ -101,8 +114,7 @@ class TLS_Ciphersuites final : public Command std::ifstream policy_file(policy_type); if(!policy_file.good()) { - throw CLI_Error("Error TLS policy '" + policy_type + - "' is neither a file nor a known policy type"); + throw CLI_Error("Error TLS policy '" + policy_type + "' is neither a file nor a known policy type"); } policy.reset(new Botan::TLS::Text_Policy(policy_file)); diff --git a/src/cli/utils.cpp b/src/cli/utils.cpp index d561f4cdf..65923ec47 100644 --- a/src/cli/utils.cpp +++ b/src/cli/utils.cpp @@ -14,31 +14,31 @@ #include <botan/entropy_src.h> #if defined(BOTAN_HAS_BASE64_CODEC) - #include <botan/base64.h> + #include <botan/base64.h> #endif #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> + #include <botan/system_rng.h> #endif #if defined(BOTAN_HAS_RDRAND_RNG) - #include <botan/rdrand_rng.h> + #include <botan/rdrand_rng.h> #endif #if defined(BOTAN_HAS_HTTP_UTIL) - #include <botan/http_util.h> + #include <botan/http_util.h> #endif #if defined(BOTAN_HAS_BCRYPT) - #include <botan/bcrypt.h> + #include <botan/bcrypt.h> #endif #if defined(BOTAN_HAS_HMAC) - #include <botan/hmac.h> + #include <botan/hmac.h> #endif namespace Botan_CLI { @@ -133,13 +133,17 @@ class Hash final : public Command std::unique_ptr<Botan::HashFunction> hash_fn(Botan::HashFunction::create(hash_algo)); if(!hash_fn) + { throw CLI_Error_Unsupported("hashing", hash_algo); + } const size_t buf_size = get_arg_sz("buf-size"); std::vector<std::string> files = get_arg_list("files"); if(files.empty()) - files.push_back("-"); // read stdin if no arguments on command line + { + files.push_back("-"); + } // read stdin if no arguments on command line for(const std::string& fsname : files) { @@ -277,9 +281,11 @@ class Base64_Encode final : public Command void go() override { - this->read_file(get_arg("file"), - [&](const uint8_t b[], size_t l) { output() << Botan::base64_encode(b, l); }, - 768); + auto onData = [&](const uint8_t b[], size_t l) + { + output() << Botan::base64_encode(b, l); + }; + this->read_file(get_arg("file"), onData, 768); } }; @@ -298,9 +304,7 @@ class Base64_Decode final : public Command output().write(reinterpret_cast<const char*>(bin.data()), bin.size()); }; - this->read_file(get_arg("file"), - write_bin, - 1024); + this->read_file(get_arg("file"), write_bin, 1024); } }; @@ -361,10 +365,11 @@ class HMAC final : public Command void go() override { const std::string hash_algo = get_arg("hash"); - std::unique_ptr<Botan::MessageAuthenticationCode> hmac(Botan::MessageAuthenticationCode::create("HMAC(" + hash_algo + ")")); + std::unique_ptr<Botan::MessageAuthenticationCode> hmac(Botan::MessageAuthenticationCode::create("HMAC(" + hash_algo + + ")")); if(!hmac) - throw CLI_Error_Unsupported("HMAC", hash_algo); + { throw CLI_Error_Unsupported("HMAC", hash_algo); } hmac->set_key(slurp_file(get_arg("key"))); @@ -372,7 +377,7 @@ class HMAC final : public Command std::vector<std::string> files = get_arg_list("files"); if(files.empty()) - files.push_back("-"); // read stdin if no arguments on command line + { files.push_back("-"); } // read stdin if no arguments on command line for(const std::string& fsname : files) { diff --git a/src/cli/x509.cpp b/src/cli/x509.cpp index c1c5f6955..e2163b987 100644 --- a/src/cli/x509.cpp +++ b/src/cli/x509.cpp @@ -16,7 +16,7 @@ #include <botan/x509self.h> #if defined(BOTAN_HAS_OCSP) - #include <botan/ocsp.h> + #include <botan/ocsp.h> #endif namespace Botan_CLI { @@ -24,8 +24,9 @@ namespace Botan_CLI { class Sign_Cert final : public Command { public: - Sign_Cert() : Command("sign_cert --ca-key-pass= --hash=SHA-256 " - "--duration=365 ca_cert ca_key pkcs10_req") {} + Sign_Cert() + : Command("sign_cert --ca-key-pass= --hash=SHA-256 " + "--duration=365 ca_cert ca_key pkcs10_req") {} void go() override { @@ -34,18 +35,17 @@ class Sign_Cert final : public Command if(flag_set("ca_key_pass")) { - key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), - rng(), - get_arg("ca_key_pass"))); + key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng(), get_arg("ca_key_pass"))); } else { - key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), - rng())); + key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng())); } if(!key) + { throw CLI_Error("Failed to load key from " + get_arg("ca_key")); + } Botan::X509_CA ca(ca_cert, *key, get_arg("hash"), rng()); @@ -59,8 +59,7 @@ class Sign_Cert final : public Command Botan::X509_Time end_time(now + days(get_arg_sz("duration"))); - Botan::X509_Certificate new_cert = ca.sign_request(req, rng(), - start_time, end_time); + Botan::X509_Certificate new_cert = ca.sign_request(req, rng(), start_time, end_time); output() << new_cert.PEM_encode(); } @@ -96,7 +95,9 @@ class Cert_Info final : public Command catch(Botan::Exception& e) { if(!in.end_of_data()) + { output() << "X509_Certificate parsing failed " << e.what() << "\n"; + } } } } @@ -128,8 +129,7 @@ class OCSP_Check final : public Command } else { - output() << "OCSP check failed " << - Botan::Path_Validation_Result::status_string(status) << "\n"; + output() << "OCSP check failed " << Botan::Path_Validation_Result::status_string(status) << "\n"; } } }; @@ -148,7 +148,7 @@ class Cert_Verify final : public Command Botan::X509_Certificate subject_cert(get_arg("subject")); Botan::Certificate_Store_In_Memory trusted; - for(auto&& certfile : get_arg_list("ca_certs")) + for(auto const& certfile : get_arg_list("ca_certs")) { trusted.add_certificate(Botan::X509_Certificate(certfile)); } @@ -176,18 +176,18 @@ BOTAN_REGISTER_COMMAND("cert_verify", Cert_Verify); class Gen_Self_Signed final : public Command { public: - Gen_Self_Signed() : Command("gen_self_signed key CN --country= --dns= " - "--organization= --email= --key-pass= --ca --hash=SHA-256") {} + Gen_Self_Signed() + : Command("gen_self_signed key CN --country= --dns= " + "--organization= --email= --key-pass= --ca --hash=SHA-256") {} void go() override { - std::unique_ptr<Botan::Private_Key> key( - Botan::PKCS8::load_key(get_arg("key"), - rng(), - get_arg("key-pass"))); + std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass"))); if(!key) + { throw CLI_Error("Failed to load key from " + get_arg("key")); + } Botan::X509_Cert_Options opts; @@ -198,10 +198,11 @@ class Gen_Self_Signed final : public Command opts.dns = get_arg("dns"); if(flag_set("ca")) + { opts.CA_key(); + } - Botan::X509_Certificate cert = - Botan::X509::create_self_signed_cert(opts, *key, get_arg("hash"), rng()); + Botan::X509_Certificate cert = Botan::X509::create_self_signed_cert(opts, *key, get_arg("hash"), rng()); output() << cert.PEM_encode(); } @@ -212,18 +213,18 @@ BOTAN_REGISTER_COMMAND("gen_self_signed", Gen_Self_Signed); class Generate_PKCS10 final : public Command { public: - Generate_PKCS10() : Command("gen_pkcs10 key CN --country= --organization= " - "--email= --key-pass= --hash=SHA-256") {} + Generate_PKCS10() + : Command("gen_pkcs10 key CN --country= --organization= " + "--email= --key-pass= --hash=SHA-256") {} void go() override { - std::unique_ptr<Botan::Private_Key> key( - Botan::PKCS8::load_key(get_arg("key"), - rng(), - get_arg("key-pass"))); + std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass"))); if(!key) + { throw CLI_Error("Failed to load key from " + get_arg("key")); + } Botan::X509_Cert_Options opts; @@ -232,10 +233,7 @@ class Generate_PKCS10 final : public Command opts.organization = get_arg("organization"); opts.email = get_arg("email"); - Botan::PKCS10_Request req = - Botan::X509::create_cert_req(opts, *key, - get_arg("hash"), - rng()); + Botan::PKCS10_Request req = Botan::X509::create_cert_req(opts, *key, get_arg("hash"), rng()); output() << req.PEM_encode(); } diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 42b01be62..4d5f67e34 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -828,6 +828,11 @@ int botan_hash_output_length(botan_hash_t hash, size_t* out) return BOTAN_FFI_DO(Botan::HashFunction, hash, h, { *out = h.output_length(); }); } +int botan_hash_block_size(botan_hash_t hash, size_t* out) + { + return BOTAN_FFI_DO(Botan::HashFunction, hash, h, { *out = h.hash_block_size(); }); + } + int botan_hash_clear(botan_hash_t hash) { return BOTAN_FFI_DO(Botan::HashFunction, hash, h, { h.clear(); }); @@ -1213,8 +1218,7 @@ int botan_bcrypt_is_valid(const char* pass, const char* hash) try { #if defined(BOTAN_HAS_BCRYPT) - if(Botan::check_bcrypt(pass, hash)) - return 0; // success + return Botan::check_bcrypt(pass, hash) ? 0 : 1; #else return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index 8fb7ca832..5638810f9 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -233,6 +233,14 @@ BOTAN_DLL int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_ BOTAN_DLL int botan_hash_output_length(botan_hash_t hash, size_t* output_length); /** +* Writes the block size of the hash function to *block_size +* @param hash hash object +* @param output_length output buffer to hold the hash function output length +* @return 0 on success, a negative value on failure +*/ +BOTAN_DLL int botan_hash_block_size(botan_hash_t hash, size_t* block_size); + +/** * Send more input to the hash function * @param hash hash object * @param in input buffer diff --git a/src/lib/prov/openssl/openssl.h b/src/lib/prov/openssl/openssl.h index 3cd39113b..37e8f9d4b 100644 --- a/src/lib/prov/openssl/openssl.h +++ b/src/lib/prov/openssl/openssl.h @@ -27,6 +27,7 @@ class BlockCipher; class Cipher_Mode; class StreamCipher; class HashFunction; +class RandomNumberGenerator; enum Cipher_Dir : int; class OpenSSL_Error : public Exception @@ -67,6 +68,8 @@ std::unique_ptr<PK_Ops::Verification> make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params); std::unique_ptr<PK_Ops::Signature> make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params); +std::unique_ptr<RSA_PrivateKey> +make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits); #endif diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp index 22cd6eb96..8c25d00ef 100644 --- a/src/lib/prov/openssl/openssl_rsa.cpp +++ b/src/lib/prov/openssl/openssl_rsa.cpp @@ -1,6 +1,7 @@ /* * RSA operations provided by OpenSSL * (C) 2015 Jack Lloyd +* (C) 2017 Alexander Bluhm * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -10,6 +11,7 @@ #if defined(BOTAN_HAS_RSA) #include <botan/rsa.h> +#include <botan/rng.h> #include <botan/internal/pk_ops_impl.h> #include <botan/internal/ct_utils.h> @@ -19,6 +21,7 @@ #include <openssl/rsa.h> #include <openssl/x509.h> #include <openssl/err.h> +#include <openssl/rand.h> namespace Botan { @@ -247,6 +250,39 @@ make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params) return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params)); } +std::unique_ptr<RSA_PrivateKey> +make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits) + { + if (rsa_bits > INT_MAX) + throw Internal_Error("rsa_bits overflow"); + + secure_vector<uint8_t> seed(BOTAN_SYSTEM_RNG_POLL_REQUEST); + rng.randomize(seed.data(), seed.size()); + RAND_seed(seed.data(), seed.size()); + + std::unique_ptr<BIGNUM, std::function<void (BIGNUM*)>> bn(BN_new(), BN_free); + if(!bn) + throw OpenSSL_Error("BN_new"); + if(!BN_set_word(bn.get(), RSA_F4)) + throw OpenSSL_Error("BN_set_word"); + + std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free); + if(!rsa) + throw OpenSSL_Error("RSA_new"); + if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), NULL)) + throw OpenSSL_Error("RSA_generate_key_ex"); + + uint8_t* der = NULL; + int bytes = i2d_RSAPrivateKey(rsa.get(), &der); + if(bytes < 0) + throw OpenSSL_Error("i2d_RSAPrivateKey"); + + const secure_vector<uint8_t> keydata(der, der + bytes); + memset(der, 0, bytes); + free(der); + return std::unique_ptr<Botan::RSA_PrivateKey> + (new RSA_PrivateKey(AlgorithmIdentifier(), keydata)); + } } #endif // BOTAN_HAS_RSA diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp index 1e1fd739a..19d7361b4 100644 --- a/src/lib/pubkey/pk_algs.cpp +++ b/src/lib/pubkey/pk_algs.cpp @@ -56,6 +56,10 @@ #include <botan/xmss.h> #endif +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> +#endif + namespace Botan { std::unique_ptr<Public_Key> @@ -203,7 +207,8 @@ load_private_key(const AlgorithmIdentifier& alg_id, std::unique_ptr<Private_Key> create_private_key(const std::string& alg_name, RandomNumberGenerator& rng, - const std::string& params) + const std::string& params, + const std::string& provider) { /* * Default paramaters are chosen for work factor > 2**128 where possible @@ -218,6 +223,17 @@ create_private_key(const std::string& alg_name, if(alg_name == "RSA") { const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params)); +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + std::unique_ptr<Botan::Private_Key> pk; + if(pk = make_openssl_rsa_private_key(rng, rsa_bits)) + return pk; + + if(!provider.empty()) + return nullptr; + } +#endif return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits)); } #endif @@ -311,4 +327,22 @@ create_private_key(const std::string& alg_name, return std::unique_ptr<Private_Key>(); } +std::vector<std::string> +probe_provider_private_key(const std::string& alg_name, + const std::vector<std::string> possible) + { + std::vector<std::string> providers; + for(auto&& prov : possible) + { + if(prov == "base" || +#if defined(BOTAN_HAS_OPENSSL) + (prov == "openssl" && alg_name == "RSA") || +#endif + 0) + { + providers.push_back(prov); // available + } + } + return providers; + } } diff --git a/src/lib/pubkey/pk_algs.h b/src/lib/pubkey/pk_algs.h index 04248459b..5deded423 100644 --- a/src/lib/pubkey/pk_algs.h +++ b/src/lib/pubkey/pk_algs.h @@ -33,7 +33,12 @@ load_private_key(const AlgorithmIdentifier& alg_id, BOTAN_DLL std::unique_ptr<Private_Key> create_private_key(const std::string& algo_name, RandomNumberGenerator& rng, - const std::string& algo_params = ""); + const std::string& algo_params = "", + const std::string& provider = ""); + +BOTAN_DLL std::vector<std::string> +probe_provider_private_key(const std::string& algo_name, + const std::vector<std::string> possible); } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 19ddfb40f..bdd751e48 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -19,19 +19,19 @@ #include <botan/hash.h> #if defined(BOTAN_HAS_HMAC_DRBG) -#include <botan/hmac_drbg.h> + #include <botan/hmac_drbg.h> #endif #if defined(BOTAN_HAS_SYSTEM_RNG) -#include <botan/system_rng.h> + #include <botan/system_rng.h> #endif #if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_OPENSSL) - #include <botan/internal/openssl.h> + #include <botan/internal/openssl.h> #endif namespace { @@ -39,7 +39,9 @@ namespace { class Test_Runner : public Botan_CLI::Command { public: - Test_Runner() : Command("test --threads=0 --run-long-tests --run-online-tests --test-runs=1 --drbg-seed= --data-dir= --pkcs11-lib= --provider= --log-success *suites") {} + Test_Runner() + : Command("test --threads=0 --run-long-tests --run-online-tests --test-runs=1 --drbg-seed= --data-dir=" + " --pkcs11-lib= --provider= --log-success *suites") {} std::string help_text() const override { @@ -54,7 +56,7 @@ class Test_Runner : public Botan_CLI::Command size_t line_len = 0; - for(auto&& test : Botan_Tests::Test::registered_tests()) + for(auto const& test : Botan_Tests::Test::registered_tests()) { err << test << " "; line_len += test.size() + 1; @@ -96,7 +98,8 @@ class Test_Runner : public Botan_CLI::Command alphabetical order. */ req = {"block", "stream", "hash", "mac", "modes", "aead" - "kdf", "pbkdf", "hmac_drbg", "x931_rng", "util"}; + "kdf", "pbkdf", "hmac_drbg", "x931_rng", "util" + }; std::set<std::string> all_others = Botan_Tests::Test::registered_tests(); @@ -126,12 +129,13 @@ class Test_Runner : public Botan_CLI::Command else if(req.size() == 1 && req.at(0) == "pkcs11") { req = {"pkcs11-manage", "pkcs11-module", "pkcs11-slot", "pkcs11-session", "pkcs11-object", "pkcs11-rsa", - "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509"}; + "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509" + }; } else { std::set<std::string> all = Botan_Tests::Test::registered_tests(); - for(auto&& r : req) + for(auto const& r : req) { if(all.find(r) == all.end()) { @@ -144,7 +148,9 @@ class Test_Runner : public Botan_CLI::Command output() << "Starting tests"; if(threads > 1) + { output() << " threads:" << threads; + } if(!pkcs11_lib.empty()) { @@ -190,7 +196,9 @@ class Test_Runner : public Botan_CLI::Command #else if(drbg_seed != "") + { throw Botan_Tests::Test_Error("HMAC_DRBG disabled in build, cannot specify DRBG seed"); + } #if defined(BOTAN_HAS_SYSTEM_RNG) output() << " rng:system"; @@ -212,7 +220,9 @@ class Test_Runner : public Botan_CLI::Command // Throw so main returns an error if(failed) + { throw Botan_Tests::Test_Error("Test suite failure"); + } } } @@ -225,7 +235,7 @@ class Test_Runner : public Botan_CLI::Command std::ostringstream out; std::map<std::string, Botan_Tests::Test::Result> combined; - for(auto&& result : results) + for(auto const& result : results) { const std::string who = result.who(); auto i = combined.find(who); @@ -238,7 +248,7 @@ class Test_Runner : public Botan_CLI::Command i->second.merge(result); } - for(auto&& result : combined) + for(auto const& result : combined) { out << result.second.result_string(verbose()); tests_failed += result.second.tests_failed(); @@ -259,13 +269,14 @@ class Test_Runner : public Botan_CLI::Command if(threads <= 1) { - for(auto&& test_name : tests_to_run) + for(auto const& test_name : tests_to_run) { - try { + try + { out << test_name << ':' << std::endl; const auto results = Botan_Tests::Test::run_test(test_name, false); out << report_out(results, tests_failed, tests_ran) << std::flush; - } + } catch(std::exception& e) { out << "Test " << test_name << " failed with exception " << e.what() << std::flush; @@ -287,19 +298,21 @@ class Test_Runner : public Botan_CLI::Command typedef std::future<std::vector<Botan_Tests::Test::Result>> FutureResults; std::deque<FutureResults> fut_results; - for(auto&& test_name : tests_to_run) + for(auto const& test_name : tests_to_run) { - auto run_it = [test_name]() -> std::vector<Botan_Tests::Test::Result> { - try { + auto run_it = [test_name]() -> std::vector<Botan_Tests::Test::Result> + { + try + { return Botan_Tests::Test::run_test(test_name, false); - } + } catch(std::exception& e) { Botan_Tests::Test::Result r(test_name); r.test_failure("Exception thrown", e.what()); - return std::vector<Botan_Tests::Test::Result>{r}; + return std::vector<Botan_Tests::Test::Result> {r}; } - }; + }; fut_results.push_back(std::async(std::launch::async, run_it)); @@ -344,9 +357,7 @@ BOTAN_REGISTER_COMMAND("test", Test_Runner); int main(int argc, char* argv[]) { - std::cerr << Botan::runtime_version_check(BOTAN_VERSION_MAJOR, - BOTAN_VERSION_MINOR, - BOTAN_VERSION_PATCH); + std::cerr << Botan::runtime_version_check(BOTAN_VERSION_MAJOR, BOTAN_VERSION_MINOR, BOTAN_VERSION_PATCH); try { diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp index c804949bb..f4da3ca57 100644 --- a/src/tests/test_aead.cpp +++ b/src/tests/test_aead.cpp @@ -8,7 +8,7 @@ #include "tests.h" #if defined(BOTAN_HAS_AEAD_MODES) - #include <botan/aead.h> + #include <botan/aead.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp index 901cd8039..0dc07aabf 100644 --- a/src/tests/test_bigint.cpp +++ b/src/tests/test_bigint.cpp @@ -7,10 +7,10 @@ #include "tests.h" #if defined(BOTAN_HAS_NUMBERTHEORY) - #include <botan/bigint.h> - #include <botan/numthry.h> - #include <botan/reducer.h> - #include <cmath> + #include <botan/bigint.h> + #include <botan/numthry.h> + #include <botan/reducer.h> + #include <cmath> #endif namespace Botan_Tests { @@ -65,10 +65,11 @@ class BigInt_Unit_Tests : public Test } else { - try { + try + { a.to_u32bit(); result.test_failure("BigInt::to_u32bit roundtripped out of range value"); - } + } catch(std::exception&) { result.test_success("BigInt::to_u32bit rejected out of range"); @@ -86,11 +87,11 @@ class BigInt_Unit_Tests : public Test { Test::Result result("BigInt prime generation"); - result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 0); }); - result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 1); }); - result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 0); }); - result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 1, 1, 3); }); - result.test_throws("Invalid arg", []{ Botan::random_prime(Test::rng(), 2, 1, 0, 2); }); + result.test_throws("Invalid arg", []() { Botan::random_prime(Test::rng(), 0); }); + result.test_throws("Invalid arg", []() { Botan::random_prime(Test::rng(), 1); }); + result.test_throws("Invalid arg", []() { Botan::random_prime(Test::rng(), 2, 0); }); + result.test_throws("Invalid arg", []() { Botan::random_prime(Test::rng(), 2, 1, 1, 3); }); + result.test_throws("Invalid arg", []() { Botan::random_prime(Test::rng(), 2, 1, 0, 2); }); BigInt p = Botan::random_prime(Test::rng(), 2); result.confirm("Only two 2-bit primes", p == 2 || p == 3); @@ -122,7 +123,7 @@ class BigInt_Unit_Tests : public Test const BigInt safe_prime = Botan::random_safe_prime(Test::rng(), safe_prime_bits); result.test_eq("Safe prime size", safe_prime.bits(), safe_prime_bits); result.confirm("P is prime", Botan::is_prime(safe_prime, Test::rng())); - result.confirm("(P-1)/2 is prime", Botan::is_prime((safe_prime-1)/2, Test::rng())); + result.confirm("(P-1)/2 is prime", Botan::is_prime((safe_prime - 1) / 2, Test::rng())); return result; } @@ -151,7 +152,9 @@ class BigInt_Unit_Tests : public Test for(size_t range_max : max_ranges) { if(range_min >= range_max) + { continue; + } std::vector<size_t> counts(range_max - range_min); @@ -200,12 +203,12 @@ class BigInt_Unit_Tests : public Test Botan::secure_vector<uint8_t> encoded_n1_n2 = BigInt::encode_fixed_length_int_pair(n1, n2, 256); result.test_eq("encode_fixed_length_int_pair", encoded_n1_n2, expected); - for (size_t i = 0; i < 256 - n1.bytes(); ++i) + for(size_t i = 0; i < 256 - n1.bytes(); ++i) { - if ( encoded_n1[i] != 0 ) - { - result.test_failure("encode_1363", "no zero byte"); - } + if(encoded_n1[i] != 0) + { + result.test_failure("encode_1363", "no zero byte"); + } } return result; @@ -215,13 +218,14 @@ class BigInt_Unit_Tests : public Test { Test::Result result("BigInt IO operators"); - const std::map<std::string, Botan::BigInt> str_to_val = { - { "-13", -Botan::BigInt(13) }, - { "0", Botan::BigInt(0) }, - { "0x13", Botan::BigInt(0x13) }, - { "1", Botan::BigInt(1) }, - { "4294967297", Botan::BigInt(2147483648)*2 + 1 } - }; + const std::map<std::string, Botan::BigInt> str_to_val = + { + { "-13", -Botan::BigInt(13) }, + { "0", Botan::BigInt(0) }, + { "0x13", Botan::BigInt(0x13) }, + { "1", Botan::BigInt(1) }, + { "4294967297", Botan::BigInt(2147483648) * 2 + 1 } + }; for(auto vec : str_to_val) { @@ -243,8 +247,7 @@ class BigInt_Unit_Tests : public Test oss << std::hex << n; result.test_eq("output 33 hex", oss.str(), "21"); - result.test_throws("octal output not supported", - [&]{ oss << std::oct << n; }); + result.test_throws("octal output not supported", [&]() { oss << std::oct << n; }); return result; } @@ -411,7 +414,7 @@ class BigInt_Mod_Test : public Text_Based_Test // if b fits into a Botan::word test %= operator for words if(b.bytes() <= sizeof(Botan::word)) { - Botan::word b_word = b.word_at( 0 ); + Botan::word b_word = b.word_at(0); e = a; e %= b_word; result.test_eq("a %= b (as word)", e, c); @@ -528,7 +531,9 @@ class BigInt_IsPrime_Test : public Text_Based_Test Test::Result run_one_test(const std::string& header, const VarMap& vars) override { if(header != "Prime" && header != "NonPrime") + { throw Test_Error("Bad header for prime test " + header); + } const BigInt value = get_req_bn(vars, "X"); const bool is_prime = (header == "Prime"); @@ -560,7 +565,7 @@ class BigInt_Ressol_Test : public Text_Based_Test if(a_sqrt > 1) { - const Botan::BigInt a_sqrt2 = (a_sqrt*a_sqrt) % p; + const Botan::BigInt a_sqrt2 = (a_sqrt * a_sqrt) % p; result.test_eq("square correct", a_sqrt2, a); } @@ -628,7 +633,9 @@ class DSA_ParamGen_Test : public Text_Based_Test const std::vector<std::string> header_parts = Botan::split_on(header, ','); if(header_parts.size() != 2) + { throw Test_Error("Unexpected header '" + header + "' in DSA param gen test"); + } const size_t p_bits = Botan::to_u32bit(header_parts[1]); const size_t q_bits = Botan::to_u32bit(header_parts[0]); @@ -637,9 +644,12 @@ class DSA_ParamGen_Test : public Text_Based_Test // These tests are very slow so skip in normal runs if(p_bits > 1024 && Test::run_long_tests() == false) + { return result; + } - try { + try + { Botan::BigInt gen_P, gen_Q; if(Botan::generate_dsa_primes(Test::rng(), gen_P, gen_Q, p_bits, q_bits, seed, offset)) { @@ -650,7 +660,7 @@ class DSA_ParamGen_Test : public Text_Based_Test { result.test_failure("Seed did not generate a DSA parameter"); } - } + } catch(Botan::Lookup_Error&) { } diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp index 62f32c21c..7f4856374 100644 --- a/src/tests/test_block.cpp +++ b/src/tests/test_block.cpp @@ -35,7 +35,7 @@ class Block_Cipher_Tests : public Text_Based_Test return result; } - for(auto&& provider_ask : providers) + for(auto const& provider_ask : providers) { std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(algo, provider_ask)); diff --git a/src/tests/test_c25519.cpp b/src/tests/test_c25519.cpp index f5fab60f4..cb6c8a2d5 100644 --- a/src/tests/test_c25519.cpp +++ b/src/tests/test_c25519.cpp @@ -7,9 +7,9 @@ #include "tests.h" #if defined(BOTAN_HAS_CURVE_25519) - #include "test_pubkey.h" - #include <botan/curve25519.h> - #include <botan/pkcs8.h> + #include "test_pubkey.h" + #include <botan/curve25519.h> + #include <botan/pkcs8.h> #endif namespace Botan_Tests { @@ -20,9 +20,8 @@ class Curve25519_Sclarmult_Tests : public Text_Based_Test { public: Curve25519_Sclarmult_Tests() : Text_Based_Test( - "pubkey/c25519_scalar.vec", - "Secret,Basepoint,Out") - {} + "pubkey/c25519_scalar.vec", + "Secret,Basepoint,Out") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -111,8 +110,14 @@ class Curve25519_Roundtrip_Test : public Test class Curve25519_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "" }; } - std::string algo_name() const override { return "Curve25519"; } + std::vector<std::string> keygen_params() const override + { + return { "" }; + } + std::string algo_name() const override + { + return "Curve25519"; + } }; BOTAN_REGISTER_TEST("curve25519_scalar", Curve25519_Sclarmult_Tests); diff --git a/src/tests/test_certstor.cpp b/src/tests/test_certstor.cpp index abe4a4ed0..bbf23da6c 100644 --- a/src/tests/test_certstor.cpp +++ b/src/tests/test_certstor.cpp @@ -45,7 +45,9 @@ Test::Result test_certstor_sqlite3_insert_find_remove_test(const std::vector<Cer Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng); for(const auto& a : certsandkeys) + { store.insert_key(a.certificate, *a.private_key); + } for(const auto certandkey : certsandkeys) { @@ -124,7 +126,9 @@ Test::Result test_certstor_sqlite3_crl_test(const std::vector<CertificateAndKey> Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng); for(const auto& a : certsandkeys) + { store.insert_cert(a.certificate); + } store.revoke_cert(certsandkeys[0].certificate, Botan::CA_COMPROMISE); store.revoke_cert(certsandkeys[3].certificate, Botan::CA_COMPROMISE); @@ -179,7 +183,9 @@ Test::Result test_certstor_sqlite3_all_subjects_test(const std::vector<Certifica Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng); for(const auto& a : certsandkeys) + { store.insert_cert(a.certificate); + } const auto subjects = store.all_subjects(); @@ -219,7 +225,9 @@ Test::Result test_certstor_find_hash_subject(const std::vector<CertificateAndKey Botan::Certificate_Store_In_Memory store; for(const auto& a : certsandkeys) + { store.add_certificate(a.certificate); + } for(const auto certandkey : certsandkeys) { @@ -236,7 +244,7 @@ Test::Result test_certstor_find_hash_subject(const std::vector<CertificateAndKey result.test_eq("Got wrong certificate", hash, found->raw_subject_dn_sha256()); } - const auto found = store.find_cert_by_raw_subject_dn_sha256(std::vector<uint8_t>(32,0)); + const auto found = store.find_cert_by_raw_subject_dn_sha256(std::vector<uint8_t>(32, 0)); if(found) { result.test_failure("Certificate found for dummy hash"); diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp index ff3b03cbe..355ee0b2a 100644 --- a/src/tests/test_compression.cpp +++ b/src/tests/test_compression.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_COMPRESSION) - #include <botan/compression.h> + #include <botan/compression.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_cryptobox.cpp b/src/tests/test_cryptobox.cpp index ad9ecdd41..97ac69f65 100644 --- a/src/tests/test_cryptobox.cpp +++ b/src/tests/test_cryptobox.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_CRYPTO_BOX) - #include <botan/cryptobox.h> - #include <botan/hex.h> + #include <botan/cryptobox.h> + #include <botan/hex.h> #endif namespace Botan_Tests { @@ -29,8 +29,8 @@ class Cryptobox_Tests : public Test const std::string password = "secret"; std::string ciphertext = Botan::CryptoBox::encrypt(msg.data(), msg.size(), - password, - Test::rng()); + password, + Test::rng()); try { diff --git a/src/tests/test_dh.cpp b/src/tests/test_dh.cpp index 7377fa1e4..028a4d1cc 100644 --- a/src/tests/test_dh.cpp +++ b/src/tests/test_dh.cpp @@ -7,9 +7,9 @@ #include "tests.h" #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include "test_pubkey.h" - #include <botan/pubkey.h> - #include <botan/dh.h> + #include "test_pubkey.h" + #include <botan/pubkey.h> + #include <botan/dh.h> #endif namespace Botan_Tests { @@ -21,14 +21,17 @@ namespace { class Diffie_Hellman_KAT_Tests : public PK_Key_Agreement_Test { public: - Diffie_Hellman_KAT_Tests() : PK_Key_Agreement_Test( - "Diffie-Hellman", - "pubkey/dh.vec", - "P,G,X,Y,Msg,OutLen,K", - "Q,KDF") - {} - - std::string default_kdf(const VarMap&) const override { return "Raw"; } + Diffie_Hellman_KAT_Tests() + : PK_Key_Agreement_Test( + "Diffie-Hellman", + "pubkey/dh.vec", + "P,G,X,Y,Msg,OutLen,K", + "Q,KDF") {} + + std::string default_kdf(const VarMap&) const override + { + return "Raw"; + } std::unique_ptr<Botan::Private_Key> load_our_key(const std::string&, const VarMap& vars) override { @@ -114,7 +117,10 @@ class DH_Invalid_Key_Tests : public Text_Based_Test DH_Invalid_Key_Tests() : Text_Based_Test("pubkey/dh_invalid.vec", "P,Q,G,InvalidKey") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -135,8 +141,14 @@ class DH_Invalid_Key_Tests : public Text_Based_Test class Diffie_Hellman_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "modp/ietf/1024", "modp/ietf/2048" }; } - std::string algo_name() const override { return "DH"; } + std::vector<std::string> keygen_params() const override + { + return { "modp/ietf/1024", "modp/ietf/2048" }; + } + std::string algo_name() const override + { + return "DH"; + } }; BOTAN_REGISTER_TEST("dh_kat", Diffie_Hellman_KAT_Tests); diff --git a/src/tests/test_dl_group.cpp b/src/tests/test_dl_group.cpp index 9e3c09cb4..40615d840 100644 --- a/src/tests/test_dl_group.cpp +++ b/src/tests/test_dl_group.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_DL_GROUP) - #include <botan/dl_group.h> + #include <botan/dl_group.h> #endif namespace Botan_Tests { @@ -90,9 +90,9 @@ class DL_Group_Tests : public Test // From FIPS 186-3 test data const std::vector<uint8_t> seed = Botan::hex_decode("1F5DA0AF598EEADEE6E6665BF880E63D8B609BA2"); - result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 1024, 224); }); - result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 3072, 224); }); - result.test_throws("invalid params", [&] { Botan::DL_Group invalid(rng, seed, 2048, 256); }); + result.test_throws("invalid params", [&]() { Botan::DL_Group invalid(rng, seed, 1024, 224); }); + result.test_throws("invalid params", [&]() { Botan::DL_Group invalid(rng, seed, 3072, 224); }); + result.test_throws("invalid params", [&]() { Botan::DL_Group invalid(rng, seed, 2048, 256); }); Botan::DL_Group dsa_from_seed(rng, seed, 1024, 160); @@ -112,7 +112,8 @@ class DL_Group_Tests : public Test Test::Result test_dl_named(Botan::RandomNumberGenerator& rng) { - const std::vector<std::string> dl_named = { + const std::vector<std::string> dl_named = + { "modp/ietf/1024", "modp/ietf/1536", "modp/ietf/2048", @@ -132,7 +133,7 @@ class DL_Group_Tests : public Test "dsa/jce/1024", "dsa/botan/2048", "dsa/botan/3072", - }; + }; Test::Result result("DL_Group named"); result.start_timer(); diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp index 9f19724b1..515f7a319 100644 --- a/src/tests/test_dlies.cpp +++ b/src/tests/test_dlies.cpp @@ -8,10 +8,10 @@ #include "tests.h" #if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include "test_pubkey.h" - #include <botan/dlies.h> - #include <botan/dh.h> - #include <botan/pubkey.h> + #include "test_pubkey.h" + #include <botan/dlies.h> + #include <botan/dh.h> + #include <botan/pubkey.h> #endif namespace Botan_Tests { @@ -23,10 +23,10 @@ namespace { class DLIES_KAT_Tests : public Text_Based_Test { public: - DLIES_KAT_Tests() : Text_Based_Test( - "pubkey/dlies.vec", - "Kdf,Mac,MacKeyLen,IV,Group,X1,X2,Msg,Ciphertext") - {} + DLIES_KAT_Tests() + : Text_Based_Test( + "pubkey/dlies.vec", + "Kdf,Mac,MacKeyLen,IV,Group,X1,X2,Msg,Ciphertext") {} Test::Result run_one_test(const std::string& cipher_algo, const VarMap& vars) override { @@ -76,8 +76,10 @@ class DLIES_KAT_Tests : public Text_Based_Test Botan::DH_PrivateKey from(Test::rng(), domain, x1); Botan::DH_PrivateKey to(Test::rng(), domain, x2); - Botan::DLIES_Encryptor encryptor(from, Test::rng(), kdf->clone(), enc.release(), cipher_key_len, mac->clone(), mac_key_len); - Botan::DLIES_Decryptor decryptor(to, Test::rng(), kdf.release(), dec.release(), cipher_key_len, mac.release(), mac_key_len); + Botan::DLIES_Encryptor encryptor(from, Test::rng(), kdf->clone(), enc.release(), cipher_key_len, mac->clone(), + mac_key_len); + Botan::DLIES_Decryptor decryptor(to, Test::rng(), kdf.release(), dec.release(), cipher_key_len, mac.release(), + mac_key_len); if(!iv.empty()) { diff --git a/src/tests/test_dsa.cpp b/src/tests/test_dsa.cpp index 69680f477..b5ade8145 100644 --- a/src/tests/test_dsa.cpp +++ b/src/tests/test_dsa.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_DSA) - #include <botan/dsa.h> - #include "test_pubkey.h" + #include <botan/dsa.h> + #include "test_pubkey.h" #endif namespace Botan_Tests { @@ -21,18 +21,20 @@ class DSA_KAT_Tests : public PK_Signature_Generation_Test { public: DSA_KAT_Tests() : PK_Signature_Generation_Test( - "DSA", + "DSA", #if defined(BOTAN_HAS_RFC6979_GENERATOR) - "pubkey/dsa_rfc6979.vec", - "P,Q,G,X,Hash,Msg,Signature", + "pubkey/dsa_rfc6979.vec", + "P,Q,G,X,Hash,Msg,Signature", #else - "pubkey/dsa_prob.vec", - "P,Q,G,X,Hash,Msg,Nonce,Signature", + "pubkey/dsa_prob.vec", + "P,Q,G,X,Hash,Msg,Nonce,Signature", #endif - "") - {} + "") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -56,8 +58,14 @@ class DSA_KAT_Tests : public PK_Signature_Generation_Test class DSA_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "dsa/jce/1024", "dsa/botan/2048" }; } - std::string algo_name() const override { return "DSA"; } + std::vector<std::string> keygen_params() const override + { + return { "dsa/jce/1024", "dsa/botan/2048" }; + } + std::string algo_name() const override + { + return "DSA"; + } }; BOTAN_REGISTER_TEST("dsa_sign", DSA_KAT_Tests); diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp index b3ba2396a..9517be400 100644 --- a/src/tests/test_ecc_pointmul.cpp +++ b/src/tests/test_ecc_pointmul.cpp @@ -7,10 +7,10 @@ #include "tests.h" #if defined(BOTAN_HAS_ECDSA) - #include "test_pubkey.h" - #include <botan/pubkey.h> - #include <botan/ecdsa.h> - #include <botan/oids.h> + #include "test_pubkey.h" + #include <botan/pubkey.h> + #include <botan/ecdsa.h> + #include <botan/oids.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_ecdh.cpp b/src/tests/test_ecdh.cpp index 270e50db3..99c8665f2 100644 --- a/src/tests/test_ecdh.cpp +++ b/src/tests/test_ecdh.cpp @@ -7,9 +7,9 @@ #include "tests.h" #if defined(BOTAN_HAS_ECDH) - #include "test_pubkey.h" - #include <botan/pubkey.h> - #include <botan/ecdh.h> + #include "test_pubkey.h" + #include <botan/pubkey.h> + #include <botan/ecdh.h> #endif namespace Botan_Tests { @@ -21,17 +21,20 @@ namespace { class ECDH_KAT_Tests : public PK_Key_Agreement_Test { public: - ECDH_KAT_Tests() : PK_Key_Agreement_Test( - "ECDH", - "pubkey/ecdh.vec", - "Group,Secret,CounterKey,K", - "KDF") - {} + ECDH_KAT_Tests() + : PK_Key_Agreement_Test( + "ECDH", + "pubkey/ecdh.vec", + "Group,Secret,CounterKey,K", + "KDF") {} - std::string default_kdf(const VarMap&) const override { return "Raw"; } + std::string default_kdf(const VarMap&) const override + { + return "Raw"; + } std::unique_ptr<Botan::Private_Key> load_our_key(const std::string& group_id, - const VarMap& vars) override + const VarMap& vars) override { Botan::EC_Group group(group_id); const Botan::BigInt secret = get_req_bn(vars, "Secret"); @@ -53,7 +56,10 @@ class ECDH_Keygen_Tests : public PK_Key_Generation_Test return { "secp256r1", "secp384r1", "secp521r1", "brainpool256r1", "brainpool384r1", "brainpool512r1", "frp256v1" }; } - std::string algo_name() const override { return "ECDH"; } + std::string algo_name() const override + { + return "ECDH"; + } }; diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index 148abaacc..73c353b3c 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -10,9 +10,9 @@ #include "test_rng.h" #if defined(BOTAN_HAS_ECDSA) - #include "test_pubkey.h" - #include <botan/ecdsa.h> - #include <botan/oids.h> + #include "test_pubkey.h" + #include <botan/ecdsa.h> + #include <botan/oids.h> #endif namespace Botan_Tests { @@ -25,17 +25,19 @@ class ECDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test { public: ECDSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( - "ECDSA", + "ECDSA", #if defined(BOTAN_HAS_RFC6979_GENERATOR) - "pubkey/ecdsa_rfc6979.vec", - "Group,X,Hash,Msg,Signature") + "pubkey/ecdsa_rfc6979.vec", + "Group,X,Hash,Msg,Signature") {} #else - "pubkey/ecdsa_prob.vec", - "Group,X,Hash,Msg,Nonce,Signature") + "pubkey/ecdsa_prob.vec", + "Group,X,Hash,Msg,Nonce,Signature") {} #endif - {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -65,8 +67,14 @@ class ECDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test class ECDSA_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "secp256r1", "secp384r1", "secp521r1", "frp256v1" }; } - std::string algo_name() const override { return "ECDSA"; } + std::vector<std::string> keygen_params() const override + { + return { "secp256r1", "secp384r1", "secp521r1", "frp256v1" }; + } + std::string algo_name() const override + { + return "ECDSA"; + } }; class ECDSA_Invalid_Key_Tests : public Text_Based_Test @@ -75,7 +83,10 @@ class ECDSA_Invalid_Key_Tests : public Text_Based_Test ECDSA_Invalid_Key_Tests() : Text_Based_Test("pubkey/ecdsa_invalid.vec", "Group,InvalidKeyX,InvalidKeyY") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } Test::Result run_one_test(const std::string&, const VarMap& vars) override { diff --git a/src/tests/test_ecgdsa.cpp b/src/tests/test_ecgdsa.cpp index e59b4dff6..25e4be0e2 100644 --- a/src/tests/test_ecgdsa.cpp +++ b/src/tests/test_ecgdsa.cpp @@ -9,9 +9,9 @@ #include "test_rng.h" #if defined(BOTAN_HAS_ECGDSA) - #include "test_pubkey.h" - #include <botan/ecgdsa.h> - #include <botan/oids.h> + #include "test_pubkey.h" + #include <botan/ecgdsa.h> + #include <botan/oids.h> #endif namespace Botan_Tests { @@ -24,12 +24,14 @@ class ECGDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test { public: ECGDSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( - "ECGDSA", - "pubkey/ecgdsa.vec", - "Group,X,Hash,Msg,Nonce,Signature") - {} + "ECGDSA", + "pubkey/ecgdsa.vec", + "Group,X,Hash,Msg,Nonce,Signature") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -57,8 +59,14 @@ class ECGDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test class ECGDSA_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "secp256r1", "secp384r1", "secp521r1" }; } - std::string algo_name() const override { return "ECGDSA"; } + std::vector<std::string> keygen_params() const override + { + return { "secp256r1", "secp384r1", "secp521r1" }; + } + std::string algo_name() const override + { + return "ECGDSA"; + } }; BOTAN_REGISTER_TEST("ecgdsa_sign", ECGDSA_Signature_KAT_Tests); diff --git a/src/tests/test_ecies.cpp b/src/tests/test_ecies.cpp index cd68bec47..6b5f92b1e 100644 --- a/src/tests/test_ecies.cpp +++ b/src/tests/test_ecies.cpp @@ -106,8 +106,7 @@ class ECIES_ISO_Tests : public Text_Based_Test public: ECIES_ISO_Tests() : Text_Based_Test( "pubkey/ecies-18033.vec", - "format,p,a,b,mu,nu,gx,gy,hx,hy,x,r,C0,K") - {} + "format,p,a,b,mu,nu,gx,gy,hx,hy,x,r,C0,K") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -141,7 +140,7 @@ class ECIES_ISO_Tests : public Text_Based_Test const Botan::ECDH_PrivateKey eph_private_key(Test::rng(), domain, r); const Botan::PointGFp eph_public_key_point = eph_private_key.public_point(); const std::vector<uint8_t> eph_public_key_bin = Botan::unlock( - Botan::EC2OSP(eph_public_key_point, compression_type)); + Botan::EC2OSP(eph_public_key_point, compression_type)); result.test_eq("encoded (ephemeral) public key", eph_public_key_bin, c0); // test secret derivation: ISO 18033 test vectors use KDF1 from ISO 18033 @@ -173,11 +172,14 @@ class ECIES_ISO_Tests : public Text_Based_Test if(cofactor_mode + check_mode + old_cofactor_mode > 1) { - result.test_throws("throw on invalid ECIES_Flags", [&] + auto onThrow = [&]() { - Botan::ECIES_System_Params(eph_private_key.domain(), "KDF2(SHA-1)", "AES-256/CBC", - 32, "HMAC(SHA-1)", 20, gen_compression_type, flags); - }); + Botan::ECIES_System_Params( + eph_private_key.domain(), + "KDF2(SHA-1)", "AES-256/CBC", 32, "HMAC(SHA-1)", 20, + gen_compression_type, flags); + }; + result.test_throws("throw on invalid ECIES_Flags", onThrow); continue; } @@ -201,11 +203,11 @@ BOTAN_REGISTER_TEST("ecies_iso", ECIES_ISO_Tests); class ECIES_Tests : public Text_Based_Test { public: - ECIES_Tests() : Text_Based_Test( - "pubkey/ecies.vec", - "Curve,PrivateKey,OtherPrivateKey,Kdf,Dem,DemKeyLen,Iv,Mac,MacKeyLen,Format," - "CofactorMode,OldCofactorMode,CheckMode,SingleHashMode,Label,Plaintext,Ciphertext") - {} + ECIES_Tests() + : Text_Based_Test( + "pubkey/ecies.vec", + "Curve,PrivateKey,OtherPrivateKey,Kdf,Dem,DemKeyLen,Iv,Mac,MacKeyLen,Format," + "CofactorMode,OldCofactorMode,CheckMode,SingleHashMode,Label,Plaintext,Ciphertext") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -373,13 +375,13 @@ Test::Result test_system_params_short_ctor() // generated with botan const std::vector<uint8_t> ciphertext = Botan::hex_decode("0401519EAA0489FF9D51E98E4C22349463E2001CD06F8CE47D81D4007A" - "79ACF98E92C814686477CEA666EFC277DC84E15FC95E38AFF8E16D478A" - "44CD5C5F1517F8B1F300000591317F261C3D04A7207F01EAE3EC70F2360" - "0F82C53CC0B85BE7AC9F6CE79EF2AB416E5934D61BA9D346385D7545C57F" - "77C7EA7C58E18C70CBFB0A24AE1B9943EC5A8D0657522CCDF30BA95674D81" - "B397635D215178CD13BD9504AE957A9888F4128FFC0F0D3F1CEC646AEC8CE" - "3F2463D233B22A7A12B679F4C06501F584D4DEFF6D26592A8D873398BD892" - "B477B3468813C053DA43C4F3D49009F7A12D6EF7"); + "79ACF98E92C814686477CEA666EFC277DC84E15FC95E38AFF8E16D478A" + "44CD5C5F1517F8B1F300000591317F261C3D04A7207F01EAE3EC70F2360" + "0F82C53CC0B85BE7AC9F6CE79EF2AB416E5934D61BA9D346385D7545C57F" + "77C7EA7C58E18C70CBFB0A24AE1B9943EC5A8D0657522CCDF30BA95674D81" + "B397635D215178CD13BD9504AE957A9888F4128FFC0F0D3F1CEC646AEC8CE" + "3F2463D233B22A7A12B679F4C06501F584D4DEFF6D26592A8D873398BD892" + "B477B3468813C053DA43C4F3D49009F7A12D6EF7"); check_encrypt_decrypt(result, private_key, other_private_key, ecies_params, iv, label, plaintext, ciphertext); diff --git a/src/tests/test_eckcdsa.cpp b/src/tests/test_eckcdsa.cpp index 83db0364d..62adb8599 100644 --- a/src/tests/test_eckcdsa.cpp +++ b/src/tests/test_eckcdsa.cpp @@ -9,9 +9,9 @@ #include "test_rng.h" #if defined(BOTAN_HAS_ECKCDSA) - #include "test_pubkey.h" - #include <botan/eckcdsa.h> - #include <botan/oids.h> + #include "test_pubkey.h" + #include <botan/eckcdsa.h> + #include <botan/oids.h> #endif namespace Botan_Tests { @@ -23,13 +23,16 @@ namespace { class ECKCDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test { public: - ECKCDSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( - "ECKCDSA", - "pubkey/eckcdsa.vec", - "Group,X,Hash,Msg,Nonce,Signature") - {} + ECKCDSA_Signature_KAT_Tests() + : PK_Signature_Generation_Test( + "ECKCDSA", + "pubkey/eckcdsa.vec", + "Group,X,Hash,Msg,Nonce,Signature") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -57,8 +60,14 @@ class ECKCDSA_Signature_KAT_Tests : public PK_Signature_Generation_Test class ECKCDSA_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "secp256r1", "secp384r1", "secp521r1" }; } - std::string algo_name() const override { return "ECKCDSA"; } + std::vector<std::string> keygen_params() const override + { + return { "secp256r1", "secp384r1", "secp521r1" }; + } + std::string algo_name() const override + { + return "ECKCDSA"; + } }; BOTAN_REGISTER_TEST("eckcdsa_sign", ECKCDSA_Signature_KAT_Tests); diff --git a/src/tests/test_elg.cpp b/src/tests/test_elg.cpp index 8219b0490..9d024cb5a 100644 --- a/src/tests/test_elg.cpp +++ b/src/tests/test_elg.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_ELGAMAL) - #include <botan/elgamal.h> - #include "test_pubkey.h" + #include <botan/elgamal.h> + #include "test_pubkey.h" #endif namespace Botan_Tests { @@ -20,12 +20,12 @@ namespace { class ElGamal_KAT_Tests : public PK_Encryption_Decryption_Test { public: - ElGamal_KAT_Tests() : PK_Encryption_Decryption_Test( - "ElGamal", - "pubkey/elgamal.vec", - "P,G,X,Msg,Nonce,Ciphertext", - "Padding") - {} + ElGamal_KAT_Tests() + : PK_Encryption_Decryption_Test( + "ElGamal", + "pubkey/elgamal.vec", + "P,G,X,Msg,Nonce,Ciphertext", + "Padding") {} std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -43,8 +43,14 @@ class ElGamal_KAT_Tests : public PK_Encryption_Decryption_Test class ElGamal_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "modp/ietf/1024", "modp/ietf/2048" }; } - std::string algo_name() const override { return "ElGamal"; } + std::vector<std::string> keygen_params() const override + { + return { "modp/ietf/1024", "modp/ietf/2048" }; + } + std::string algo_name() const override + { + return "ElGamal"; + } }; BOTAN_REGISTER_TEST("elgamal_encrypt", ElGamal_KAT_Tests); diff --git a/src/tests/test_entropy.cpp b/src/tests/test_entropy.cpp index 0fc757612..232b30d7d 100644 --- a/src/tests/test_entropy.cpp +++ b/src/tests/test_entropy.cpp @@ -9,7 +9,7 @@ #include <botan/entropy_src.h> #if defined(BOTAN_HAS_COMPRESSION) - #include <botan/compression.h> + #include <botan/compression.h> #endif namespace Botan_Tests { @@ -27,7 +27,7 @@ class Entropy_Source_Tests : public Test std::vector<Test::Result> results; - for(auto&& src_name : src_names) + for(auto const& src_name : src_names) { Test::Result result("Entropy source " + src_name); @@ -104,7 +104,7 @@ class Entropy_Source_Tests : public Test size_t comp_diff = comp2_size - comp1_size; result.test_gte(comp_algo + " diff compressed entropy better than advertised", - comp_diff*8, bits2); + comp_diff * 8, bits2); } catch(std::exception& e) { diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index d5ddace04..966691b7f 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -9,8 +9,8 @@ #include <botan/version.h> #if defined(BOTAN_HAS_FFI) -#include <botan/hex.h> -#include <botan/ffi.h> + #include <botan/hex.h> + #include <botan/ffi.h> #endif namespace Botan_Tests { @@ -58,7 +58,7 @@ class FFI_Unit_Tests : public Test std::vector<uint8_t> outbuf; //char namebuf[32]; - outstr.resize(2*bin.size()); + outstr.resize(2 * bin.size()); TEST_FFI_OK(botan_hex_encode, (bin.data(), bin.size(), &outstr[0], 0)); result.test_eq("uppercase hex", outstr, "AADE01"); @@ -106,6 +106,11 @@ class FFI_Unit_Tests : public Test result.test_eq("hash name", std::string(namebuf), "SHA-256"); } */ + size_t block_size; + if (TEST_FFI_OK(botan_hash_block_size, (hash, &block_size))) + { + result.test_eq("hash block size", block_size, 64); + } size_t output_len; if(TEST_FFI_OK(botan_hash_output_length, (hash, &output_len))) @@ -241,14 +246,14 @@ class FFI_Unit_Tests : public Test size_t date_len = 0; TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_time_starts, (cert, nullptr, &date_len)); - std::string date(date_len-1, '0'); + std::string date(date_len - 1, '0'); TEST_FFI_OK(botan_x509_cert_get_time_starts, (cert, &date[0], &date_len)); result.test_eq("cert valid from", date, "070719152718Z"); date_len = 0; TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_time_expires, (cert, nullptr, &date_len)); - date.resize(date_len-1); + date.resize(date_len - 1); TEST_FFI_OK(botan_x509_cert_get_time_expires, (cert, &date[0], &date_len)); result.test_eq("cert valid until", date, "280119151800Z"); @@ -261,28 +266,35 @@ class FFI_Unit_Tests : public Test result.test_int_eq(serial[0], 1, "cert serial"); size_t fingerprint_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_fingerprint, (cert, "SHA-256", nullptr, &fingerprint_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_fingerprint, + (cert, "SHA-256", nullptr, &fingerprint_len)); std::vector<uint8_t> fingerprint(fingerprint_len); TEST_FFI_OK(botan_x509_cert_get_fingerprint, (cert, "SHA-256", fingerprint.data(), &fingerprint_len)); - result.test_eq("cert fingerprint", reinterpret_cast<const char*>(fingerprint.data()), "3B:6C:99:1C:D6:5A:51:FC:EB:17:E3:AA:F6:3C:1A:DA:14:1F:82:41:30:6F:64:EE:FF:63:F3:1F:D6:07:14:9F"); + result.test_eq("cert fingerprint", reinterpret_cast<const char*>(fingerprint.data()), + "3B:6C:99:1C:D6:5A:51:FC:EB:17:E3:AA:F6:3C:1A:DA:14:1F:82:41:30:6F:64:EE:FF:63:F3:1F:D6:07:14:9F"); size_t key_id_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_authority_key_id, (cert, nullptr, &key_id_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_authority_key_id, + (cert, nullptr, &key_id_len)); std::vector<uint8_t> key_id(key_id_len); TEST_FFI_OK(botan_x509_cert_get_authority_key_id, (cert, key_id.data(), &key_id_len)); - result.test_eq("cert authority key id", Botan::hex_encode(key_id.data(), key_id.size(), true), "0096452DE588F966C4CCDF161DD1F3F5341B71E7"); + result.test_eq("cert authority key id", Botan::hex_encode(key_id.data(), key_id.size(), true), + "0096452DE588F966C4CCDF161DD1F3F5341B71E7"); key_id_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_key_id, (cert, nullptr, &key_id_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_key_id, + (cert, nullptr, &key_id_len)); key_id.resize(key_id_len); TEST_FFI_OK(botan_x509_cert_get_subject_key_id, (cert, key_id.data(), &key_id_len)); - result.test_eq("cert subject key id", Botan::hex_encode(key_id.data(), key_id.size(), true), "0096452DE588F966C4CCDF161DD1F3F5341B71E7"); + result.test_eq("cert subject key id", Botan::hex_encode(key_id.data(), key_id.size(), true), + "0096452DE588F966C4CCDF161DD1F3F5341B71E7"); size_t pubkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_public_key_bits, (cert, nullptr, &pubkey_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_public_key_bits, + (cert, nullptr, &pubkey_len)); std::vector<uint8_t> pubkey(pubkey_len); TEST_FFI_OK(botan_x509_cert_get_public_key_bits, (cert, pubkey.data(), &pubkey_len)); @@ -294,23 +306,26 @@ class FFI_Unit_Tests : public Test } size_t dn_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_issuer_dn, (cert, "Name", 0, nullptr, &dn_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_issuer_dn, + (cert, "Name", 0, nullptr, &dn_len)); std::vector<uint8_t> dn(dn_len); TEST_FFI_OK(botan_x509_cert_get_issuer_dn, (cert, "Name", 0, dn.data(), &dn_len)); result.test_eq("issuer dn", reinterpret_cast<const char*>(dn.data()), "csca-germany"); dn_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_dn, (cert, "Name", 0, nullptr, &dn_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_get_subject_dn, + (cert, "Name", 0, nullptr, &dn_len)); dn.resize(dn_len); TEST_FFI_OK(botan_x509_cert_get_subject_dn, (cert, "Name", 0, dn.data(), &dn_len)); result.test_eq("subject dn", reinterpret_cast<const char*>(dn.data()), "csca-germany"); size_t printable_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_to_string, (cert, nullptr, &printable_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_x509_cert_to_string, + (cert, nullptr, &printable_len)); - std::string printable(printable_len-1, '0'); + std::string printable(printable_len - 1, '0'); TEST_FFI_OK(botan_x509_cert_to_string, (cert, &printable[0], &printable_len)); TEST_FFI_RC(0, botan_x509_cert_allowed_usage, (cert, KEY_CERT_SIGN)); @@ -373,10 +388,12 @@ class FFI_Unit_Tests : public Test result.test_int_eq(max_keylen, 16, "Max key length"); // from https://github.com/geertj/bluepass/blob/master/tests/vectors/aes-cbc-pkcs7.txt - const std::vector<uint8_t> plaintext = Botan::hex_decode("0397f4f6820b1f9386f14403be5ac16e50213bd473b4874b9bcbf5f318ee686b1d"); + const std::vector<uint8_t> plaintext = + Botan::hex_decode("0397f4f6820b1f9386f14403be5ac16e50213bd473b4874b9bcbf5f318ee686b1d"); const std::vector<uint8_t> symkey = Botan::hex_decode("898be9cc5004ed0fa6e117c9a3099d31"); const std::vector<uint8_t> nonce = Botan::hex_decode("9dea7621945988f96491083849b068df"); - const std::vector<uint8_t> exp_ciphertext = Botan::hex_decode("e232cd6ef50047801ee681ec30f61d53cfd6b0bca02fd03c1b234baa10ea82ac9dab8b960926433a19ce6dea08677e34"); + const std::vector<uint8_t> exp_ciphertext = + Botan::hex_decode("e232cd6ef50047801ee681ec30f61d53cfd6b0bca02fd03c1b234baa10ea82ac9dab8b960926433a19ce6dea08677e34"); std::vector<uint8_t> ciphertext(16 + plaintext.size()); // TODO: no way to know this size from API @@ -389,13 +406,14 @@ class FFI_Unit_Tests : public Test TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size())); TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size())); TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, 0, ciphertext.data(), ciphertext.size(), &output_written, - plaintext.data(), plaintext.size(), &input_consumed)); + plaintext.data(), plaintext.size(), &input_consumed)); TEST_FFI_OK(botan_cipher_clear, (cipher_encrypt)); TEST_FFI_OK(botan_cipher_set_key, (cipher_encrypt, symkey.data(), symkey.size())); TEST_FFI_OK(botan_cipher_start, (cipher_encrypt, nonce.data(), nonce.size())); - TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL, ciphertext.data(), ciphertext.size(), &output_written, - plaintext.data(), plaintext.size(), &input_consumed)); + TEST_FFI_OK(botan_cipher_update, (cipher_encrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL, + ciphertext.data(), ciphertext.size(), &output_written, + plaintext.data(), plaintext.size(), &input_consumed)); ciphertext.resize(output_written); result.test_eq("AES/CBC ciphertext", ciphertext, exp_ciphertext); @@ -406,8 +424,9 @@ class FFI_Unit_Tests : public Test TEST_FFI_OK(botan_cipher_set_key, (cipher_decrypt, symkey.data(), symkey.size())); TEST_FFI_OK(botan_cipher_start, (cipher_decrypt, nonce.data(), nonce.size())); - TEST_FFI_OK(botan_cipher_update, (cipher_decrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL, decrypted.data(), decrypted.size(), &output_written, - ciphertext.data(), ciphertext.size(), &input_consumed)); + TEST_FFI_OK(botan_cipher_update, (cipher_decrypt, BOTAN_CIPHER_UPDATE_FLAG_FINAL, + decrypted.data(), decrypted.size(), &output_written, + ciphertext.data(), ciphertext.size(), &input_consumed)); result.test_eq("AES/CBC plaintext", decrypted, plaintext); @@ -457,7 +476,7 @@ class FFI_Unit_Tests : public Test const std::vector<uint8_t> symkey = Botan::hex_decode("FEFFE9928665731C6D6A8F9467308308"); const std::vector<uint8_t> nonce = Botan::hex_decode("CAFEBABEFACEDBADDECAF888"); const std::vector<uint8_t> exp_ciphertext = Botan::hex_decode( - "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E0915BC94FBC3221A5DB94FAE95AE7121A47"); + "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E0915BC94FBC3221A5DB94FAE95AE7121A47"); const std::vector<uint8_t> aad = Botan::hex_decode("FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2"); std::vector<uint8_t> ciphertext(tag_len + plaintext.size()); @@ -520,9 +539,9 @@ class FFI_Unit_Tests : public Test const std::vector<uint8_t> key = Botan::hex_decode("2B7E151628AED2A6ABF7158809CF4F3C"); const std::vector<uint8_t> nonce = Botan::hex_decode("F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF"); const std::vector<uint8_t> pt = Botan::hex_decode( - "AE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"); + "AE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"); const std::vector<uint8_t> exp_ct = Botan::hex_decode( - "9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE"); + "9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE"); botan_cipher_t ctr; @@ -629,45 +648,45 @@ class FFI_Unit_Tests : public Test TEST_FFI_RC(0, botan_mp_is_zero, (x)); - { - botan_mp_t zero; - botan_mp_init(&zero); - int cmp; - TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero)); - result.confirm("bigint_mp_cmp(+, 0)", cmp == 1); + { + botan_mp_t zero; + botan_mp_init(&zero); + int cmp; + TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero)); + result.confirm("bigint_mp_cmp(+, 0)", cmp == 1); - TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x)); - result.confirm("bigint_mp_cmp(0, +)", cmp == -1); + TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x)); + result.confirm("bigint_mp_cmp(0, +)", cmp == -1); - TEST_FFI_RC(0, botan_mp_is_negative, (x)); - TEST_FFI_RC(1, botan_mp_is_positive, (x)); - TEST_FFI_OK(botan_mp_flip_sign, (x)); - TEST_FFI_RC(1, botan_mp_is_negative, (x)); - TEST_FFI_RC(0, botan_mp_is_positive, (x)); + TEST_FFI_RC(0, botan_mp_is_negative, (x)); + TEST_FFI_RC(1, botan_mp_is_positive, (x)); + TEST_FFI_OK(botan_mp_flip_sign, (x)); + TEST_FFI_RC(1, botan_mp_is_negative, (x)); + TEST_FFI_RC(0, botan_mp_is_positive, (x)); - // test no negative zero - TEST_FFI_RC(0, botan_mp_is_negative, (zero)); - TEST_FFI_RC(1, botan_mp_is_positive, (zero)); - TEST_FFI_OK(botan_mp_flip_sign, (zero)); - TEST_FFI_RC(0, botan_mp_is_negative, (zero)); - TEST_FFI_RC(1, botan_mp_is_positive, (zero)); + // test no negative zero + TEST_FFI_RC(0, botan_mp_is_negative, (zero)); + TEST_FFI_RC(1, botan_mp_is_positive, (zero)); + TEST_FFI_OK(botan_mp_flip_sign, (zero)); + TEST_FFI_RC(0, botan_mp_is_negative, (zero)); + TEST_FFI_RC(1, botan_mp_is_positive, (zero)); - TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero)); - result.confirm("bigint_mp_cmp(-, 0)", cmp == -1); + TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero)); + result.confirm("bigint_mp_cmp(-, 0)", cmp == -1); - TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x)); - result.confirm("bigint_mp_cmp(0, -)", cmp == 1); + TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x)); + result.confirm("bigint_mp_cmp(0, -)", cmp == 1); - TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, zero)); - result.confirm("bigint_mp_cmp(0, 0)", cmp == 0); + TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, zero)); + result.confirm("bigint_mp_cmp(0, 0)", cmp == 0); - TEST_FFI_OK(botan_mp_cmp, (&cmp, x, x)); - result.confirm("bigint_mp_cmp(x, x)", cmp == 0); + TEST_FFI_OK(botan_mp_cmp, (&cmp, x, x)); + result.confirm("bigint_mp_cmp(x, x)", cmp == 0); - TEST_FFI_OK(botan_mp_flip_sign, (x)); + TEST_FFI_OK(botan_mp_flip_sign, (x)); - botan_mp_destroy(zero); - } + botan_mp_destroy(zero); + } size_t x_bits = 0; TEST_FFI_OK(botan_mp_num_bits, (x, &x_bits)); @@ -786,7 +805,7 @@ class FFI_Unit_Tests : public Test size_t x_bytes; botan_mp_rand_bits(x, rng, 512); TEST_FFI_OK(botan_mp_num_bytes, (x, &x_bytes)); - result.test_lte("botan_mp_num_bytes", x_bytes, 512/8); + result.test_lte("botan_mp_num_bytes", x_bytes, 512 / 8); TEST_FFI_OK(botan_mp_set_from_radix_str, (x, "909A", 16)); TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32)); @@ -811,13 +830,15 @@ class FFI_Unit_Tests : public Test // export public key size_t pubkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export, (pub, nullptr, &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export, (pub, nullptr, &pubkey_len, + BOTAN_PRIVKEY_EXPORT_FLAG_DER)); std::vector<uint8_t> pubkey(pubkey_len); TEST_FFI_OK(botan_pubkey_export, (pub, pubkey.data(), &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER)); pubkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export, (pub, nullptr, &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_export, + (pub, nullptr, &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); pubkey.resize(pubkey_len); TEST_FFI_OK(botan_pubkey_export, (pub, pubkey.data(), &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); @@ -832,7 +853,8 @@ class FFI_Unit_Tests : public Test size_t privkey_len = 0; // call with nullptr to query the length - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export, (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export, + (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_DER)); privkey.resize(privkey_len); privkey_len = privkey.size(); // set buffer size @@ -846,25 +868,30 @@ class FFI_Unit_Tests : public Test // Now again for PEM privkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export, (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export, + (priv, nullptr, &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); privkey.resize(privkey_len); TEST_FFI_OK(botan_privkey_export, (priv, privkey.data(), &privkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); // export private key encrypted privkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr, &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr, + &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER)); privkey.resize(privkey_len); privkey_len = privkey.size(); - TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER)); + TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter, + "", "", BOTAN_PRIVKEY_EXPORT_FLAG_DER)); privkey_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr, &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_privkey_export_encrypted_pbkdf_iter, (priv, nullptr, + &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); privkey.resize(privkey_len); - TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter, "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); + TEST_FFI_OK(botan_privkey_export_encrypted_pbkdf_iter, (priv, privkey.data(), &privkey_len, rng, "password", pbkdf_iter, + "", "", BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); // calculate fingerprint size_t strength = 0; @@ -872,7 +899,8 @@ class FFI_Unit_Tests : public Test result.test_gte("estimated strength", strength, 1); size_t fingerprint_len = 0; - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_fingerprint, (pub, "SHA-512", nullptr, &fingerprint_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_pubkey_fingerprint, + (pub, "SHA-512", nullptr, &fingerprint_len)); std::vector<uint8_t> fingerprint(fingerprint_len); TEST_FFI_OK(botan_pubkey_fingerprint, (pub, "SHA-512", fingerprint.data(), &fingerprint_len)); @@ -908,18 +936,18 @@ class FFI_Unit_Tests : public Test TEST_FFI_OK(botan_privkey_rsa_get_n, (n, priv)); // Confirm same (e,n) values in public key - { - botan_mp_t pub_e, pub_n; - botan_mp_init(&pub_e); - botan_mp_init(&pub_n); - TEST_FFI_OK(botan_pubkey_rsa_get_e, (pub_e, pub)); - TEST_FFI_OK(botan_pubkey_rsa_get_n, (pub_n, pub)); - - TEST_FFI_RC(1, botan_mp_equal, (pub_e, e)); - TEST_FFI_RC(1, botan_mp_equal, (pub_n, n)); - botan_mp_destroy(pub_e); - botan_mp_destroy(pub_n); - } + { + botan_mp_t pub_e, pub_n; + botan_mp_init(&pub_e); + botan_mp_init(&pub_n); + TEST_FFI_OK(botan_pubkey_rsa_get_e, (pub_e, pub)); + TEST_FFI_OK(botan_pubkey_rsa_get_n, (pub_n, pub)); + + TEST_FFI_RC(1, botan_mp_equal, (pub_e, e)); + TEST_FFI_RC(1, botan_mp_equal, (pub_n, n)); + botan_mp_destroy(pub_e); + botan_mp_destroy(pub_n); + } TEST_FFI_RC(1, botan_mp_is_prime, (p, rng, 64)); TEST_FFI_RC(1, botan_mp_is_prime, (q, rng, 64)); @@ -1060,14 +1088,14 @@ class FFI_Unit_Tests : public Test botan_pk_op_sign_t signer; std::vector<uint8_t> message(6, 6); - std::vector<uint8_t> signature(20*2); + std::vector<uint8_t> signature(20 * 2); if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, "EMSA1(SHA-256)", 0))) { // TODO: break input into multiple calls to update TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size())); - signature.resize(20*2); // TODO: no way to derive this from API + signature.resize(20 * 2); // TODO: no way to derive this from API size_t sig_len = signature.size(); TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len)); signature.resize(sig_len); @@ -1250,7 +1278,7 @@ class FFI_Unit_Tests : public Test botan_privkey_t priv; #if defined(BOTAN_HAS_MCELIECE) - if (TEST_FFI_OK(botan_privkey_create_mceliece, (&priv, rng, 2048, 50))) + if(TEST_FFI_OK(botan_privkey_create_mceliece, (&priv, rng, 2048, 50))) { botan_pubkey_t pub; TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv)); @@ -1259,7 +1287,7 @@ class FFI_Unit_Tests : public Test char namebuf[32] = { 0 }; size_t name_len = sizeof(namebuf); - if (TEST_FFI_OK(botan_pubkey_algo_name, (pub, namebuf, &name_len))) + if(TEST_FFI_OK(botan_pubkey_algo_name, (pub, namebuf, &name_len))) { result.test_eq("algo name", std::string(namebuf), "McEliece"); } @@ -1274,16 +1302,19 @@ class FFI_Unit_Tests : public Test size_t ciphertext_len = 0; // first calculate ciphertext length - TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(), plaintext.size(), ad, ad_len, nullptr, &ciphertext_len)); + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(), + plaintext.size(), ad, ad_len, nullptr, &ciphertext_len)); std::vector<uint8_t> ciphertext(ciphertext_len); // now encrypt - if (TEST_FFI_OK(botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(), plaintext.size(), ad, ad_len, ciphertext.data(), &ciphertext_len))) + if(TEST_FFI_OK(botan_mceies_encrypt, (pub, rng, "AES-256/OCB", plaintext.data(), plaintext.size(), ad, ad_len, + ciphertext.data(), &ciphertext_len))) { std::vector<uint8_t> decrypted(plaintext.size()); size_t decrypted_len = plaintext_len; - TEST_FFI_OK(botan_mceies_decrypt, (priv, "AES-256/OCB", ciphertext.data(), ciphertext.size(), ad, ad_len, decrypted.data(), &decrypted_len)); + TEST_FFI_OK(botan_mceies_decrypt, (priv, "AES-256/OCB", ciphertext.data(), ciphertext.size(), ad, ad_len, + decrypted.data(), &decrypted_len)); result.test_eq("MCIES plaintext", decrypted, plaintext); } @@ -1323,7 +1354,7 @@ class FFI_Unit_Tests : public Test TEST_FFI_OK(botan_pubkey_get_field, (p, pub, "p")); TEST_FFI_OK(botan_pubkey_get_field, (g, pub, "g")); TEST_FFI_OK(botan_pubkey_get_field, (y, pub, "y")); - TEST_FFI_OK(botan_privkey_get_field,(x, priv,"x")); + TEST_FFI_OK(botan_privkey_get_field, (x, priv, "x")); size_t p_len = 0; TEST_FFI_OK(botan_mp_num_bytes, (p, &p_len)); @@ -1348,7 +1379,7 @@ class FFI_Unit_Tests : public Test // Test encryption botan_pk_op_encrypt_t op_enc; - size_t ct_len = ciphertext.size(); + size_t ct_len = ciphertext.size(); REQUIRE_FFI_OK(botan_pk_op_encrypt_create, (&op_enc, loaded_pubkey, "Raw", 0)); TEST_FFI_OK(botan_pk_op_encrypt, (op_enc, rng, ciphertext.data(), &ct_len, plaintext.data(), plaintext.size())); TEST_FFI_OK(botan_pk_op_encrypt_destroy, (op_enc)); diff --git a/src/tests/test_filters.cpp b/src/tests/test_filters.cpp index b9bd15ced..3c50d94ce 100644 --- a/src/tests/test_filters.cpp +++ b/src/tests/test_filters.cpp @@ -10,17 +10,17 @@ #include "tests.h" #if defined(BOTAN_HAS_FILTERS) - #include <botan/secqueue.h> - #include <botan/pipe.h> - #include <botan/filters.h> - #include <botan/data_snk.h> - #include <botan/comp_filter.h> - #include <botan/cipher_filter.h> + #include <botan/secqueue.h> + #include <botan/pipe.h> + #include <botan/filters.h> + #include <botan/data_snk.h> + #include <botan/comp_filter.h> + #include <botan/cipher_filter.h> #endif #if defined(BOTAN_HAS_CODEC_FILTERS) - #include <botan/hex_filt.h> - #include <botan/b64_filt.h> + #include <botan/hex_filt.h> + #include <botan/b64_filt.h> #endif namespace Botan_Tests { @@ -80,7 +80,7 @@ class Filter_Tests : public Test queue_a = queue_b; result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0); } - catch (std::exception& e) + catch(std::exception& e) { result.test_failure("SecureQueue", e.what()); } @@ -117,29 +117,29 @@ class Filter_Tests : public Test } Test::Result test_data_src_sink_flush() - { - Test::Result result("DataSinkFlush"); + { + Test::Result result("DataSinkFlush"); #if defined(BOTAN_HAS_CODEC_FILTERS) - std::string tmp_name("botan_test_data_src_sink_flush.tmp"); - std::ofstream outfile(tmp_name); + std::string tmp_name("botan_test_data_src_sink_flush.tmp"); + std::ofstream outfile(tmp_name); - Botan::Pipe pipe(new Botan::Hex_Decoder, new Botan::DataSink_Stream(outfile)); + Botan::Pipe pipe(new Botan::Hex_Decoder, new Botan::DataSink_Stream(outfile)); - Botan::DataSource_Memory input_mem("65666768"); - pipe.process_msg(input_mem); + Botan::DataSource_Memory input_mem("65666768"); + pipe.process_msg(input_mem); - std::ifstream outfile_read(tmp_name); - std::stringstream ss; - ss << outfile_read.rdbuf(); - std::string foo = ss.str(); + std::ifstream outfile_read(tmp_name); + std::stringstream ss; + ss << outfile_read.rdbuf(); + std::string foo = ss.str(); - result.test_eq("output string", ss.str(), "efgh"); + result.test_eq("output string", ss.str(), "efgh"); - std::remove(tmp_name.c_str()); + std::remove(tmp_name.c_str()); #endif - return result; - } + return result; + } Test::Result test_pipe_io() { @@ -178,20 +178,20 @@ class Filter_Tests : public Test pipe.pop(); // empty pipe, so ignored // can't explicitly insert a queue into the pipe because they are implicit - result.test_throws("pipe error", "Invalid argument Pipe::append: SecureQueue cannot be used", - [&]() { pipe.append(new Botan::SecureQueue); }); - result.test_throws("pipe error", "Invalid argument Pipe::prepend: SecureQueue cannot be used", - [&]() { pipe.prepend(new Botan::SecureQueue); }); + result.test_throws("pipe error", "Invalid argument Pipe::append: SecureQueue cannot be used", [&]() + { pipe.append(new Botan::SecureQueue); }); + result.test_throws("pipe error", "Invalid argument Pipe::prepend: SecureQueue cannot be used", [&]() + { pipe.prepend(new Botan::SecureQueue); }); pipe.start_msg(); // now inside a message, cannot modify pipe structure - result.test_throws("pipe error", "Cannot append to a Pipe while it is processing", - [&]() { pipe.append(nullptr); }); - result.test_throws("pipe error", "Cannot prepend to a Pipe while it is processing", - [&]() { pipe.prepend(nullptr); }); - result.test_throws("pipe error", "Cannot pop off a Pipe while it is processing", - [&]() { pipe.pop(); }); + result.test_throws("pipe error", "Cannot append to a Pipe while it is processing", [&]() + { pipe.append(nullptr); }); + result.test_throws("pipe error", "Cannot prepend to a Pipe while it is processing", [&]() + { pipe.prepend(nullptr); }); + result.test_throws("pipe error", "Cannot pop off a Pipe while it is processing", [&]() + { pipe.pop(); }); pipe.end_msg(); @@ -290,7 +290,7 @@ class Filter_Tests : public Test result.test_eq("Cipher key length max", cipher->key_spec().maximum_keylength(), 16); result.test_eq("Cipher key length min", cipher->key_spec().minimum_keylength(), 16); - // takes ownership of cipher + // takes ownership of cipher Botan::Pipe pipe(cipher); cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); @@ -410,8 +410,8 @@ class Filter_Tests : public Test pipe.reset(); pipe.append(new Botan::Hex_Decoder); pipe.append(new Botan::Base64_Encoder(/*break_lines=*/true, - /*line_length=*/4, - /*trailing_newline=*/true)); + /*line_length=*/4, + /*trailing_newline=*/true)); pipe.process_msg("6dab1eeb8a2eb69bad"); result.test_eq("base64 with linebreaks and trailing newline", pipe.read_all_as_string(5), "base\n64ou\ntput\n\n"); @@ -488,7 +488,7 @@ class Filter_Tests : public Test new Botan::Fork( new Botan::Chain(new Botan::Hash_Filter("SHA-256"), new Botan::Hex_Encoder), new Botan::Chain(new Botan::Hash_Filter("SHA-512-256"), new Botan::Hex_Encoder) - )); + )); result.test_eq("Fork has a name", fork->name(), "Fork"); Botan::Pipe pipe(fork.release()); @@ -497,8 +497,10 @@ class Filter_Tests : public Test pipe.process_msg("OMG"); result.test_eq("Message count", pipe.message_count(), 2); - result.test_eq("Hash 1", pipe.read_all_as_string(0), "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF"); - result.test_eq("Hash 2", pipe.read_all_as_string(1), "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0"); + result.test_eq("Hash 1", pipe.read_all_as_string(0), + "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF"); + result.test_eq("Hash 2", pipe.read_all_as_string(1), + "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0"); #endif return result; @@ -507,11 +509,10 @@ class Filter_Tests : public Test Test::Result test_threaded_fork() { - Test::Result result("Threaded_Fork"); + Test::Result result("Threaded_Fork"); #if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_HAS_CODEC_FILTERS) && defined(BOTAN_HAS_SHA2_32) - Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder, - new Botan::Base64_Encoder)); + Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder, new Botan::Base64_Encoder)); result.test_eq("Message count", pipe.message_count(), 0); pipe.process_msg("woo"); @@ -526,7 +527,9 @@ class Filter_Tests : public Test const size_t filter_count = 5; Botan::Filter* filters[filter_count]; for(size_t i = 0; i != filter_count; ++i) + { filters[i] = new Botan::Hash_Filter("SHA-256"); + } pipe.append(new Botan::Threaded_Fork(filters, filter_count)); @@ -540,11 +543,12 @@ class Filter_Tests : public Test } pipe.end_msg(); - result.test_eq("Message count after end_msg", pipe.message_count(), 2+filter_count); + result.test_eq("Message count after end_msg", pipe.message_count(), 2 + filter_count); for(size_t i = 0; i != filter_count; ++i) - result.test_eq("Output " + std::to_string(i), - pipe.read_all(2+i), + { + result.test_eq("Output " + std::to_string(i), pipe.read_all(2 + i), "327AD8055223F5926693D8BEA40F7B35BDEEB535647DFB93F464E40EA01939A9"); + } #endif return result; } diff --git a/src/tests/test_fpe.cpp b/src/tests/test_fpe.cpp index a88b793c7..47070de86 100644 --- a/src/tests/test_fpe.cpp +++ b/src/tests/test_fpe.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_FPE_FE1) - #include <botan/fpe_fe1.h> + #include <botan/fpe_fe1.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_fuzzer.cpp b/src/tests/test_fuzzer.cpp index 2be8e7c08..85dde5859 100644 --- a/src/tests/test_fuzzer.cpp +++ b/src/tests/test_fuzzer.cpp @@ -9,13 +9,13 @@ #include <botan/internal/filesystem.h> #if defined(BOTAN_HAS_X509_CERTIFICATES) - #include <botan/x509cert.h> - #include <botan/x509_crl.h> - #include <botan/base64.h> + #include <botan/x509cert.h> + #include <botan/x509_crl.h> + #include <botan/base64.h> #endif #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - #include <botan/pkcs8.h> + #include <botan/pkcs8.h> #endif namespace Botan_Tests { @@ -57,7 +57,7 @@ class Fuzzer_Input_Tests : public Test return result; } - for(auto vec_file: files) + for(auto vec_file : files) { try { @@ -90,7 +90,7 @@ class Fuzzer_Input_Tests : public Test return result; } - for(auto vec_file: files) + for(auto vec_file : files) { auto start = std::chrono::steady_clock::now(); diff --git a/src/tests/test_gf2m.cpp b/src/tests/test_gf2m.cpp index 75bac705e..c8110034e 100644 --- a/src/tests/test_gf2m.cpp +++ b/src/tests/test_gf2m.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_MCELIECE) - #include <botan/gf2m_small_m.h> + #include <botan/gf2m_small_m.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp index 55750d416..bc036e037 100644 --- a/src/tests/test_gost_3410.cpp +++ b/src/tests/test_gost_3410.cpp @@ -7,9 +7,9 @@ #include "tests.h" #if defined(BOTAN_HAS_GOST_34_10_2001) - #include <botan/gost_3410.h> - #include <botan/oids.h> - #include "test_pubkey.h" + #include <botan/gost_3410.h> + #include <botan/oids.h> + #include "test_pubkey.h" #endif namespace Botan_Tests { @@ -22,10 +22,9 @@ 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", - "pubkey/gost_3410_verify.vec", - "Group,Pubkey,Hash,Msg,Signature") - {} + "GOST 34.10-2001", + "pubkey/gost_3410_verify.vec", + "Group,Pubkey,Hash,Msg,Signature") {} std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override { @@ -47,10 +46,9 @@ class GOST_3410_2001_Signature_Tests : public PK_Signature_Generation_Test { public: GOST_3410_2001_Signature_Tests() : PK_Signature_Generation_Test( - "GOST 34.10-2001", - "pubkey/gost_3410_sign.vec", - "Group,Privkey,Hash,Nonce,Msg,Signature") - {} + "GOST 34.10-2001", + "pubkey/gost_3410_sign.vec", + "Group,Privkey,Hash,Nonce,Msg,Signature") {} std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -76,8 +74,14 @@ class GOST_3410_2001_Signature_Tests : public PK_Signature_Generation_Test class GOST_3410_2001_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "gost_256A", "secp256r1" }; } - std::string algo_name() const override { return "GOST-34.10"; } + std::vector<std::string> keygen_params() const override + { + return { "gost_256A", "secp256r1" }; + } + std::string algo_name() const override + { + return "GOST-34.10"; + } }; BOTAN_REGISTER_TEST("gost_3410_verify", GOST_3410_2001_Verification_Tests); diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp index 6584a20d1..9c6051f49 100644 --- a/src/tests/test_hash.cpp +++ b/src/tests/test_hash.cpp @@ -37,7 +37,7 @@ class Hash_Function_Tests : public Text_Based_Test return result; } - for(auto&& provider_ask : providers) + for(auto const& provider_ask : providers) { std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider_ask)); diff --git a/src/tests/test_kdf.cpp b/src/tests/test_kdf.cpp index 2d58914fe..ef0d71fbb 100644 --- a/src/tests/test_kdf.cpp +++ b/src/tests/test_kdf.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_KDF_BASE) - #include <botan/kdf.h> + #include <botan/kdf.h> #endif namespace Botan_Tests { @@ -18,10 +18,7 @@ namespace { class KDF_KAT_Tests : public Text_Based_Test { public: - KDF_KAT_Tests() : Text_Based_Test("kdf", - "OutputLen,Salt,Secret,Label,Output", - "IKM,XTS") - {} + KDF_KAT_Tests() : Text_Based_Test("kdf", "OutputLen,Salt,Secret,Label,Output", "IKM,XTS") {} Test::Result run_one_test(const std::string& kdf_name, const VarMap& vars) override { diff --git a/src/tests/test_keywrap.cpp b/src/tests/test_keywrap.cpp index 46f37d4dd..3a036ba8f 100644 --- a/src/tests/test_keywrap.cpp +++ b/src/tests/test_keywrap.cpp @@ -9,7 +9,7 @@ #include <botan/hex.h> #if defined(BOTAN_HAS_RFC3394_KEYWRAP) - #include <botan/rfc3394.h> + #include <botan/rfc3394.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp index 2e12ee6ed..fd1c920ec 100644 --- a/src/tests/test_mac.cpp +++ b/src/tests/test_mac.cpp @@ -8,7 +8,7 @@ #include "tests.h" #if defined(BOTAN_HAS_MAC) - #include <botan/mac.h> + #include <botan/mac.h> #endif namespace Botan_Tests { @@ -44,7 +44,7 @@ class Message_Auth_Tests : public Text_Based_Test return result; } - for(auto&& provider_ask : providers) + for(auto const& provider_ask : providers) { std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create(algo, provider_ask)); @@ -67,8 +67,8 @@ class Message_Auth_Tests : public Text_Based_Test result.test_eq(provider, "correct mac", mac->final(), expected); // Test to make sure clear() resets what we need it to - mac->set_key( key ); - mac->update( "some discarded input"); + mac->set_key(key); + mac->update("some discarded input"); mac->clear(); // do the same to test verify_mac() @@ -92,7 +92,7 @@ class Message_Auth_Tests : public Text_Based_Test mac->update(input[0]); mac->update(&input[1], input.size() - 2); - mac->update(input[input.size()-1]); + mac->update(input[input.size() - 1]); result.test_eq(provider, "split mac", mac->final(), expected); diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp index c8203e474..ad5fc9055 100644 --- a/src/tests/test_mceliece.cpp +++ b/src/tests/test_mceliece.cpp @@ -10,20 +10,20 @@ #if defined(BOTAN_HAS_MCELIECE) -#include <botan/mceliece.h> -#include <botan/pubkey.h> -#include <botan/oids.h> -#include <botan/loadstor.h> -#include <botan/hash.h> -#include <botan/hex.h> + #include <botan/mceliece.h> + #include <botan/pubkey.h> + #include <botan/oids.h> + #include <botan/loadstor.h> + #include <botan/hash.h> + #include <botan/hex.h> -#if defined(BOTAN_HAS_HMAC_DRBG) - #include <botan/hmac_drbg.h> -#endif + #if defined(BOTAN_HAS_HMAC_DRBG) + #include <botan/hmac_drbg.h> + #endif -#if defined(BOTAN_HAS_MCEIES) - #include <botan/mceies.h> -#endif + #if defined(BOTAN_HAS_MCEIES) + #include <botan/mceies.h> + #endif #endif @@ -37,12 +37,11 @@ namespace { class McEliece_Keygen_Encrypt_Test : public Text_Based_Test { public: - McEliece_Keygen_Encrypt_Test() : - Text_Based_Test("pubkey/mce.vec", - "McElieceSeed,KeyN,KeyT,PublicKeyFingerprint,PrivateKeyFingerprint," - "EncryptPRNGSeed,SharedKey,Ciphertext", - "") - {} + McEliece_Keygen_Encrypt_Test() + : Text_Based_Test("pubkey/mce.vec", + "McElieceSeed,KeyN,KeyT,PublicKeyFingerprint,PrivateKeyFingerprint," + "EncryptPRNGSeed,SharedKey,Ciphertext", + "") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -127,7 +126,9 @@ class McEliece_Tests : public Test { std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(hash_algo)); if(!hash) + { throw Test_Error("Hash " + hash_algo + " not available"); + } hash->update(key.private_key_bits()); return Botan::hex_encode(hash->final()); @@ -137,7 +138,9 @@ class McEliece_Tests : public Test { std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(hash_algo)); if(!hash) + { throw Test_Error("Hash " + hash_algo + " not available"); + } hash->update(key.public_key_bits()); return Botan::hex_encode(hash->final()); @@ -147,18 +150,23 @@ class McEliece_Tests : public Test { struct keygen_params { size_t code_length, t_min, t_max; }; - const keygen_params param_sets[] = { { 256, 5, 15 }, - { 512, 5, 33 }, - { 1024, 15, 35 }, - { 2048, 33, 50 }, - { 6624, 110, 115 } }; + const keygen_params param_sets[] = + { + { 256, 5, 15 }, + { 512, 5, 33 }, + { 1024, 15, 35 }, + { 2048, 33, 50 }, + { 6624, 110, 115 } + }; std::vector<Test::Result> results; - for(size_t i = 0; i < sizeof(param_sets)/sizeof(param_sets[0]); ++i) + for(size_t i = 0; i < sizeof(param_sets) / sizeof(param_sets[0]); ++i) { if(Test::run_long_tests() == false && param_sets[i].code_length >= 2048) + { continue; + } for(size_t t = param_sets[i].t_min; t <= param_sets[i].t_max; ++t) { diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp index 63edba5f1..74b04f7ac 100644 --- a/src/tests/test_modes.cpp +++ b/src/tests/test_modes.cpp @@ -8,7 +8,7 @@ #include "tests.h" #if defined(BOTAN_HAS_MODES) - #include <botan/cipher_mode.h> + #include <botan/cipher_mode.h> #endif namespace Botan_Tests { @@ -18,9 +18,8 @@ namespace Botan_Tests { class Cipher_Mode_Tests : public Text_Based_Test { public: - Cipher_Mode_Tests() : - Text_Based_Test("modes", "Key,Nonce,In,Out") - {} + Cipher_Mode_Tests() + : Text_Based_Test("modes", "Key,Nonce,In,Out") {} std::vector<std::string> possible_providers(const std::string& algo) override { @@ -47,9 +46,9 @@ class Cipher_Mode_Tests : public Text_Based_Test for(auto&& provider_ask : providers) { std::unique_ptr<Botan::Cipher_Mode> enc(Botan::get_cipher_mode( - algo, Botan::ENCRYPTION, provider_ask)); + algo, Botan::ENCRYPTION, provider_ask)); std::unique_ptr<Botan::Cipher_Mode> dec(Botan::get_cipher_mode( - algo, Botan::DECRYPTION, provider_ask)); + algo, Botan::DECRYPTION, provider_ask)); if(!enc || !dec) { diff --git a/src/tests/test_mp.cpp b/src/tests/test_mp.cpp index cbaf465a4..16ca8b4ab 100644 --- a/src/tests/test_mp.cpp +++ b/src/tests/test_mp.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_BIGINT_MP) - #include <botan/internal/mp_core.h> + #include <botan/internal/mp_core.h> #endif namespace Botan_Tests { @@ -132,7 +132,7 @@ class MP_Unit_Tests : public Test for(size_t i = 0; i != 4; ++i) { - result.test_int_eq(x5[i], 3-i, "Swap x5"); + result.test_int_eq(x5[i], 3 - i, "Swap x5"); } result.test_int_eq(x5[4], 4, "Not touched"); diff --git a/src/tests/test_name_constraint.cpp b/src/tests/test_name_constraint.cpp index 11336bb1f..4fc6f437d 100644 --- a/src/tests/test_name_constraint.cpp +++ b/src/tests/test_name_constraint.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_X509_CERTIFICATES) - #include <botan/x509path.h> - #include <botan/calendar.h> + #include <botan/x509path.h> + #include <botan/calendar.h> #endif #include <algorithm> @@ -30,45 +30,46 @@ class Name_Constraint_Tests : public Test public: std::vector<Test::Result> run() override { - const std::vector<std::tuple<std::string,std::string,std::string,std::string>> test_cases = { - std::make_tuple( - "Root_Email_Name_Constraint.crt", - "Invalid_Email_Name_Constraint.crt", - "Invalid Email Name Constraint", - "Certificate does not pass name constraint"), - std::make_tuple( - "Root_DN_Name_Constraint.crt", - "Invalid_DN_Name_Constraint.crt", - "Invalid DN Name Constraint", - "Certificate does not pass name constraint"), - std::make_tuple( - "Root_DN_Name_Constraint.crt", - "Valid_DN_Name_Constraint.crt", - "Valid DN Name Constraint", - "Verified"), - std::make_tuple( - "Root_DNS_Name_Constraint.crt", - "Valid_DNS_Name_Constraint.crt", - "aexample.com", - "Verified"), - std::make_tuple( - "Root_IP_Name_Constraint.crt", - "Valid_IP_Name_Constraint.crt", - "Valid IP Name Constraint", - "Verified"), - std::make_tuple( - "Root_IP_Name_Constraint.crt", - "Invalid_IP_Name_Constraint.crt", - "Invalid IP Name Constraint", - "Certificate does not pass name constraint"), - }; + const std::vector<std::tuple<std::string, std::string, std::string, std::string>> test_cases = + { + std::make_tuple( + "Root_Email_Name_Constraint.crt", + "Invalid_Email_Name_Constraint.crt", + "Invalid Email Name Constraint", + "Certificate does not pass name constraint"), + std::make_tuple( + "Root_DN_Name_Constraint.crt", + "Invalid_DN_Name_Constraint.crt", + "Invalid DN Name Constraint", + "Certificate does not pass name constraint"), + std::make_tuple( + "Root_DN_Name_Constraint.crt", + "Valid_DN_Name_Constraint.crt", + "Valid DN Name Constraint", + "Verified"), + std::make_tuple( + "Root_DNS_Name_Constraint.crt", + "Valid_DNS_Name_Constraint.crt", + "aexample.com", + "Verified"), + std::make_tuple( + "Root_IP_Name_Constraint.crt", + "Valid_IP_Name_Constraint.crt", + "Valid IP Name Constraint", + "Verified"), + std::make_tuple( + "Root_IP_Name_Constraint.crt", + "Invalid_IP_Name_Constraint.crt", + "Invalid IP Name Constraint", + "Certificate does not pass name constraint"), + }; std::vector<Test::Result> results; const Botan::Path_Validation_Restrictions restrictions(false, 80); std::chrono::system_clock::time_point validation_time = - Botan::calendar_point(2016,10,21,4,20,0).to_std_timepoint(); + Botan::calendar_point(2016, 10, 21, 4, 20, 0).to_std_timepoint(); - for(const auto& t: test_cases) + for(const auto& t : test_cases) { Botan::X509_Certificate root(Test::data_file("name_constraint/" + std::get<0>(t))); Botan::X509_Certificate sub(Test::data_file("name_constraint/" + std::get<1>(t))); @@ -77,11 +78,13 @@ class Name_Constraint_Tests : public Test trusted.add_certificate(root); Botan::Path_Validation_Result path_result = Botan::x509_path_validate( - sub, restrictions, trusted, std::get<2>(t), Botan::Usage_Type::TLS_SERVER_AUTH, - validation_time); + sub, restrictions, trusted, std::get<2>(t), Botan::Usage_Type::TLS_SERVER_AUTH, + validation_time); if(path_result.successful_validation() && path_result.trust_root() != root) + { path_result = Botan::Path_Validation_Result(Botan::Certificate_Status_Code::CANNOT_ESTABLISH_TRUST); + } result.test_eq("validation result", path_result.result_string(), std::get<3>(t)); results.push_back(result); diff --git a/src/tests/test_newhope.cpp b/src/tests/test_newhope.cpp index ddd5a8101..112b1f4a7 100644 --- a/src/tests/test_newhope.cpp +++ b/src/tests/test_newhope.cpp @@ -7,10 +7,10 @@ #include "tests.h" #if defined(BOTAN_HAS_NEWHOPE) && defined(BOTAN_HAS_CHACHA) - #include <botan/newhope.h> - #include <botan/sha3.h> - #include <botan/chacha.h> - #include <botan/rng.h> + #include <botan/newhope.h> + #include <botan/sha3.h> + #include <botan/chacha.h> + #include <botan/rng.h> #endif namespace Botan_Tests { @@ -20,15 +20,23 @@ namespace Botan_Tests { class NEWHOPE_RNG : public Botan::RandomNumberGenerator { public: - std::string name() const override { return "NEWHOPE_RNG"; } - void clear() override { /* ignored */ } + std::string name() const override + { + return "NEWHOPE_RNG"; + } + void clear() override + { + /* ignored */ + } void randomize(uint8_t out[], size_t len) override { if(m_first.size() == len) { if(len != 32) + { throw Test_Error("NEWHOPE_RNG called in unexpected way, bad test?"); + } Botan::copy_mem(out, m_first.data(), m_first.size()); return; @@ -58,9 +66,15 @@ class NEWHOPE_RNG : public Botan::RandomNumberGenerator m_chacha.set_iv(nonce, 8); } - bool is_seeded() const override { return true; } + bool is_seeded() const override + { + return true; + } - void add_entropy(const uint8_t[], size_t) override { /* ignored */ } + void add_entropy(const uint8_t[], size_t) override + { + /* ignored */ + } NEWHOPE_RNG(const std::vector<uint8_t>& seed) { @@ -89,10 +103,10 @@ class NEWHOPE_RNG : public Botan::RandomNumberGenerator class NEWHOPE_Tests : public Text_Based_Test { public: - NEWHOPE_Tests() : Text_Based_Test( - "pubkey/newhope.vec", - "DRBG_SeedA,H_OutputA,DRBG_SeedB,H_OutputB,SharedKey") - {} + NEWHOPE_Tests() + : Text_Based_Test( + "pubkey/newhope.vec", + "DRBG_SeedA,H_OutputA,DRBG_SeedB,H_OutputB,SharedKey") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp index c477ed3a3..3b056fd12 100644 --- a/src/tests/test_ocb.cpp +++ b/src/tests/test_ocb.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_AEAD_OCB) - #include <botan/ocb.h> - #include <botan/loadstor.h> + #include <botan/ocb.h> + #include <botan/loadstor.h> #endif namespace Botan_Tests { @@ -20,8 +20,9 @@ namespace { class OCB_Long_KAT_Tests : public Text_Based_Test { public: - OCB_Long_KAT_Tests() : Text_Based_Test("ocb_long.vec", - "Keylen,Taglen,Output") {} + OCB_Long_KAT_Tests() + : Text_Based_Test("ocb_long.vec", + "Keylen,Taglen,Output") {} Test::Result run_one_test(const std::string&, const VarMap& vars) override { @@ -45,8 +46,8 @@ class OCB_Long_KAT_Tests : public Text_Based_Test Botan::OCB_Encryption enc(aes->clone(), taglen / 8); Botan::OCB_Decryption dec(aes->clone(), taglen / 8); - std::vector<uint8_t> key(keylen/8); - key[keylen/8-1] = taglen; + std::vector<uint8_t> key(keylen / 8); + key[keylen / 8 - 1] = taglen; enc.set_key(key); dec.set_key(key); @@ -59,12 +60,12 @@ class OCB_Long_KAT_Tests : public Text_Based_Test { const std::vector<uint8_t> S(i); - Botan::store_be(static_cast<uint32_t>(3*i+1), &N[8]); + Botan::store_be(static_cast<uint32_t>(3 * i + 1), &N[8]); ocb_encrypt(result, C, enc, dec, N, S, S); - Botan::store_be(static_cast<uint32_t>(3*i+2), &N[8]); + Botan::store_be(static_cast<uint32_t>(3 * i + 2), &N[8]); ocb_encrypt(result, C, enc, dec, N, S, empty); - Botan::store_be(static_cast<uint32_t>(3*i+3), &N[8]); + Botan::store_be(static_cast<uint32_t>(3 * i + 3), &N[8]); ocb_encrypt(result, C, enc, dec, N, empty, S); } @@ -118,4 +119,3 @@ BOTAN_REGISTER_TEST("ocb_long", OCB_Long_KAT_Tests); } } - diff --git a/src/tests/test_ocsp.cpp b/src/tests/test_ocsp.cpp index 587977149..18708ddf6 100644 --- a/src/tests/test_ocsp.cpp +++ b/src/tests/test_ocsp.cpp @@ -7,10 +7,10 @@ #include "tests.h" #if defined(BOTAN_HAS_OCSP) - #include <botan/ocsp.h> - #include <botan/x509path.h> - #include <botan/certstor.h> - #include <botan/calendar.h> + #include <botan/ocsp.h> + #include <botan/x509path.h> + #include <botan/certstor.h> + #include <botan/calendar.h> #endif namespace Botan_Tests { @@ -25,7 +25,9 @@ class OCSP_Tests : public Test const std::string fsname = Test::data_file(path); std::ifstream file(fsname.c_str(), std::ios::binary); if(!file.good()) + { throw Test_Error("Error reading from " + fsname); + } std::vector<uint8_t> contents; @@ -36,7 +38,9 @@ class OCSP_Tests : public Test size_t got = file.gcount(); if(got == 0 && file.eof()) + { break; + } contents.insert(contents.end(), buf.data(), buf.data() + got); } @@ -59,11 +63,12 @@ class OCSP_Tests : public Test Test::Result result("OCSP response parsing"); // Simple parsing tests - const std::vector<std::string> ocsp_input_paths = { + const std::vector<std::string> ocsp_input_paths = + { "ocsp/resp1.der", "ocsp/resp2.der", "ocsp/resp3.der" - }; + }; for(std::string ocsp_input_path : ocsp_input_paths) { @@ -99,7 +104,8 @@ class OCSP_Tests : public Test } - const std::string expected_request = "ME4wTKADAgEAMEUwQzBBMAkGBSsOAwIaBQAEFPLgavmFih2NcJtJGSN6qbUaKH5kBBRK3QYWG7z2aLV29YG2u2IaulqBLwIIQkg+DF+RYMY="; + const std::string expected_request = + "ME4wTKADAgEAMEUwQzBBMAkGBSsOAwIaBQAEFPLgavmFih2NcJtJGSN6qbUaKH5kBBRK3QYWG7z2aLV29YG2u2IaulqBLwIIQkg+DF+RYMY="; const Botan::OCSP::Request req1(issuer, end_entity); result.test_eq("Encoded OCSP request", @@ -130,13 +136,8 @@ class OCSP_Tests : public Test certstore.add_certificate(trust_root); // Some arbitrary time within the validity period of the test certs - const auto valid_time = Botan::calendar_point(2016,11,20,8,30,0).to_std_timepoint(); - - std::vector<std::set<Botan::Certificate_Status_Code>> ocsp_status = Botan::PKIX::check_ocsp( - cert_path, - { ocsp }, - { &certstore }, - valid_time); + const auto valid_time = Botan::calendar_point(2016, 11, 20, 8, 30, 0).to_std_timepoint(); + const auto ocsp_status = Botan::PKIX::check_ocsp(cert_path, { ocsp }, { &certstore }, valid_time); if(result.test_eq("Expected size of ocsp_status", ocsp_status.size(), 1)) { @@ -164,12 +165,9 @@ class OCSP_Tests : public Test Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); - std::vector<std::set<Botan::Certificate_Status_Code>> ocsp_status = Botan::PKIX::check_ocsp_online( - cert_path, - { &certstore }, - std::chrono::system_clock::now(), - std::chrono::milliseconds(3000), - true); + typedef std::chrono::system_clock Clock; + const auto ocspTimeout = std::chrono::milliseconds(3000); + auto ocsp_status = Botan::PKIX::check_ocsp_online(cert_path, { &certstore }, Clock::now(), ocspTimeout, true); if(result.test_eq("Expected size of ocsp_status", ocsp_status.size(), 2)) { @@ -198,7 +196,9 @@ class OCSP_Tests : public Test #if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) if(Test::run_online_tests()) + { results.push_back(test_online_request()); + } #endif return results; diff --git a/src/tests/test_os_utils.cpp b/src/tests/test_os_utils.cpp index 5153338d7..881f65a56 100644 --- a/src/tests/test_os_utils.cpp +++ b/src/tests/test_os_utils.cpp @@ -11,7 +11,7 @@ // For __ud2 intrinsic #if defined(BOTAN_TARGET_COMPILER_IS_MSVC) - #include <intrin.h> + #include <intrin.h> #endif namespace Botan_Tests { @@ -78,9 +78,13 @@ class OS_Utils_Tests : public Test uint64_t proc_ts2 = Botan::OS::get_processor_timestamp(); if(proc_ts1 == 0) + { result.test_is_eq("Disabled processor timestamp stays at zero", proc_ts1, proc_ts2); + } else + { result.confirm("Processor timestamp does not duplicate", proc_ts1 != proc_ts2); + } return result; } @@ -180,7 +184,7 @@ class OS_Utils_Tests : public Test return result; } -}; + }; BOTAN_REGISTER_TEST("os_utils", OS_Utils_Tests); diff --git a/src/tests/test_package_transform.cpp b/src/tests/test_package_transform.cpp index 6ad6c51c7..880f2ac50 100644 --- a/src/tests/test_package_transform.cpp +++ b/src/tests/test_package_transform.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_PACKAGE_TRANSFORM) - #include <botan/package.h> + #include <botan/package.h> #endif namespace Botan_Tests { @@ -51,7 +51,7 @@ class Package_Transform_Tests : public Test // More tests including KATs would be useful for these functions - return std::vector<Test::Result>{result}; + return std::vector<Test::Result> {result}; } }; diff --git a/src/tests/test_pad.cpp b/src/tests/test_pad.cpp index 1eb8b615f..592ae660b 100644 --- a/src/tests/test_pad.cpp +++ b/src/tests/test_pad.cpp @@ -17,9 +17,7 @@ namespace Botan_Tests { class Cipher_Mode_Padding_Tests : public Text_Based_Test { public: - Cipher_Mode_Padding_Tests() : - Text_Based_Test("pad.vec", "In,Blocksize", "Out") - {} + Cipher_Mode_Padding_Tests() : Text_Based_Test("pad.vec", "In,Blocksize", "Out") {} Test::Result run_one_test(const std::string& header, const VarMap& vars) override { @@ -32,8 +30,10 @@ class Cipher_Mode_Padding_Tests : public Text_Based_Test auto underscore = algo.find('_'); if(underscore != std::string::npos) { - if(algo.substr(underscore+1,std::string::npos) != "Invalid") + if(algo.substr(underscore + 1, std::string::npos) != "Invalid") + { throw Test_Error("Unexpected padding header " + header); + } algo = algo.substr(0, underscore); } diff --git a/src/tests/test_passhash.cpp b/src/tests/test_passhash.cpp index 6eae25f8d..5497e35fc 100644 --- a/src/tests/test_passhash.cpp +++ b/src/tests/test_passhash.cpp @@ -7,11 +7,11 @@ #include "tests.h" #if defined(BOTAN_HAS_BCRYPT) - #include <botan/bcrypt.h> + #include <botan/bcrypt.h> #endif #if defined(BOTAN_HAS_PASSHASH9) - #include <botan/passhash9.h> + #include <botan/passhash9.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp index a4db5d8e0..bd2fd8f89 100644 --- a/src/tests/test_pbkdf.cpp +++ b/src/tests/test_pbkdf.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_PBKDF) - #include <botan/pbkdf.h> + #include <botan/pbkdf.h> #endif namespace Botan_Tests { @@ -18,9 +18,7 @@ namespace { class PBKDF_KAT_Tests : public Text_Based_Test { public: - PBKDF_KAT_Tests() : Text_Based_Test("pbkdf", - "OutputLen,Iterations,Salt,Passphrase,Output") - {} + PBKDF_KAT_Tests() : Text_Based_Test("pbkdf", "OutputLen,Iterations,Salt,Passphrase,Output") {} Test::Result run_one_test(const std::string& pbkdf_name, const VarMap& vars) override { diff --git a/src/tests/test_pk_pad.cpp b/src/tests/test_pk_pad.cpp index 33277da2b..f802bf048 100644 --- a/src/tests/test_pk_pad.cpp +++ b/src/tests/test_pk_pad.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_PK_PADDING) - #include <botan/emsa.h> - #include <botan/eme.h> + #include <botan/emsa.h> + #include <botan/eme.h> #endif namespace Botan_Tests { @@ -18,10 +18,11 @@ namespace Botan_Tests { class EME_Decoding_Tests : public Text_Based_Test { public: - EME_Decoding_Tests() : - Text_Based_Test("pk_pad_eme", - "RawCiphertext,ValidInput", - "Plaintext") {} + EME_Decoding_Tests() + : Text_Based_Test( + "pk_pad_eme", + "RawCiphertext,ValidInput", + "Plaintext") {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { @@ -44,7 +45,9 @@ class EME_Decoding_Tests : public Text_Based_Test const bool is_valid = get_req_bool(vars, "ValidInput"); if(is_valid == false) + { result.test_eq("Plaintext value is empty for invalid EME inputs", plaintext.size(), 0); + } uint8_t valid_mask = 0; Botan::secure_vector<uint8_t> decoded = @@ -69,5 +72,3 @@ BOTAN_REGISTER_TEST("pk_pad_eme", EME_Decoding_Tests); #endif } - - diff --git a/src/tests/test_pkcs11.cpp b/src/tests/test_pkcs11.cpp index 85110cabf..289e34466 100644 --- a/src/tests/test_pkcs11.cpp +++ b/src/tests/test_pkcs11.cpp @@ -7,7 +7,7 @@ #include "test_pkcs11.h" namespace Botan_Tests { - + #if defined(BOTAN_HAS_PKCS11) using namespace Botan; diff --git a/src/tests/test_pkcs11_high_level.cpp b/src/tests/test_pkcs11_high_level.cpp index 5944a2b1d..0a170fda9 100644 --- a/src/tests/test_pkcs11_high_level.cpp +++ b/src/tests/test_pkcs11_high_level.cpp @@ -80,7 +80,10 @@ class TestSession m_session->login(UserType::User, PIN_SECVEC); } } - inline Session& session() const { return *m_session; } + inline Session& session() const + { + return *m_session; + } private: std::unique_ptr<Module> m_module = nullptr; @@ -565,7 +568,7 @@ Test::Result test_object_finder() Object obj_found(test_session.session(), search_result.at(0)); result.test_eq("found the object just created (same application)", - obj_found.get_attribute_value(AttributeType::Application) , data_obj.get_attribute_value(AttributeType::Application)); + obj_found.get_attribute_value(AttributeType::Application), data_obj.get_attribute_value(AttributeType::Application)); auto search_result2 = Object::search<Object>(test_session.session(), search_template.attributes()); result.test_eq("found the object just created (same label)", obj_found.get_attribute_value(AttributeType::Label), @@ -623,10 +626,10 @@ class Object_Tests : public PKCS11_Test { test_attribute_container #if defined(BOTAN_HAS_ASN1) - ,test_create_destroy_data_object - ,test_get_set_attribute_values - ,test_object_finder - ,test_object_copy + , test_create_destroy_data_object + , test_get_set_attribute_values + , test_object_finder + , test_object_copy #endif }; @@ -793,7 +796,7 @@ Test::Result test_rsa_encrypt_decrypt() // generate key pair PKCS11_RSA_KeyPair keypair = generate_rsa_keypair(test_session); - auto encrypt_and_decrypt = [&keypair, &result](const std::vector<uint8_t>& plaintext, const std::string& padding) -> void + auto encrypt_and_decrypt = [&keypair, &result](const std::vector<uint8_t>& plaintext, const std::string& padding) { Botan::PK_Encryptor_EME encryptor(keypair.first, Test::rng(), padding, "pkcs11"); auto encrypted = encryptor.encrypt(plaintext, Test::rng()); @@ -833,11 +836,11 @@ Test::Result test_rsa_sign_verify() std::vector<uint8_t> plaintext(256); std::iota(std::begin(plaintext), std::end(plaintext), 0); - auto sign_and_verify = [&keypair, &plaintext, &result](const std::string& emsa, bool multipart) -> void + auto sign_and_verify = [&keypair, &plaintext, &result](std::string const& emsa, bool multipart) { Botan::PK_Signer signer(keypair.second, Test::rng(), emsa, Botan::IEEE_1363, "pkcs11"); std::vector<uint8_t> signature; - if ( multipart ) + if(multipart) { signer.update(plaintext.data(), plaintext.size() / 2); signature = signer.sign_message(plaintext.data() + plaintext.size() / 2, plaintext.size() / 2, Test::rng()); @@ -847,13 +850,13 @@ Test::Result test_rsa_sign_verify() signature = signer.sign_message(plaintext, Test::rng()); } - Botan::PK_Verifier verifier(keypair.first, emsa, Botan::IEEE_1363, "pkcs11"); bool rsa_ok = false; - if ( multipart ) + if(multipart) { verifier.update(plaintext.data(), plaintext.size() / 2); - rsa_ok = verifier.verify_message(plaintext.data() + plaintext.size() / 2, plaintext.size() / 2, signature.data(), signature.size()); + rsa_ok = verifier.verify_message(plaintext.data() + plaintext.size() / 2, plaintext.size() / 2, + signature.data(), signature.size()); } else { @@ -1094,7 +1097,7 @@ Test::Result test_ecdsa_sign_verify() std::vector<uint8_t> plaintext(20, 0x01); - auto sign_and_verify = [ &keypair, &plaintext, &result ](const std::string& emsa) -> void + auto sign_and_verify = [ &keypair, &plaintext, &result ](const std::string& emsa) { Botan::PK_Signer signer(keypair.second, Test::rng(), emsa, Botan::IEEE_1363, "pkcs11"); auto signature = signer.sign_message(plaintext, Test::rng()); @@ -1436,9 +1439,9 @@ class PKCS11_RNG_Tests : public PKCS11_Test std::vector<std::function<Test::Result()>> fns = { test_rng_generate_random - ,test_rng_add_entropy + , test_rng_add_entropy #if defined(BOTAN_HAS_HMAC_DRBG )&& defined(BOTAN_HAS_SHA2_64) - ,test_pkcs11_hmac_drbg + , test_pkcs11_hmac_drbg #endif }; diff --git a/src/tests/test_pkcs11_low_level.cpp b/src/tests/test_pkcs11_low_level.cpp index 289ff5995..01933b359 100644 --- a/src/tests/test_pkcs11_low_level.cpp +++ b/src/tests/test_pkcs11_low_level.cpp @@ -573,9 +573,9 @@ Test::Result test_c_set_pin() const secure_vector<uint8_t>& new_pin) -> PKCS11_BoundTestFunction { return std::bind(static_cast< bool (LowLevel::*)(SessionHandle, const secure_vector<uint8_t>&, - const secure_vector<uint8_t>&, ReturnValue*) const> - (&LowLevel::C_SetPIN<secure_allocator<uint8_t>>), *p11_low_level.get(), session_handle, - old_pin, new_pin, std::placeholders::_1); + const secure_vector<uint8_t>&, ReturnValue*) const> + (&LowLevel::C_SetPIN<secure_allocator<uint8_t>>), *p11_low_level.get(), session_handle, + old_pin, new_pin, std::placeholders::_1); }; const std::string test_pin("654321"); @@ -799,28 +799,28 @@ class LowLevelTests : public Test std::vector<std::function<Test::Result()>> fns = { test_c_get_function_list - ,test_low_level_ctor - ,test_initialize_finalize - ,test_c_get_info - ,test_c_get_slot_list - ,test_c_get_slot_info - ,test_c_get_token_info - ,test_c_wait_for_slot_event - ,test_c_get_mechanism_list - ,test_c_get_mechanism_info - ,test_open_close_session - ,test_c_close_all_sessions - ,test_c_get_session_info - ,test_c_init_token - ,test_c_login_logout_security_officier /* only possible if token is initialized */ - ,test_c_init_pin - ,test_c_login_logout_user /* only possible if token is initialized and user pin is set */ - ,test_c_set_pin - ,test_c_create_object_c_destroy_object - ,test_c_get_object_size - ,test_c_get_attribute_value - ,test_c_set_attribute_value - ,test_c_copy_object + , test_low_level_ctor + , test_initialize_finalize + , test_c_get_info + , test_c_get_slot_list + , test_c_get_slot_info + , test_c_get_token_info + , test_c_wait_for_slot_event + , test_c_get_mechanism_list + , test_c_get_mechanism_info + , test_open_close_session + , test_c_close_all_sessions + , test_c_get_session_info + , test_c_init_token + , test_c_login_logout_security_officier /* only possible if token is initialized */ + , test_c_init_pin + , test_c_login_logout_user /* only possible if token is initialized and user pin is set */ + , test_c_set_pin + , test_c_create_object_c_destroy_object + , test_c_get_object_size + , test_c_get_attribute_value + , test_c_set_attribute_value + , test_c_copy_object }; for(size_t i = 0; i != fns.size(); ++i) diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp index d392437c9..a38b7d3f3 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -111,7 +111,7 @@ PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& var std::vector<std::unique_ptr<Botan::PK_Verifier>> verifiers; - for(std::string verify_provider : possible_providers(algo_name())) + for(auto const& verify_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Verifier> verifier; @@ -131,7 +131,7 @@ PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& var verifiers.push_back(std::move(verifier)); } - for(auto&& sign_provider : possible_providers(algo_name())) + for(auto const& sign_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::RandomNumberGenerator> rng; if(vars.count("Nonce")) @@ -185,7 +185,7 @@ PK_Signature_Verification_Test::run_one_test(const std::string&, const VarMap& v Test::Result result(algo_name() + "/" + padding + " signature verification"); - for(auto&& verify_provider : possible_providers(algo_name())) + for(auto const& verify_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Verifier> verifier; @@ -215,7 +215,7 @@ PK_Signature_NonVerification_Test::run_one_test(const std::string&, const VarMap Test::Result result(algo_name() + "/" + padding + " verify invalid signature"); - for(auto&& verify_provider : possible_providers(algo_name())) + for(auto const& verify_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Verifier> verifier; @@ -251,7 +251,7 @@ PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& va std::vector<std::unique_ptr<Botan::PK_Decryptor>> decryptors; - for(auto&& dec_provider : possible_providers(algo_name())) + for(auto const& dec_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Decryptor> decryptor; @@ -269,13 +269,13 @@ PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& va } - for(auto&& enc_provider : possible_providers(algo_name())) + for(auto const& enc_provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Encryptor> encryptor; try { - encryptor.reset(new Botan::PK_Encryptor_EME(*pubkey, Test::rng(),padding, enc_provider)); + encryptor.reset(new Botan::PK_Encryptor_EME(*pubkey, Test::rng(), padding, enc_provider)); } catch(Botan::Lookup_Error&) { @@ -384,7 +384,7 @@ Test::Result PK_Key_Agreement_Test::run_one_test(const std::string& header, cons const size_t key_len = get_opt_sz(vars, "OutLen", 0); - for(auto&& provider : possible_providers(algo_name())) + for(auto const& provider : possible_providers(algo_name())) { std::unique_ptr<Botan::PK_Key_Agreement> kas; @@ -402,125 +402,143 @@ Test::Result PK_Key_Agreement_Test::run_one_test(const std::string& header, cons return result; } +std::vector<std::string> PK_Key_Generation_Test::possible_providers( + const std::string& algo) + { + std::vector<std::string> pk_provider = + Botan::probe_provider_private_key(algo, { "base", "openssl", "tpm" }); + return Test::provider_filter(pk_provider); + } + std::vector<Test::Result> PK_Key_Generation_Test::run() { std::vector<Test::Result> results; - for(auto&& param : keygen_params()) + for(auto const& param : keygen_params()) { const std::string report_name = algo_name() + (param.empty() ? param : " " + param); Test::Result result(report_name + " keygen"); + const std::vector<std::string> providers = possible_providers(algo_name()); + + if(providers.empty()) + { + result.note_missing("provider key generation " + algo_name()); + } + result.start_timer(); - std::unique_ptr<Botan::Private_Key> key_p = - Botan::create_private_key(algo_name(), Test::rng(), param); + for(auto&& prov : providers) + { + std::unique_ptr<Botan::Private_Key> key_p = + Botan::create_private_key(algo_name(), Test::rng(), param, prov); - const Botan::Private_Key& key = *key_p; + const Botan::Private_Key& key = *key_p; - result.confirm("Key passes self tests", key.check_key(Test::rng(), true)); + result.confirm("Key passes self tests", key.check_key(Test::rng(), true)); - result.test_gte("Key has reasonable estimated strength (lower)", key.estimated_strength(), 64); - result.test_lt("Key has reasonable estimated strength (upper)", key.estimated_strength(), 512); + result.test_gte("Key has reasonable estimated strength (lower)", key.estimated_strength(), 64); + result.test_lt("Key has reasonable estimated strength (upper)", key.estimated_strength(), 512); - // Test PEM public key round trips OK - try - { - Botan::DataSource_Memory data_src(Botan::X509::PEM_encode(key)); - std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src)); + // Test PEM public key round trips OK + try + { + Botan::DataSource_Memory data_src(Botan::X509::PEM_encode(key)); + std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src)); - result.confirm("recovered public key from private", loaded.get() != nullptr); - result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip PEM public key", e.what()); - } + result.confirm("recovered public key from private", loaded.get() != nullptr); + result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip PEM public key", e.what()); + } - // Test DER public key round trips OK - try - { - Botan::DataSource_Memory data_src(Botan::X509::BER_encode(key)); - std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src)); + // Test DER public key round trips OK + try + { + Botan::DataSource_Memory data_src(Botan::X509::BER_encode(key)); + std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src)); - result.confirm("recovered public key from private", loaded.get() != nullptr); - result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip BER public key", e.what()); - } + result.confirm("recovered public key from private", loaded.get() != nullptr); + result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip BER public key", e.what()); + } - // Test PEM private key round trips OK - try - { - Botan::DataSource_Memory data_src(Botan::PKCS8::PEM_encode(key)); - std::unique_ptr<Botan::Private_Key> loaded( - Botan::PKCS8::load_key(data_src, Test::rng())); + // Test PEM private key round trips OK + try + { + Botan::DataSource_Memory data_src(Botan::PKCS8::PEM_encode(key)); + std::unique_ptr<Botan::Private_Key> loaded( + Botan::PKCS8::load_key(data_src, Test::rng())); - result.confirm("recovered private key from PEM blob", loaded.get() != nullptr); - result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip PEM private key", e.what()); - } + result.confirm("recovered private key from PEM blob", loaded.get() != nullptr); + result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip PEM private key", e.what()); + } - try - { - Botan::DataSource_Memory data_src(Botan::PKCS8::BER_encode(key)); - std::unique_ptr<Botan::Public_Key> loaded(Botan::PKCS8::load_key(data_src, Test::rng())); + try + { + Botan::DataSource_Memory data_src(Botan::PKCS8::BER_encode(key)); + std::unique_ptr<Botan::Public_Key> loaded(Botan::PKCS8::load_key(data_src, Test::rng())); - result.confirm("recovered public key from private", loaded.get() != nullptr); - result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip BER private key", e.what()); - } + result.confirm("recovered public key from private", loaded.get() != nullptr); + result.test_eq("public key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip BER private key", e.what()); + } - const std::string passphrase = Test::random_password(); + const std::string passphrase = Test::random_password(); - try - { - Botan::DataSource_Memory data_src( - Botan::PKCS8::PEM_encode(key, Test::rng(), passphrase, - std::chrono::milliseconds(10))); + try + { + Botan::DataSource_Memory data_src( + Botan::PKCS8::PEM_encode(key, Test::rng(), passphrase, + std::chrono::milliseconds(10))); - std::unique_ptr<Botan::Private_Key> loaded( - Botan::PKCS8::load_key(data_src, Test::rng(), passphrase)); + std::unique_ptr<Botan::Private_Key> loaded( + Botan::PKCS8::load_key(data_src, Test::rng(), passphrase)); - result.confirm("recovered private key from encrypted blob", loaded.get() != nullptr); - result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip encrypted PEM private key", e.what()); - } + result.confirm("recovered private key from encrypted blob", loaded.get() != nullptr); + result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip encrypted PEM private key", e.what()); + } - try - { - Botan::DataSource_Memory data_src( - Botan::PKCS8::BER_encode(key, Test::rng(), passphrase, - std::chrono::milliseconds(10))); + try + { + Botan::DataSource_Memory data_src( + Botan::PKCS8::BER_encode(key, Test::rng(), passphrase, + std::chrono::milliseconds(10))); - std::unique_ptr<Botan::Private_Key> loaded( - Botan::PKCS8::load_key(data_src, Test::rng(), passphrase)); + std::unique_ptr<Botan::Private_Key> loaded( + Botan::PKCS8::load_key(data_src, Test::rng(), passphrase)); - result.confirm("recovered private key from BER blob", loaded.get() != nullptr); - result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); - result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); - } - catch(std::exception& e) - { - result.test_failure("roundtrip encrypted BER private key", e.what()); - } + result.confirm("recovered private key from BER blob", loaded.get() != nullptr); + result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name()); + result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true); + } + catch(std::exception& e) + { + result.test_failure("roundtrip encrypted BER private key", e.what()); + } + } result.end_timer(); results.push_back(result); diff --git a/src/tests/test_pubkey.h b/src/tests/test_pubkey.h index 7709f51c7..4a2ca6866 100644 --- a/src/tests/test_pubkey.h +++ b/src/tests/test_pubkey.h @@ -21,14 +21,15 @@ class PK_Test : public Text_Based_Test { public: PK_Test(const std::string& algo, - const std::string& test_src, - const std::string& required_keys, - const std::string& optional_keys = {}) : - Text_Based_Test(test_src, required_keys, optional_keys), - m_algo(algo) - {} + const std::string& test_src, + const std::string& required_keys, + const std::string& optional_keys = {}) + : Text_Based_Test(test_src, required_keys, optional_keys), m_algo(algo) {} - std::string algo_name() const { return m_algo; } + std::string algo_name() const + { + return m_algo; + } protected: std::vector<std::string> possible_providers(const std::string&) override; @@ -43,8 +44,8 @@ class PK_Signature_Generation_Test : public PK_Test PK_Signature_Generation_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} virtual std::string default_padding(const VarMap&) const { @@ -68,8 +69,8 @@ class PK_Signature_Verification_Test : public PK_Test PK_Signature_Verification_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} virtual std::string default_padding(const VarMap&) const { @@ -87,10 +88,13 @@ class PK_Signature_NonVerification_Test : public PK_Test PK_Signature_NonVerification_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } virtual std::string default_padding(const VarMap&) const { @@ -108,15 +112,18 @@ class PK_Encryption_Decryption_Test : public PK_Test PK_Encryption_Decryption_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} virtual std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) = 0; - virtual std::string default_padding(const VarMap&) const { return "Raw"; } + virtual std::string default_padding(const VarMap&) const + { + return "Raw"; + } private: Test::Result run_one_test(const std::string& header, const VarMap& vars) override final; -}; + }; class PK_Key_Agreement_Test : public PK_Test { @@ -124,16 +131,19 @@ class PK_Key_Agreement_Test : public PK_Test PK_Key_Agreement_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} virtual std::unique_ptr<Botan::Private_Key> load_our_key(const std::string& header, - const VarMap& vars) = 0; + const VarMap& vars) = 0; virtual std::vector<uint8_t> load_their_key(const std::string& header, - const VarMap& vars) = 0; + const VarMap& vars) = 0; - virtual std::string default_kdf(const VarMap&) const { return "Raw"; } + virtual std::string default_kdf(const VarMap&) const + { + return "Raw"; + } private: Test::Result run_one_test(const std::string& header, const VarMap& vars) override final; @@ -145,8 +155,8 @@ class PK_KEM_Test : public PK_Test PK_KEM_Test(const std::string& algo, const std::string& test_src, const std::string& required_keys, - const std::string& optional_keys = "") : - PK_Test(algo, test_src, required_keys, optional_keys) {} + const std::string& optional_keys = "") + : PK_Test(algo, test_src, required_keys, optional_keys) {} virtual std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) = 0; private: @@ -161,6 +171,8 @@ class PK_Key_Generation_Test : public Test virtual std::vector<std::string> keygen_params() const = 0; virtual std::string algo_name() const = 0; + + std::vector<std::string> possible_providers(const std::string&) override; }; void check_invalid_signatures(Test::Result& result, diff --git a/src/tests/test_rfc6979.cpp b/src/tests/test_rfc6979.cpp index e7605b580..a9992b4f2 100644 --- a/src/tests/test_rfc6979.cpp +++ b/src/tests/test_rfc6979.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_RFC6979_GENERATOR) - #include <botan/rfc6979.h> - #include <botan/hex.h> + #include <botan/rfc6979.h> + #include <botan/hex.h> #endif #include <botan/hash.h> @@ -46,7 +46,7 @@ class RFC6979_KAT_Tests : public Text_Based_Test Botan::RFC6979_Nonce_Generator gen(hash, Q, X); result.test_eq("vector matches", gen.nonce_for(H), K); - result.test_ne("different output for H+1", gen.nonce_for(H+1), K); + result.test_ne("different output for H+1", gen.nonce_for(H + 1), K); result.test_eq("vector matches when run again", gen.nonce_for(H), K); return result; diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp index d057f0e55..ed432944a 100644 --- a/src/tests/test_rng.cpp +++ b/src/tests/test_rng.cpp @@ -9,20 +9,20 @@ #include "test_rng.h" #if defined(BOTAN_HAS_HMAC_DRBG) - #include <botan/hmac_drbg.h> + #include <botan/hmac_drbg.h> #endif #if defined(BOTAN_HAS_AUTO_RNG) - #include <botan/auto_rng.h> + #include <botan/auto_rng.h> #endif #if defined(BOTAN_HAS_ENTROPY_SOURCE) - #include <botan/entropy_src.h> + #include <botan/entropy_src.h> #endif #if defined(BOTAN_TARGET_OS_TYPE_IS_UNIX) - #include <unistd.h> - #include <sys/wait.h> + #include <unistd.h> + #include <sys/wait.h> #endif #include <iostream> @@ -36,9 +36,10 @@ namespace { class HMAC_DRBG_Tests : public Text_Based_Test { public: - HMAC_DRBG_Tests() : Text_Based_Test("hmac_drbg.vec", - "EntropyInput,EntropyInputReseed,Out", - "AdditionalInput1,AdditionalInput2") {} + HMAC_DRBG_Tests() + : Text_Based_Test("hmac_drbg.vec", + "EntropyInput,EntropyInputReseed,Out", + "AdditionalInput1,AdditionalInput2") {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { @@ -83,7 +84,10 @@ class HMAC_DRBG_Unit_Tests : public Test class Broken_Entropy_Source : public Botan::Entropy_Source { public: - std::string name() const override { return "Broken Entropy Source"; } + std::string name() const override + { + return "Broken Entropy Source"; + } size_t poll(Botan::RandomNumberGenerator&) override { @@ -94,7 +98,10 @@ class HMAC_DRBG_Unit_Tests : public Test class Insufficient_Entropy_Source : public Botan::Entropy_Source { public: - std::string name() const override { return "Insufficient Entropy Source"; } + std::string name() const override + { + return "Insufficient Entropy Source"; + } size_t poll(Botan::RandomNumberGenerator&) override { @@ -107,7 +114,10 @@ class HMAC_DRBG_Unit_Tests : public Test public: Request_Counting_RNG() : m_randomize_count(0) {} - bool is_seeded() const override { return true; } + bool is_seeded() const override + { + return true; + } void clear() override { @@ -121,9 +131,15 @@ class HMAC_DRBG_Unit_Tests : public Test void add_entropy(const uint8_t[], size_t) override {} - std::string name() const override { return "Request_Counting_RNG"; } + std::string name() const override + { + return "Request_Counting_RNG"; + } - size_t randomize_count() { return m_randomize_count; } + size_t randomize_count() + { + return m_randomize_count; + } private: size_t m_randomize_count; @@ -144,14 +160,18 @@ class HMAC_DRBG_Unit_Tests : public Test Request_Counting_RNG counting_rng; Botan::HMAC_DRBG rng(std::move(mac), counting_rng, Botan::Entropy_Sources::global_sources(), 2); Botan::secure_vector<uint8_t> seed_input( - {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, - 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}); + { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }); Botan::secure_vector<uint8_t> output_after_initialization( - {0x48,0xD3,0xB4,0x5A,0xAB,0x65,0xEF,0x92,0xCC,0xFC,0xB9,0x42,0x7E,0xF2,0x0C,0x90, - 0x29,0x70,0x65,0xEC,0xC1,0xB8,0xA5,0x25,0xBF,0xE4,0xDC,0x6F,0xF3,0x6D,0x0E,0x38}); + { + 0x48, 0xD3, 0xB4, 0x5A, 0xAB, 0x65, 0xEF, 0x92, 0xCC, 0xFC, 0xB9, 0x42, 0x7E, 0xF2, 0x0C, 0x90, + 0x29, 0x70, 0x65, 0xEC, 0xC1, 0xB8, 0xA5, 0x25, 0xBF, 0xE4, 0xDC, 0x6F, 0xF3, 0x6D, 0x0E, 0x38 + }); Botan::secure_vector<uint8_t> output_without_reseed( - {0xC4,0x90,0x04,0x5B,0x35,0x4F,0x50,0x09,0x68,0x45,0xF0,0x4B,0x11,0x03,0x58,0xF0}); - result.test_eq("is_seeded",rng.is_seeded(),false); + {0xC4, 0x90, 0x04, 0x5B, 0x35, 0x4F, 0x50, 0x09, 0x68, 0x45, 0xF0, 0x4B, 0x11, 0x03, 0x58, 0xF0}); + result.test_eq("is_seeded", rng.is_seeded(), false); rng.initialize_with(seed_input.data(), seed_input.size()); @@ -200,10 +220,10 @@ class HMAC_DRBG_Unit_Tests : public Test result.test_eq("still second reseed", counting_rng.randomize_count(), 3); // request > max_number_of_bits_per_request, do reseeds occur? - rng.random_vec(64*1024 + 1); + rng.random_vec(64 * 1024 + 1); result.test_eq("request exceeds output limit", counting_rng.randomize_count(), 4); - rng.random_vec(9*64*1024 + 1); + rng.random_vec(9 * 64 * 1024 + 1); result.test_eq("request exceeds output limit", counting_rng.randomize_count(), 9); return result; @@ -283,7 +303,7 @@ class HMAC_DRBG_Unit_Tests : public Test Botan::Null_RNG broken_entropy_input_rng; Botan::HMAC_DRBG rng_with_broken_rng(std::move(mac), broken_entropy_input_rng, reseed_interval); - result.test_throws("broken underlying rng", [&rng_with_broken_rng] () { rng_with_broken_rng.random_vec(16); }); + result.test_throws("broken underlying rng", [&rng_with_broken_rng]() { rng_with_broken_rng.random_vec(16); }); // entropy_sources throw exception std::unique_ptr<Broken_Entropy_Source> broken_entropy_source_1(new Broken_Entropy_Source()); @@ -295,7 +315,7 @@ class HMAC_DRBG_Unit_Tests : public Test mac = Botan::MessageAuthenticationCode::create("HMAC(SHA-256)"); Botan::HMAC_DRBG rng_with_broken_es(std::move(mac), broken_entropy_sources, reseed_interval); - result.test_throws("broken entropy sources", [&rng_with_broken_es] () { rng_with_broken_es.random_vec(16); }); + result.test_throws("broken entropy sources", [&rng_with_broken_es]() { rng_with_broken_es.random_vec(16); }); // entropy source returns insufficient entropy Botan::Entropy_Sources insufficient_entropy_sources; @@ -304,24 +324,25 @@ class HMAC_DRBG_Unit_Tests : public Test mac = Botan::MessageAuthenticationCode::create("HMAC(SHA-256)"); Botan::HMAC_DRBG rng_with_insufficient_es(std::move(mac), insufficient_entropy_sources, reseed_interval); - result.test_throws("insufficient entropy source", [&rng_with_insufficient_es] () { rng_with_insufficient_es.random_vec(16); }); + result.test_throws("insufficient entropy source", [&rng_with_insufficient_es]() { rng_with_insufficient_es.random_vec(16); }); // one of or both underlying_rng and entropy_sources throw exception mac = Botan::MessageAuthenticationCode::create("HMAC(SHA-256)"); Botan::HMAC_DRBG rng_with_broken_rng_and_es(std::move(mac), broken_entropy_input_rng, Botan::Entropy_Sources::global_sources(), reseed_interval); - result.test_throws("broken underlying rng but good entropy sources", [&rng_with_broken_rng_and_es] () - { rng_with_broken_rng_and_es.random_vec(16); }); + result.test_throws("broken underlying rng but good entropy sources", [&rng_with_broken_rng_and_es]() + { rng_with_broken_rng_and_es.random_vec(16); }); mac = Botan::MessageAuthenticationCode::create("HMAC(SHA-256)"); Botan::HMAC_DRBG rng_with_rng_and_broken_es(std::move(mac), Test::rng(), broken_entropy_sources, reseed_interval); - result.test_throws("good underlying rng but broken entropy sources", [&rng_with_rng_and_broken_es] () - { rng_with_rng_and_broken_es.random_vec(16); }); + result.test_throws("good underlying rng but broken entropy sources", [&rng_with_rng_and_broken_es]() + { rng_with_rng_and_broken_es.random_vec(16); }); mac = Botan::MessageAuthenticationCode::create("HMAC(SHA-256)"); - Botan::HMAC_DRBG rng_with_broken_rng_and_broken_es(std::move(mac), broken_entropy_input_rng, broken_entropy_sources, reseed_interval); - result.test_throws("underlying rng and entropy sources broken", [&rng_with_broken_rng_and_broken_es] () - { rng_with_broken_rng_and_broken_es.random_vec(16); }); + Botan::HMAC_DRBG rng_with_broken_rng_and_broken_es(std::move(mac), broken_entropy_input_rng, broken_entropy_sources, + reseed_interval); + result.test_throws("underlying rng and entropy sources broken", [&rng_with_broken_rng_and_broken_es]() + { rng_with_broken_rng_and_broken_es.random_vec(16); }); return result; } @@ -340,7 +361,7 @@ class HMAC_DRBG_Unit_Tests : public Test // make sure the nonce has at least 1/2*security_strength bits // SHA-256 -> 256 bits security strength - for( auto nonce_size : { 0, 4, 8, 16, 31, 32, 34 } ) + for(auto nonce_size : { 0, 4, 8, 16, 31, 32, 34 }) { if(!mac) { @@ -355,7 +376,7 @@ class HMAC_DRBG_Unit_Tests : public Test if(nonce_size < 32) { result.test_eq("not seeded", rng.is_seeded(), false); - result.test_throws("invalid nonce size", [&rng, &nonce] () { rng.random_vec(32); }); + result.test_throws("invalid nonce size", [&rng, &nonce]() { rng.random_vec(32); }); } else { @@ -426,12 +447,12 @@ class HMAC_DRBG_Unit_Tests : public Test } pid_t pid = ::fork(); - if ( pid == -1 ) + if(pid == -1) { result.test_failure("failed to fork process"); return result; } - else if ( pid != 0 ) + else if(pid != 0) { // parent process, wait for randomize_count from child's rng ::close(fd[1]); // close write end in parent @@ -473,9 +494,10 @@ class HMAC_DRBG_Unit_Tests : public Test rng.randomize(&child_bytes[0], child_bytes.size()); count = counting_rng.randomize_count(); ssize_t written = ::write(fd[1], &count, sizeof(count)); - try { + try + { rng.randomize(&child_bytes[0], child_bytes.size()); - } + } catch(std::exception& e) { fprintf(stderr, "%s", e.what()); @@ -496,7 +518,7 @@ class HMAC_DRBG_Unit_Tests : public Test std::vector<std::string> approved_hash_fns { "SHA-160", "SHA-224", "SHA-256", "SHA-512/256", "SHA-384", "SHA-512" }; std::vector<uint32_t> security_strengths { 128, 192, 256, 256, 256, 256 }; - for( size_t i = 0; i < approved_hash_fns.size(); ++i ) + for(size_t i = 0; i < approved_hash_fns.size(); ++i) { std::string hash_fn = approved_hash_fns[i]; std::string mac_name = "HMAC(" + hash_fn + ")"; diff --git a/src/tests/test_rng.h b/src/tests/test_rng.h index 9086aaf12..1cfc3a254 100644 --- a/src/tests/test_rng.h +++ b/src/tests/test_rng.h @@ -24,12 +24,17 @@ namespace Botan_Tests { class Fixed_Output_RNG : public Botan::RandomNumberGenerator { public: - bool is_seeded() const override { return !m_buf.empty(); } + bool is_seeded() const override + { + return !m_buf.empty(); + } virtual uint8_t random() { if(!is_seeded()) + { throw Test_Error("Fixed output RNG ran out of bytes, test bug?"); + } uint8_t out = m_buf.front(); m_buf.pop_front(); @@ -38,12 +43,17 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator size_t reseed(Botan::Entropy_Sources&, size_t, - std::chrono::milliseconds) override { return 0; } + std::chrono::milliseconds) override + { + return 0; + } void randomize(uint8_t out[], size_t len) override { for(size_t j = 0; j != len; j++) + { out[j] = random(); + } } void add_entropy(const uint8_t b[], size_t s) override @@ -51,7 +61,10 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator m_buf.insert(m_buf.end(), b, b + s); } - std::string name() const override { return "Fixed_Output_RNG"; } + std::string name() const override + { + return "Fixed_Output_RNG"; + } void clear() BOTAN_NOEXCEPT override {} @@ -68,7 +81,10 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator Fixed_Output_RNG() = default; protected: - size_t remaining() const { return m_buf.size(); } + size_t remaining() const + { + return m_buf.size(); + } std::deque<uint8_t> m_buf; }; @@ -80,7 +96,10 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator class Fixed_Output_Position_RNG : public Fixed_Output_RNG { public: - bool is_seeded() const override { return !m_buf.empty() || Test::rng().is_seeded(); } + bool is_seeded() const override + { + return !m_buf.empty() || Test::rng().is_seeded(); + } uint8_t random() override { @@ -99,15 +118,17 @@ class Fixed_Output_Position_RNG : public Fixed_Output_RNG ++m_requests; if(m_requests == m_pos) - { // return fixed output + { + // return fixed output for(size_t j = 0; j != len; j++) { out[j] = random(); } } else - { // return random - Test::rng().randomize(out,len); + { + // return random + Test::rng().randomize(out, len); } } @@ -116,19 +137,18 @@ class Fixed_Output_Position_RNG : public Fixed_Output_RNG throw Botan::Exception("add_entropy() not supported by this RNG, test bug?"); } - std::string name() const override { return "Fixed_Output_Position_RNG"; } - - explicit Fixed_Output_Position_RNG(const std::vector<uint8_t>& in, uint32_t pos) : - Fixed_Output_RNG(in), - m_pos(pos) + std::string name() const override { + return "Fixed_Output_Position_RNG"; } - explicit Fixed_Output_Position_RNG(const std::string& in_str, uint32_t pos) : - Fixed_Output_RNG(in_str), - m_pos(pos) - { - } + explicit Fixed_Output_Position_RNG(const std::vector<uint8_t>& in, uint32_t pos) + : Fixed_Output_RNG(in) + , m_pos(pos) {} + + explicit Fixed_Output_Position_RNG(const std::string& in_str, uint32_t pos) + : Fixed_Output_RNG(in_str) + , m_pos(pos) {} private: uint32_t m_pos = 0; @@ -139,7 +159,9 @@ class SeedCapturing_RNG : public Botan::RandomNumberGenerator { public: void randomize(uint8_t[], size_t) override - { throw Botan::Exception("SeedCapturing_RNG has no output"); } + { + throw Botan::Exception("SeedCapturing_RNG has no output"); + } void add_entropy(const uint8_t input[], size_t len) override { @@ -148,12 +170,24 @@ class SeedCapturing_RNG : public Botan::RandomNumberGenerator } void clear() override {} - bool is_seeded() const override { return false; } - std::string name() const override { return "SeedCapturing"; } + bool is_seeded() const override + { + return false; + } + std::string name() const override + { + return "SeedCapturing"; + } - size_t samples() const { return m_samples; } + size_t samples() const + { + return m_samples; + } - const std::vector<uint8_t>& seed_material() const { return m_seed; } + const std::vector<uint8_t>& seed_material() const + { + return m_seed; + } private: std::vector<uint8_t> m_seed; diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp index 80a0ca30b..48922f95f 100644 --- a/src/tests/test_rsa.cpp +++ b/src/tests/test_rsa.cpp @@ -8,8 +8,8 @@ #include "test_rng.h" #if defined(BOTAN_HAS_RSA) - #include <botan/rsa.h> - #include "test_pubkey.h" + #include <botan/rsa.h> + #include "test_pubkey.h" #endif namespace Botan_Tests { @@ -21,12 +21,12 @@ namespace { class RSA_ES_KAT_Tests : public PK_Encryption_Decryption_Test { public: - RSA_ES_KAT_Tests() : PK_Encryption_Decryption_Test( - "RSA", - "pubkey/rsaes.vec", - "E,P,Q,Msg,Ciphertext", - "Padding,Nonce") - {} + RSA_ES_KAT_Tests() + : PK_Encryption_Decryption_Test( + "RSA", + "pubkey/rsaes.vec", + "E,P,Q,Msg,Ciphertext", + "Padding,Nonce") {} std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -42,11 +42,11 @@ class RSA_ES_KAT_Tests : public PK_Encryption_Decryption_Test class RSA_KEM_Tests : public PK_KEM_Test { public: - RSA_KEM_Tests() : PK_KEM_Test( - "RSA", - "pubkey/rsa_kem.vec", - "E,P,Q,R,C0,KDF,OutLen,K") - {} + RSA_KEM_Tests() + : PK_KEM_Test( + "RSA", + "pubkey/rsa_kem.vec", + "E,P,Q,R,C0,KDF,OutLen,K") {} std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -63,14 +63,17 @@ class RSA_KEM_Tests : public PK_KEM_Test class RSA_Signature_KAT_Tests : public PK_Signature_Generation_Test { public: - RSA_Signature_KAT_Tests() : PK_Signature_Generation_Test( - "RSA", - "pubkey/rsa_sig.vec", - "E,P,Q,Msg,Signature", - "Padding,Nonce") - {} - - std::string default_padding(const VarMap&) const override { return "Raw"; } + RSA_Signature_KAT_Tests() + : PK_Signature_Generation_Test( + "RSA", + "pubkey/rsa_sig.vec", + "E,P,Q,Msg,Signature", + "Padding,Nonce") {} + + std::string default_padding(const VarMap&) const override + { + return "Raw"; + } std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override { @@ -86,14 +89,17 @@ class RSA_Signature_KAT_Tests : public PK_Signature_Generation_Test class RSA_Signature_Verify_Tests : public PK_Signature_Verification_Test { public: - RSA_Signature_Verify_Tests() : PK_Signature_Verification_Test( - "RSA", - "pubkey/rsa_verify.vec", - "E,N,Msg,Signature", - "Padding") - {} - - std::string default_padding(const VarMap&) const override { return "Raw"; } + RSA_Signature_Verify_Tests() + : PK_Signature_Verification_Test( + "RSA", + "pubkey/rsa_verify.vec", + "E,N,Msg,Signature", + "Padding") {} + + std::string default_padding(const VarMap&) const override + { + return "Raw"; + } std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override { @@ -108,13 +114,16 @@ class RSA_Signature_Verify_Tests : public PK_Signature_Verification_Test class RSA_Signature_Verify_Invalid_Tests : public PK_Signature_NonVerification_Test { public: - RSA_Signature_Verify_Invalid_Tests() : PK_Signature_NonVerification_Test( - "RSA", - "pubkey/rsa_invalid.vec", - "Padding,E,N,Msg,InvalidSignature") - {} + RSA_Signature_Verify_Invalid_Tests() + : PK_Signature_NonVerification_Test( + "RSA", + "pubkey/rsa_invalid.vec", + "Padding,E,N,Msg,InvalidSignature") {} - std::string default_padding(const VarMap&) const override { return "Raw"; } + std::string default_padding(const VarMap&) const override + { + return "Raw"; + } std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override { @@ -128,8 +137,14 @@ class RSA_Signature_Verify_Invalid_Tests : public PK_Signature_NonVerification_T class RSA_Keygen_Tests : public PK_Key_Generation_Test { public: - std::vector<std::string> keygen_params() const override { return { "1024", "1280" }; } - std::string algo_name() const override { return "RSA"; } + std::vector<std::string> keygen_params() const override + { + return { "1024", "1280" }; + } + std::string algo_name() const override + { + return "RSA"; + } }; class RSA_Blinding_Tests : public Test @@ -160,7 +175,7 @@ class RSA_Blinding_Tests : public Test for(size_t i = 1; i <= BOTAN_BLINDING_REINIT_INTERVAL * 6; ++i) { std::vector<uint8_t> input(16); - input[input.size()-1] = static_cast<uint8_t>(i); + input[input.size() - 1] = static_cast<uint8_t>(i); signer.update(input); @@ -207,7 +222,7 @@ class RSA_Blinding_Tests : public Test // one more decryption should trigger a blinder reinitialization result.test_throws("RSA blinding reinit", "Test error Fixed output RNG ran out of bytes, test bug?", - [&decryptor,&encryptor,&null_rng]() + [&decryptor, &encryptor, &null_rng]() { std::vector<uint8_t> ciphertext = encryptor.encrypt(std::vector<uint8_t>(16, 5), null_rng); decryptor.decrypt(ciphertext); @@ -215,7 +230,7 @@ class RSA_Blinding_Tests : public Test #endif - return std::vector<Test::Result>{result}; + return std::vector<Test::Result> {result}; } }; diff --git a/src/tests/test_simd.cpp b/src/tests/test_simd.cpp index 1465d9269..a502432f5 100644 --- a/src/tests/test_simd.cpp +++ b/src/tests/test_simd.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_SIMD_32) - #include <botan/internal/simd_32.h> - #include <botan/cpuid.h> + #include <botan/internal/simd_32.h> + #include <botan/cpuid.h> #endif namespace Botan_Tests { @@ -34,7 +34,7 @@ class SIMD_32_Tests : public Test const uint32_t pat4 = 0xC0D0E0F0; test_eq(result, "default init", Botan::SIMD_4x32(), 0, 0, 0, 0); - test_eq(result, "SIMD scalar constructor", Botan::SIMD_4x32(1,2,3,4), 1, 2, 3, 4); + test_eq(result, "SIMD scalar constructor", Botan::SIMD_4x32(1, 2, 3, 4), 1, 2, 3, 4); const Botan::SIMD_4x32 splat = Botan::SIMD_4x32::splat(pat1); @@ -61,21 +61,21 @@ class SIMD_32_Tests : public Test Botan::rotate_right(pat4, 9)); Botan::SIMD_4x32 add = input + splat; - test_eq(result, "add +", add, pat1+pat1, pat2+pat1, pat3+pat1, pat4+pat1); + test_eq(result, "add +", add, pat1 + pat1, pat2 + pat1, pat3 + pat1, pat4 + pat1); add -= splat; test_eq(result, "sub -=", add, pat1, pat2, pat3, pat4); add += splat; - test_eq(result, "add +=", add, pat1+pat1, pat2+pat1, pat3+pat1, pat4+pat1); + test_eq(result, "add +=", add, pat1 + pat1, pat2 + pat1, pat3 + pat1, pat4 + pat1); - test_eq(result, "xor", input ^ splat, 0, pat2^pat1, pat3^pat1, pat4^pat1); + test_eq(result, "xor", input ^ splat, 0, pat2 ^ pat1, pat3 ^ pat1, pat4 ^ pat1); test_eq(result, "or", input | splat, pat1, pat2 | pat1, pat3 | pat1, pat4 | pat1); test_eq(result, "and", input & splat, pat1, pat2 & pat1, pat3 & pat1, pat4 & pat1); Botan::SIMD_4x32 blender = input; blender |= splat; - test_eq(result, "|=", blender, pat1, pat2|pat1, pat3|pat1, pat4|pat1); + test_eq(result, "|=", blender, pat1, pat2 | pat1, pat3 | pat1, pat4 | pat1); blender &= splat; test_eq(result, "&=", blender, pat1, pat1, pat1, pat1); blender ^= splat; @@ -105,16 +105,16 @@ class SIMD_32_Tests : public Test Botan::reverse_bytes(pat4)); Botan::SIMD_4x32 t1(pat1, pat2, pat3, pat4); - Botan::SIMD_4x32 t2(pat1+1, pat2+1, pat3+1, pat4+1); - Botan::SIMD_4x32 t3(pat1+2, pat2+2, pat3+2, pat4+2); - Botan::SIMD_4x32 t4(pat1+3, pat2+3, pat3+3, pat4+3); + Botan::SIMD_4x32 t2(pat1 + 1, pat2 + 1, pat3 + 1, pat4 + 1); + Botan::SIMD_4x32 t3(pat1 + 2, pat2 + 2, pat3 + 2, pat4 + 2); + Botan::SIMD_4x32 t4(pat1 + 3, pat2 + 3, pat3 + 3, pat4 + 3); Botan::SIMD_4x32::transpose(t1, t2, t3, t4); - test_eq(result, "transpose t1", t1, pat1, pat1+1, pat1+2, pat1+3); - test_eq(result, "transpose t2", t2, pat2, pat2+1, pat2+2, pat2+3); - test_eq(result, "transpose t3", t3, pat3, pat3+1, pat3+2, pat3+3); - test_eq(result, "transpose t4", t4, pat4, pat4+1, pat4+2, pat4+3); + test_eq(result, "transpose t1", t1, pat1, pat1 + 1, pat1 + 2, pat1 + 3); + test_eq(result, "transpose t2", t2, pat2, pat2 + 1, pat2 + 2, pat2 + 3); + test_eq(result, "transpose t3", t3, pat3, pat3 + 1, pat3 + 2, pat3 + 3); + test_eq(result, "transpose t4", t4, pat4, pat4 + 1, pat4 + 2, pat4 + 3); return {result}; } @@ -127,10 +127,14 @@ class SIMD_32_Tests : public Test uint8_t mem_be[16]; simd.store_be(mem_be); - result.test_int_eq("SIMD_4x32 " + op + " elem0 BE", Botan::make_uint32(mem_be[ 0], mem_be[ 1], mem_be[ 2], mem_be[ 3]), exp0); - result.test_int_eq("SIMD_4x32 " + op + " elem1 BE", Botan::make_uint32(mem_be[ 4], mem_be[ 5], mem_be[ 6], mem_be[ 7]), exp1); - result.test_int_eq("SIMD_4x32 " + op + " elem2 BE", Botan::make_uint32(mem_be[ 8], mem_be[ 9], mem_be[10], mem_be[11]), exp2); - result.test_int_eq("SIMD_4x32 " + op + " elem3 BE", Botan::make_uint32(mem_be[12], mem_be[13], mem_be[14], mem_be[15]), exp3); + result.test_int_eq("SIMD_4x32 " + op + " elem0 BE", Botan::make_uint32(mem_be[ 0], mem_be[ 1], mem_be[ 2], mem_be[ 3]), + exp0); + result.test_int_eq("SIMD_4x32 " + op + " elem1 BE", Botan::make_uint32(mem_be[ 4], mem_be[ 5], mem_be[ 6], mem_be[ 7]), + exp1); + result.test_int_eq("SIMD_4x32 " + op + " elem2 BE", Botan::make_uint32(mem_be[ 8], mem_be[ 9], mem_be[10], mem_be[11]), + exp2); + result.test_int_eq("SIMD_4x32 " + op + " elem3 BE", Botan::make_uint32(mem_be[12], mem_be[13], mem_be[14], mem_be[15]), + exp3); // Check load_be+store_be results in same value const Botan::SIMD_4x32 reloaded_be = Botan::SIMD_4x32::load_be(mem_be); @@ -141,10 +145,14 @@ class SIMD_32_Tests : public Test uint8_t mem_le[16]; simd.store_le(mem_le); - result.test_int_eq("SIMD_4x32 " + op + " elem0 LE", Botan::make_uint32(mem_le[ 3], mem_le[ 2], mem_le[ 1], mem_le[ 0]), exp0); - result.test_int_eq("SIMD_4x32 " + op + " elem1 LE", Botan::make_uint32(mem_le[ 7], mem_le[ 6], mem_le[ 5], mem_le[ 4]), exp1); - result.test_int_eq("SIMD_4x32 " + op + " elem2 LE", Botan::make_uint32(mem_le[11], mem_le[10], mem_le[ 9], mem_le[ 8]), exp2); - result.test_int_eq("SIMD_4x32 " + op + " elem3 LE", Botan::make_uint32(mem_le[15], mem_le[14], mem_le[13], mem_le[12]), exp3); + result.test_int_eq("SIMD_4x32 " + op + " elem0 LE", Botan::make_uint32(mem_le[ 3], mem_le[ 2], mem_le[ 1], mem_le[ 0]), + exp0); + result.test_int_eq("SIMD_4x32 " + op + " elem1 LE", Botan::make_uint32(mem_le[ 7], mem_le[ 6], mem_le[ 5], mem_le[ 4]), + exp1); + result.test_int_eq("SIMD_4x32 " + op + " elem2 LE", Botan::make_uint32(mem_le[11], mem_le[10], mem_le[ 9], mem_le[ 8]), + exp2); + result.test_int_eq("SIMD_4x32 " + op + " elem3 LE", Botan::make_uint32(mem_le[15], mem_le[14], mem_le[13], mem_le[12]), + exp3); // Check load_le+store_le results in same value const Botan::SIMD_4x32 reloaded_le = Botan::SIMD_4x32::load_le(mem_le); diff --git a/src/tests/test_srp6.cpp b/src/tests/test_srp6.cpp index 82eea9266..fe3353571 100644 --- a/src/tests/test_srp6.cpp +++ b/src/tests/test_srp6.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_SRP6) - #include <botan/srp6.h> + #include <botan/srp6.h> #endif namespace Botan_Tests { diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp index c2c7ce901..11c723166 100644 --- a/src/tests/test_stream.cpp +++ b/src/tests/test_stream.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_STREAM_CIPHER) -#include <botan/stream_cipher.h> + #include <botan/stream_cipher.h> #endif namespace Botan_Tests { @@ -28,7 +28,9 @@ class Stream_Cipher_Tests : public Text_Based_Test std::vector<uint8_t> input = get_opt_bin(vars, "In"); if(input.empty()) + { input.resize(expected.size()); + } Test::Result result(algo); @@ -41,7 +43,7 @@ class Stream_Cipher_Tests : public Text_Based_Test return result; } - for(auto&& provider_ask : providers) + for(auto const& provider_ask : providers) { std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider_ask)); @@ -59,7 +61,9 @@ class Stream_Cipher_Tests : public Text_Based_Test if(nonce.size()) { if(!cipher->valid_iv_length(nonce.size())) + { throw Test_Error("Invalid nonce for " + algo); + } cipher->set_iv(nonce.data(), nonce.size()); } else @@ -70,12 +74,16 @@ class Stream_Cipher_Tests : public Text_Based_Test * set_iv accepts it. */ if(!cipher->valid_iv_length(0)) + { throw Test_Error("Stream cipher " + algo + " requires nonce but none provided"); + } cipher->set_iv(nullptr, 0); } - if (seek != 0) + if(seek != 0) + { cipher->seek(seek); + } // Test that clone works and does not affect parent object std::unique_ptr<Botan::StreamCipher> clone(cipher->clone()); diff --git a/src/tests/test_tls_messages.cpp b/src/tests/test_tls_messages.cpp index d04bea8a0..383959b19 100644 --- a/src/tests/test_tls_messages.cpp +++ b/src/tests/test_tls_messages.cpp @@ -7,48 +7,47 @@ #include "tests.h" #if defined(BOTAN_HAS_TLS) - #include <exception> - #include <botan/hex.h> - #include <botan/mac.h> - #include <botan/tls_ciphersuite.h> - #include <botan/tls_handshake_msg.h> - #include <botan/tls_messages.h> - #include <botan/tls_alert.h> + #include <exception> + #include <botan/hex.h> + #include <botan/mac.h> + #include <botan/tls_ciphersuite.h> + #include <botan/tls_handshake_msg.h> + #include <botan/tls_messages.h> + #include <botan/tls_alert.h> #endif namespace Botan_Tests { namespace { -#if defined(BOTAN_HAS_TLS) +#if defined(BOTAN_HAS_TLS) Test::Result test_hello_verify_request() { Test::Result result("hello_verify_request construction"); - + std::vector<uint8_t> test_data; std::vector<uint8_t> key_data(32); Botan::SymmetricKey sk(key_data); - + // Compute cookie over an empty string with an empty test data Botan::TLS::Hello_Verify_Request hfr(test_data, "", sk); - + // Compute HMAC std::unique_ptr<Botan::MessageAuthenticationCode> hmac(Botan::MessageAuthenticationCode::create("HMAC(SHA-256)")); hmac->set_key(sk); hmac->update_be(size_t(0)); hmac->update_be(size_t(0)); std::vector<uint8_t> test = unlock(hmac->final()); - + result.test_eq("Cookie comparison", hfr.cookie(), test); return result; } - + class TLS_Message_Parsing_Test : public Text_Based_Test { public: - TLS_Message_Parsing_Test() : - Text_Based_Test("tls", "Buffer,Protocol,Ciphersuite,AdditionalData,Name,Exception") - {} + TLS_Message_Parsing_Test() + : Text_Based_Test("tls", "Buffer,Protocol,Ciphersuite,AdditionalData,Name,Exception") {} Test::Result run_one_test(const std::string& algo, const VarMap& vars) override { @@ -58,9 +57,9 @@ class TLS_Message_Parsing_Test : public Text_Based_Test const std::string exception = get_req_str(vars, "Exception"); const std::string expected_name = get_opt_str(vars, "Name", ""); const bool is_positive_test = exception.empty(); - + Test::Result result(algo + " parsing"); - + if(is_positive_test) { try @@ -118,8 +117,8 @@ class TLS_Message_Parsing_Test : public Text_Based_Test { Botan::secure_vector<uint8_t> sb(buffer.begin(), buffer.end()); Botan::TLS::Alert message(sb); - result.test_lt("Alert type vectors result to UNKNOWN_CA or ACCESS_DENIED, which is shorter than 15", - message.type_string().size(), 15); + result.test_lt("Alert type vectors result to UNKNOWN_CA or ACCESS_DENIED, which is shorter than 15", + message.type_string().size(), 15); } else if(algo == "cert_status") { @@ -141,7 +140,7 @@ class TLS_Message_Parsing_Test : public Text_Based_Test { throw Test_Error("Unknown message type " + algo + " in TLS parsing tests"); } - result.test_success("Correct parsing"); + result.test_success("Correct parsing"); } catch(std::exception& e) { diff --git a/src/tests/test_tpm.cpp b/src/tests/test_tpm.cpp index d6d0158ca..039dd2551 100644 --- a/src/tests/test_tpm.cpp +++ b/src/tests/test_tpm.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_TPM) - #include <botan/tpm.h> + #include <botan/tpm.h> #endif namespace Botan_Tests { @@ -18,7 +18,7 @@ class TPM_Tests : public Test { public: - static std::string pin_cb(const std::string& ) + static std::string pin_cb(const std::string&) { return "123456"; } @@ -55,12 +55,14 @@ class TPM_Tests : public Test std::vector<uint8_t> blob = key.export_blob(); // Has to be at least as large as the key - result.test_gte("Blob size is reasonable", blob.size(), 1024/8); + result.test_gte("Blob size is reasonable", blob.size(), 1024 / 8); std::vector<std::string> registered_keys = Botan::TPM_PrivateKey::registered_keys(*ctx); for(auto url : registered_keys) + { result.test_note("TPM registered key " + url); + } // TODO export public key // TODO generate a signature, verify it diff --git a/src/tests/test_tss.cpp b/src/tests/test_tss.cpp index aacacd0bc..01e0da92f 100644 --- a/src/tests/test_tss.cpp +++ b/src/tests/test_tss.cpp @@ -7,10 +7,12 @@ #include "tests.h" #if defined(BOTAN_HAS_THRESHOLD_SECRET_SHARING) - #include <botan/tss.h> - #include <botan/hex.h> + #include <botan/tss.h> + #include <botan/hex.h> #endif +#include <numeric> + namespace Botan_Tests { namespace { @@ -26,8 +28,7 @@ class TSS_Tests : public Test Test::Result result("TSS"); uint8_t id[16]; - for(int i = 0; i != 16; ++i) - id[i] = i; + std::iota(id, id + sizeof(id), 0); const std::vector<uint8_t> S = Botan::hex_decode("7465737400"); @@ -35,7 +36,7 @@ class TSS_Tests : public Test Botan::RTSS_Share::split(2, 4, S.data(), S.size(), id, Test::rng()); result.test_eq("reconstruction", Botan::RTSS_Share::reconstruct(shares), S); - shares.resize(shares.size()-1); + shares.resize(shares.size() - 1); result.test_eq("reconstruction after removal", Botan::RTSS_Share::reconstruct(shares), S); results.push_back(result); diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp index 8c1d353b4..a1e583cd8 100644 --- a/src/tests/test_utils.cpp +++ b/src/tests/test_utils.cpp @@ -16,7 +16,7 @@ #include <botan/parsing.h> #if defined(BOTAN_HAS_BASE64_CODEC) - #include <botan/base64.h> + #include <botan/base64.h> #endif namespace Botan_Tests { @@ -26,8 +26,7 @@ namespace { class Utility_Function_Tests : public Text_Based_Test { public: - Utility_Function_Tests() : Text_Based_Test("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 { @@ -181,17 +180,18 @@ BOTAN_REGISTER_TEST("util", Utility_Function_Tests); class Date_Format_Tests : public Text_Based_Test { public: - Date_Format_Tests() : Text_Based_Test("dates.vec", "Date") - {} + Date_Format_Tests() : Text_Based_Test("dates.vec", "Date") {} std::vector<uint32_t> parse_date(const std::string& s) { const std::vector<std::string> parts = Botan::split_on(s, ','); if(parts.size() != 6) + { throw Test_Error("Bad date format '" + s + "'"); + } std::vector<uint32_t> u32s; - for(auto&& sub : parts) + for(auto const& sub : parts) { u32s.push_back(Botan::to_u32bit(sub)); } @@ -231,8 +231,7 @@ class Date_Format_Tests : public Text_Based_Test } else if(type == "invalid") { - result.test_throws("invalid date", - [d]() { Botan::calendar_point c(d[0], d[1], d[2], d[3], d[4], d[5]); }); + result.test_throws("invalid date", [d]() { Botan::calendar_point c(d[0], d[1], d[2], d[3], d[4], d[5]); }); } else { @@ -337,8 +336,7 @@ BOTAN_REGISTER_TEST("base64", Base64_Tests); class Charset_Tests : public Text_Based_Test { public: - Charset_Tests() : Text_Based_Test("charset.vec", "In,Out") - {} + Charset_Tests() : Text_Based_Test("charset.vec", "In,Out") {} Test::Result run_one_test(const std::string& type, const VarMap& vars) override { @@ -385,8 +383,8 @@ class Charset_Tests : public Text_Based_Test { // "abcdefŸabcdef" std::vector<uint8_t> input = { 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x01, - 0x78, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66 - }; + 0x78, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66 + }; Charset::transcode(std::string(input.begin(), input.end()), Character_Set::LATIN1_CHARSET, Character_Set::UCS2_CHARSET); @@ -413,8 +411,8 @@ class Charset_Tests : public Text_Based_Test { // "abcdefŸabcdef" std::vector<uint8_t> input = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xC5, - 0xB8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 - }; + 0xB8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; Charset::transcode(std::string(input.begin(), input.end()), Character_Set::LATIN1_CHARSET, Character_Set::UTF8_CHARSET); @@ -473,7 +471,7 @@ class Hostname_Tests : public Text_Based_Test const bool expected = (type == "Invalid") ? false : true; const std::string what = hostname + ((expected == true) ? - " matches " : " does not match ") + issued; + " matches " : " does not match ") + issued; result.test_eq(what, Botan::host_wildcard_match(issued, hostname), expected); return result; diff --git a/src/tests/test_workfactor.cpp b/src/tests/test_workfactor.cpp index a9f9fd062..fecda7d04 100644 --- a/src/tests/test_workfactor.cpp +++ b/src/tests/test_workfactor.cpp @@ -7,7 +7,7 @@ #include "tests.h" #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - #include <botan/workfactor.h> + #include <botan/workfactor.h> #endif namespace Botan_Tests { @@ -17,8 +17,7 @@ class PK_Workfactor_Tests : public Text_Based_Test { public: PK_Workfactor_Tests() : - Text_Based_Test("pubkey/workfactor.vec", "ParamSize,Workfactor") - {} + Text_Based_Test("pubkey/workfactor.vec", "ParamSize,Workfactor") {} Test::Result run_one_test(const std::string& type, const VarMap& vars) override { @@ -30,9 +29,13 @@ class PK_Workfactor_Tests : public Text_Based_Test // TODO: test McEliece strength tests also if(type == "RSA_Strength") + { output = Botan::if_work_factor(param_size); + } else if(type == "DL_Exponent_Size") + { output = Botan::dl_exponent_size(param_size) / 2; + } Test::Result result(type + " work factor calculation"); result.test_eq("Calculated workfactor for " + std::to_string(param_size), diff --git a/src/tests/test_x509_dn.cpp b/src/tests/test_x509_dn.cpp index 3a2fdf7d0..f7a672a73 100644 --- a/src/tests/test_x509_dn.cpp +++ b/src/tests/test_x509_dn.cpp @@ -7,8 +7,8 @@ #include "tests.h" #if defined(BOTAN_HAS_ASN1) - #include <botan/x509_dn.h> - #include <botan/ber_dec.h> + #include <botan/x509_dn.h> + #include <botan/ber_dec.h> #endif namespace Botan_Tests { @@ -17,9 +17,7 @@ namespace Botan_Tests { class X509_DN_Comparisons_Tests : public Text_Based_Test { public: - X509_DN_Comparisons_Tests() : - Text_Based_Test("x509_dn.vec", "DN1,DN2") - {} + X509_DN_Comparisons_Tests() : Text_Based_Test("x509_dn.vec", "DN1,DN2") {} Test::Result run_one_test(const std::string& type, const VarMap& vars) override { diff --git a/src/tests/test_x509_path.cpp b/src/tests/test_x509_path.cpp index ff402bfa4..5fc20e3d7 100644 --- a/src/tests/test_x509_path.cpp +++ b/src/tests/test_x509_path.cpp @@ -7,9 +7,9 @@ #include "tests.h" #if defined(BOTAN_HAS_X509_CERTIFICATES) - #include <botan/x509path.h> - #include <botan/calendar.h> - #include <botan/internal/filesystem.h> + #include <botan/x509path.h> + #include <botan/calendar.h> + #include <botan/internal/filesystem.h> #endif #include <algorithm> @@ -30,7 +30,9 @@ std::map<std::string, std::string> read_results(const std::string& results_file) { std::ifstream in(results_file); if(!in.good()) + { throw Test_Error("Failed reading " + results_file); + } std::map<std::string, std::string> m; std::string line; @@ -38,14 +40,20 @@ std::map<std::string, std::string> read_results(const std::string& results_file) { std::getline(in, line); if(line == "") + { continue; + } if(line[0] == '#') + { continue; + } std::vector<std::string> parts = Botan::split_on(line, ':'); if(parts.size() != 2) + { throw Test_Error("Invalid line " + line); + } m[parts[0]] = parts[1]; } @@ -72,7 +80,7 @@ class X509test_Path_Validation_Tests : public Test Botan::Certificate_Store_In_Memory trusted; trusted.add_certificate(root); - auto validation_time = Botan::calendar_point(2016,10,21,4,20,0).to_std_timepoint(); + auto validation_time = Botan::calendar_point(2016, 10, 21, 4, 20, 0).to_std_timepoint(); for(auto i = expected.begin(); i != expected.end(); ++i) { @@ -85,15 +93,19 @@ class X509test_Path_Validation_Tests : public Test load_cert_file(Test::data_file("x509test/" + filename)); if(certs.empty()) + { throw Test_Error("Failed to read certs from " + filename); + } Botan::Path_Validation_Result path_result = Botan::x509_path_validate( - certs, restrictions, trusted, - "www.tls.test", Botan::Usage_Type::TLS_SERVER_AUTH, - validation_time); + certs, restrictions, trusted, + "www.tls.test", Botan::Usage_Type::TLS_SERVER_AUTH, + validation_time); if(path_result.successful_validation() && path_result.trust_root() != root) + { path_result = Botan::Path_Validation_Result(Botan::Certificate_Status_Code::CANNOT_ESTABLISH_TRUST); + } result.test_eq("test " + filename, path_result.result_string(), expected_result); result.end_timer(); @@ -112,9 +124,10 @@ class X509test_Path_Validation_Tests : public Test std::vector<Botan::X509_Certificate> certs; while(!in.end_of_data()) { - try { - certs.emplace_back(in); - } + try + { + certs.emplace_back(in); + } catch(Botan::Decoding_Error&) {} } @@ -190,7 +203,7 @@ std::vector<Test::Result> NIST_Path_Validation_Tests::run() store.add_certificate(root_cert); store.add_crl(root_crl); - for(auto&& file : all_files) + for(auto const& file : all_files) { if(file.find(".crt") != std::string::npos && file != "end.crt") { diff --git a/src/tests/test_xmss.cpp b/src/tests/test_xmss.cpp index da58057e2..5e3b7bab6 100644 --- a/src/tests/test_xmss.cpp +++ b/src/tests/test_xmss.cpp @@ -8,8 +8,8 @@ #include "tests.h" #if defined(BOTAN_HAS_XMSS) - #include <botan/xmss.h> - #include "test_pubkey.h" + #include <botan/xmss.h> + #include "test_pubkey.h" #endif namespace Botan_Tests { @@ -21,11 +21,11 @@ namespace { class XMSS_Signature_Tests : public PK_Signature_Generation_Test { public: - XMSS_Signature_Tests() : PK_Signature_Generation_Test( - "XMSS", - "pubkey/xmss_sig.vec", - "Params,Msg,PrivateKey,Signature") - {} + XMSS_Signature_Tests() + : PK_Signature_Generation_Test( + "XMSS", + "pubkey/xmss_sig.vec", + "Params,Msg,PrivateKey,Signature") {} bool skip_this_test(const std::string&, const VarMap& vars) override @@ -35,7 +35,9 @@ class XMSS_Signature_Tests : public PK_Signature_Generation_Test const std::string params = get_req_str(vars, "Params"); if(params == "SHAKE128_W16_H10") + { return false; + } return true; } @@ -61,11 +63,11 @@ class XMSS_Signature_Tests : public PK_Signature_Generation_Test class XMSS_Signature_Verify_Tests : public PK_Signature_Verification_Test { public: - XMSS_Signature_Verify_Tests() : PK_Signature_Verification_Test( - "XMSS", - "pubkey/xmss_verify.vec", - "Params,Msg,PublicKey,Signature") - {} + XMSS_Signature_Verify_Tests() + : PK_Signature_Verification_Test( + "XMSS", + "pubkey/xmss_verify.vec", + "Params,Msg,PublicKey,Signature") {} std::string default_padding(const VarMap& vars) const override { @@ -87,7 +89,10 @@ class XMSS_Keygen_Tests : public PK_Key_Generation_Test { return { "XMSS_SHA2-256_W16_H10" }; } - std::string algo_name() const override { return "XMSS"; } + std::string algo_name() const override + { + return "XMSS"; + } }; BOTAN_REGISTER_TEST("xmss_sign", XMSS_Signature_Tests); diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index a678c64ae..2252cb221 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -30,7 +30,9 @@ Test::Registration::Registration(const std::string& name, Test* test) void Test::Result::merge(const Result& other) { if(who() != other.who()) + { throw Test_Error("Merging tests from different sources"); + } m_ns_taken += other.m_ns_taken; m_tests_passed += other.m_tests_passed; @@ -62,7 +64,9 @@ void Test::Result::test_note(const std::string& note, const char* extra) std::ostringstream out; out << who() << " " << note; if(extra) + { out << ": " << extra; + } m_log.push_back(out.str()); } } @@ -80,10 +84,11 @@ void Test::Result::note_missing(const std::string& whatever) bool Test::Result::test_throws(const std::string& what, std::function<void ()> fn) { - try { + try + { fn(); return test_failure(what + " failed to throw expected exception"); - } + } catch(std::exception& e) { return test_success(what + " threw exception " + e.what()); @@ -96,19 +101,21 @@ bool Test::Result::test_throws(const std::string& what, std::function<void ()> f bool Test::Result::test_throws(const std::string& what, const std::string& expected, std::function<void ()> fn) { - try { + try + { fn(); return test_failure(what + " failed to throw expected exception"); - } + } catch(std::exception& e) { - if(expected == e.what()) + if(expected == e.what()) { return test_success(what + " threw exception " + e.what()); } - else + else { - return test_failure(what + " failed to throw an exception with the expected text:\n Expected: " + expected + "\n Got: " + e.what()); + return test_failure(what + " failed to throw an exception with the expected text:\n Expected: " + expected + + "\n Got: " + e.what()); } } catch(...) @@ -150,7 +157,9 @@ bool Test::Result::test_ne(const std::string& what, const uint8_t expected[], size_t expected_len) { if(produced_len == expected_len && Botan::same_mem(produced, expected, expected_len)) + { return test_failure(who() + ": " + what + " produced matching"); + } return test_success(); } @@ -159,7 +168,9 @@ bool Test::Result::test_eq(const char* producer, const std::string& what, const uint8_t expected[], size_t expected_size) { if(produced_size == expected_size && Botan::same_mem(produced, expected, expected_size)) + { return test_success(); + } std::ostringstream err; @@ -201,7 +212,9 @@ bool Test::Result::test_eq(const char* producer, const std::string& what, bool Test::Result::test_is_nonempty(const std::string& what_is_it, const std::string& to_examine) { if(to_examine.empty()) + { return test_failure(what_is_it + " was empty"); + } return test_success(); } @@ -307,7 +320,9 @@ bool Test::Result::test_eq(const std::string& what, const BigInt& produced, cons bool Test::Result::test_ne(const std::string& what, const BigInt& produced, const BigInt& expected) { if(produced != expected) + { return test_success(); + } std::ostringstream err; err << who() << " " << what << " produced " << produced << " prohibited value"; @@ -321,7 +336,9 @@ bool Test::Result::test_eq(const std::string& what, { //return test_is_eq(what, a, b); if(a == b) + { return test_success(); + } std::ostringstream err; err << who() << " " << what << " a=(" << a.get_affine_x() << "," << a.get_affine_y() << ")" @@ -349,6 +366,11 @@ bool Test::Result::test_rc(const std::string& func, int expected, int rc) return test_success(); } +std::vector<std::string> Test::possible_providers(const std::string&) + { + return Test::provider_filter({ "base" }); + } + //static std::string Test::format_time(uint64_t ns) { @@ -356,11 +378,11 @@ std::string Test::format_time(uint64_t ns) if(ns > 1000000000) { - o << std::setprecision(2) << std::fixed << ns/1000000000.0 << " sec"; + o << std::setprecision(2) << std::fixed << ns / 1000000000.0 << " sec"; } else { - o << std::setprecision(2) << std::fixed << ns/1000000.0 << " msec"; + o << std::setprecision(2) << std::fixed << ns / 1000000.0 << " msec"; } return o.str(); @@ -369,7 +391,9 @@ std::string Test::format_time(uint64_t ns) std::string Test::Result::result_string(bool verbose) const { if(tests_run() == 0 && !verbose) + { return ""; + } std::ostringstream report; @@ -403,34 +427,34 @@ std::string Test::Result::result_string(bool verbose) const for(size_t i = 0; i != m_fail_log.size(); ++i) { - report << "Failure " << (i+1) << ": " << m_fail_log[i] << "\n"; + report << "Failure " << (i + 1) << ": " << m_fail_log[i] << "\n"; } if(m_fail_log.size() > 0 || tests_run() == 0 || verbose) { for(size_t i = 0; i != m_log.size(); ++i) { - report << "Note " << (i+1) << ": " << m_log[i] << "\n"; + report << "Note " << (i + 1) << ": " << m_log[i] << "\n"; } } return report.str(); } -std::vector<std::string> Provider_Filter::filter(const std::vector<std::string> &in) const +std::vector<std::string> Provider_Filter::filter(const std::vector<std::string>& in) const { - if(m_provider.empty()) - { - return in; - } - for(auto&& provider : in) + if(m_provider.empty()) + { + return in; + } + for(auto&& provider : in) + { + if(provider == m_provider) { - if(provider == m_provider) - { - return std::vector<std::string> { provider }; - } + return std::vector<std::string> { provider }; } - return std::vector<std::string> {}; + } + return std::vector<std::string> {}; } // static Test:: functions @@ -459,7 +483,9 @@ Test* Test::get_test(const std::string& test_name) { auto i = Test::global_registry().find(test_name); if(i != Test::global_registry().end()) + { return i->second.get(); + } return nullptr; } @@ -479,9 +505,13 @@ std::vector<Test::Result> Test::run_test(const std::string& test_name, bool fail { Test::Result result(test_name); if(fail_if_missing) + { result.test_failure("Test missing or unavailable"); + } else + { result.test_note("Test missing or unavailable"); + } results.push_back(result); } } @@ -570,7 +600,9 @@ std::vector<std::string> Test::provider_filter(const std::vector<std::string>& i Botan::RandomNumberGenerator& Test::rng() { if(!m_test_rng) + { throw Test_Error("No usable RNG in build, and this test requires an RNG"); + } return *m_test_rng; } @@ -586,7 +618,9 @@ Text_Based_Test::Text_Based_Test(const std::string& data_src, m_data_src(data_src) { if(required_keys_str.empty()) + { throw Test_Error("Invalid test spec"); + } std::vector<std::string> required_keys = Botan::split_on(required_keys_str, ','); std::vector<std::string> optional_keys = Botan::split_on(optional_keys_str, ','); @@ -597,11 +631,13 @@ Text_Based_Test::Text_Based_Test(const std::string& data_src, } std::vector<uint8_t> Text_Based_Test::get_req_bin(const VarMap& vars, - const std::string& key) const + const std::string& key) const { auto i = vars.find(key); if(i == vars.end()) + { throw Test_Error("Test missing variable " + key); + } try { @@ -615,12 +651,14 @@ std::vector<uint8_t> Text_Based_Test::get_req_bin(const VarMap& vars, } std::string Text_Based_Test::get_opt_str(const VarMap& vars, - const std::string& key, const std::string& def_value) const + const std::string& key, const std::string& def_value) const { auto i = vars.find(key); if(i == vars.end()) + { return def_value; + } return i->second; } @@ -628,21 +666,31 @@ bool Text_Based_Test::get_req_bool(const VarMap& vars, const std::string& key) c { auto i = vars.find(key); if(i == vars.end()) + { throw Test_Error("Test missing variable " + key); + } if(i->second == "true") + { return true; + } else if(i->second == "false") + { return false; + } else + { throw Test_Error("Invalid boolean for key '" + key + "' value '" + i->second + "'"); + } } size_t Text_Based_Test::get_req_sz(const VarMap& vars, const std::string& key) const { auto i = vars.find(key); if(i == vars.end()) + { throw Test_Error("Test missing variable " + key); + } return Botan::to_u32bit(i->second); } @@ -650,16 +698,20 @@ size_t Text_Based_Test::get_opt_sz(const VarMap& vars, const std::string& key, c { auto i = vars.find(key); if(i == vars.end()) + { return def_value; + } return Botan::to_u32bit(i->second); } std::vector<uint8_t> Text_Based_Test::get_opt_bin(const VarMap& vars, - const std::string& key) const + const std::string& key) const { auto i = vars.find(key); if(i == vars.end()) + { return std::vector<uint8_t>(); + } try { @@ -668,7 +720,7 @@ std::vector<uint8_t> Text_Based_Test::get_opt_bin(const VarMap& vars, catch(std::exception&) { throw Test_Error("Test invalid hex input '" + i->second + "'" + - + " for key " + key); + + " for key " + key); } } @@ -676,17 +728,21 @@ std::string Text_Based_Test::get_req_str(const VarMap& vars, const std::string& { auto i = vars.find(key); if(i == vars.end()) + { throw Test_Error("Test missing variable " + key); + } return i->second; } #if defined(BOTAN_HAS_BIGINT) Botan::BigInt Text_Based_Test::get_req_bn(const VarMap& vars, - const std::string& key) const + const std::string& key) const { auto i = vars.find(key); if(i == vars.end()) + { throw Test_Error("Test missing variable " + key); + } try { @@ -699,8 +755,8 @@ Botan::BigInt Text_Based_Test::get_req_bn(const VarMap& vars, } Botan::BigInt Text_Based_Test::get_opt_bn(const VarMap& vars, - const std::string& key, - const Botan::BigInt& def_value) const + const std::string& key, + const Botan::BigInt& def_value) const { auto i = vars.find(key); @@ -740,7 +796,9 @@ std::string Text_Based_Test::get_next_line() 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 " + full_path); + } } m_first = false; @@ -762,7 +820,9 @@ std::string Text_Based_Test::get_next_line() } if(!m_cur->good()) + { throw Test_Error("Could not open input file '" + m_cur_src_name); + } m_srcs.pop_front(); } @@ -773,14 +833,20 @@ std::string Text_Based_Test::get_next_line() std::getline(*m_cur, line); if(line.empty()) + { continue; + } if(line[0] == '#') { if(line.compare(0, 6, "#test ") == 0) + { return line; + } else + { continue; + } } return line; @@ -797,7 +863,9 @@ std::string strip_ws(const std::string& in) const auto first_c = in.find_first_not_of(whitespace); if(first_c == std::string::npos) + { return ""; + } const auto last_c = in.find_last_not_of(whitespace); @@ -849,11 +917,6 @@ parse_cpuid_bits(const std::vector<std::string>& tok) } -std::vector<std::string> Text_Based_Test::possible_providers(const std::string&) - { - return Test::provider_filter({ "base" }); - } - bool Text_Based_Test::skip_this_test(const std::string& /*header*/, const VarMap& /*vars*/) { @@ -872,17 +935,23 @@ std::vector<Test::Result> Text_Based_Test::run() { const std::string line = get_next_line(); if(line.empty()) // EOF + { break; + } if(line.compare(0, 6, "#test ") == 0) { std::vector<std::string> pragma_tokens = Botan::split_on(line.substr(6), ' '); if(pragma_tokens.empty()) + { throw Test_Error("Empty pragma found in " + m_cur_src_name); + } if(pragma_tokens[0] != "cpuid") + { throw Test_Error("Unknown test pragma '" + line + "' in " + m_cur_src_name); + } m_cpu_flags = parse_cpuid_bits(pragma_tokens); @@ -893,7 +962,7 @@ std::vector<Test::Result> Text_Based_Test::run() throw Test_Error("Unknown test pragma '" + line + "' in " + m_cur_src_name); } - if(line[0] == '[' && line[line.size()-1] == ']') + if(line[0] == '[' && line[line.size() - 1] == ']') { header = line.substr(1, line.size() - 2); header_or_name = header; @@ -927,7 +996,7 @@ std::vector<Test::Result> Text_Based_Test::run() try { if(possible_providers(header).empty() || - skip_this_test(header, vars)) + skip_this_test(header, vars)) { continue; } @@ -939,7 +1008,7 @@ std::vector<Test::Result> Text_Based_Test::run() Test::Result result = run_one_test(header, vars); if(m_cpu_flags.size() > 0) { - for(auto&& cpuid_bit : m_cpu_flags) + for(auto const& cpuid_bit : m_cpu_flags) { if(Botan::CPUID::has_cpuid_bit(cpuid_bit)) { @@ -953,7 +1022,9 @@ std::vector<Test::Result> Text_Based_Test::run() result.set_ns_consumed(Test::timestamp() - start); if(result.tests_failed()) + { result.test_note("Test #" + std::to_string(test_cnt) + " failed"); + } results.push_back(result); } catch(std::exception& e) @@ -990,4 +1061,3 @@ std::vector<Test::Result> Text_Based_Test::run() } } - diff --git a/src/tests/tests.h b/src/tests/tests.h index 406cff57a..0673705d9 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -15,11 +15,11 @@ #include <botan/cpuid.h> #if defined(BOTAN_HAS_BIGINT) - #include <botan/bigint.h> + #include <botan/bigint.h> #endif #if defined(BOTAN_HAS_EC_CURVE_GFP) - #include <botan/point_gfp.h> + #include <botan/point_gfp.h> #endif #include <fstream> @@ -35,7 +35,7 @@ namespace Botan_Tests { #if defined(BOTAN_HAS_BIGINT) -using Botan::BigInt; + using Botan::BigInt; #endif using Botan::OctetString; @@ -51,7 +51,7 @@ class Provider_Filter public: Provider_Filter() {} void set(const std::string& provider) { m_provider = provider; } - std::vector<std::string> filter(const std::vector<std::string> &) const; + std::vector<std::string> filter(const std::vector<std::string>&) const; private: std::string m_provider; }; @@ -75,12 +75,27 @@ class Test public: explicit Result(const std::string& who) : m_who(who) {} - size_t tests_passed() const { return m_tests_passed; } - size_t tests_failed() const { return m_fail_log.size(); } - size_t tests_run() const { return tests_passed() + tests_failed(); } - bool any_results() const { return tests_run() > 0; } + size_t tests_passed() const + { + return m_tests_passed; + } + size_t tests_failed() const + { + return m_fail_log.size(); + } + size_t tests_run() const + { + return tests_passed() + tests_failed(); + } + bool any_results() const + { + return tests_run() > 0; + } - const std::string& who() const { return m_who; } + const std::string& who() const + { + return m_who; + } std::string result_string(bool verbose) const; static Result Failure(const std::string& who, @@ -310,9 +325,12 @@ class Test bool test_throws(const std::string& what, std::function<void ()> fn); bool test_throws(const std::string& what, const std::string& expected, - std::function<void ()> fn); + std::function<void ()> fn); - void set_ns_consumed(uint64_t ns) { m_ns_taken = ns; } + void set_ns_consumed(uint64_t ns) + { + m_ns_taken = ns; + } void start_timer(); void end_timer(); @@ -334,6 +352,7 @@ class Test virtual std::vector<Test::Result> run() = 0; virtual ~Test() = default; + virtual std::vector<std::string> possible_providers(const std::string&); static std::vector<Test::Result> run_test(const std::string& what, bool fail_if_missing); @@ -432,7 +451,10 @@ class Text_Based_Test : public Test const std::string& required_keys, const std::string& optional_keys = ""); - virtual bool clear_between_callbacks() const { return true; } + virtual bool clear_between_callbacks() const + { + return true; + } std::vector<Test::Result> run() override; protected: @@ -442,11 +464,13 @@ class Text_Based_Test : public Test virtual Test::Result run_one_test(const std::string& header, const VarMap& vars) = 0; // Called before run_one_test - virtual std::vector<std::string> possible_providers(const std::string&); virtual bool skip_this_test(const std::string& header, const VarMap& vars); - virtual std::vector<Test::Result> run_final_tests() { return std::vector<Test::Result>(); } + virtual std::vector<Test::Result> run_final_tests() + { + return std::vector<Test::Result>(); + } bool get_req_bool(const VarMap& vars, const std::string& key) const; diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp index 1672c289d..e1e1a15ab 100644 --- a/src/tests/unit_ecc.cpp +++ b/src/tests/unit_ecc.cpp @@ -9,17 +9,17 @@ #include "tests.h" #if defined(BOTAN_HAS_ECC_GROUP) - #include <botan/bigint.h> - #include <botan/numthry.h> - #include <botan/curve_gfp.h> - #include <botan/curve_nistp.h> - #include <botan/point_gfp.h> - #include <botan/ec_group.h> - #include <botan/reducer.h> - #include <botan/oids.h> - #include <botan/hex.h> - #include <botan/data_src.h> - #include <botan/x509_key.h> + #include <botan/bigint.h> + #include <botan/numthry.h> + #include <botan/curve_gfp.h> + #include <botan/curve_nistp.h> + #include <botan/point_gfp.h> + #include <botan/ec_group.h> + #include <botan/reducer.h> + #include <botan/oids.h> + #include <botan/hex.h> + #include <botan/data_src.h> + #include <botan/x509_key.h> #endif namespace Botan_Tests { @@ -28,31 +28,32 @@ namespace { #if defined(BOTAN_HAS_ECC_GROUP) -const std::vector<std::string> ec_groups = { - "brainpool160r1", - "brainpool192r1", - "brainpool224r1", - "brainpool256r1", - "brainpool320r1", - "brainpool384r1", - "brainpool512r1", - "gost_256A", - "secp160k1", - "secp160r1", - "secp160r2", - "secp192k1", - "secp192r1", - "secp224k1", - "secp224r1", - "secp256k1", - "secp256r1", - "secp384r1", - "secp521r1", - "x962_p192v2", - "x962_p192v3", - "x962_p239v1", - "x962_p239v2", - "x962_p239v3" +const std::vector<std::string> ec_groups = + { + "brainpool160r1", + "brainpool192r1", + "brainpool224r1", + "brainpool256r1", + "brainpool320r1", + "brainpool384r1", + "brainpool512r1", + "gost_256A", + "secp160k1", + "secp160r1", + "secp160r2", + "secp192k1", + "secp192r1", + "secp224k1", + "secp224r1", + "secp256k1", + "secp256r1", + "secp384r1", + "secp521r1", + "x962_p192v2", + "x962_p192v3", + "x962_p239v1", + "x962_p239v2", + "x962_p239v3" }; Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigInt max) @@ -63,15 +64,22 @@ Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigIn */ Botan::BigInt x = 0; - auto flip_prob = [](size_t i) -> double { + auto flip_prob = [](size_t i) -> double + { if(i % 64 == 0) + { return .5; + } if(i % 32 == 0) + { return .4; + } if(i % 8 == 0) + { return .05; + } return .01; - }; + }; bool active = rng.next_byte() % 2; for(size_t i = 0; i != bits; ++i) @@ -83,7 +91,9 @@ Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigIn const double sample = double(rng.next_byte() % 100) / 100.0; // biased if(sample < prob) + { active = !active; + } } if(max > 0) @@ -132,7 +142,7 @@ class ECC_Randomized_Tests : public Test std::vector<Test::Result> ECC_Randomized_Tests::run() { std::vector<Test::Result> results; - for(auto&& group_name : ec_groups) + for(auto const& group_name : ec_groups) { Test::Result result("ECC randomized " + group_name); @@ -217,7 +227,7 @@ class NIST_Curve_Reduction_Tests : public Test const Botan::BigInt& p, reducer_fn redc_fn) { - const Botan::BigInt p2 = p*p; + const Botan::BigInt p2 = p * p; const size_t p_bits = p.bits(); Botan::Modular_Reducer p_redc(p); @@ -230,7 +240,7 @@ class NIST_Curve_Reduction_Tests : public Test for(size_t i = 0; i <= trials; ++i) { - const Botan::BigInt x = test_integer(Test::rng(), 2*p_bits, p2); + const Botan::BigInt x = test_integer(Test::rng(), 2 * p_bits, p2); // TODO: time and report all three approaches const Botan::BigInt v1 = x % p; @@ -240,7 +250,7 @@ class NIST_Curve_Reduction_Tests : public Test redc_fn(v3, ws); if(!result.test_eq("reference redc", v1, v2) || - !result.test_eq("specialized redc", v2, v3)) + !result.test_eq("specialized redc", v2, v3)) { result.test_note("failing input" + Botan::hex_encode(Botan::BigInt::encode(x))); } @@ -287,7 +297,7 @@ Version 0.3; Section 2.1.2 -------- */ -Test::Result test_point_transformation () +Test::Result test_point_transformation() { Test::Result result("ECC Unit"); @@ -306,7 +316,7 @@ Test::Result test_point_transformation () return result; } -Test::Result test_point_mult () +Test::Result test_point_mult() { Test::Result result("ECC Unit"); @@ -348,8 +358,8 @@ Test::Result test_zeropoint() const Botan::CurveGFp& curve = secp160r1.get_curve(); Botan::PointGFp p1(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p1.on_the_curve()); p1 -= p1; @@ -387,8 +397,8 @@ Test::Result test_calc_with_zeropoint() const Botan::CurveGFp& curve = secp160r1.get_curve(); Botan::PointGFp p(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p.on_the_curve()); result.confirm("point is not zero", !p.is_zero()); @@ -422,8 +432,8 @@ Test::Result test_add_point() p1 += p0; Botan::PointGFp expected(curve, - Botan::BigInt("704859595002530890444080436569091156047721708633"), - Botan::BigInt("1147993098458695153857594941635310323215433166682")); + Botan::BigInt("704859595002530890444080436569091156047721708633"), + Botan::BigInt("1147993098458695153857594941635310323215433166682")); result.test_eq("point addition", p1, expected); return result; @@ -488,15 +498,15 @@ Test::Result test_basic_operations() const Botan::PointGFp simplePlus = p1 + p0; const Botan::PointGFp exp_simplePlus(curve, - Botan::BigInt("704859595002530890444080436569091156047721708633"), - Botan::BigInt("1147993098458695153857594941635310323215433166682")); + Botan::BigInt("704859595002530890444080436569091156047721708633"), + Botan::BigInt("1147993098458695153857594941635310323215433166682")); result.test_eq("point addition", simplePlus, exp_simplePlus); const Botan::PointGFp simpleMinus = p1 - p0; const Botan::PointGFp exp_simpleMinus(curve, - Botan::BigInt("425826231723888350446541592701409065913635568770"), - Botan::BigInt("203520114162904107873991457957346892027982641970")); + Botan::BigInt("425826231723888350446541592701409065913635568770"), + Botan::BigInt("203520114162904107873991457957346892027982641970")); result.test_eq("point subtraction", simpleMinus, exp_simpleMinus); @@ -538,18 +548,18 @@ Test::Result test_enc_dec_compressed_256() std::string b_secp = "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"; std::string G_secp_comp = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"; - std::vector<uint8_t> sv_p_secp = Botan::hex_decode ( p_secp ); - std::vector<uint8_t> sv_a_secp = Botan::hex_decode ( a_secp ); - std::vector<uint8_t> sv_b_secp = Botan::hex_decode ( b_secp ); - std::vector<uint8_t> sv_G_secp_comp = Botan::hex_decode ( G_secp_comp ); + std::vector<uint8_t> sv_p_secp = Botan::hex_decode(p_secp); + std::vector<uint8_t> sv_a_secp = Botan::hex_decode(a_secp); + std::vector<uint8_t> sv_b_secp = Botan::hex_decode(b_secp); + std::vector<uint8_t> sv_G_secp_comp = Botan::hex_decode(G_secp_comp); - Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() ); - Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() ); - Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() ); + Botan::BigInt bi_p_secp = Botan::BigInt::decode(sv_p_secp.data(), sv_p_secp.size()); + Botan::BigInt bi_a_secp = Botan::BigInt::decode(sv_a_secp.data(), sv_a_secp.size()); + Botan::BigInt bi_b_secp = Botan::BigInt::decode(sv_b_secp.data(), sv_b_secp.size()); Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - Botan::PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve ); + Botan::PointGFp p_G = OS2ECP(sv_G_secp_comp, curve); std::vector<uint8_t> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::COMPRESSED)); result.test_eq("compressed_256", sv_result, sv_G_secp_comp); @@ -568,18 +578,18 @@ Test::Result test_enc_dec_uncompressed_112() std::string b_secp = "51DEF1815DB5ED74FCC34C85D709"; std::string G_secp_uncomp = "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97"; - std::vector<uint8_t> sv_p_secp = Botan::hex_decode ( p_secp ); - std::vector<uint8_t> sv_a_secp = Botan::hex_decode ( a_secp ); - std::vector<uint8_t> sv_b_secp = Botan::hex_decode ( b_secp ); - std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp ); + std::vector<uint8_t> sv_p_secp = Botan::hex_decode(p_secp); + std::vector<uint8_t> sv_a_secp = Botan::hex_decode(a_secp); + std::vector<uint8_t> sv_b_secp = Botan::hex_decode(b_secp); + std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode(G_secp_uncomp); - Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() ); - Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() ); - Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() ); + Botan::BigInt bi_p_secp = Botan::BigInt::decode(sv_p_secp.data(), sv_p_secp.size()); + Botan::BigInt bi_a_secp = Botan::BigInt::decode(sv_a_secp.data(), sv_a_secp.size()); + Botan::BigInt bi_b_secp = Botan::BigInt::decode(sv_b_secp.data(), sv_b_secp.size()); Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - Botan::PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve ); + Botan::PointGFp p_G = OS2ECP(sv_G_secp_uncomp, curve); std::vector<uint8_t> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED)); result.test_eq("uncompressed_112", sv_result, sv_G_secp_uncomp); @@ -591,23 +601,27 @@ Test::Result test_enc_dec_uncompressed_521() Test::Result result("ECC Unit"); // Test for uncompressed conversion(04) with big values(521 bit) - std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - std::string a_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"; - std::string b_secp = "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; - std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"; - - std::vector<uint8_t> sv_p_secp = Botan::hex_decode ( p_secp ); - std::vector<uint8_t> sv_a_secp = Botan::hex_decode ( a_secp ); - std::vector<uint8_t> sv_b_secp = Botan::hex_decode ( b_secp ); - std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp ); - - Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() ); - Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() ); - Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() ); + std::string p_secp = + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + std::string a_secp = + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"; + std::string b_secp = + "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; + std::string G_secp_uncomp = + "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"; + + std::vector<uint8_t> sv_p_secp = Botan::hex_decode(p_secp); + std::vector<uint8_t> sv_a_secp = Botan::hex_decode(a_secp); + std::vector<uint8_t> sv_b_secp = Botan::hex_decode(b_secp); + std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode(G_secp_uncomp); + + Botan::BigInt bi_p_secp = Botan::BigInt::decode(sv_p_secp.data(), sv_p_secp.size()); + Botan::BigInt bi_a_secp = Botan::BigInt::decode(sv_a_secp.data(), sv_a_secp.size()); + Botan::BigInt bi_b_secp = Botan::BigInt::decode(sv_b_secp.data(), sv_b_secp.size()); Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_secp_uncomp, curve ); + Botan::PointGFp p_G = Botan::OS2ECP(sv_G_secp_uncomp, curve); std::vector<uint8_t> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED)); @@ -620,26 +634,30 @@ Test::Result test_enc_dec_uncompressed_521_prime_too_large() Test::Result result("ECC Unit"); // Test for uncompressed conversion(04) with big values(521 bit) - std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // length increased by "ff" - std::string a_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"; - std::string b_secp = "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; - std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"; - - std::vector<uint8_t> sv_p_secp = Botan::hex_decode ( p_secp ); - std::vector<uint8_t> sv_a_secp = Botan::hex_decode ( a_secp ); - std::vector<uint8_t> sv_b_secp = Botan::hex_decode ( b_secp ); - std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp ); - - Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() ); - Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() ); - Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() ); - - Botan::CurveGFp secp521r1 (bi_p_secp, bi_a_secp, bi_b_secp); + std::string p_secp = + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // length increased by "ff" + std::string a_secp = + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFC"; + std::string b_secp = + "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; + std::string G_secp_uncomp = + "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"; + + std::vector<uint8_t> sv_p_secp = Botan::hex_decode(p_secp); + std::vector<uint8_t> sv_a_secp = Botan::hex_decode(a_secp); + std::vector<uint8_t> sv_b_secp = Botan::hex_decode(b_secp); + std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode(G_secp_uncomp); + + Botan::BigInt bi_p_secp = Botan::BigInt::decode(sv_p_secp.data(), sv_p_secp.size()); + Botan::BigInt bi_a_secp = Botan::BigInt::decode(sv_a_secp.data(), sv_a_secp.size()); + Botan::BigInt bi_b_secp = Botan::BigInt::decode(sv_b_secp.data(), sv_b_secp.size()); + + Botan::CurveGFp secp521r1(bi_p_secp, bi_a_secp, bi_b_secp); std::unique_ptr<Botan::PointGFp> p_G; try { - p_G = std::unique_ptr<Botan::PointGFp>(new Botan::PointGFp(Botan::OS2ECP ( sv_G_secp_uncomp, secp521r1))); + p_G = std::unique_ptr<Botan::PointGFp>(new Botan::PointGFp(Botan::OS2ECP(sv_G_secp_uncomp, secp521r1))); result.test_failure("point decoding with too large value accepted"); } catch(std::exception&) @@ -671,16 +689,20 @@ Test::Result test_cdc_curve_33() { Test::Result result("ECC Unit"); - std::string G_secp_uncomp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; + std::string G_secp_uncomp = + "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; - std::vector<uint8_t> sv_G_uncomp = Botan::hex_decode ( G_secp_uncomp ); + std::vector<uint8_t> sv_G_uncomp = Botan::hex_decode(G_secp_uncomp); - Botan::BigInt bi_p_secp = Botan::BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); - Botan::BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); - Botan::BigInt bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); + Botan::BigInt bi_p_secp = + Botan::BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); + Botan::BigInt + bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); + Botan::BigInt + bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_uncomp, curve); + Botan::PointGFp p_G = Botan::OS2ECP(sv_G_uncomp, curve); result.confirm("point is on the curve", p_G.on_the_curve()); return result; } @@ -695,8 +717,8 @@ Test::Result test_more_zeropoint() const Botan::CurveGFp& curve = secp160r1.get_curve(); Botan::PointGFp p1(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p1.on_the_curve()); Botan::PointGFp minus_p1 = -p1; @@ -760,7 +782,7 @@ Test::Result test_mult_sec_mass() Test::Result result("ECC Unit"); Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); - for(int i = 0; i<50; i++) + for(int i = 0; i < 50; i++) { try { @@ -806,8 +828,8 @@ class ECC_Unit_Tests : public Test std::vector<Test::Result> results; results.push_back(test_coordinates()); - results.push_back(test_point_transformation ()); - results.push_back(test_point_mult ()); + results.push_back(test_point_transformation()); + results.push_back(test_point_mult()); results.push_back(test_point_negative()); results.push_back(test_zeropoint()); results.push_back(test_zeropoint_enc_dec()); @@ -841,7 +863,10 @@ class ECC_Invalid_Key_Tests : public Text_Based_Test ECC_Invalid_Key_Tests() : Text_Based_Test("pubkey/ecc_invalid.vec", "SubjectPublicKey") {} - bool clear_between_callbacks() const override { return false; } + bool clear_between_callbacks() const override + { + return false; + } Test::Result run_one_test(const std::string&, const VarMap& vars) override { diff --git a/src/tests/unit_ecdh.cpp b/src/tests/unit_ecdh.cpp index 1f2786440..8489d00d4 100644 --- a/src/tests/unit_ecdh.cpp +++ b/src/tests/unit_ecdh.cpp @@ -10,8 +10,8 @@ #include "tests.h" #if defined(BOTAN_HAS_ECDH) - #include <botan/pubkey.h> - #include <botan/ecdh.h> + #include <botan/pubkey.h> + #include <botan/ecdh.h> #endif namespace Botan_Tests { @@ -38,7 +38,7 @@ class ECDH_Unit_Tests : public Test std::vector<std::string> params = { "secp256r1", "secp384r1", "secp521r1", "brainpool256r1" }; - for(auto&& param : params) + for(auto const& param : params) { try { diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index 96aa36969..fa77814ad 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -10,18 +10,19 @@ #include "tests.h" #include <botan/hex.h> +#include <numeric> #if defined(BOTAN_HAS_ECDSA) - #include <botan/pubkey.h> - #include <botan/ecdsa.h> - #include <botan/ec_group.h> - #include <botan/oids.h> - #include <botan/pkcs8.h> - #include <botan/hash.h> + #include <botan/pubkey.h> + #include <botan/ecdsa.h> + #include <botan/ec_group.h> + #include <botan/oids.h> + #include <botan/pkcs8.h> + #include <botan/hash.h> #endif #if defined(BOTAN_HAS_X509_CERTIFICATES) - #include <botan/x509cert.h> + #include <botan/x509cert.h> #endif namespace Botan_Tests { @@ -41,14 +42,13 @@ Test::Result test_hash_larger_than_n() Test::Result result("ECDSA Unit"); Botan::EC_Group dom_pars("secp160r1"); - + // n = 0x0100000000000000000001f4c8f927aed3ca752257 (21 bytes) Botan::ECDSA_PrivateKey priv_key(Test::rng(), dom_pars); std::vector<uint8_t> message(20); - for(size_t i = 0; i != message.size(); ++i) - message[i] = i; + std::iota(message.begin(), message.end(), 0); auto sha1 = Botan::HashFunction::create("SHA-1"); auto sha224 = Botan::HashFunction::create("SHA-224"); @@ -85,7 +85,8 @@ Test::Result test_decode_ecdsa_X509() result.test_eq("serial number", cert.serial_number(), Botan::hex_decode("01")); result.test_eq("authority key id", cert.authority_key_id(), cert.subject_key_id()); - result.test_eq("key fingerprint", cert.fingerprint("SHA-1"), "32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9"); + result.test_eq("key fingerprint", cert.fingerprint("SHA-1"), + "32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9"); std::unique_ptr<Botan::Public_Key> pubkey(cert.subject_public_key()); result.test_eq("verify self-signed signature", cert.check_signature(*pubkey), true); @@ -171,9 +172,11 @@ Test::Result test_ec_sign() // now check with original input, modified signature - sig[sig.size()/2]++; + sig[sig.size() / 2]++; for(size_t i = 0; i != 256; ++i) + { verifier.update(static_cast<uint8_t>(i)); + } result.test_eq("invalid ECDSA signature invalid", verifier.check_signature(sig), false); } @@ -227,17 +230,23 @@ Test::Result test_unusual_curve() Test::Result result("ECDSA Unit"); //calc a curve which is not in the registry - const std::string G_secp_comp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; - const Botan::BigInt bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); - const Botan::BigInt bi_a_secp("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); - const Botan::BigInt bi_b_secp("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); + const std::string G_secp_comp = + "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; + const Botan::BigInt + bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); + const Botan::BigInt + bi_a_secp("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); + const Botan::BigInt + bi_b_secp("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); Botan::BigInt bi_order_g("0x0e1a16196e6000000000bc7f1618d867b15bb86474418f"); Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); Botan::PointGFp p_G = Botan::OS2ECP(Botan::hex_decode(G_secp_comp), curve); Botan::EC_Group dom_params(curve, p_G, bi_order_g, Botan::BigInt(1)); if(!result.confirm("point is on curve", p_G.on_the_curve())) + { return result; + } Botan::ECDSA_PrivateKey key_odd_curve(Test::rng(), dom_params); std::string key_odd_curve_str = Botan::PKCS8::PEM_encode(key_odd_curve); @@ -258,11 +267,14 @@ Test::Result test_read_pkcs8() try { - std::unique_ptr<Botan::Private_Key> loaded_key_nodp(Botan::PKCS8::load_key(Test::data_file("ecc/nodompar_private.pkcs8.pem"), Test::rng())); + 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()); if(!ecdsa_nodp) + { throw Test_Error("Unable to load valid PKCS8 ECDSA key"); + } Botan::PK_Signer signer(*ecdsa_nodp, Test::rng(), "EMSA1(SHA-256)"); Botan::PK_Verifier verifier(*ecdsa_nodp, "EMSA1(SHA-256)"); @@ -295,7 +307,8 @@ Test::Result test_read_pkcs8() Test::Result test_curve_registry() { - const std::vector<std::string> oids = { + const std::vector<std::string> oids = + { "1.3.132.0.8", "1.2.840.10045.3.1.1", "1.2.840.10045.3.1.2", @@ -323,7 +336,7 @@ Test::Result test_curve_registry() Test::Result result("ECDSA Unit"); - for(auto&& oid_str : oids) + for(auto const& oid_str : oids) { try { diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index 28152e624..5ec44331c 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -16,25 +16,25 @@ #if defined(BOTAN_HAS_TLS) -#include <botan/tls_client.h> -#include <botan/tls_server.h> - -#include <botan/ec_group.h> -#include <botan/hex.h> -#include <botan/pkcs10.h> -#include <botan/rsa.h> -#include <botan/ecdsa.h> -#include <botan/tls_handshake_msg.h> -#include <botan/x509_ca.h> -#include <botan/x509self.h> - -#if defined(BOTAN_HAS_DSA) - #include <botan/dsa.h> -#endif - -#if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) - #include <botan/tls_session_manager_sqlite.h> -#endif + #include <botan/tls_client.h> + #include <botan/tls_server.h> + + #include <botan/ec_group.h> + #include <botan/hex.h> + #include <botan/pkcs10.h> + #include <botan/rsa.h> + #include <botan/ecdsa.h> + #include <botan/tls_handshake_msg.h> + #include <botan/x509_ca.h> + #include <botan/x509self.h> + + #if defined(BOTAN_HAS_DSA) + #include <botan/dsa.h> + #endif + + #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) + #include <botan/tls_session_manager_sqlite.h> + #endif #endif @@ -93,8 +93,10 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager const std::string&) override { std::vector<Botan::Certificate_Store*> v; - for(auto&& store : m_stores) + for(auto const& store : m_stores) + { v.push_back(store.get()); + } return v; } @@ -107,7 +109,7 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager if(type == "tls-server" || (type == "tls-client" && m_provides_client_certs)) { - for(auto&& key_type : cert_key_types) + for(auto const& key_type : cert_key_types) { if(key_type == "RSA") { @@ -146,11 +148,17 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager const std::string&) override { if(crt == m_rsa_cert) + { return m_rsa_key.get(); + } if(crt == m_ecdsa_cert) + { return m_ecdsa_key.get(); + } if(crt == *m_dsa_cert) + { return m_dsa_key.get(); + } return nullptr; } @@ -159,13 +167,19 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager const std::string&) override { if(type == "tls-server" && context == "session-ticket") + { return Botan::SymmetricKey("AABBCCDDEEFF012345678012345678"); + } if(context == "server.example.com" && type == "tls-client") + { return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD"); + } if(context == "server.example.com" && type == "tls-server") + { return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD"); + } throw Test_Error("No PSK set for " + type + "/" + context); } @@ -249,14 +263,14 @@ create_creds(Botan::RandomNumberGenerator& rng, dsa_ca_opts.CA_key(1); dsa_ca_cert.reset(new Botan::X509_Certificate( - Botan::X509::create_self_signed_cert(dsa_ca_opts, *dsa_ca_key, "SHA-256", rng))); + Botan::X509::create_self_signed_cert(dsa_ca_opts, *dsa_ca_key, "SHA-256", rng))); const Botan::PKCS10_Request dsa_req = - Botan::X509::create_cert_req(server_opts, *dsa_srv_key, "SHA-256", rng); + Botan::X509::create_cert_req(server_opts, *dsa_srv_key, "SHA-256", rng); Botan::X509_CA dsa_ca(*dsa_ca_cert, *dsa_ca_key, "SHA-256", rng); dsa_srv_cert.reset(new Botan::X509_Certificate( - dsa_ca.sign_request(dsa_req, rng, start_time, end_time))); + dsa_ca.sign_request(dsa_req, rng, start_time, end_time))); dsa_crl.reset(new Botan::X509_CRL(dsa_ca.new_crl(rng))); #endif @@ -301,7 +315,8 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, result.test_note("Test round " + std::to_string(r)); - auto handshake_complete = [&](const Botan::TLS::Session& session) -> bool { + auto handshake_complete = [&](const Botan::TLS::Session& session) + { handshake_done = true; const std::string session_report = @@ -313,16 +328,18 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, if(session.version() != offer_version) { - result.test_failure("Offered " + offer_version.to_string() + - " got " + session.version().to_string()); + result.test_failure("Offered " + offer_version.to_string() + " got " + session.version().to_string()); } if(r <= 2) + { return true; + } return false; - }; + }; - auto next_protocol_chooser = [&](std::vector<std::string> protos) -> std::string { + auto next_protocol_chooser = [&](std::vector<std::string> protos) -> std::string + { if(r <= 2) { result.test_eq("protocol count", protos.size(), 2); @@ -330,7 +347,7 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, result.test_eq("protocol[1]", protos[1], "test/2"); } return "test/3"; - }; + }; const std::vector<std::string> protocols_offered = { "test/1", "test/2" }; @@ -339,12 +356,12 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, std::vector<uint8_t> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent; std::unique_ptr<Botan::TLS::Callbacks> server_cb(new Botan::TLS::Compat_Callbacks( - queue_inserter(s2c_traffic), - queue_inserter(server_recv), - std::function<void (Botan::TLS::Alert, const uint8_t[], size_t)>(alert_cb_with_data), - handshake_complete, - nullptr, - next_protocol_chooser)); + queue_inserter(s2c_traffic), + queue_inserter(server_recv), + std::function<void (Botan::TLS::Alert, const uint8_t[], size_t)>(alert_cb_with_data), + handshake_complete, + nullptr, + next_protocol_chooser)); // TLS::Server object constructed by new constructor using virtual callback interface. std::unique_ptr<Botan::TLS::Server> server( @@ -356,10 +373,10 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, false)); std::unique_ptr<Botan::TLS::Callbacks> client_cb(new Botan::TLS::Compat_Callbacks( - queue_inserter(c2s_traffic), - queue_inserter(client_recv), - std::function<void (Botan::TLS::Alert, const uint8_t[], size_t)>(alert_cb_with_data), - handshake_complete)); + queue_inserter(c2s_traffic), + queue_inserter(client_recv), + std::function<void (Botan::TLS::Alert, const uint8_t[], size_t)>(alert_cb_with_data), + handshake_complete)); // TLS::Client object constructed by new constructor using virtual callback interface. std::unique_ptr<Botan::TLS::Client> client( @@ -428,7 +445,9 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, } if(handshake_done && (client->is_closed() || server->is_closed())) + { break; + } if(client->is_active() && client_sent.empty()) { @@ -491,8 +510,8 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, size_t total_consumed = needed; while(needed > 0 && - result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE+1) && - result.test_lt("Total requested is readonable", total_consumed, 128*1024)) + result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE + 1) && + result.test_lt("Total requested is readonable", total_consumed, 128 * 1024)) { input.resize(needed); rng.randomize(input.data(), input.size()); @@ -521,7 +540,8 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, size_t total_consumed = 0; - while(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE+1)) + while(needed > 0 && + result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE + 1)) { input.resize(needed); rng.randomize(input.data(), input.size()); @@ -557,7 +577,9 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, } if(client->is_closed() && server->is_closed()) + { break; + } if(server_recv.size() && client_recv.size()) { @@ -567,9 +589,13 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, result.test_eq("TLS key material export", client_key.bits_of(), server_key.bits_of()); if(r % 2 == 0) + { client->close(); + } else + { server->close(); + } } } } @@ -621,19 +647,20 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, { bool handshake_done = false; - auto handshake_complete = [&](const Botan::TLS::Session& session) -> bool { + auto handshake_complete = [&](const Botan::TLS::Session & session) -> bool + { handshake_done = true; if(session.version() != offer_version) { - result.test_failure("Offered " + offer_version.to_string() + - " got " + session.version().to_string()); + result.test_failure("Offered " + offer_version.to_string() + " got " + session.version().to_string()); } return true; - }; + }; - auto next_protocol_chooser = [&](std::vector<std::string> protos) -> std::string { + auto next_protocol_chooser = [&](std::vector<std::string> protos) -> std::string + { if(r <= 2) { result.test_eq("protocol count", protos.size(), 2); @@ -641,7 +668,7 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, result.test_eq("protocol[1]", protos[1], "test/2"); } return "test/3"; - }; + }; const std::vector<std::string> protocols_offered = { "test/1", "test/2" }; @@ -650,18 +677,18 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, std::vector<uint8_t> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent; std::unique_ptr<Botan::TLS::Callbacks> server_cb(new Botan::TLS::Compat_Callbacks( - queue_inserter(s2c_traffic), - queue_inserter(server_recv), - std::function<void (Botan::TLS::Alert)>(print_alert), - handshake_complete, - nullptr, - next_protocol_chooser)); + queue_inserter(s2c_traffic), + queue_inserter(server_recv), + std::function<void (Botan::TLS::Alert)>(print_alert), + handshake_complete, + nullptr, + next_protocol_chooser)); std::unique_ptr<Botan::TLS::Callbacks> client_cb(new Botan::TLS::Compat_Callbacks( - queue_inserter(c2s_traffic), - queue_inserter(client_recv), - std::function<void (Botan::TLS::Alert)>(print_alert), - handshake_complete)); + queue_inserter(c2s_traffic), + queue_inserter(client_recv), + std::function<void (Botan::TLS::Alert)>(print_alert), + handshake_complete)); // TLS::Server object constructed by new constructor using virtual callback interface. std::unique_ptr<Botan::TLS::Server> server( @@ -686,7 +713,7 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, size_t rounds = 0; // Test DTLS using both new and legacy constructors. - for(size_t ctor_sel = 0; ctor_sel < 2; ctor_sel++) + for(size_t ctor_sel = 0; ctor_sel < 2; ++ctor_sel) { if(ctor_sel == 1) { @@ -737,7 +764,9 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, } if(handshake_done && (client->is_closed() || server->is_closed())) + { break; + } if(client->is_active() && client_sent.empty()) { @@ -776,7 +805,8 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, input = Test::mutate_vec(input, true, 5); size_t needed = server->received_data(input.data(), input.size()); - if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE+1)) + if(needed > 0 && + result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE + 1)) { input.resize(needed); rng.randomize(input.data(), input.size()); @@ -816,7 +846,8 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, input = Test::mutate_vec(input, true, 5); size_t needed = client->received_data(input.data(), input.size()); - if(needed > 0 && result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE+1)) + if(needed > 0 && + result.test_lt("Never requesting more than max protocol len", needed, Botan::TLS::MAX_CIPHERTEXT_SIZE + 1)) { input.resize(needed); rng.randomize(input.data(), input.size()); @@ -846,9 +877,13 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, // If we corrupted a DTLS application message, resend it: if(client->is_active() && corrupt_client_data && server_recv.empty()) + { client->send(client_sent); + } if(server->is_active() && corrupt_server_data && client_recv.empty()) + { server->send(server_sent); + } if(client_recv.size()) { @@ -861,7 +896,9 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, } if(client->is_closed() && server->is_closed()) + { break; + } if(server_recv.size() && client_recv.size()) { @@ -871,9 +908,13 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, result.test_eq("key material export", client_key.bits_of(), server_key.bits_of()); if(r % 2 == 0) + { client->close(); + } else + { server->close(); + } } } } @@ -909,22 +950,41 @@ class Test_Policy : public Botan::TLS::Text_Policy { public: Test_Policy() : Text_Policy("") {} - bool acceptable_protocol_version(Botan::TLS::Protocol_Version) const override { return true; } - bool send_fallback_scsv(Botan::TLS::Protocol_Version) const override { return false; } + bool acceptable_protocol_version(Botan::TLS::Protocol_Version) const override + { + return true; + } + bool send_fallback_scsv(Botan::TLS::Protocol_Version) const override + { + return false; + } - size_t dtls_initial_timeout() const override { return 1; } - size_t dtls_maximum_timeout() const override { return 8; } + size_t dtls_initial_timeout() const override + { + return 1; + } + size_t dtls_maximum_timeout() const override + { + return 8; + } - size_t minimum_rsa_bits() const override { return 1024; } + size_t minimum_rsa_bits() const override + { + return 1024; + } - size_t minimum_signature_strength() const override { return 80; } + size_t minimum_signature_strength() const override + { + return 80; + } }; Test::Result test_tls_alert_strings() { Test::Result result("TLS::Alert::type_string"); - const std::vector<Botan::TLS::Alert::Type> alert_types = { + const std::vector<Botan::TLS::Alert::Type> alert_types = + { Botan::TLS::Alert::CLOSE_NOTIFY, Botan::TLS::Alert::UNEXPECTED_MESSAGE, Botan::TLS::Alert::BAD_RECORD_MAC, @@ -957,7 +1017,7 @@ Test::Result test_tls_alert_strings() Botan::TLS::Alert::BAD_CERTIFICATE_HASH_VALUE, Botan::TLS::Alert::UNKNOWN_PSK_IDENTITY, Botan::TLS::Alert:: NO_APPLICATION_PROTOCOL, - }; + }; std::set<std::string> seen; @@ -968,7 +1028,7 @@ Test::Result test_tls_alert_strings() seen.insert(str); } - Botan::TLS::Alert unknown_alert = Botan::TLS::Alert(Botan::secure_vector<uint8_t>{01, 66}); + Botan::TLS::Alert unknown_alert = Botan::TLS::Alert({01, 66}); result.test_eq("Unknown alert str", unknown_alert.type_string(), "unrecognized_alert_66"); @@ -982,7 +1042,9 @@ std::string read_tls_policy(const std::string& policy_str) std::ifstream is(fspath.c_str()); if(!is.good()) + { throw Test_Error("Missing policy file " + fspath); + } Botan::TLS::Text_Policy policy(is); return policy.to_string(); @@ -992,17 +1054,29 @@ std::string tls_policy_string(const std::string& policy_str) { std::unique_ptr<Botan::TLS::Policy> policy; if(policy_str == "default") + { policy.reset(new Botan::TLS::Policy); + } else if(policy_str == "suiteb") + { policy.reset(new Botan::TLS::NSA_Suite_B_128); + } else if(policy_str == "bsi") + { policy.reset(new Botan::TLS::BSI_TR_02102_2); + } else if(policy_str == "strict") + { policy.reset(new Botan::TLS::Strict_Policy); + } else if(policy_str == "datagram") + { policy.reset(new Botan::TLS::Datagram_Policy); + } else + { throw Test_Error("Unknown TLS policy type '" + policy_str + "'"); + } return policy->to_string(); } @@ -1035,12 +1109,16 @@ class TLS_Unit_Tests : public Test { Botan::RandomNumberGenerator& rng = Test::rng(); - for(auto&& version : versions) + for(auto const& version : versions) { if(version.is_datagram_protocol()) + { results.push_back(test_dtls_handshake(version, creds, policy, rng, client_ses, server_ses)); + } else + { results.push_back(test_tls_handshake(version, creds, policy, rng, client_ses, server_ses)); + } } } @@ -1060,15 +1138,18 @@ class TLS_Unit_Tests : public Test policy.set("negotiate_encrypt_then_mac", etm_policy); if(kex_policy == "RSA") + { policy.set("signature_methods", "RSA"); + } - std::vector<Botan::TLS::Protocol_Version> versions = { + std::vector<Botan::TLS::Protocol_Version> versions = + { Botan::TLS::Protocol_Version::TLS_V10, Botan::TLS::Protocol_Version::TLS_V11, Botan::TLS::Protocol_Version::TLS_V12, Botan::TLS::Protocol_Version::DTLS_V10, Botan::TLS::Protocol_Version::DTLS_V12 - }; + }; return test_with_policy(results, client_ses, server_ses, creds, versions, policy); } @@ -1100,13 +1181,16 @@ class TLS_Unit_Tests : public Test policy.set("macs", mac_policy); policy.set("key_exchange_methods", kex_policy); - for(auto&& kv : extra_policies) + for(auto const& kv : extra_policies) + { policy.set(kv.first, kv.second); + } - std::vector<Botan::TLS::Protocol_Version> versions = { + std::vector<Botan::TLS::Protocol_Version> versions = + { Botan::TLS::Protocol_Version::TLS_V12, Botan::TLS::Protocol_Version::DTLS_V12 - }; + }; return test_with_policy(results, client_ses, server_ses, creds, versions, policy); } @@ -1124,9 +1208,13 @@ class TLS_Unit_Tests : public Test result.test_eq("Valid Ciphersuite is not SCSV", Botan::TLS::Ciphersuite::is_scsv(csuite_id), false); if(ciphersuite.cbc_ciphersuite() == false) + { result.test_eq("Expected MAC name for AEAD ciphersuites", ciphersuite.mac_algo(), "AEAD"); + } else + { result.test_eq("MAC algo and PRF algo same for CBC suites", ciphersuite.prf_algo(), ciphersuite.mac_algo()); + } // TODO more tests here } @@ -1151,10 +1239,10 @@ class TLS_Unit_Tests : public Test #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) client_ses.reset( new Botan::TLS::Session_Manager_SQLite("pass", rng, ":memory:", 5, - std::chrono::seconds(2))); + std::chrono::seconds(2))); server_ses.reset( new Botan::TLS::Session_Manager_SQLite("pass", rng, ":memory:", 10, - std::chrono::seconds(4))); + std::chrono::seconds(4))); #else client_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng)); server_ses.reset(new Botan::TLS::Session_Manager_In_Memory(rng)); @@ -1173,7 +1261,8 @@ class TLS_Unit_Tests : public Test #if defined(BOTAN_HAS_CAMELLIA) test_all_versions(results, *client_ses, *server_ses, *creds, "RSA", "Camellia-128", "SHA-256 SHA-1", etm_setting); - test_all_versions(results, *client_ses, *server_ses, *creds, "RSA", "Camellia-256", "SHA-256 SHA-384 SHA-1", etm_setting); + test_all_versions(results, *client_ses, *server_ses, *creds, "RSA", "Camellia-256", "SHA-256 SHA-384 SHA-1", + etm_setting); #endif #if defined(BOTAN_HAS_DES) @@ -1193,20 +1282,20 @@ class TLS_Unit_Tests : public Test #if defined(BOTAN_HAS_DSA) test_modern_versions(results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256", - { { "signature_methods", "DSA" } }); + { { "signature_methods", "DSA" } }); test_modern_versions(results, *client_ses, *server_ses, *creds, "DH", "AES-256", "SHA-256", - { { "signature_methods", "DSA" } }); + { { "signature_methods", "DSA" } }); #endif #endif Botan::TLS::Strict_Policy strict_policy; test_with_policy(results, *client_ses, *server_ses, *creds, - {Botan::TLS::Protocol_Version::TLS_V12}, strict_policy); + {Botan::TLS::Protocol_Version::TLS_V12}, strict_policy); Botan::TLS::NSA_Suite_B_128 suiteb_128; test_with_policy(results, *client_ses, *server_ses, *creds, - {Botan::TLS::Protocol_Version::TLS_V12}, suiteb_128); + {Botan::TLS::Protocol_Version::TLS_V12}, suiteb_128); // Remove server sessions before client, so clients retry with session server doesn't know server_ses->remove_all(); @@ -1215,13 +1304,13 @@ class TLS_Unit_Tests : public Test test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM"); test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", - { { "signature_methods", "RSA" } }); + { { "signature_methods", "RSA" } }); #if defined(BOTAN_HAS_DSA) test_modern_versions(results, *client_ses, *server_ses, *creds, "DH", "AES-128/GCM", "AEAD", - { { "signature_methods", "DSA" } }); + { { "signature_methods", "DSA" } }); test_modern_versions(results, *client_ses, *server_ses, *creds, "DH", "AES-256/GCM", "AEAD", - { { "signature_methods", "DSA" } }); + { { "signature_methods", "DSA" } }); #endif client_ses->remove_all(); @@ -1242,26 +1331,26 @@ class TLS_Unit_Tests : public Test #if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_AEAD_OCB) test_modern_versions(results, *client_ses, *server_ses, *creds, "CECPQ1", "AES-256/OCB(12)", "AEAD"); test_modern_versions(results, *client_ses, *server_ses, *creds, "CECPQ1", "AES-256/OCB(12)", "AEAD", - {{ "signature_methods", "RSA" }}); + {{ "signature_methods", "RSA" }}); #endif #if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) test_modern_versions(results, *client_ses, *server_ses, *creds, "CECPQ1", "ChaCha20Poly1305", "AEAD", - { { "signature_methods", "RSA" }}); + { { "signature_methods", "RSA" }}); #endif #endif test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", - { { "use_ecc_point_compression", "true" } }); + { { "use_ecc_point_compression", "true" } }); test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-256/GCM", "AEAD", - { { "ecc_curves", "secp521r1" } }); + { { "ecc_curves", "secp521r1" } }); test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", - { { "ecc_curves", "brainpool256r1" } }); + { { "ecc_curves", "brainpool256r1" } }); #if defined(BOTAN_HAS_CURVE_25519) test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", - { { "ecc_curves", "x25519" } }); + { { "ecc_curves", "x25519" } }); #endif std::unique_ptr<Botan::Credentials_Manager> creds_with_client_cert(create_creds(rng, true)); @@ -1297,7 +1386,7 @@ class TLS_Unit_Tests : public Test #if defined(BOTAN_HOUSE_ECC_CURVE_NAME) test_modern_versions(results, *client_ses, *server_ses, *creds, "ECDH", "AES-128/GCM", "AEAD", - { { "ecc_curves", BOTAN_HOUSE_ECC_CURVE_NAME } }); + { { "ecc_curves", BOTAN_HOUSE_ECC_CURVE_NAME } }); #endif return results; diff --git a/src/tests/unit_tls_policy.cpp b/src/tests/unit_tls_policy.cpp index 66080a283..909a3cd57 100644 --- a/src/tests/unit_tls_policy.cpp +++ b/src/tests/unit_tls_policy.cpp @@ -9,30 +9,30 @@ #include "tests.h" #if defined(BOTAN_HAS_TLS) - #include <botan/pubkey.h> - #include <botan/oids.h> - #include <botan/tls_policy.h> - #include <botan/tls_exceptn.h> + #include <botan/pubkey.h> + #include <botan/oids.h> + #include <botan/tls_policy.h> + #include <botan/tls_exceptn.h> #endif #if defined(BOTAN_HAS_RSA) - #include <botan/rsa.h> + #include <botan/rsa.h> #endif #if defined(BOTAN_HAS_ECDH) - #include <botan/ecdh.h> + #include <botan/ecdh.h> #endif #if defined(BOTAN_HAS_ECDSA) - #include <botan/ecdsa.h> + #include <botan/ecdsa.h> #endif #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include <botan/dh.h> + #include <botan/dh.h> #endif #if defined(BOTAN_HAS_DSA) - #include <botan/dsa.h> + #include <botan/dsa.h> #endif namespace Botan_Tests { @@ -60,9 +60,9 @@ class TLS_Policy_Unit_Tests : public Test { Test::Result result("TLS Policy RSA key verification"); #if defined(BOTAN_HAS_RSA) - std::unique_ptr<Botan::Private_Key> rsa_key_1024 (new Botan::RSA_PrivateKey(Test::rng(), 1024)); + std::unique_ptr<Botan::Private_Key> rsa_key_1024(new Botan::RSA_PrivateKey(Test::rng(), 1024)); Botan::TLS::Policy policy; - + try { policy.check_peer_key_acceptable(*rsa_key_1024); @@ -72,20 +72,20 @@ class TLS_Policy_Unit_Tests : public Test { result.test_success("Correctly rejecting 1024 bit RSA keys"); } - - std::unique_ptr<Botan::Private_Key> rsa_key_2048 (new Botan::RSA_PrivateKey(Test::rng(), 2048)); + + std::unique_ptr<Botan::Private_Key> rsa_key_2048(new Botan::RSA_PrivateKey(Test::rng(), 2048)); policy.check_peer_key_acceptable(*rsa_key_2048); result.test_success("Correctly accepting 2048 bit RSA keys"); #endif return result; } - + Test::Result test_peer_key_acceptable_ecdh() { Test::Result result("TLS Policy ECDH key verification"); -#if defined(BOTAN_HAS_ECDH) +#if defined(BOTAN_HAS_ECDH) Botan::EC_Group group_192("secp192r1"); - std::unique_ptr<Botan::Private_Key> ecdh_192 (new Botan::ECDH_PrivateKey(Test::rng(), group_192)); + std::unique_ptr<Botan::Private_Key> ecdh_192(new Botan::ECDH_PrivateKey(Test::rng(), group_192)); Botan::TLS::Policy policy; try @@ -97,21 +97,21 @@ class TLS_Policy_Unit_Tests : public Test { result.test_success("Correctly rejecting 192 bit EC keys"); } - + Botan::EC_Group group_256("secp256r1"); - std::unique_ptr<Botan::Private_Key> ecdh_256 (new Botan::ECDH_PrivateKey(Test::rng(), group_256)); + std::unique_ptr<Botan::Private_Key> ecdh_256(new Botan::ECDH_PrivateKey(Test::rng(), group_256)); policy.check_peer_key_acceptable(*ecdh_256); result.test_success("Correctly accepting 256 bit EC keys"); #endif return result; } - + Test::Result test_peer_key_acceptable_ecdsa() { Test::Result result("TLS Policy ECDSA key verification"); -#if defined(BOTAN_HAS_ECDSA) +#if defined(BOTAN_HAS_ECDSA) Botan::EC_Group group_192("secp192r1"); - std::unique_ptr<Botan::Private_Key> ecdsa_192 (new Botan::ECDSA_PrivateKey(Test::rng(), group_192)); + std::unique_ptr<Botan::Private_Key> ecdsa_192(new Botan::ECDSA_PrivateKey(Test::rng(), group_192)); Botan::TLS::Policy policy; try @@ -123,25 +123,25 @@ class TLS_Policy_Unit_Tests : public Test { result.test_success("Correctly rejecting 192 bit EC keys"); } - + Botan::EC_Group group_256("secp256r1"); - std::unique_ptr<Botan::Private_Key> ecdsa_256 (new Botan::ECDSA_PrivateKey(Test::rng(), group_256)); + std::unique_ptr<Botan::Private_Key> ecdsa_256(new Botan::ECDSA_PrivateKey(Test::rng(), group_256)); policy.check_peer_key_acceptable(*ecdsa_256); result.test_success("Correctly accepting 256 bit EC keys"); #endif return result; } - + Test::Result test_peer_key_acceptable_dh() { Test::Result result("TLS Policy DH key verification"); -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) const BigInt g("2"); const BigInt p("58458002095536094658683755258523362961421200751439456159756164191494576279467"); const Botan::DL_Group grp(p, g); const Botan::BigInt x("46205663093589612668746163860870963912226379131190812163519349848291472898748"); - std::unique_ptr<Botan::Private_Key> dhkey (new Botan::DH_PrivateKey(Test::rng(), grp, x)); - + std::unique_ptr<Botan::Private_Key> dhkey(new Botan::DH_PrivateKey(Test::rng(), grp, x)); + Botan::TLS::Policy policy; try { diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp index 981897ab0..89eef51d7 100644 --- a/src/tests/unit_x509.cpp +++ b/src/tests/unit_x509.cpp @@ -9,17 +9,17 @@ #if defined(BOTAN_HAS_X509_CERTIFICATES) -#include <botan/calendar.h> -#include <botan/pkcs8.h> -#include <botan/hash.h> -#include <botan/pkcs10.h> -#include <botan/x509self.h> -#include <botan/x509path.h> -#include <botan/x509_ca.h> -#include <botan/pk_algs.h> -#include <botan/ber_dec.h> -#include <botan/der_enc.h> -#include <botan/oids.h> + #include <botan/calendar.h> + #include <botan/pkcs8.h> + #include <botan/hash.h> + #include <botan/pkcs10.h> + #include <botan/x509self.h> + #include <botan/x509path.h> + #include <botan/x509_ca.h> + #include <botan/pk_algs.h> + #include <botan/ber_dec.h> + #include <botan/der_enc.h> + #include <botan/oids.h> #endif @@ -87,16 +87,23 @@ Botan::X509_Cert_Options req_opts2() std::unique_ptr<Botan::Private_Key> make_a_private_key(const std::string& algo) { - const std::string params = [&]{ + const std::string params = [&] + { // Here we override defaults as needed if(algo == "RSA") - return "1024"; + { + return "1024"; + } if(algo == "GOST-34.10") - return "gost_256A"; + { + return "gost_256A"; + } if(algo == "ECKCDSA" || algo == "ECGDSA") - return "brainpool256r1"; + { + return "brainpool256r1"; + } return ""; // default "" means choose acceptable algo-specific params - }(); + }(); return Botan::create_private_key(algo, Test::rng(), params); } @@ -112,7 +119,8 @@ Test::Result test_cert_status_strings() Botan::to_string(Botan::Certificate_Status_Code::OK), Botan::to_string(Botan::Certificate_Status_Code::VERIFIED)); - const Botan::Certificate_Status_Code codes[]{ + const Botan::Certificate_Status_Code codes[] + { Botan::Certificate_Status_Code::OCSP_RESPONSE_GOOD, Botan::Certificate_Status_Code::OCSP_SIGNATURE_OK, Botan::Certificate_Status_Code::VALID_CRL_CHECKED, @@ -150,7 +158,7 @@ Test::Result test_cert_status_strings() Botan::Certificate_Status_Code::CRL_BAD_SIGNATURE, Botan::Certificate_Status_Code::SIGNATURE_ERROR, Botan::Certificate_Status_Code::CERT_PUBKEY_INVALID, - }; + }; for(const auto code : codes) { @@ -179,16 +187,19 @@ Test::Result test_x509_dates() result.test_eq("UTC_TIME readable_string", time.readable_string(), "2020/03/05 10:03:50 UTC"); time = Botan::X509_Time("200305100350Z", Botan::ASN1_Tag::UTC_OR_GENERALIZED_TIME); - result.test_eq("UTC_OR_GENERALIZED_TIME from UTC_TIME readable_string", time.readable_string(), "2020/03/05 10:03:50 UTC"); + result.test_eq("UTC_OR_GENERALIZED_TIME from UTC_TIME readable_string", time.readable_string(), + "2020/03/05 10:03:50 UTC"); time = Botan::X509_Time("20200305100350Z", Botan::ASN1_Tag::UTC_OR_GENERALIZED_TIME); - result.test_eq("UTC_OR_GENERALIZED_TIME from GENERALIZED_TIME readable_string", time.readable_string(), "2020/03/05 10:03:50 UTC"); + result.test_eq("UTC_OR_GENERALIZED_TIME from GENERALIZED_TIME readable_string", time.readable_string(), + "2020/03/05 10:03:50 UTC"); time = Botan::X509_Time("20200305100350Z", Botan::ASN1_Tag::GENERALIZED_TIME); result.test_eq("GENERALIZED_TIME readable_string", time.readable_string(), "2020/03/05 10:03:50 UTC"); // Dates that are valid per X.500 but rejected as unsupported - const std::string valid_but_unsup[]{ + const std::string valid_but_unsup[] + { "0802010000-0000", "0802011724+0000", "0406142334-0500", @@ -202,18 +213,20 @@ Test::Result test_x509_dates() "990614233444+0500", "000614233455-0530", "000614233455+0530", - }; + }; // valid length 13 - const std::string valid_utc[]{ + const std::string valid_utc[] + { "080201000000Z", "080201172412Z", "040614233433Z", "990614233444Z", "000614233455Z", - }; + }; - const std::string invalid_utc[]{ + const std::string invalid_utc[] + { "", " ", "2008`02-01", @@ -282,14 +295,16 @@ Test::Result test_x509_dates() // Swapped type "20170217180154Z", - }; + }; // valid length 15 - const std::string valid_generalized_time[]{ + const std::string valid_generalized_time[] + { "20000305100350Z", - }; + }; - const std::string invalid_generalized[]{ + const std::string invalid_generalized[] + { // No trailing Z "20000305100350", @@ -313,7 +328,7 @@ Test::Result test_x509_dates() // Swapped type "170217180154Z", - }; + }; for(const auto& v : valid_but_unsup) { @@ -335,7 +350,7 @@ Test::Result test_x509_dates() result.test_throws("invalid", [v]() { Botan::X509_Time t(v, Botan::ASN1_Tag::UTC_TIME); }); } - for (const auto& v : invalid_generalized) + for(const auto& v : invalid_generalized) { result.test_throws("invalid", [v]() { Botan::X509_Time t(v, Botan::ASN1_Tag::GENERALIZED_TIME); }); } @@ -358,14 +373,12 @@ Test::Result test_x509_cert(const std::string& sig_algo, const std::string& hash } /* Create the self-signed cert */ - const Botan::X509_Certificate ca_cert = - Botan::X509::create_self_signed_cert(ca_opts(), - *ca_key, - hash_fn, - Test::rng()); + const auto ca_cert = Botan::X509::create_self_signed_cert(ca_opts(), *ca_key, hash_fn, Test::rng()); - result.test_eq("ca key usage", (ca_cert.constraints() & Botan::Key_Constraints(Botan::KEY_CERT_SIGN | Botan::CRL_SIGN)) == - Botan::Key_Constraints(Botan::KEY_CERT_SIGN | Botan::CRL_SIGN), true); + { + const auto constraints = Botan::Key_Constraints(Botan::KEY_CERT_SIGN | Botan::CRL_SIGN); + result.test_eq("ca key usage", (ca_cert.constraints() & constraints) == constraints, true); + } /* Create user #1's key and cert request */ std::unique_ptr<Botan::Private_Key> user1_key(make_a_private_key(sig_algo)); @@ -400,13 +413,12 @@ Test::Result test_x509_cert(const std::string& sig_algo, const std::string& hash from_date(2033, 01, 01)); // user#1 creates a self-signed cert on the side - Botan::X509_Certificate user1_ss_cert = - Botan::X509::create_self_signed_cert(req_opts1(sig_algo), - *user1_key, - hash_fn, - Test::rng()); + const auto user1_ss_cert = Botan::X509::create_self_signed_cert(req_opts1(sig_algo), *user1_key, hash_fn, Test::rng()); - result.test_eq("user1 key usage", (user1_cert.constraints() & req_opts1(sig_algo).constraints) == req_opts1(sig_algo).constraints, true); + { + auto constrains = req_opts1(sig_algo).constraints; + result.test_eq("user1 key usage", (user1_cert.constraints() & constrains) == constrains, true); + } /* Copy, assign and compare */ Botan::X509_Certificate user1_cert_copy(user1_cert); @@ -523,11 +535,11 @@ Test::Result test_usage(const std::string& sig_algo, const std::string& hash_fn } /* Create the self-signed cert */ - const Botan::X509_Certificate ca_cert = - Botan::X509::create_self_signed_cert(ca_opts(), - *ca_key, - hash_fn, - Test::rng()); + const Botan::X509_Certificate ca_cert = Botan::X509::create_self_signed_cert( + ca_opts(), + *ca_key, + hash_fn, + Test::rng()); /* Create the CA object */ const Botan::X509_CA ca(ca_cert, *ca_key, hash_fn, Test::rng()); @@ -537,55 +549,55 @@ Test::Result test_usage(const std::string& sig_algo, const std::string& hash_fn Botan::X509_Cert_Options opts("Test User 1/US/Botan Project/Testing"); opts.constraints = Key_Constraints::DIGITAL_SIGNATURE; - const Botan::PKCS10_Request user1_req = - Botan::X509::create_cert_req(opts, - *user1_key, - hash_fn, - Test::rng()); + const Botan::PKCS10_Request user1_req = Botan::X509::create_cert_req( + opts, + *user1_key, + hash_fn, + Test::rng()); - const Botan::X509_Certificate user1_cert = - ca.sign_request(user1_req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); + const Botan::X509_Certificate user1_cert = ca.sign_request( + user1_req, + Test::rng(), + from_date(2008, 01, 01), + from_date(2033, 01, 01)); // cert only allows digitalSignature, but we check for both digitalSignature and cRLSign - result.test_eq("key usage cRLSign not allowed", user1_cert.allowed_usage(Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | - Key_Constraints::CRL_SIGN)), false); + result.test_eq("key usage cRLSign not allowed", + user1_cert.allowed_usage( + Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::CRL_SIGN)), false); // cert only allows digitalSignature, so checking for only that should be ok result.confirm("key usage digitalSignature allowed", user1_cert.allowed_usage(Key_Constraints::DIGITAL_SIGNATURE)); opts.constraints = Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::CRL_SIGN); - const Botan::PKCS10_Request mult_usage_req = - Botan::X509::create_cert_req(opts, - *user1_key, - hash_fn, - Test::rng()); + const Botan::PKCS10_Request mult_usage_req = Botan::X509::create_cert_req( + opts, + *user1_key, + hash_fn, + Test::rng()); - const Botan::X509_Certificate mult_usage_cert = - ca.sign_request(mult_usage_req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); + const Botan::X509_Certificate mult_usage_cert = ca.sign_request( + mult_usage_req, + Test::rng(), + from_date(2008, 01, 01), + from_date(2033, 01, 01)); // cert allows multiple usages, so each one of them as well as both together should be allowed - result.confirm("key usage multiple digitalSignature allowed", mult_usage_cert.allowed_usage(Key_Constraints::DIGITAL_SIGNATURE)); + result.confirm("key usage multiple digitalSignature allowed", + mult_usage_cert.allowed_usage(Key_Constraints::DIGITAL_SIGNATURE)); result.confirm("key usage multiple cRLSign allowed", mult_usage_cert.allowed_usage(Key_Constraints::CRL_SIGN)); result.confirm("key usage multiple digitalSignature and cRLSign allowed", mult_usage_cert.allowed_usage( - Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::CRL_SIGN))); + Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::CRL_SIGN))); opts.constraints = Key_Constraints::NO_CONSTRAINTS; - const Botan::PKCS10_Request no_usage_req = - Botan::X509::create_cert_req(opts, - *user1_key, - hash_fn, - Test::rng()); + const Botan::PKCS10_Request no_usage_req = Botan::X509::create_cert_req(opts, *user1_key, hash_fn, Test::rng()); const Botan::X509_Certificate no_usage_cert = - ca.sign_request(no_usage_req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); + ca.sign_request(no_usage_req, Test::rng(), + from_date(2008, 01, 01), + from_date(2033, 01, 01)); // cert allows every usage result.confirm("key usage digitalSignature allowed", no_usage_cert.allowed_usage(Key_Constraints::DIGITAL_SIGNATURE)); @@ -611,11 +623,8 @@ Test::Result test_self_issued(const std::string& sig_algo, const std::string& ha } // create the self-signed cert - const Botan::X509_Certificate ca_cert = - Botan::X509::create_self_signed_cert(ca_opts(), - *ca_key, - hash_fn, - Test::rng()); + const Botan::X509_Certificate ca_cert = Botan::X509::create_self_signed_cert( + ca_opts(), *ca_key, hash_fn, Test::rng()); /* Create the CA object */ const Botan::X509_CA ca(ca_cert, *ca_key, hash_fn, Test::rng()); @@ -627,26 +636,18 @@ Test::Result test_self_issued(const std::string& sig_algo, const std::string& ha Botan::X509_Cert_Options opts = ca_opts(); opts.constraints = Key_Constraints::DIGITAL_SIGNATURE; - const Botan::PKCS10_Request self_issued_req = - Botan::X509::create_cert_req(opts, - *user_key, - hash_fn, - Test::rng()); + const Botan::PKCS10_Request self_issued_req = Botan::X509::create_cert_req(opts, *user_key, hash_fn, Test::rng()); - const Botan::X509_Certificate self_issued_cert = - ca.sign_request(self_issued_req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); + const Botan::X509_Certificate self_issued_cert = ca.sign_request( + self_issued_req, Test::rng(), from_date(2008, 01, 01), from_date(2033, 01, 01)); // check that this chain can can be verified successfully const Botan::Certificate_Store_In_Memory trusted(ca.ca_certificate()); const Botan::Path_Validation_Restrictions restrictions(false, 80); - const Botan::Path_Validation_Result validation_result = - Botan::x509_path_validate(self_issued_cert, - restrictions, - trusted); + const Botan::Path_Validation_Result validation_result = Botan::x509_path_validate( + self_issued_cert, restrictions, trusted); result.confirm("chain with self-issued cert validates", validation_result.successful_validation()); @@ -663,20 +664,35 @@ struct typical_usage_constraints { // ALL constraints are not typical at all, but we use them for a negative test Key_Constraints all = Key_Constraints( - Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::NON_REPUDIATION | Key_Constraints::KEY_ENCIPHERMENT | - Key_Constraints::DATA_ENCIPHERMENT | Key_Constraints::KEY_AGREEMENT | Key_Constraints::KEY_CERT_SIGN | - Key_Constraints::CRL_SIGN | Key_Constraints::ENCIPHER_ONLY | Key_Constraints::DECIPHER_ONLY); + Key_Constraints::DIGITAL_SIGNATURE | + Key_Constraints::NON_REPUDIATION | + Key_Constraints::KEY_ENCIPHERMENT | + Key_Constraints::DATA_ENCIPHERMENT | + Key_Constraints::KEY_AGREEMENT | + Key_Constraints::KEY_CERT_SIGN | + Key_Constraints::CRL_SIGN | + Key_Constraints::ENCIPHER_ONLY | + Key_Constraints::DECIPHER_ONLY); Key_Constraints ca = Key_Constraints(Key_Constraints::KEY_CERT_SIGN); Key_Constraints sign_data = Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE); - Key_Constraints non_repudiation = Key_Constraints(Key_Constraints::NON_REPUDIATION | Key_Constraints::DIGITAL_SIGNATURE); + Key_Constraints non_repudiation = Key_Constraints( + Key_Constraints::NON_REPUDIATION | + Key_Constraints::DIGITAL_SIGNATURE); Key_Constraints key_encipherment = Key_Constraints(Key_Constraints::KEY_ENCIPHERMENT); Key_Constraints data_encipherment = Key_Constraints(Key_Constraints::DATA_ENCIPHERMENT); Key_Constraints key_agreement = Key_Constraints(Key_Constraints::KEY_AGREEMENT); - Key_Constraints key_agreement_encipher_only = Key_Constraints(Key_Constraints::KEY_AGREEMENT | Key_Constraints::ENCIPHER_ONLY); - Key_Constraints key_agreement_decipher_only = Key_Constraints(Key_Constraints::KEY_AGREEMENT | Key_Constraints::DECIPHER_ONLY); - Key_Constraints crl_sign = Key_Constraints(Key_Constraints::CRL_SIGN); - Key_Constraints sign_everything = Key_Constraints(Key_Constraints::DIGITAL_SIGNATURE | Key_Constraints::KEY_CERT_SIGN | Key_Constraints::CRL_SIGN); + Key_Constraints key_agreement_encipher_only = Key_Constraints( + Key_Constraints::KEY_AGREEMENT | + Key_Constraints::ENCIPHER_ONLY); + Key_Constraints key_agreement_decipher_only = Key_Constraints( + Key_Constraints::KEY_AGREEMENT | + Key_Constraints::DECIPHER_ONLY); + Key_Constraints crl_sign = Key_Constraints::CRL_SIGN; + Key_Constraints sign_everything = Key_Constraints( + Key_Constraints::DIGITAL_SIGNATURE | + Key_Constraints::KEY_CERT_SIGN | + Key_Constraints::CRL_SIGN); }; @@ -702,33 +718,51 @@ Test::Result test_valid_constraints(const std::string& pk_algo) if(pk_algo == "DH" || pk_algo == "ECDH") { // DH and ECDH only for key agreement - result.test_throws("all constraints not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.all); }); - result.test_throws("cert sign not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.ca); }); - result.test_throws("signature not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.sign_data); }); - result.test_throws("non repudiation not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.non_repudiation); }); - result.test_throws("key encipherment not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_encipherment); }); - result.test_throws("data encipherment not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.data_encipherment); }); + result.test_throws("all constraints not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.all); + }); + result.test_throws("cert sign not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.ca); + }); + result.test_throws("signature not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_data); + }); + result.test_throws("non repudiation not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.non_repudiation); + }); + result.test_throws("key encipherment not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_encipherment); + }); + result.test_throws("data encipherment not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.data_encipherment); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement); verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_encipher_only); verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_decipher_only); - result.test_throws("crl sign not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.crl_sign); }); - result.test_throws("sign, cert sign, crl sign not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.sign_everything); }); + result.test_throws("crl sign not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.crl_sign); + }); + result.test_throws("sign, cert sign, crl sign not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_everything); + }); } else if(pk_algo == "RSA") { // RSA can do everything except key agreement - result.test_throws("all constraints not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.all); }); + result.test_throws("all constraints not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.all); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.ca); verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_data); @@ -736,12 +770,18 @@ Test::Result test_valid_constraints(const std::string& pk_algo) verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_encipherment); verify_cert_constraints_valid_for_key_type(*key, typical_usage.data_encipherment); - result.test_throws("key agreement not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement); }); - result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_encipher_only); }); - result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_decipher_only); }); + result.test_throws("key agreement not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement); + }); + result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_encipher_only); + }); + result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_decipher_only); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.crl_sign); verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_everything); @@ -749,45 +789,72 @@ Test::Result test_valid_constraints(const std::string& pk_algo) else if(pk_algo == "ElGamal") { // only ElGamal encryption is currently implemented - result.test_throws("all constraints not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.all); }); - result.test_throws("cert sign not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.ca); }); + result.test_throws("all constraints not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.all); + }); + result.test_throws("cert sign not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.ca); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.data_encipherment); verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_encipherment); - result.test_throws("key agreement not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement); }); - result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_encipher_only); }); - result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_decipher_only); }); - result.test_throws("crl sign not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.crl_sign); }); - result.test_throws("sign, cert sign, crl sign not permitted not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.sign_everything); }); + result.test_throws("key agreement not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement); + }); + result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_encipher_only); + }); + result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_decipher_only); + }); + result.test_throws("crl sign not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.crl_sign); + }); + result.test_throws("sign, cert sign, crl sign not permitted not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_everything); + }); } - else if(pk_algo == "DSA" || pk_algo == "ECDSA" || pk_algo == "ECGDSA" || pk_algo == "ECKCDSA" || pk_algo == "GOST-34.10") + else if(pk_algo == "DSA" || pk_algo == "ECDSA" || pk_algo == "ECGDSA" || pk_algo == "ECKCDSA" || + pk_algo == "GOST-34.10") { // these are signature algorithms only - result.test_throws("all constraints not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.all); }); + result.test_throws("all constraints not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.all); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.ca); verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_data); verify_cert_constraints_valid_for_key_type(*key, typical_usage.non_repudiation); - result.test_throws("key encipherment not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_encipherment); }); - result.test_throws("data encipherment not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.data_encipherment); }); - result.test_throws("key agreement not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement); }); - result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_encipher_only); }); - result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() { verify_cert_constraints_valid_for_key_type(*key, - typical_usage.key_agreement_decipher_only); }); + result.test_throws("key encipherment not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_encipherment); + }); + result.test_throws("data encipherment not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.data_encipherment); + }); + result.test_throws("key agreement not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement); + }); + result.test_throws("key agreement, encipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_encipher_only); + }); + result.test_throws("key agreement, decipher only not permitted", [&key, &typical_usage]() + { + verify_cert_constraints_valid_for_key_type(*key, typical_usage.key_agreement_decipher_only); + }); verify_cert_constraints_valid_for_key_type(*key, typical_usage.crl_sign); verify_cert_constraints_valid_for_key_type(*key, typical_usage.sign_everything); @@ -805,26 +872,38 @@ class String_Extension : public Botan::Certificate_Extension String_Extension() = default; String_Extension(const std::string& val) : m_contents(val) {} - std::string value() const { return m_contents; } + std::string value() const + { + return m_contents; + } - String_Extension* copy() const override { return new String_Extension(m_contents); } + String_Extension* copy() const override + { + return new String_Extension(m_contents); + } - Botan::OID oid_of() const override { return m_oid; } - std::string oid_name() const override { return "String Extension"; } + Botan::OID oid_of() const override + { + return m_oid; + } + std::string oid_name() const override + { + return "String Extension"; + } void contents_to(Botan::Data_Store&, Botan::Data_Store&) const override {} std::vector<uint8_t> encode_inner() const override - { + { return Botan::DER_Encoder().encode(Botan::ASN1_String(m_contents, Botan::UTF8_STRING)).get_contents_unlocked(); - } + } void decode_inner(const std::vector<uint8_t>& in) override - { + { Botan::ASN1_String str; Botan::BER_Decoder(in).decode(str, Botan::UTF8_STRING).verify_end(); m_contents = str.value(); - } + } private: Botan::OID m_oid {"1.2.3.4.5.6.7.8.9.1"}; @@ -848,11 +927,7 @@ Test::Result test_x509_extensions(const std::string& sig_algo, const std::string } /* Create the self-signed cert */ - Botan::X509_Certificate ca_cert = - Botan::X509::create_self_signed_cert(ca_opts(), - *ca_key, - hash_fn, - Test::rng()); + Botan::X509_Certificate ca_cert = Botan::X509::create_self_signed_cert(ca_opts(), *ca_key, hash_fn, Test::rng()); /* Create the CA object */ Botan::X509_CA ca(ca_cert, *ca_key, hash_fn, Test::rng()); @@ -869,14 +944,15 @@ Test::Result test_x509_extensions(const std::string& sig_algo, const std::string opts.extensions = req_extensions; /* Create a self-signed certificate */ - const Botan::X509_Certificate self_signed_cert = Botan::X509::create_self_signed_cert(opts, *user_key, hash_fn, Test::rng()); + const Botan::X509_Certificate self_signed_cert = Botan::X509::create_self_signed_cert( + opts, *user_key, hash_fn, Test::rng()); // check if known Key_Usage extension is present in self-signed cert auto key_usage_ext = self_signed_cert.v3_extensions().get(Botan::OIDS::lookup("X509v3.KeyUsage")); if(result.confirm("Key_Usage extension present in self-signed certificate", key_usage_ext != nullptr)) { result.confirm("Key_Usage extension value matches in self-signed certificate", - dynamic_cast<Botan::Cert_Extension::Key_Usage&>(*key_usage_ext).get_constraints() == opts.constraints); + dynamic_cast<Botan::Cert_Extension::Key_Usage&>(*key_usage_ext).get_constraints() == opts.constraints); } // check if custom extension is present in self-signed cert @@ -887,24 +963,18 @@ Test::Result test_x509_extensions(const std::string& sig_algo, const std::string } - const Botan::PKCS10_Request user_req = - Botan::X509::create_cert_req(opts, - *user_key, - hash_fn, - Test::rng()); + const Botan::PKCS10_Request user_req = Botan::X509::create_cert_req(opts, *user_key, hash_fn, Test::rng()); /* Create a CA-signed certificate */ - const Botan::X509_Certificate user_cert = - ca.sign_request(user_req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); + const Botan::X509_Certificate user_cert = ca.sign_request( + user_req, Test::rng(), from_date(2008, 01, 01), from_date(2033, 01, 01)); // check if known Key_Usage extension is present in CA-signed cert key_usage_ext = self_signed_cert.v3_extensions().get(Botan::OIDS::lookup("X509v3.KeyUsage")); if(result.confirm("Key_Usage extension present in user certificate", key_usage_ext != nullptr)) { result.confirm("Key_Usage extension value matches in user certificate", - dynamic_cast<Botan::Cert_Extension::Key_Usage&>(*key_usage_ext).get_constraints() == Botan::DIGITAL_SIGNATURE); + dynamic_cast<Botan::Cert_Extension::Key_Usage&>(*key_usage_ext).get_constraints() == Botan::DIGITAL_SIGNATURE); } // check if custom extension is present in CA-signed cert @@ -917,59 +987,70 @@ Test::Result test_x509_extensions(const std::string& sig_algo, const std::string return result; } -Test::Result test_hashes(const std::string &algo, const std::string &hash_fn = "SHA-256") +Test::Result test_hashes(const std::string& algo, const std::string& hash_fn = "SHA-256") { - Test::Result result("X509 Hashes"); - - const std::unique_ptr<Botan::Private_Key> key(make_a_private_key(algo)); - - struct TestData { - const std::string issuer, subject, issuer_hash, subject_hash; - } const cases[]{ - {"", - "", - "E4F60D0AA6D7F3D3B6A6494B1C861B99F649C6F9EC51ABAF201B20F297327C95", - "E4F60D0AA6D7F3D3B6A6494B1C861B99F649C6F9EC51ABAF201B20F297327C95"}, - {"a", - "b", - "BC2E013472F39AC579964880E422737C82BA812CB8BC2FD17E013060D71E6E19", - "5E31CFAA3FAFB1A5BA296A0D2BAB9CA44D7936E9BF0BBC54637D0C53DBC4A432"}, - {"A", - "B", - "4B3206201C4BC9B6CD6C36532A97687DF9238155D99ADB60C66BF2B2220643D8", - "FFF635A52A16618B4A0E9CD26B5E5A2FA573D343C051E6DE8B0811B1ACC89B86"}, - {"Test Issuer/US/Botan Project/Testing", - "Test Subject/US/Botan Project/Testing", - "E2407027922619C0673E0AA59A9CD3673730C36A39F891BCE0806D1DD225A937", - "42A63CB4FCCA81AC6D14D5E209B3156E033B90FF1007216927EA9324BA4EF2DB"}, - {"Test Subject/US/Botan Project/Testing", - "Test Issuer/US/Botan Project/Testing", - "42A63CB4FCCA81AC6D14D5E209B3156E033B90FF1007216927EA9324BA4EF2DB", - "E2407027922619C0673E0AA59A9CD3673730C36A39F891BCE0806D1DD225A937"}}; - - for (const auto& a : cases) - { - Botan::X509_Cert_Options opts{a.issuer}; - opts.CA_key(); - - const Botan::X509_Certificate issuer_cert = - Botan::X509::create_self_signed_cert(opts, *key, hash_fn, Test::rng()); - - result.test_eq(a.issuer, Botan::hex_encode(issuer_cert.raw_issuer_dn_sha256()), a.issuer_hash); - result.test_eq(a.issuer, Botan::hex_encode(issuer_cert.raw_subject_dn_sha256()), a.issuer_hash); - - const Botan::X509_CA ca(issuer_cert, *key, hash_fn, Test::rng()); - const Botan::PKCS10_Request req = - Botan::X509::create_cert_req(a.subject, *key, hash_fn, Test::rng()); - const Botan::X509_Certificate subject_cert = - ca.sign_request(req, Test::rng(), - from_date(2008, 01, 01), - from_date(2033, 01, 01)); - - result.test_eq(a.subject, Botan::hex_encode(subject_cert.raw_issuer_dn_sha256()), a.issuer_hash); - result.test_eq(a.subject, Botan::hex_encode(subject_cert.raw_subject_dn_sha256()), a.subject_hash); - } - return result; + Test::Result result("X509 Hashes"); + + const std::unique_ptr<Botan::Private_Key> key(make_a_private_key(algo)); + + struct TestData + { + const std::string issuer, subject, issuer_hash, subject_hash; + } const cases[] + { + { + "", + "", + "E4F60D0AA6D7F3D3B6A6494B1C861B99F649C6F9EC51ABAF201B20F297327C95", + "E4F60D0AA6D7F3D3B6A6494B1C861B99F649C6F9EC51ABAF201B20F297327C95" + }, + { + "a", + "b", + "BC2E013472F39AC579964880E422737C82BA812CB8BC2FD17E013060D71E6E19", + "5E31CFAA3FAFB1A5BA296A0D2BAB9CA44D7936E9BF0BBC54637D0C53DBC4A432" + }, + { + "A", + "B", + "4B3206201C4BC9B6CD6C36532A97687DF9238155D99ADB60C66BF2B2220643D8", + "FFF635A52A16618B4A0E9CD26B5E5A2FA573D343C051E6DE8B0811B1ACC89B86" + }, + { + "Test Issuer/US/Botan Project/Testing", + "Test Subject/US/Botan Project/Testing", + "E2407027922619C0673E0AA59A9CD3673730C36A39F891BCE0806D1DD225A937", + "42A63CB4FCCA81AC6D14D5E209B3156E033B90FF1007216927EA9324BA4EF2DB" + }, + { + "Test Subject/US/Botan Project/Testing", + "Test Issuer/US/Botan Project/Testing", + "42A63CB4FCCA81AC6D14D5E209B3156E033B90FF1007216927EA9324BA4EF2DB", + "E2407027922619C0673E0AA59A9CD3673730C36A39F891BCE0806D1DD225A937" + } + }; + + for(const auto& a : cases) + { + Botan::X509_Cert_Options opts{a.issuer}; + opts.CA_key(); + + const Botan::X509_Certificate issuer_cert = + Botan::X509::create_self_signed_cert(opts, *key, hash_fn, Test::rng()); + + result.test_eq(a.issuer, Botan::hex_encode(issuer_cert.raw_issuer_dn_sha256()), a.issuer_hash); + result.test_eq(a.issuer, Botan::hex_encode(issuer_cert.raw_subject_dn_sha256()), a.issuer_hash); + + const Botan::X509_CA ca(issuer_cert, *key, hash_fn, Test::rng()); + const Botan::PKCS10_Request req = + Botan::X509::create_cert_req(a.subject, *key, hash_fn, Test::rng()); + const Botan::X509_Certificate subject_cert = + ca.sign_request(req, Test::rng(), from_date(2008, 01, 01), from_date(2033, 01, 01)); + + result.test_eq(a.subject, Botan::hex_encode(subject_cert.raw_issuer_dn_sha256()), a.issuer_hash); + result.test_eq(a.subject, Botan::hex_encode(subject_cert.raw_subject_dn_sha256()), a.subject_hash); + } + return result; } class X509_Cert_Unit_Tests : public Test @@ -987,33 +1068,37 @@ class X509_Cert_Unit_Tests : public Test for(const auto& algo : sig_algos) { - try { + try + { cert_result.merge(test_x509_cert(algo)); - } + } catch(std::exception& e) { cert_result.test_failure("test_x509_cert " + algo, e.what()); } - try { - usage_result.merge(test_usage(algo)); - } + try + { + usage_result.merge(test_usage(algo)); + } catch(std::exception& e) { usage_result.test_failure("test_usage " + algo, e.what()); } - try { - self_issued_result.merge(test_self_issued(algo)); - } + try + { + self_issued_result.merge(test_self_issued(algo)); + } catch(std::exception& e) { self_issued_result.test_failure("test_self_issued " + algo, e.what()); } - try { - extensions_result.merge(test_x509_extensions(algo)); - } + try + { + extensions_result.merge(test_x509_extensions(algo)); + } catch(std::exception& e) { extensions_result.test_failure("test_extensions " + algo, e.what()); @@ -1025,8 +1110,11 @@ class X509_Cert_Unit_Tests : public Test results.push_back(self_issued_result); results.push_back(extensions_result); - const std::vector<std::string> pk_algos { "DH", "ECDH", "RSA", "ElGamal", "GOST-34.10", - "DSA", "ECDSA", "ECGDSA", "ECKCDSA" }; + const std::vector<std::string> pk_algos + { + "DH", "ECDH", "RSA", "ElGamal", "GOST-34.10", + "DSA", "ECDSA", "ECGDSA", "ECKCDSA" + }; Test::Result valid_constraints_result("X509 Valid Constraints"); for(const auto& algo : pk_algos) |