diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 0d20b64..dde3895 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +.DS_Store *.pyc diff --git a/FPE/Destination.py b/FPE/Destination.py old mode 100644 new mode 100755 index 4e054f1..f3092be --- a/FPE/Destination.py +++ b/FPE/Destination.py @@ -1,4 +1,6 @@ import base64 +import math +from Identity import Identity from Transport import Transport from cryptography.fernet import Fernet from cryptography.hazmat.primitives import hashes @@ -8,6 +10,10 @@ from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import padding class Destination: + KEYSIZE = Identity.KEYSIZE; + PADDINGSIZE= Identity.PADDINGSIZE; + + # Constants SINGLE = 0x01; GROUP = 0x02; PLAIN = 0x03; @@ -86,7 +92,7 @@ class Destination: if self.type == Destination.SINGLE: self.prv = rsa.generate_private_key( public_exponent=65337, - key_size=2048, + key_size=Destination.KEYSIZE, backend=default_backend() ) self.prv_bytes = self.prv.private_bytes( @@ -99,6 +105,9 @@ class Destination: encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ) + print("Keys created, private length is "+str(len(self.prv_bytes))) + print("Keys created, public length is "+str(len(self.pub_bytes))) + #+", public length is "+str(len(self.pub_bytes)))) if self.type == Destination.GROUP: self.prv_bytes = Fernet.generate_key() @@ -142,14 +151,28 @@ class Destination: return plaintext if self.type == Destination.SINGLE and self.prv != None: - ciphertext = self.pub.encrypt( - plaintext, - padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA1()), - algorithm=hashes.SHA1(), - label=None + chunksize = (Destination.KEYSIZE-Destination.PADDINGSIZE)/8 + chunks = int(math.ceil(len(plaintext)/(float(chunksize)))) + print("Plaintext size is "+str(len(plaintext))+", with "+str(chunks)+" chunks") + + ciphertext = ""; + for chunk in range(chunks): + start = chunk*chunksize + end = (chunk+1)*chunksize + if (chunk+1)*chunksize > len(plaintext): + end = len(plaintext) + + print("Processing chunk "+str(chunk+1)+" of "+str(chunks)+". Starting at "+str(start)+" and stopping at "+str(end)+". The length is "+str(len(plaintext[start:end]))) + + ciphertext += self.pub.encrypt( + plaintext[start:end], + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA1()), + algorithm=hashes.SHA1(), + label=None + ) ) - ) + print("Plaintext encrypted, ciphertext length is "+str(len(ciphertext))+" bytes.") return ciphertext if self.type == Destination.GROUP and self.prv != None: @@ -164,14 +187,27 @@ class Destination: return ciphertext if self.type == Destination.SINGLE and self.prv != None: - plaintext = self.prv.decrypt( - ciphertext, - padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA1()), - algorithm=hashes.SHA1(), - label=None + print("Ciphertext length is "+str(len(ciphertext))+". ") + chunksize = (Destination.KEYSIZE)/8 + chunks = int(math.ceil(len(ciphertext)/(float(chunksize)))) + + plaintext = ""; + for chunk in range(chunks): + start = chunk*chunksize + end = (chunk+1)*chunksize + if (chunk+1)*chunksize > len(ciphertext): + end = len(ciphertext) + + print("Processing chunk "+str(chunk+1)+" of "+str(chunks)+". Starting at "+str(start)+" and stopping at "+str(end)+". The length is "+str(len(ciphertext[start:end]))) + + plaintext += self.prv.decrypt( + ciphertext[start:end], + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA1()), + algorithm=hashes.SHA1(), + label=None + ) ) - ) return plaintext; if self.type == Destination.GROUP: diff --git a/FPE/FlexPE.py b/FPE/FlexPE.py old mode 100644 new mode 100755 index e3b34ec..89bc44d --- a/FPE/FlexPE.py +++ b/FPE/FlexPE.py @@ -8,7 +8,7 @@ import os.path import os class FlexPE: - MTU = 700 + MTU = 600 router = None config = None destinations = [] @@ -25,8 +25,6 @@ class FlexPE: self.createDefaultConfig() self.applyConfig() - print FlexPE.interfaces - FlexPE.router = self @staticmethod diff --git a/FPE/Identity.py b/FPE/Identity.py new file mode 100644 index 0000000..748864f --- /dev/null +++ b/FPE/Identity.py @@ -0,0 +1,7 @@ + +class Identity: + # Configure key size + KEYSIZE = 1536; + + # Padding size, not configurable + PADDINGSIZE= 336; \ No newline at end of file diff --git a/FPE/Interfaces/Interface.py b/FPE/Interfaces/Interface.py old mode 100644 new mode 100755 diff --git a/FPE/Interfaces/SerialInterface.py b/FPE/Interfaces/SerialInterface.py old mode 100644 new mode 100755 diff --git a/FPE/Interfaces/UdpInterface.py b/FPE/Interfaces/UdpInterface.py old mode 100644 new mode 100755 diff --git a/FPE/Interfaces/__init__.py b/FPE/Interfaces/__init__.py old mode 100644 new mode 100755 diff --git a/FPE/Packet.py b/FPE/Packet.py old mode 100644 new mode 100755 index 2909691..d897673 --- a/FPE/Packet.py +++ b/FPE/Packet.py @@ -21,8 +21,9 @@ class Packet: self.raw = self.header + self.ciphertext if len(self.raw) > self.MTU: - raise IOError("Packet size exceeds MTU of "+Packet.MTU+" bytes") + raise IOError("Packet size of "+str(len(self.raw))+" exceeds MTU of "+str(self.MTU)+" bytes") + print("Size: "+str(len(self.raw))) Transport.outbound(self.raw) self.sent = True else: diff --git a/FPE/Transport.py b/FPE/Transport.py old mode 100644 new mode 100755 diff --git a/FPE/__init__.py b/FPE/__init__.py old mode 100644 new mode 100755 index e3164b0..9ab3853 --- a/FPE/__init__.py +++ b/FPE/__init__.py @@ -1,5 +1,11 @@ import os import glob +from .Destination import Destination +from .FlexPE import FlexPE +from .Identity import Identity +from .Packet import Packet +from .Transport import Transport + modules = glob.glob(os.path.dirname(__file__)+"/*.py") -__all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')] +__all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')] \ No newline at end of file diff --git a/FPE/vendor/__init__.py b/FPE/vendor/__init__.py old mode 100644 new mode 100755 diff --git a/FPE/vendor/configobj.py b/FPE/vendor/configobj.py old mode 100644 new mode 100755 diff --git a/README b/README old mode 100644 new mode 100755 diff --git a/TODO b/TODO new file mode 100755 index 0000000..abb6089 --- /dev/null +++ b/TODO @@ -0,0 +1,12 @@ +To do: + + - Transport + - SerialKISS interface + - MicroModemGP interface (Packet queue) + - Forwarding to other interfaces + + - Shared instance + - JSON api + + + - Resource storage \ No newline at end of file diff --git a/t.py b/t.py new file mode 100755 index 0000000..2d81d29 --- /dev/null +++ b/t.py @@ -0,0 +1,47 @@ +# from FPE.Destination import * +# from FPE.Packet import * +# from FPE import FlexPE +from FPE import * +# from FPE import Destination +import time + +def testCallback(message, receiver): + print("Got message from "+str(receiver)+": ") + print(message) + print("----------") + + +fpe = FlexPE() +d1=Destination(Destination.IN, Destination.SINGLE, "messenger", "markqvist") +d1.createKey() +d1.setCallback(testCallback) + +d2=Destination(Destination.IN, Destination.PLAIN, "plainchat", "markqvist") +d2.setCallback(testCallback) + +print d1.name +print d1.hexhash +print d1.pub +print "---" +print + +# p1=Packet(d1, "testmessage") +# p1.send() +msg="" +for x in range(300): + msg += "a" +signed = d1.sign(msg) +sl = len(signed) +pl = len(d1.pub_bytes) +print("Signature length is "+str(sl)) +print("Minimum announce is "+str(pl+sl+8)) + + +p2=Packet(d1, msg) +p2.send() + +# p2=Packet(d2, "something else") +# p2.send() + +raw_input() +