diff options
author | lloyd <[email protected]> | 2006-09-02 05:32:28 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-09-02 05:32:28 +0000 |
commit | cc1d7c0010f9e3437813f50b618153c4d3fa29f3 (patch) | |
tree | eb316178f55dccf79eddb25195890f879aa48ac7 /misc/python/src | |
parent | af89b658d84c0a6930f2c6b4ce2c39c5d6ee5dbd (diff) |
Allow for implementing hash functions in Python
Move some code that is used in several places into a common header
Diffstat (limited to 'misc/python/src')
-rw-r--r-- | misc/python/src/algos.cpp | 35 | ||||
-rw-r--r-- | misc/python/src/block.cpp | 46 | ||||
-rw-r--r-- | misc/python/src/common.h | 45 | ||||
-rw-r--r-- | misc/python/src/hash.cpp | 104 |
4 files changed, 163 insertions, 67 deletions
diff --git a/misc/python/src/algos.cpp b/misc/python/src/algos.cpp index cb1255ccf..23dd969ff 100644 --- a/misc/python/src/algos.cpp +++ b/misc/python/src/algos.cpp @@ -41,30 +41,6 @@ class Py_StreamCipher StreamCipher* cipher; }; -class Py_HashFunction - { - public: - u32bit output_length() const { return hash->OUTPUT_LENGTH; } - std::string name() const { return hash->name(); } - void clear() throw() { hash->clear(); } - - void update(const std::string& in) { hash->update(in); } - - std::string final() - { - SecureVector<byte> result = hash->final(); - return std::string((const char*)result.begin(), result.size()); - } - - Py_HashFunction(const std::string& name) - { - hash = get_hash(name); - } - ~Py_HashFunction() { delete hash; } - private: - HashFunction* hash; - }; - class Py_MAC { public: @@ -99,11 +75,13 @@ class Py_MAC MessageAuthenticationCode* mac; }; -void export_block_ciphers(); +extern void export_block_ciphers(); +extern void export_hash_functions(); void export_basic_algos() { export_block_ciphers(); + export_hash_functions(); python::class_<Py_StreamCipher>("StreamCipher", python::init<std::string>()) .add_property("keylength_min", &Py_StreamCipher::keylength_min) @@ -115,13 +93,6 @@ void export_basic_algos() .def("set_key", &Py_StreamCipher::set_key) .def("crypt", &Py_StreamCipher::crypt); - python::class_<Py_HashFunction>("HashFunction", python::init<std::string>()) - .add_property("output_length", &Py_HashFunction::output_length) - .add_property("name", &Py_HashFunction::name) - .def("clear", &Py_HashFunction::clear) - .def("update", &Py_HashFunction::update) - .def("final", &Py_HashFunction::final); - python::class_<Py_MAC>("MAC", python::init<std::string>()) .add_property("output_length", &Py_MAC::output_length) .add_property("keylength_min", &Py_MAC::keylength_min) diff --git a/misc/python/src/block.cpp b/misc/python/src/block.cpp index 1b950772c..3e40da6e3 100644 --- a/misc/python/src/block.cpp +++ b/misc/python/src/block.cpp @@ -6,17 +6,7 @@ #include <botan/botan.h> using namespace Botan; -#include <boost/python.hpp> -namespace python = boost::python; - -class Bad_Size : public Exception - { - public: - Bad_Size(const std::string& name, u32bit got, u32bit expected) : - Exception("Bad size encountered in " + name + "; got " + - to_string(got) + " bytes, expected " + to_string(expected)) - {} - }; +#include "common.h" class Py_BlockCipher : public BlockCipher { @@ -27,22 +17,16 @@ class Py_BlockCipher : public BlockCipher void enc(const byte in[], byte out[]) const { - std::string out_str = enc_str( - std::string((const char*)in, BLOCK_SIZE) - ); - if(out_str.size() != BLOCK_SIZE) - throw Bad_Size(name(), out_str.size(), BLOCK_SIZE); - std::memcpy(out, out_str.data(), BLOCK_SIZE); + string2binary( + enc_str(make_string(in, BLOCK_SIZE)), + out, BLOCK_SIZE); } void dec(const byte in[], byte out[]) const { - std::string out_str = dec_str( - std::string((const char*)in, BLOCK_SIZE) - ); - if(out_str.size() != BLOCK_SIZE) - throw Bad_Size(name(), out_str.size(), BLOCK_SIZE); - std::memcpy(out, out_str.data(), BLOCK_SIZE); + string2binary( + dec_str(make_string(in, BLOCK_SIZE)), + out, BLOCK_SIZE); } void key(const byte key[], u32bit len) @@ -59,29 +43,21 @@ class Py_BlockCipher : public BlockCipher std::string encrypt_string(BlockCipher* cipher, const std::string& in) { if(in.size() != cipher->BLOCK_SIZE) - throw Bad_Size(cipher->name(), in.size(), cipher->BLOCK_SIZE); + throw Bad_Size(in.size(), cipher->BLOCK_SIZE); SecureVector<byte> out(cipher->BLOCK_SIZE); cipher->encrypt((const byte*)in.data(), out); - return std::string((const char*)out.begin(), out.size()); + return make_string(out); } std::string decrypt_string(BlockCipher* cipher, const std::string& in) { if(in.size() != cipher->BLOCK_SIZE) - throw Bad_Size(cipher->name(), in.size(), cipher->BLOCK_SIZE); + throw Bad_Size(in.size(), cipher->BLOCK_SIZE); SecureVector<byte> out(cipher->BLOCK_SIZE); cipher->decrypt((const byte*)in.data(), out); - return std::string((const char*)out.begin(), out.size()); - } - -template<typename T> -python::object get_owner(T* me) - { - return python::object( - python::handle<>( - python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); + return make_string(out); } class Wrapped_Block_Cipher : public BlockCipher diff --git a/misc/python/src/common.h b/misc/python/src/common.h new file mode 100644 index 000000000..968cc3908 --- /dev/null +++ b/misc/python/src/common.h @@ -0,0 +1,45 @@ + +#ifndef BOTAN_BOOST_PYTHON_COMMON_H__ +#define BOTAN_BOOST_PYTHON_COMMON_H__ + +#include <botan/base.h> +using namespace Botan; + +#include <boost/python.hpp> +namespace python = boost::python; + +class Bad_Size : public Exception + { + public: + Bad_Size(u32bit got, u32bit expected) : + Exception("Bad size detected in Python/C++ conversion layer: got " + + to_string(got) + " bytes, expected " + to_string(expected)) + {} + }; + +inline std::string make_string(const byte input[], u32bit length) + { + return std::string((const char*)input, length); + } + +inline std::string make_string(const MemoryRegion<byte>& in) + { + return make_string(in.begin(), in.size()); + } + +inline void string2binary(const std::string& from, byte to[], u32bit expected) + { + if(from.size() != expected) + throw Bad_Size(from.size(), expected); + std::memcpy(to, from.data(), expected); + } + +template<typename T> +inline python::object get_owner(T* me) + { + return python::object( + python::handle<>( + python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); + } + +#endif diff --git a/misc/python/src/hash.cpp b/misc/python/src/hash.cpp new file mode 100644 index 000000000..133133972 --- /dev/null +++ b/misc/python/src/hash.cpp @@ -0,0 +1,104 @@ +/************************************************* +* Boost.Python module definition * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/botan.h> +using namespace Botan; + +#include "common.h" + +class Py_HashFunction : public HashFunction + { + public: + virtual void hash_str(const std::string&) = 0; + virtual std::string final_str() = 0; + + void add_data(const byte input[], u32bit length) + { + hash_str(make_string(input, length)); + } + + void final_result(byte output[]) + { + string2binary(final_str(), output, OUTPUT_LENGTH); + } + + Py_HashFunction(u32bit digest_size, u32bit block_size) : + HashFunction(digest_size, block_size) {} + }; + +class Wrapped_HashFunction : public HashFunction + { + public: + void add_data(const byte in[], u32bit len) { hash->update(in, len); } + void final_result(byte out[]) { hash->final(out); } + + std::string name() const { return hash->name(); } + HashFunction* clone() const { return hash->clone(); } + + Wrapped_HashFunction(python::object py_obj, HashFunction* h) : + HashFunction(h->OUTPUT_LENGTH, h->HASH_BLOCK_SIZE), + obj(py_obj), hash(h) {} + private: + python::object obj; + HashFunction* hash; + }; + +class Py_HashFunction_Wrapper : public Py_HashFunction, + public python::wrapper<Py_HashFunction> + { + public: + HashFunction* clone() const + { + python::object self = get_owner(this); + python::object py_clone = self.attr("__class__")(); + HashFunction* hf = python::extract<HashFunction*>(py_clone); + return new Wrapped_HashFunction(py_clone, hf); + } + + std::string name() const + { + return this->get_override("name")(); + } + + void hash_str(const std::string& in) + { + this->get_override("update")(in); + } + + std::string final_str() + { + return this->get_override("final")(); + } + + Py_HashFunction_Wrapper(u32bit digest_size, u32bit block_size) : + Py_HashFunction(digest_size, block_size) {} + }; + +std::string final_str(HashFunction* hash) + { + SecureVector<byte> digest = hash->final(); + return std::string((const char*)digest.begin(), digest.size()); + } + +void export_hash_functions() + { + void (HashFunction::*update_str)(const std::string&) = + &HashFunction::update; + + python::class_<HashFunction, boost::noncopyable> + ("HashFunction", python::no_init) + .def("__init__", python::make_constructor(get_hash)) + .def_readonly("digest_size", &HashFunction::OUTPUT_LENGTH) + .def("name", &HashFunction::name) + .def("update", update_str) + .def("final", final_str); + + python::class_<Py_HashFunction_Wrapper, python::bases<HashFunction>, + boost::noncopyable> + ("HashFunctionImpl", python::init<u32bit, u32bit>()) + .def("name", python::pure_virtual(&Py_HashFunction::name)) + .def("update", python::pure_virtual(&Py_HashFunction::hash_str)) + .def("final", python::pure_virtual(&Py_HashFunction::final_str)); + } |