Test::Result test_pipe_errors() { Test::Result result("Pipe"); Botan::Pipe pipe; pipe.append(nullptr); // ignored pipe.prepend(nullptr); // ignored 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); }); 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(); }); pipe.end_msg(); pipe.append(nullptr); // ignored pipe.prepend(nullptr); // ignored pipe.pop(); // empty pipe, so ignored return result; }
int main(int argc, char* argv[]) { if(argc < 2) { std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl; return 1; } Botan::LibraryInitializer init; const int COUNT = 3; std::string name[COUNT] = { "MD5", "SHA-1", "RIPEMD-160" }; Botan::Pipe pipe; int skipped = 0; for(int j = 1; argv[j] != 0; j++) { Botan::Filter* hash[COUNT] = { new Botan::Hash_Filter(name[0]), new Botan::Hash_Filter(name[1]), new Botan::Hash_Filter(name[2]), }; std::ifstream file(argv[j], std::ios::binary); if(!file) { std::cout << "ERROR: could not open " << argv[j] << std::endl; skipped++; continue; } for(int k = 0; k != COUNT; k++) { pipe.reset(); pipe.append(hash[k]); pipe.append(new Botan::Hex_Encoder); pipe.start_msg(); // trickiness: the >> op reads until EOF, but seekg won't work // unless we're in the "good" state (which EOF is not). file.clear(); file.seekg(0, std::ios::beg); file >> pipe; pipe.end_msg(); } file.close(); for(int k = 0; k != COUNT; k++) { std::string out = pipe.read_all_as_string(COUNT*(j-1-skipped) + k); std::cout << name[k] << "(" << argv[j] << ") = " << out << std::endl; } } return 0; }
bool failed_test(const std::string& algo, std::vector<std::string> params, bool is_extension, bool exp_pass, std::string& last_missing, Botan::RandomNumberGenerator& rng) { #if !EXTRA_TESTS if(!exp_pass) return true; #endif std::map<std::string, std::string> vars; vars["input"] = params[0]; vars["output"] = params[1]; if(params.size() > 2) vars["key"] = params[2]; if(params.size() > 3) vars["iv"] = params[3]; std::map<std::string, bool> results = algorithm_kat(algo, vars, global_state().algorithm_factory()); if(results.size()) { for(std::map<std::string, bool>::const_iterator i = results.begin(); i != results.end(); ++i) { if(i->second == false) { std::cout << algo << " test with provider " << i->first << " failed\n"; return true; } } return false; // OK } const std::string in = params[0]; const std::string expected = params[1]; params.erase(params.begin()); params.erase(params.begin()); if(in.size() % 2 == 1) { std::cout << "Can't have an odd sized hex string!" << std::endl; return true; } Botan::Pipe pipe; try { Botan::Filter* test = lookup(algo, params); if(test == 0 && is_extension) return !exp_pass; if(test == 0) { if(algo != last_missing) { std::cout << "WARNING: \"" + algo + "\" is not a known " << "algorithm name." << std::endl; last_missing = algo; } return 0; } pipe.reset(); pipe.append(test); pipe.append(new Botan::Hex_Encoder); Botan::SecureVector<byte> data = Botan::hex_decode(in); const byte* data_ptr = &data[0]; // this can help catch errors with buffering, etc size_t len = data.size(); pipe.start_msg(); while(len) { u32bit how_much = random_word(rng, len); pipe.write(data_ptr, how_much); data_ptr += how_much; len -= how_much; } pipe.end_msg(); } catch(Botan::Algorithm_Not_Found& e) { std::cout << "Algorithm not found: " << e.what() << std::endl; return false; } catch(Botan::Exception& e) { if(exp_pass || DEBUG) std::cout << "Exception caught: " << e.what() << std::endl; return true; } catch(std::exception& e) { if(exp_pass || DEBUG) std::cout << "Standard library exception caught: " << e.what() << std::endl; return true; } catch(...) { if(exp_pass || DEBUG) std::cout << "Unknown exception caught." << std::endl; return true; } std::string output; if(pipe.remaining()) { /* Test peeking at an offset in Pipe/SecureQueue */ size_t offset = random_word(rng, pipe.remaining() - 1); size_t length = random_word(rng, pipe.remaining() - offset); Botan::SecureVector<byte> peekbuf(length); pipe.peek(&peekbuf[0], peekbuf.size(), offset); output = pipe.read_all_as_string(); bool OK = true; for(size_t j = offset; j != offset+length; j++) if(static_cast<byte>(output[j]) != peekbuf[j-offset]) OK = false; if(!OK) throw Botan::Self_Test_Failure("Peek testing failed in validate.cpp"); } if(output == expected && !exp_pass) { std::cout << "FAILED: " << expected << " == " << std::endl << " " << output << std::endl; return false; } if(output != expected && exp_pass) { std::cout << "\nFAILED: " << expected << " != " << std::endl << " " << output << std::endl; return true; } if(output != expected && !exp_pass) return true; return false; }
int main(int argc, char* argv[]) { if(argc < 2) { std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl; return 1; } Botan::LibraryInitializer init; // this is a pretty vacuous example, but it's useful as a test Botan::Pipe pipe; // CPS == Current Pipe Status, ie what Filters are set up pipe.prepend(new Botan::Hash_Filter("MD5")); // CPS: MD5 pipe.prepend(new Botan::Hash_Filter("RIPEMD-160")); // CPS: RIPEMD-160 | MD5 pipe.prepend(new Botan::Chain( new Botan::Hash_Filter("RIPEMD-160"), new Botan::Hash_Filter("RIPEMD-160"))); // CPS: (RIPEMD-160 | RIPEMD-160) | RIPEMD-160 | MD5 pipe.pop(); // will pop everything inside the Chain as well as Chain itself // CPS: RIPEMD-160 | MD5 pipe.pop(); // will get rid of the RIPEMD-160 Hash_Filter // CPS: MD5 pipe.prepend(new Botan::Hash_Filter("SHA-1")); // CPS: SHA-1 | MD5 pipe.append(new Botan::Hex_Encoder); // CPS: SHA-1 | MD5 | Hex_Encoder pipe.prepend(new Botan::Hash_Filter("SHA-1")); // CPS: SHA-1 | SHA-1 | MD5 | Hex_Encoder pipe.pop(); // Get rid of the Hash_Filter(SHA-1) pipe.pop(); // Get rid of the other Hash_Filter(SHA-1) // CPS: MD5 | Hex_Encoder // The Hex_Encoder is safe because it is at the end of the Pipe, // and pop() pulls off the Filter that is at the start. pipe.prepend(new Botan::Hash_Filter("RIPEMD-160")); // CPS: RIPEMD-160 | MD5 | Hex_Encoder pipe.pop(); // Get rid of that last prepended Hash_Filter(RIPEMD-160) // CPS: MD5 | Hex_Encoder int skipped = 0; for(int j = 1; argv[j] != 0; j++) { std::ifstream file(argv[j], std::ios::binary); if(!file) { std::cout << "ERROR: could not open " << argv[j] << std::endl; skipped++; continue; } pipe.start_msg(); file >> pipe; pipe.end_msg(); file.close(); pipe.set_default_msg(j-1-skipped); std::cout << pipe << " " << argv[j] << std::endl; } return 0; }