#
#
# add_file "botan_pipe_cache.hh"
# content [6a935f221e4a9368cbef90618e4a3847d1053dbc]
#
# patch "Makefile.am"
# from [242b7438c47167c49dc69f129232bd6b91261a22]
# to [868eff98716b795d27b9f00b523e2c42d9e1f0ce]
#
# patch "file_io.cc"
# from [358fb964dc42e7f936a136342b93bb3a4744d1b3]
# to [db5ed54600200ee2cda6ff1a2a8b0ecb463b653b]
#
# patch "gzip.cc"
# from [93f149779d9f0132940a206e008eeef3ca618b92]
# to [72e05981fe6cc8aa932363eef6c187241a4bb31d]
#
# patch "hmac.cc"
# from [115a8c2bd6e81ea28d4628e77e4ad4dfae8e00a9]
# to [da58d8141987a07675d0a8aaf8ab70b60d53ac90]
#
# patch "hmac.hh"
# from [6953e20a8a307882b42c317e31714a53f8dae510]
# to [38920db37f7ac41a26c51b97a9fb2a394d0f37ff]
#
# patch "key_store.cc"
# from [167e6637e117ee23709dc32bb029cb0288064606]
# to [0f3eb9d8e4e664f42a1099f299c325604fae9cc9]
#
# patch "monotone.cc"
# from [c105422e7de754e19a87af2cd8ad4b798159520e]
# to [e7cb1f117494c4853f3320a4add02474b6a2ff6c]
#
# patch "tester.cc"
# from [5698be54abe68883c1ce41db0ba95e461a1f3fad]
# to [da1589e5c3cc77aa51b5658a71b613e6b1ec64db]
#
# patch "transforms.cc"
# from [144f5ceb3515a7b9a392e6963c5841788a8bdbd0]
# to [47dcee3eac105e9bc2d39f8f9802d606dcf5c5bd]
#
# patch "unit_tests.cc"
# from [45a81af10ac5ffd8be8d0bf9c4c8ee03f63bf16d]
# to [5baf8acaed8b1a76321a7b8e95de47414bf97de7]
#
============================================================
--- botan_pipe_cache.hh 6a935f221e4a9368cbef90618e4a3847d1053dbc
+++ botan_pipe_cache.hh 6a935f221e4a9368cbef90618e4a3847d1053dbc
@@ -0,0 +1,90 @@
+#ifndef __BOTAN_PIPE_CACHE_HH__
+#define __BOTAN_PIPE_CACHE_HH__
+
+// Copyright (C) 2008 Zack Weinberg
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include
+#include
+#include "sanity.hh"
+
+// This file defines a simple lifetime-of-the-program caching strategy for
+// Botan::Pipe objects. Instead of writing
+//
+// Botan::Pipe p(...);
+//
+// you do
+//
+// static cached_botan_pipe p(new Botan::Pipe(...));
+//
+// and then use p like a Botan::Pipe object (except with -> instead of .).
+//
+// The global pipe_cache_cleanup object takes care of destroying all such
+// cached pipes before the Botan::LibraryInitializer object is destroyed.
+
+class pipe_cache_cleanup;
+
+class cached_botan_pipe
+{
+ friend class pipe_cache_cleanup;
+ cached_botan_pipe * next_tbd;
+ boost::scoped_ptr pipe;
+
+public:
+ cached_botan_pipe(Botan::Pipe * p);
+ ~cached_botan_pipe() { I(!pipe); }
+ Botan::Pipe & operator*()
+ { I(pipe); return *pipe; }
+ Botan::Pipe * operator->()
+ { I(pipe); return pipe.get(); }
+
+ // ??? operator bool, operator! a la boost::scoped_ptr
+ // (what's with the bizarro unspecified_bool_type thing?)
+};
+
+extern Botan::Pipe * unfiltered_pipe;
+extern pipe_cache_cleanup * global_pipe_cleanup_object;
+
+class pipe_cache_cleanup
+{
+ friend class cached_botan_pipe;
+ struct cached_botan_pipe * to_be_destroyed;
+
+public:
+ pipe_cache_cleanup() : to_be_destroyed(0)
+ {
+ I(!global_pipe_cleanup_object);
+ global_pipe_cleanup_object = this;
+ }
+ ~pipe_cache_cleanup()
+ {
+ for (cached_botan_pipe * p = to_be_destroyed; p; p = p->next_tbd)
+ p->pipe.reset(0);
+ global_pipe_cleanup_object = 0;
+ }
+};
+
+// must be defined after class pipe_cache_cleanup
+inline cached_botan_pipe::cached_botan_pipe(Botan::Pipe * p)
+ : pipe(p)
+{
+ I(global_pipe_cleanup_object);
+ this->next_tbd = global_pipe_cleanup_object->to_be_destroyed;
+ global_pipe_cleanup_object->to_be_destroyed = this;
+}
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
+
+#endif // __BOTAN_PIPE_CACHE_HH__
============================================================
--- Makefile.am 242b7438c47167c49dc69f129232bd6b91261a22
+++ Makefile.am 868eff98716b795d27b9f00b523e2c42d9e1f0ce
@@ -25,6 +25,7 @@ MOST_SOURCES = \
$(SANITY_CORE_SOURCES) $(LUAEXT_SOURCES) platform-wrapped.hh \
rev_types.hh mtn-sanity.cc mtn-sanity.hh ui.cc ui.hh \
app_state.cc app_state.hh \
+ botan_pipe_cache.hh \
commands.cc commands.hh $(CMD_SOURCES) \
diff_patch.cc diff_patch.hh \
lua_hooks.cc lua_hooks.hh \
============================================================
--- file_io.cc 358fb964dc42e7f936a136342b93bb3a4744d1b3
+++ file_io.cc db5ed54600200ee2cda6ff1a2a8b0ecb463b653b
@@ -12,6 +12,7 @@
#include
#include "botan/botan.h"
+#include "botan_pipe_cache.hh"
#include "file_io.hh"
#include "sanity.hh"
@@ -334,11 +335,10 @@ read_data(any_path const & p, data & dat
ifstream file(p.as_external().c_str(),
ios_base::in | ios_base::binary);
N(file, F("cannot open file %s for reading") % p);
- Botan::Pipe pipe;
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- dat = data(pipe.read_all_as_string());
+ unfiltered_pipe->start_msg();
+ file >> *unfiltered_pipe;
+ unfiltered_pipe->end_msg();
+ dat = data(unfiltered_pipe->read_all_as_string(Botan::Pipe::LAST_MESSAGE));
}
void read_directory(any_path const & path,
@@ -358,11 +358,10 @@ read_data_stdin(data & dat)
static bool have_consumed_stdin = false;
N(!have_consumed_stdin, F("Cannot read standard input multiple times"));
have_consumed_stdin = true;
- Botan::Pipe pipe;
- pipe.start_msg();
- cin >> pipe;
- pipe.end_msg();
- dat = data(pipe.read_all_as_string());
+ unfiltered_pipe->start_msg();
+ cin >> *unfiltered_pipe;
+ unfiltered_pipe->end_msg();
+ dat = data(unfiltered_pipe->read_all_as_string(Botan::Pipe::LAST_MESSAGE));
}
void
@@ -562,13 +561,16 @@ calculate_ident(file_path const & file,
hexenc & ident)
{
// no conversions necessary, use streaming form
+ static cached_botan_pipe
+ p(new Botan::Pipe(new Botan::Hash_Filter("SHA-160"),
+ new Botan::Hex_Encoder(Botan::Hex_Encoder::Lowercase)));
+
// Best to be safe and check it isn't a dir.
assert_path_is_file(file);
- Botan::Pipe p(new Botan::Hash_Filter("SHA-160"), new Botan::Hex_Encoder());
Botan::DataSource_Stream infile(file.as_external(), true);
- p.process_msg(infile);
+ p->process_msg(infile);
- ident = hexenc(lowercase(p.read_all_as_string()));
+ ident = hexenc(p->read_all_as_string(Botan::Pipe::LAST_MESSAGE));
}
// Local Variables:
============================================================
--- gzip.cc 93f149779d9f0132940a206e008eeef3ca618b92
+++ gzip.cc 72e05981fe6cc8aa932363eef6c187241a4bb31d
@@ -200,7 +200,7 @@ void Gzip_Compression::put_footer()
SecureVector buf(4);
SecureVector tmpbuf(4);
- pipe.read(tmpbuf.begin(), tmpbuf.size());
+ pipe.read(tmpbuf.begin(), tmpbuf.size(), Pipe::LAST_MESSAGE);
// CRC32 is the reverse order to what gzip expects.
for (int i = 0; i < 4; i++)
@@ -365,7 +365,7 @@ void Gzip_Decompression::check_footer()
// 4 byte CRC32, and 4 byte length field
SecureVector buf(4);
SecureVector tmpbuf(4);
- pipe.read(tmpbuf.begin(), tmpbuf.size());
+ pipe.read(tmpbuf.begin(), tmpbuf.size(), Pipe::LAST_MESSAGE);
// CRC32 is the reverse order to what gzip expects.
for (int i = 0; i < 4; i++)
@@ -406,7 +406,7 @@ void Gzip_Decompression::clear()
no_writes = true;
inflateReset(&(zlib->stream));
- footer.clear();
+ footer.destroy();
pos = 0;
datacount = 0;
}
============================================================
--- hmac.cc 115a8c2bd6e81ea28d4628e77e4ad4dfae8e00a9
+++ hmac.cc da58d8141987a07675d0a8aaf8ab70b60d53ac90
@@ -12,7 +12,10 @@ chained_hmac::chained_hmac(netsync_sessi
chained_hmac::chained_hmac(netsync_session_key const & session_key, bool active) :
hmac_length(constants::sha1_digest_length),
active(active),
- key(reinterpret_cast(session_key().data()), session_key().size())
+ key(reinterpret_cast(session_key().data()),
+ session_key().size()),
+ engine(new Botan::MAC_Filter("HMAC(SHA-160)", key,
+ constants::sha1_digest_length))
{
chain_val.assign(hmac_length, 0x00);
}
@@ -24,6 +27,9 @@ chained_hmac::set_key(netsync_session_ke
{
key = Botan::SymmetricKey(reinterpret_cast(session_key().data()),
session_key().size());
+ engine.reset();
+ engine.append(new Botan::MAC_Filter("HMAC(SHA-160)", key,
+ constants::sha1_digest_length));
}
}
@@ -38,14 +44,12 @@ chained_hmac::process(string const & str
I(pos + n <= str.size());
- Botan::Pipe p(new Botan::MAC_Filter("HMAC(SHA-160)", key,
- constants::sha1_digest_length));
- p.start_msg();
- p.write(chain_val);
- p.write(reinterpret_cast(str.data() + pos), n);
- p.end_msg();
+ engine.start_msg();
+ engine.write(chain_val);
+ engine.write(reinterpret_cast(str.data() + pos), n);
+ engine.end_msg();
- chain_val = p.read_all_as_string();
+ chain_val = engine.read_all_as_string(Botan::Pipe::LAST_MESSAGE);
I(chain_val.size() == constants::sha1_digest_length);
return chain_val;
@@ -62,15 +66,13 @@ chained_hmac::process(string_queue const
I(pos + n <= str.size());
- Botan::Pipe p(new Botan::MAC_Filter("HMAC(SHA-160)", key,
- constants::sha1_digest_length));
- p.start_msg();
- p.write(chain_val);
- p.write(reinterpret_cast(str.front_pointer(n) + pos), n);
-
- p.end_msg();
+ engine.start_msg();
+ engine.write(chain_val);
+ engine.write(reinterpret_cast(str.front_pointer(n)
+ + pos), n);
+ engine.end_msg();
- chain_val = p.read_all_as_string();
+ chain_val = engine.read_all_as_string(Botan::Pipe::LAST_MESSAGE);
I(chain_val.size() == constants::sha1_digest_length);
return chain_val;
============================================================
--- hmac.hh 6953e20a8a307882b42c317e31714a53f8dae510
+++ hmac.hh 38920db37f7ac41a26c51b97a9fb2a394d0f37ff
@@ -23,6 +23,7 @@ private:
private:
bool active;
Botan::SymmetricKey key;
+ Botan::Pipe engine;
std::string chain_val;
};
============================================================
--- key_store.cc 167e6637e117ee23709dc32bb029cb0288064606
+++ key_store.cc 0f3eb9d8e4e664f42a1099f299c325604fae9cc9
@@ -17,6 +17,7 @@
#include "botan/rsa.h"
#include "botan/keypair.h"
#include "botan/pem.h"
+#include "botan_pipe_cache.hh"
using std::make_pair;
using std::istringstream;
@@ -377,9 +378,8 @@ key_store_state::decrypt_private_key(rsa
shared_ptr pkcs8_key;
try // with empty passphrase
{
- Pipe p;
- p.process_msg(kp.priv());
- pkcs8_key.reset(Botan::PKCS8::load_key(p, ""));
+ Botan::DataSource_Memory ds(kp.priv());
+ pkcs8_key.reset(Botan::PKCS8::load_key(ds, ""));
}
catch (Botan::Exception & e)
{
@@ -397,9 +397,8 @@ key_store_state::decrypt_private_key(rsa
for (;;)
try
{
- Pipe p;
- p.process_msg(kp.priv());
- pkcs8_key.reset(Botan::PKCS8::load_key(p, phrase()));
+ Botan::DataSource_Memory ds(kp.priv());
+ pkcs8_key.reset(Botan::PKCS8::load_key(ds, phrase()));
break;
}
catch (Botan::Exception & e)
@@ -469,22 +468,23 @@ key_store::create_key_pair(database & db
// serialize and maybe encrypt the private key
keypair kp;
SecureVector pubkey, privkey;
- Pipe p;
- p.start_msg();
+
+ unfiltered_pipe->start_msg();
if ((*maybe_passphrase)().length())
- Botan::PKCS8::encrypt_key(priv, p,
+ Botan::PKCS8::encrypt_key(priv, *unfiltered_pipe,
(*maybe_passphrase)(),
"PBE-PKCS5v20(SHA-1,TripleDES/CBC)",
Botan::RAW_BER);
else
- Botan::PKCS8::encode(priv, p);
- kp.priv = rsa_priv_key(p.read_all_as_string());
+ Botan::PKCS8::encode(priv, *unfiltered_pipe);
+ unfiltered_pipe->end_msg();
+ kp.priv = rsa_priv_key(unfiltered_pipe->read_all_as_string(Pipe::LAST_MESSAGE));
// serialize the public key
- Pipe p2;
- p2.start_msg();
- Botan::X509::encode(priv, p2, Botan::RAW_BER);
- kp.pub = rsa_pub_key(p2.read_all_as_string());
+ unfiltered_pipe->start_msg();
+ Botan::X509::encode(priv, *unfiltered_pipe, Botan::RAW_BER);
+ unfiltered_pipe->end_msg();
+ kp.pub = rsa_pub_key(unfiltered_pipe->read_all_as_string(Pipe::LAST_MESSAGE));
// convert to storage format
L(FL("generated %d-byte public key\n"
@@ -519,12 +519,12 @@ key_store::change_key_passphrase(rsa_key
utf8 new_phrase;
get_passphrase(new_phrase, id, true, false);
- Pipe p;
- p.start_msg();
- Botan::PKCS8::encrypt_key(*priv, p, new_phrase(),
+ unfiltered_pipe->start_msg();
+ Botan::PKCS8::encrypt_key(*priv, *unfiltered_pipe, new_phrase(),
"PBE-PKCS5v20(SHA-1,TripleDES/CBC)",
Botan::RAW_BER);
- kp.priv = rsa_priv_key(p.read_all_as_string());
+ unfiltered_pipe->end_msg();
+ kp.priv = rsa_priv_key(unfiltered_pipe->read_all_as_string(Pipe::LAST_MESSAGE));
delete_key(id);
put_key_pair(id, kp);
@@ -684,6 +684,7 @@ key_store::export_key_for_agent(rsa_keyp
utf8 new_phrase;
get_passphrase(new_phrase, id, true, false);
+ // This pipe cannot sensibly be recycled.
Pipe p(new Botan::DataSink_Stream(os));
p.start_msg();
if (new_phrase().length())
@@ -734,10 +735,9 @@ key_store_state::migrate_old_key_pair
// recognize an unencrypted, raw-BER blob as such, but gets it
// right if it's PEM-coded.
SecureVector arc4_decrypt(arc4_decryptor.read_all());
- Pipe p;
- p.process_msg(Botan::PEM_Code::encode(arc4_decrypt, "PRIVATE KEY"));
-
- pkcs8_key.reset(Botan::PKCS8::load_key(p));
+ Botan::DataSource_Memory ds(Botan::PEM_Code::encode(arc4_decrypt,
+ "PRIVATE KEY"));
+ pkcs8_key.reset(Botan::PKCS8::load_key(ds));
break;
}
catch (Botan::Exception & e)
@@ -758,20 +758,20 @@ key_store_state::migrate_old_key_pair
I(priv_key);
// now we can write out the new key
- Pipe p;
- p.start_msg();
- Botan::PKCS8::encrypt_key(*priv_key, p, phrase(),
+ unfiltered_pipe->start_msg();
+ Botan::PKCS8::encrypt_key(*priv_key, *unfiltered_pipe, phrase(),
"PBE-PKCS5v20(SHA-1,TripleDES/CBC)",
Botan::RAW_BER);
- kp.priv = rsa_priv_key(p.read_all_as_string());
+ unfiltered_pipe->end_msg();
+ kp.priv = rsa_priv_key(unfiltered_pipe->read_all_as_string(Pipe::LAST_MESSAGE));
// also the public key (which is derivable from the private key; asking
// Botan for the X.509 encoding of the private key implies that we want
// it to derive and produce the public key)
- Pipe p2;
- p2.start_msg();
- Botan::X509::encode(*priv_key, p2, Botan::RAW_BER);
- kp.pub = rsa_pub_key(p2.read_all_as_string());
+ unfiltered_pipe->start_msg();
+ Botan::X509::encode(*priv_key, *unfiltered_pipe, Botan::RAW_BER);
+ unfiltered_pipe->end_msg();
+ kp.pub = rsa_pub_key(unfiltered_pipe->read_all_as_string(Pipe::LAST_MESSAGE));
// if the database had a public key entry for this key, make sure it
// matches what we derived from the private key entry, but don't abort the
============================================================
--- monotone.cc c105422e7de754e19a87af2cd8ad4b798159520e
+++ monotone.cc e7cb1f117494c4853f3320a4add02474b6a2ff6c
@@ -19,9 +19,9 @@
#include "botan/botan.h"
#include "i18n.h"
#include "app_state.hh"
+#include "botan_pipe_cache.hh"
#include "commands.hh"
#include "sanity.hh"
-#include "cleanup.hh"
#include "file_io.hh"
#include "charset.hh"
#include "ui.hh"
@@ -99,6 +99,11 @@ void localize_monotone()
}
}
+// define the global objects needed by botan_pipe_cache.hh
+pipe_cache_cleanup * global_pipe_cleanup_object;
+Botan::Pipe * unfiltered_pipe;
+static unsigned char unfiltered_pipe_cleanup_mem[sizeof(cached_botan_pipe)];
+
option::concrete_option_set
read_global_options(options & opts, args_vector & args)
{
@@ -166,9 +171,14 @@ cpp_main(int argc, char ** argv)
Botan::LibraryInitializer acquire_botan("thread_safe=0 selftest=0 "
"seed_rng=1 use_engines=0 "
"secure_memory=1 fips140=0");
+
+ // and caching for botan pipes
+ pipe_cache_cleanup acquire_botan_pipe_caching;
+ unfiltered_pipe = new Botan::Pipe;
+ new (unfiltered_pipe_cleanup_mem) cached_botan_pipe(unfiltered_pipe);
// Record where we are. This has to happen before any use of
- // boost::filesystem.
+ // paths.hh objects.
save_initial_path();
// decode all argv values into a UTF-8 array
============================================================
--- tester.cc 5698be54abe68883c1ce41db0ba95e461a1f3fad
+++ tester.cc da1589e5c3cc77aa51b5658a71b613e6b1ec64db
@@ -6,6 +6,8 @@
#include "tester-plaf.hh"
#include "vector.hh"
#include "sanity.hh"
+#include "botan/botan.h"
+#include "botan_pipe_cache.hh"
#include
#include
@@ -38,6 +40,11 @@ sanity & global_sanity = real_sanity;
tester_sanity real_sanity;
sanity & global_sanity = real_sanity;
+// define the global objects needed by botan_pipe_cache.hh
+pipe_cache_cleanup * global_pipe_cleanup_object;
+Botan::Pipe * unfiltered_pipe;
+static unsigned char unfiltered_pipe_cleanup_mem[sizeof(cached_botan_pipe)];
+
string basename(string const & s)
{
string::size_type sep = s.rfind('/');
@@ -904,7 +911,7 @@ parse_makeflags(char const * mflags,
}
}
else if (int_int_option(i->c_str(), "--jobserver-fds=", jread, jwrite))
- ;
+ 0;
}
// do not permit -j in MAKEFLAGS to override -j on the command line.
@@ -1004,6 +1011,16 @@ int main(int argc, char **argv)
try
{
global_sanity.initialize(argc, argv, "C");
+ // Set up secure memory allocation etc
+ Botan::LibraryInitializer acquire_botan("thread_safe=0 selftest=0 "
+ "seed_rng=1 use_engines=0 "
+ "secure_memory=1 fips140=0");
+
+ // and caching for botan pipes
+ pipe_cache_cleanup acquire_botan_pipe_caching;
+ unfiltered_pipe = new Botan::Pipe;
+ new (unfiltered_pipe_cleanup_mem) cached_botan_pipe(unfiltered_pipe);
+
parse_command_line(argc, argv,
want_help, need_help, debugging, list_only,
run_one, jobs, tests_to_run);
============================================================
--- transforms.cc 144f5ceb3515a7b9a392e6963c5841788a8bdbd0
+++ transforms.cc 47dcee3eac105e9bc2d39f8f9802d606dcf5c5bd
@@ -8,26 +8,25 @@
// PURPOSE.
#include "base.hh"
-#include
-#include
#include
-#include
-#include "vector.hh"
-
+#include "botan_pipe_cache.hh"
#include "botan/botan.h"
#include "botan/sha160.h"
#include "gzip.hh"
-#include "cleanup.hh"
-#include "constants.hh"
-#include "sanity.hh"
#include "transforms.hh"
-#include "simplestring_xform.hh"
-#include "vocab.hh"
#include "xdelta.hh"
#include "char_classifiers.hh"
using std::string;
+using Botan::Pipe;
+using Botan::Base64_Encoder;
+using Botan::Base64_Decoder;
+using Botan::Hex_Encoder;
+using Botan::Hex_Decoder;
+using Botan::Gzip_Compression;
+using Botan::Gzip_Decompression;
+using Botan::Hash_Filter;
// this file contans various sorts of string transformations. each
// transformation should be self-explanatory from its type signature. see
@@ -98,37 +97,33 @@ error_in_transform(Botan::Exception & e)
I(false); // can't get here
}
-// worker function for the visible functions below
-namespace {
-template string xform(XFM * x, string const & in)
-{
- string out;
- try
- {
- Botan::Pipe pipe(x);
- pipe.process_msg(in);
- out = pipe.read_all_as_string();
- }
- catch (Botan::Exception & e)
- {
- error_in_transform(e);
- }
- return out;
-}
-}
-
// full specializations for the usable cases of xform()
// use extra error checking in base64 and hex decoding
-#define SPECIALIZE_XFORM(T, carg) \
- template<> string xform(string const &in) \
- { return xform(new T(carg), in); }
+#define SPECIALIZE_XFORM(T, carg) \
+ template<> string xform(string const & in) \
+ { \
+ string out; \
+ try \
+ { \
+ static cached_botan_pipe pipe(new Pipe(new T(carg))); \
+ /* this might actually be a problem here */ \
+ I(pipe->message_count() < Pipe::LAST_MESSAGE); \
+ pipe->process_msg(in); \
+ out = pipe->read_all_as_string(Pipe::LAST_MESSAGE); \
+ } \
+ catch (Botan::Exception & e) \
+ { \
+ error_in_transform(e); \
+ } \
+ return out; \
+ }
-SPECIALIZE_XFORM(Botan::Base64_Encoder,);
-SPECIALIZE_XFORM(Botan::Base64_Decoder, Botan::IGNORE_WS);
-SPECIALIZE_XFORM(Botan::Hex_Encoder, Botan::Hex_Encoder::Lowercase);
-SPECIALIZE_XFORM(Botan::Hex_Decoder, Botan::IGNORE_WS);
-SPECIALIZE_XFORM(Botan::Gzip_Compression,);
-SPECIALIZE_XFORM(Botan::Gzip_Decompression,);
+SPECIALIZE_XFORM(Base64_Encoder,);
+SPECIALIZE_XFORM(Base64_Decoder, Botan::IGNORE_WS);
+SPECIALIZE_XFORM(Hex_Encoder, Hex_Encoder::Lowercase);
+SPECIALIZE_XFORM(Hex_Decoder, Botan::IGNORE_WS);
+SPECIALIZE_XFORM(Gzip_Compression,);
+SPECIALIZE_XFORM(Gzip_Decompression,);
template
void pack(T const & in, base64< gzip > & out)
@@ -138,10 +133,10 @@ void pack(T const & in, base64< gzip
try
{
- Botan::Pipe pipe(new Botan::Gzip_Compression(),
- new Botan::Base64_Encoder);
- pipe.process_msg(in());
- tmp = pipe.read_all_as_string();
+ static cached_botan_pipe pipe(new Pipe(new Gzip_Compression,
+ new Base64_Encoder));
+ pipe->process_msg(in());
+ tmp = pipe->read_all_as_string(Pipe::LAST_MESSAGE);
out = base64< gzip >(tmp);
}
catch (Botan::Exception & e)
@@ -155,10 +150,10 @@ void unpack(base64< gzip > const & in
{
try
{
- Botan::Pipe pipe(new Botan::Base64_Decoder(),
- new Botan::Gzip_Decompression());
- pipe.process_msg(in());
- out = T(pipe.read_all_as_string());
+ static cached_botan_pipe pipe(new Pipe(new Base64_Decoder,
+ new Gzip_Decompression));
+ pipe->process_msg(in());
+ out = T(pipe->read_all_as_string(Pipe::LAST_MESSAGE));
}
catch (Botan::Exception & e)
{
@@ -202,10 +197,10 @@ calculate_ident(data const & dat,
{
try
{
- Botan::Pipe p(new Botan::Hash_Filter("SHA-160"),
- new Botan::Hex_Encoder(Botan::Hex_Encoder::Lowercase));
- p.process_msg(dat());
- ident = hexenc(p.read_all_as_string());
+ static cached_botan_pipe p(new Pipe(new Hash_Filter("SHA-160"),
+ new Hex_Encoder(Hex_Encoder::Lowercase)));
+ p->process_msg(dat());
+ ident = hexenc(p->read_all_as_string(Pipe::LAST_MESSAGE));
}
catch (Botan::Exception & e)
{
============================================================
--- unit_tests.cc 45a81af10ac5ffd8be8d0bf9c4c8ee03f63bf16d
+++ unit_tests.cc 5baf8acaed8b1a76321a7b8e95de47414bf97de7
@@ -25,6 +25,7 @@
#include "sanity.hh"
#include "ui.hh"
#include "current_exception.hh"
+#include "botan_pipe_cache.hh"
using std::map;
using std::pair;
@@ -149,9 +150,10 @@ void unit_test::do_checkpoint(char const
log_state(file, line, "CHECKPOINT", message);
}
-static int run_test(test_t test)
-{
-}
+// define the global objects needed by botan_pipe_cache.hh
+pipe_cache_cleanup * global_pipe_cleanup_object;
+Botan::Pipe * unfiltered_pipe;
+static unsigned char unfiltered_pipe_cleanup_mem[sizeof(cached_botan_pipe)];
int main(int argc, char * argv[])
{
@@ -198,7 +200,14 @@ int main(int argc, char * argv[])
// set up some global state before running the tests
- Botan::LibraryInitializer::initialize();
+ // keep this in sync with monotone.cc, except for selftest=1 here, =0 there
+ Botan::LibraryInitializer acquire_botan("thread_safe=0 selftest=1 "
+ "seed_rng=1 use_engines=0 "
+ "secure_memory=1 fips140=0");
+ // and caching for botan pipes
+ pipe_cache_cleanup acquire_botan_pipe_caching;
+ unfiltered_pipe = new Botan::Pipe;
+ new (unfiltered_pipe_cleanup_mem) cached_botan_pipe(unfiltered_pipe);
// Make clog and cout use the same streambuf as cerr; this ensures
// that all messages will appear in the order written, no matter what