aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-17 22:42:36 +0000
committerlloyd <[email protected]>2008-09-17 22:42:36 +0000
commit2b6ad3a07e89e3c93425b1fffb78d4877299b414 (patch)
treecc7794b7dcecffe5b29d29a33f8f914a850a1663
parente65adc861146a0d88064a3889ed2efa2bbd9133f (diff)
Add an old attempt I made to wrap Botan using SWIG. Includes some tests
in Python. There are probably bugs and it may not even compile currently. (Just cleaning out the old ~ today... everything goes into mtn or /dev/null)
-rw-r--r--misc/swig/Makefile32
-rw-r--r--misc/swig/base.cpp61
-rw-r--r--misc/swig/base.h102
-rw-r--r--misc/swig/botan.swg26
-rwxr-xr-xmisc/swig/doit.py49
-rw-r--r--misc/swig/filter.cpp39
-rw-r--r--misc/swig/pipe.cpp89
-rw-r--r--misc/swig/pk.swg8
-rw-r--r--misc/swig/readme.txt34
-rw-r--r--misc/swig/tests/block.py52
-rw-r--r--misc/swig/tests/block2.py44
-rw-r--r--misc/swig/tests/encrypt.py37
-rw-r--r--misc/swig/tests/filter.py27
-rw-r--r--misc/swig/tests/hash.py30
-rw-r--r--misc/swig/tests/mac.py12
-rw-r--r--misc/swig/tests/pubkey.py10
-rw-r--r--misc/swig/tests/stream.py17
-rw-r--r--misc/swig/x509.swg9
18 files changed, 678 insertions, 0 deletions
diff --git a/misc/swig/Makefile b/misc/swig/Makefile
new file mode 100644
index 000000000..ff55c793c
--- /dev/null
+++ b/misc/swig/Makefile
@@ -0,0 +1,32 @@
+LANG=-python
+LANG_INC=/usr/include/python2.3
+
+CFLAGS=$(shell botan-config --cflags)
+LIBS=$(shell botan-config --libs)
+
+CXX = g++ -g
+SWIG = swig -Wall
+
+all: _botan.so
+
+_botan.so: base.o pipe.o filter.o botan_wrap.o
+ $(CXX) -shared $^ $(LIBS) -o $@
+
+botan_wrap.cpp: botan.swg base.h
+ $(SWIG) $(LANG) -c++ -o $@ $<
+
+botan_wrap.o: botan_wrap.cpp
+ $(CXX) $(CFLAGS) -I$(LANG_INC) -c $^ -o $@
+
+base.o: base.cpp base.h
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+pipe.o: pipe.cpp base.h
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+filter.o: filter.cpp base.h
+ $(CXX) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f *.o _botan.so botan.py botan.pyc
+ rm -f *_wrap.o *_wrap.cpp
diff --git a/misc/swig/base.cpp b/misc/swig/base.cpp
new file mode 100644
index 000000000..2550b915b
--- /dev/null
+++ b/misc/swig/base.cpp
@@ -0,0 +1,61 @@
+/*************************************************
+* SWIG Interface for basic Botan interface *
+* (C) 1999-2003 The Botan Project *
+*************************************************/
+
+#include "base.h"
+#include <botan/init.h>
+
+#include <stdio.h>
+
+/*************************************************
+* Initialize the library *
+*************************************************/
+LibraryInitializer::LibraryInitializer(const char* args)
+ {
+ Botan::Init::initialize(args);
+ }
+
+/*************************************************
+* Shut down the library *
+*************************************************/
+LibraryInitializer::~LibraryInitializer()
+ {
+ Botan::Init::deinitialize();
+ }
+
+/*************************************************
+* Create a SymmetricKey *
+*************************************************/
+SymmetricKey::SymmetricKey(const std::string& str)
+ {
+ key = new Botan::SymmetricKey(str);
+ printf("STR CON: %p %p\n", this, key);
+ }
+
+/*************************************************
+* Create a SymmetricKey *
+*************************************************/
+SymmetricKey::SymmetricKey(u32bit n)
+ {
+ key = new Botan::SymmetricKey(n);
+ printf("N CON: %p %p\n", this, key);
+ }
+
+/*************************************************
+* Destroy a SymmetricKey *
+*************************************************/
+SymmetricKey::~SymmetricKey()
+ {
+ printf("DESTR: %p %p\n", this, key);
+ delete key;
+ key = 0;
+ //printf("deleted\n");
+ }
+
+/*************************************************
+* Create an InitializationVector *
+*************************************************/
+InitializationVector::InitializationVector(const std::string& str) : iv(str)
+ {
+ }
diff --git a/misc/swig/base.h b/misc/swig/base.h
new file mode 100644
index 000000000..c3fd8426e
--- /dev/null
+++ b/misc/swig/base.h
@@ -0,0 +1,102 @@
+/*************************************************
+* SWIG Interface for Botan *
+* (C) 1999-2003 The Botan Project *
+*************************************************/
+
+#ifndef BOTAN_WRAP_BASE_H__
+#define BOTAN_WRAP_BASE_H__
+
+#include <botan/pipe.h>
+
+#if !defined(SWIG)
+ #define OUTPUT
+ #define INOUT
+#endif
+
+/*************************************************
+* Typedefs *
+*************************************************/
+typedef unsigned char byte;
+typedef unsigned int u32bit;
+
+/*************************************************
+* Library Initalization/Shutdown Object *
+*************************************************/
+class LibraryInitializer
+ {
+ public:
+ LibraryInitializer(const char*);
+ ~LibraryInitializer();
+ };
+
+/*************************************************
+* Symmetric Key Object *
+*************************************************/
+class SymmetricKey
+ {
+ public:
+ std::string as_string() const { return key->as_string(); }
+ u32bit length() const { return key->length(); }
+ SymmetricKey(u32bit = 0);
+ SymmetricKey(const std::string&);
+ ~SymmetricKey();
+ private:
+ Botan::SymmetricKey* key;
+ };
+
+/*************************************************
+* Initialization Vector Object *
+*************************************************/
+class InitializationVector
+ {
+ public:
+ std::string as_string() const { return iv.as_string(); }
+ u32bit length() const { return iv.length(); }
+ InitializationVector(u32bit n = 0) { iv.change(n); }
+ InitializationVector(const std::string&);
+ private:
+ Botan::InitializationVector iv;
+ };
+
+/*************************************************
+* Filter Object *
+*************************************************/
+class Filter
+ {
+ public:
+ Filter(const char*);
+ //Filter(const char*, const SymmetricKey&);
+ //Filter(const char*, const SymmetricKey&, const InitializationVector&);
+ ~Filter();
+ private:
+ friend class Pipe;
+ Botan::Filter* filter;
+ bool pipe_owns;
+ };
+
+/*************************************************
+* Pipe Object *
+*************************************************/
+class Pipe
+ {
+ public:
+ static const u32bit DEFAULT_MESSAGE = 0xFFFFFFFF;
+
+ void write_file(const char*);
+ void write_string(const char*);
+
+ u32bit read(byte*, u32bit, u32bit = DEFAULT_MESSAGE);
+ std::string read_all_as_string(u32bit = DEFAULT_MESSAGE);
+
+ u32bit remaining(u32bit = DEFAULT_MESSAGE);
+
+ void start_msg();
+ void end_msg();
+
+ Pipe(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0);
+ ~Pipe();
+ private:
+ Botan::Pipe* pipe;
+ };
+
+#endif
diff --git a/misc/swig/botan.swg b/misc/swig/botan.swg
new file mode 100644
index 000000000..9088f4272
--- /dev/null
+++ b/misc/swig/botan.swg
@@ -0,0 +1,26 @@
+/*************************************************
+* SWIG Interface for Botan *
+*************************************************/
+%module botan
+
+%include "typemaps.i"
+%include "std_string.i"
+%include "exception.i"
+%include "constraints.i"
+%include "carrays.i"
+
+%{
+#include "base.h"
+%}
+
+%exception {
+ try {
+ $action
+ }
+ catch(std::exception& e)
+ {
+ SWIG_exception(SWIG_RuntimeError, e.what());
+ }
+}
+
+%include "base.h"
diff --git a/misc/swig/doit.py b/misc/swig/doit.py
new file mode 100755
index 000000000..98bc97087
--- /dev/null
+++ b/misc/swig/doit.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python2
+
+import botan
+
+def hash_it(hash, input):
+ f1 = botan.Filter("MD5")
+ f2 = botan.Filter("Hex_Encoder")
+ pipe = botan.Pipe(f1, f2)
+
+ pipe.start_msg()
+ pipe.write_string(input)
+ pipe.end_msg()
+
+ print pipe.remaining()
+
+ out = pipe.read(0)
+
+
+
+
+def main:
+ init = botan.LibraryInitializer
+
+ print hash_it("MD5", "foo")
+
+
+ key1 = botan.SymmetricKey("ABCD")
+ print key1.as_string()
+ key2 = botan.SymmetricKey(16)
+ print key2.as_string()
+
+ iv1 = botan.InitializationVector(8)
+ print iv1.as_string()
+
+
+ f3 = pipe.read(pipe.remaining())
+
+ size = pipe.remaining()
+ out = botan.byte_array(size)
+ pipe.read(out.cast,size)
+
+ for i in range (0,size):
+ print "%02X" % out[i]
+
+ print pipe.read_all_as_string()
+
+if __name__ == "__main__":
+ sys.exit(main())
+
diff --git a/misc/swig/filter.cpp b/misc/swig/filter.cpp
new file mode 100644
index 000000000..ec9ce6603
--- /dev/null
+++ b/misc/swig/filter.cpp
@@ -0,0 +1,39 @@
+/*************************************************
+* SWIG Interface for Filter Retrieval *
+* (C) 1999-2003 The Botan Project *
+*************************************************/
+
+#include "base.h"
+#include <botan/lookup.h>
+#include <botan/filters.h>
+
+/*************************************************
+* Filter Creation *
+*************************************************/
+Filter::Filter(const char* filt_string)
+ {
+ filter = 0;
+ pipe_owns = false;
+
+ /*
+ Fixme: This is all so totally wrong. It needs to have full argument
+ processing for everything, all that kind of crap.
+ */
+ const std::string filt_name = filt_string;
+
+ if(Botan::have_hash(filt_name))
+ filter = new Botan::Hash_Filter(filt_name);
+ else if(filt_name == "Hex_Encoder")
+ filter = new Botan::Hex_Encoder;
+ }
+
+/*************************************************
+* Filter Destruction *
+*************************************************/
+Filter::~Filter()
+ {
+ /*
+ if(!pipe_owns)
+ delete filter;
+ */
+ }
diff --git a/misc/swig/pipe.cpp b/misc/swig/pipe.cpp
new file mode 100644
index 000000000..2ccdd5dfd
--- /dev/null
+++ b/misc/swig/pipe.cpp
@@ -0,0 +1,89 @@
+/*************************************************
+* SWIG Interface for Botan Pipe API *
+* (C) 1999-2003 The Botan Project *
+*************************************************/
+
+#include "base.h"
+#include <botan/pipe.h>
+
+#include <stdio.h>
+
+/*************************************************
+* Write the contents of a file into a Pipe *
+*************************************************/
+void Pipe::write_file(const char* filename)
+ {
+ Botan::DataSource_Stream in(filename);
+ pipe->write(in);
+ }
+
+/*************************************************
+* Write the contents of a string into a Pipe *
+*************************************************/
+void Pipe::write_string(const char* string)
+ {
+ pipe->write(string);
+ }
+
+/*************************************************
+* Read the contents of a Pipe into a buffer *
+*************************************************/
+u32bit Pipe::read(byte* buf, u32bit length, u32bit msg)
+ {
+ printf("read %p %d\n", buf, length);
+ return 0;
+ //return pipe->read(buf, length, msg);
+ }
+
+/*************************************************
+* Read the contents of a Pipe as a string *
+*************************************************/
+std::string Pipe::read_all_as_string(u32bit msg)
+ {
+ return pipe->read_all_as_string(msg);
+ }
+
+/*************************************************
+* Find out how much stuff the Pipe still has *
+*************************************************/
+u32bit Pipe::remaining(u32bit msg)
+ {
+ return pipe->remaining();
+ }
+
+/*************************************************
+* Start a new message *
+*************************************************/
+void Pipe::start_msg()
+ {
+ pipe->start_msg();
+ }
+
+/*************************************************
+* End the current msessage *
+*************************************************/
+void Pipe::end_msg()
+ {
+ pipe->end_msg();
+ }
+
+/*************************************************
+* Create a new Pipe *
+*************************************************/
+Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4)
+ {
+ pipe = new Botan::Pipe();
+
+ if(f1) { pipe->append(f1->filter); f1->pipe_owns = true; }
+ if(f2) { pipe->append(f2->filter); f2->pipe_owns = true; }
+ if(f3) { pipe->append(f3->filter); f3->pipe_owns = true; }
+ if(f4) { pipe->append(f4->filter); f4->pipe_owns = true; }
+ }
+
+/*************************************************
+* Destroy this Pipe *
+*************************************************/
+Pipe::~Pipe()
+ {
+ delete pipe;
+ }
diff --git a/misc/swig/pk.swg b/misc/swig/pk.swg
new file mode 100644
index 000000000..8e03cf120
--- /dev/null
+++ b/misc/swig/pk.swg
@@ -0,0 +1,8 @@
+%module botan
+
+%{
+#undef ANY
+#include "botan/pubkey.h"
+%}
+
+%include "botan/pubkey.h"
diff --git a/misc/swig/readme.txt b/misc/swig/readme.txt
new file mode 100644
index 000000000..a9965d914
--- /dev/null
+++ b/misc/swig/readme.txt
@@ -0,0 +1,34 @@
+This is the beginning of an attempt to SWIG-ify Botan so it can be accessed by
+other languages. You should use the latest SWIG 1.3 release (I am currently
+using SWIG 1.3.19). Currently I am only testing this code with Python 2.2.1,
+since that is the language I am mainly interested in at this point. Feel free
+to send me patches so this is usable with Perl or whatever.
+
+I'm not attempting to make everything in Botan usable from a script -
+basically, I just want the parts that *I* want to use. Most things are not
+supported yet, and there are lots of bugs in the stuff that does exist. If
+there is something in particular that you would like to be able to use from a
+script, let me know (patches are good, too).
+
+Todo:
+ * Why does it seg fault if we don't create a LibraryInitializer. It should
+ throw an exception, like it does in C++. Maybe have it init Botan when the
+ module is loaded? That seems a lot cleaner/nicer, but I don't know how to
+ do it yet.
+ * Lots of problems with exceptions
+ * Use constraints to prevent bad args when possible
+ * Pipe/Filter
+ - Better argument processing for all filters
+ - Support for ciphers, MACs, etc
+ - Chain + Fork
+ - Support for append/prepend/pop/reset in Pipe?
+ * Public Key Crypto
+ - RSA
+ - DSA
+ - DH
+ - Generic X.509 and PKCS #8 stuff
+ * PKI
+ - X.509 certs + CRLs
+ - PKCS #10 requests
+ - X.509 stores
+ - X.509 CA
diff --git a/misc/swig/tests/block.py b/misc/swig/tests/block.py
new file mode 100644
index 000000000..593937c81
--- /dev/null
+++ b/misc/swig/tests/block.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+import botan, base64
+
+class MyCipher(botan.BlockCipher):
+ def __init__(self):
+ botan.BlockCipher.__init__(self, 16, 16, 32, 8)
+ def encrypt(self, val):
+ print "encrypt", val
+ return val.swapcase()
+ def decrypt(self, val):
+ print "decrypt", val
+ return val.swapcase()
+ def set_key(self, key):
+ print "set_key", key
+ def clone(self):
+ print "cloning"
+ return MyCipher()
+ def name(self):
+ print "naming"
+ return "MyCipher"
+
+cipher = botan.BlockCipher("AES-128")
+
+print cipher.block_size
+print cipher.keylength_min
+print cipher.keylength_max
+print cipher.keylength_mod
+print cipher.name()
+
+for kl in range(1, 128):
+ if cipher.valid_keylength(kl):
+ print "1",
+ else:
+ print "0",
+print
+key = botan.SymmetricKey(16)
+
+cipher.set_key(key)
+ciphertext = cipher.encrypt("ABCDEFGH12345678")
+print base64.b16encode(ciphertext)
+
+cipher2 = cipher.clone()
+cipher2.set_key(key)
+
+plaintext = cipher2.decrypt(ciphertext)
+print plaintext
+
+botan.get_info(cipher)
+
+mycipher = MyCipher()
+botan.get_info(mycipher)
diff --git a/misc/swig/tests/block2.py b/misc/swig/tests/block2.py
new file mode 100644
index 000000000..5faccaf9a
--- /dev/null
+++ b/misc/swig/tests/block2.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+import botan, base64
+
+class MyCipher(botan.BlockCipherImpl):
+ def __init__(self):
+ botan.BlockCipherImpl.__init__(self, 8, 8, 16, 1)
+
+ def name(self):
+ return "MyCipher"
+
+ def encrypt(self, input):
+ return input.swapcase()
+
+ def decrypt(self, input):
+ return input.swapcase()
+
+ def set_key(self, key):
+ print "Got key",key
+
+def test(cipher):
+ print
+ print cipher
+ print "Testing", cipher.name()
+ print cipher.block_size
+ print cipher.keylength_min, cipher.keylength_max, cipher.keylength_mod
+ for i in range(1, 64):
+ if cipher.valid_keylength(i):
+ print "1",
+ else:
+ print "0",
+ print
+ cipher.set_key(botan.SymmetricKey(16))
+ ciphertext = cipher.encrypt("aBcDeFgH" * (cipher.block_size / 8))
+ print repr(ciphertext)
+ print cipher.decrypt(ciphertext)
+
+def main():
+ test(botan.BlockCipher("Blowfish"))
+ test(MyCipher())
+ test(botan.BlockCipher("AES"))
+
+if __name__ == "__main__":
+ main()
diff --git a/misc/swig/tests/encrypt.py b/misc/swig/tests/encrypt.py
new file mode 100644
index 000000000..9896777d4
--- /dev/null
+++ b/misc/swig/tests/encrypt.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+import sys, botan
+
+def encrypt(input):
+ cipher_key = botan.SymmetricKey("AABB")
+ print cipher_key.length
+ cipher_key = botan.SymmetricKey("AABBCCDD")
+ print cipher_key.length
+
+ cipher = botan.Filter("ARC4", key = cipher_key)
+
+ pipe = botan.Pipe(cipher, botan.Filter("Hex_Encoder"))
+
+ pipe.start_msg()
+ pipe.write(input)
+ pipe.end_msg()
+
+ str = pipe.read_all()
+ print str
+ return str
+
+def decrypt(input):
+ pipe = botan.Pipe(botan.Filter("Hex_Decoder"),
+ botan.Filter("ARC4",
+ key = botan.SymmetricKey("AABBCCDD")))
+
+ pipe.process_msg(input)
+ return pipe.read_all()
+
+def main():
+ ciphertext = encrypt("hi chappy")
+ print ciphertext
+ print decrypt(ciphertext)
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/misc/swig/tests/filter.py b/misc/swig/tests/filter.py
new file mode 100644
index 000000000..2b65d9ff2
--- /dev/null
+++ b/misc/swig/tests/filter.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import sys, botan
+
+class MyFilter(botan.FilterObj):
+ def write(self, input):
+ print "MyFilter::write",input
+ self.send(input)
+ def start_msg(self):
+ print "MyFilter::start_msg"
+ def end_msg(self):
+ print "MyFilter::end_msg"
+ def __del__(self):
+ print "~MyFilter"
+
+def main():
+ filter = MyFilter()
+
+ pipe = botan.Pipe(botan.Filter("Hex_Encoder"), filter,
+ botan.Filter("Hex_Decoder"))
+ pipe.start_msg()
+ pipe.write("hi chappy")
+ pipe.end_msg()
+ print pipe.read_all()
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/misc/swig/tests/hash.py b/misc/swig/tests/hash.py
new file mode 100644
index 000000000..930b8c81a
--- /dev/null
+++ b/misc/swig/tests/hash.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+
+import botan, base64, md5
+
+class PyMD5(botan.HashFunctionImpl):
+ def name(self):
+ return "PyMD5"
+ def update(self, input):
+ self.md5.update(input)
+ def final(self):
+ output = self.md5.digest()
+ self.md5 = md5.new()
+ return output
+ def __init__(self):
+ botan.HashFunctionImpl.__init__(self, 16, 64)
+ self.md5 = md5.new()
+
+hash = botan.HashFunction("SHA-256")
+
+print hash.name()
+print hash.digest_size
+
+hash.update("hi")
+hash.update(" ")
+hash.update("chappy")
+print base64.b16encode(hash.final())
+
+hash2 = PyMD5()
+hash2.update("hi chappy")
+print base64.b16encode(hash2.final())
diff --git a/misc/swig/tests/mac.py b/misc/swig/tests/mac.py
new file mode 100644
index 000000000..6110b6102
--- /dev/null
+++ b/misc/swig/tests/mac.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+
+import botan, base64
+
+mac = botan.MAC("HMAC(SHA-512)")
+
+print mac.name
+print mac.output_length
+
+mac.set_key(botan.SymmetricKey("abcd"))
+mac.update("hi chappy")
+print base64.b16encode(mac.final())
diff --git a/misc/swig/tests/pubkey.py b/misc/swig/tests/pubkey.py
new file mode 100644
index 000000000..456c52069
--- /dev/null
+++ b/misc/swig/tests/pubkey.py
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+
+import botan
+
+key = botan.X509_PublicKey("rsapub.pem")
+print key
+print key.key_id()
+print key.max_input_bits
+print key.algo
+print key.oid
diff --git a/misc/swig/tests/stream.py b/misc/swig/tests/stream.py
new file mode 100644
index 000000000..59d3ffa16
--- /dev/null
+++ b/misc/swig/tests/stream.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import botan, base64
+
+cipher = botan.StreamCipher("ARC4")
+
+print cipher.name
+
+key = botan.SymmetricKey(16)
+
+cipher.set_key(key)
+ciphertext = cipher.crypt("hi chappy")
+
+cipher.set_key(key)
+plaintext = cipher.crypt(ciphertext)
+
+print plaintext
diff --git a/misc/swig/x509.swg b/misc/swig/x509.swg
new file mode 100644
index 000000000..736d3a385
--- /dev/null
+++ b/misc/swig/x509.swg
@@ -0,0 +1,9 @@
+%module botan
+
+class X509_Certificate
+ {
+ public:
+
+
+ private:
+ };