aboutsummaryrefslogtreecommitdiffstats
path: root/misc/python/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-09-02 05:32:28 +0000
committerlloyd <[email protected]>2006-09-02 05:32:28 +0000
commitcc1d7c0010f9e3437813f50b618153c4d3fa29f3 (patch)
treeeb316178f55dccf79eddb25195890f879aa48ac7 /misc/python/src
parentaf89b658d84c0a6930f2c6b4ce2c39c5d6ee5dbd (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.cpp35
-rw-r--r--misc/python/src/block.cpp46
-rw-r--r--misc/python/src/common.h45
-rw-r--r--misc/python/src/hash.cpp104
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));
+ }