Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

moved shared packet work into packet.py

git-svn-id: svn://forre.st/undns@1191 470744a7-cac9-478e-843e-5ec1b25c69e8
  • Loading branch information...
commit 9d4430bd011c8bcb66c85cb2f69f1cfb3b332158 1 parent 940d7aa
forrest authored
Showing with 105 additions and 64 deletions.
  1. +83 −0 packet.py
  2. +10 −39 server.py
  3. +12 −23 tool.py
  4. +0 −2  util.py
View
83 packet.py
@@ -0,0 +1,83 @@
+import json
+import hashlib
+
+from Crypto.PublicKey import RSA
+import twisted.names.common, twisted.names.client, twisted.names.dns, twisted.names.server, twisted.names.error, twisted.names.authority
+del twisted
+from twisted import names
+
+import util
+
+class BindStringAuthority(names.authority.BindAuthority):
+ def __init__(self, contents, origin):
+ names.common.ResolverBase.__init__(self)
+ self.origin = origin
+ lines = contents.splitlines(True)
+ lines = self.stripComments(lines)
+ lines = self.collapseContinuations(lines)
+ self.parseLines(lines)
+ self._cache = {}
+
+class Packet(object):
+ @classmethod
+ def from_json(cls, x, address=None, address_hash=None):
+ d = json.loads(x)
+ return cls(util.tuple_to_key(d['public_key']), d['zone_file'], d['signature'], address, address_hash)
+
+ def __init__(self, public_key, zone_file, signature, address=None, address_hash=None):
+ if public_key.has_private():
+ raise ValueError("key not public")
+ if not public_key.verify(hashlib.sha1(zone_file).digest(), signature):
+ raise ValueError("signature invalid")
+
+ self._public_key = public_key
+ self._zone_file = zone_file
+ self._signature = signature
+
+ self._address = util.key_to_address(self._public_key)
+ self._address_hash = hashlib.sha1(self._address).digest()
+ self._zone = BindStringAuthority(self._zone_file.encode('utf8'), self._address + '.')
+
+ if address is not None and self.get_address() != address:
+ raise ValueError("address not correct")
+ if address_hash is not None and self.get_address_hash() != address_hash:
+ raise ValueError("address hash hot correct")
+
+ def to_json(self):
+ return json.dumps(dict(public_key=util.key_to_tuple(self._public_key), zone_file=self._zone_file, signature=self._signature))
+
+ def get_address(self):
+ return self._address
+
+ def get_address_hash(self):
+ return self._address_hash
+
+ def get_zone_file(self):
+ return self._zone_file
+
+ def get_zone(self):
+ return self._zone
+
+class PrivateKey(object):
+ @classmethod
+ def generate(cls, rng):
+ return cls(RSA.generate(1024, rng))
+
+ @classmethod
+ def from_json(cls, x):
+ return cls(util.tuple_to_key(json.loads(x)))
+
+ def __init__(self, private_key):
+ if not private_key.has_private():
+ raise ValueError("key not private")
+
+ self._private_key = private_key
+
+ def to_json(self):
+ return json.dumps(util.key_to_tuple(self._private_key))
+
+ def get_address(self):
+ return util.key_to_address(self._private_key.publickey())
+
+ def encode(self, zone_file, rng):
+ return Packet(self._private_key.publickey(), zone_file, self._private_key.sign(hashlib.sha1(zone_file).digest(), rng))
View
49 server.py
@@ -15,6 +15,7 @@
from entangled.kademlia import node, datastore
import util
+import packet
parser = optparse.OptionParser()
parser.add_option("-a", "--authoritative", metavar="PORT",
@@ -36,17 +37,7 @@ def parse(x):
return ip, int(port)
knownNodes = map(parse, args)
-# some DNS
-
-class UnDNSAuthority(names.authority.BindAuthority):
- def __init__(self, contents, origin):
- names.common.ResolverBase.__init__(self)
- self.origin = origin
- lines = contents.splitlines(True)
- lines = self.stripComments(lines)
- lines = self.collapseContinuations(lines)
- self.parseLines(lines)
- self._cache = {}
+packets = [packet.Packet.from_json(open(filename).read()) for filename in options.packet_filenames]
# DHT
@@ -60,19 +51,8 @@ class UnDNSNode(node.Node):
def store(self, key, value, originalPublisherID=None, age=0, **kwargs):
print repr((self, key, value, originalPublisherID, age, kwargs))
- packet = json.loads(value)
- RSApubkey = util.tuple_to_key(packet['pubkey'])
- address = util.key_to_address(RSApubkey)
- data = packet['data']
- data_hash_signed = packet['data_hash_signed']
-
- if not (hashlib.sha1(address).digest() == key) or \
- not RSApubkey.verify(hashlib.sha1(data).digest(), data_hash_signed):
- print name_alone, "failed verify"
- raise ValueError("invalid packet")
+ packet.Packet.from_json(value, address_hash=key) # will throw an exception if not valid
- zone = UnDNSAuthority(data.encode('utf8'), address + '.')
- print "success"
node.Node.store(self, key, value, originalPublisherID, age, **kwargs)
n = UnDNSNode(udpPort=port, dataStore=dataStore)
@@ -81,11 +61,9 @@ def store(self, key, value, originalPublisherID=None, age=0, **kwargs):
print "ID:", n.id.encode('hex')
def store(*args):
- for packet_filename in options.packet_filenames:
- packet = json.loads(open(packet_filename).read())
- RSApubkey = util.tuple_to_key(packet['pubkey'])
- print "publishing", util.key_to_address(RSApubkey)
- n.iterativeStore(hashlib.sha1(util.key_to_address(RSApubkey)).digest(), json.dumps(packet))
+ for packet in packets:
+ print "publishing", packet.get_address()
+ n.iterativeStore(packet.get_address_hash(), packet.to_json())
reactor.callLater(13.23324141, store)
n._joinDeferred.addCallback(store)
@@ -117,20 +95,13 @@ def callback(result):
return defer.fail(failure.Failure(names.dns.AuthoritativeDomainError(name)))
assert isinstance(result, dict), result
- packet = json.loads(result[name_hash])
+ packet = packet.Packet.from_json(result[name_hash])
- RSApubkey = util.tuple_to_key(packet['pubkey'])
- address = util.key_to_address(RSApubkey)
- data = packet['data']
- data_hash_signed = packet['data_hash_signed']
-
- if not (address == name_alone) or \
- not RSApubkey.verify(hashlib.sha1(data).digest(), data_hash_signed):
- print name_alone, "failed verify"
+ if packet.get_address() != name_alone:
return defer.fail(failure.Failure(names.dns.AuthoritativeDomainError(name)))
- zone = UnDNSAuthority(data.encode('utf8'), address + '.')
- print name_alone, "succeeded!"
+ zone = UnDNSAuthority(packet.get_data().encode('utf8'), packet.get_address() + '.')
+
return zone._lookup(name, cls, type, timeout)
return self.dht.iterativeFindValue(name_hash).addCallback(callback)
View
35 tool.py
@@ -2,41 +2,30 @@
import hashlib
import json
-from Crypto.PublicKey import RSA
from Crypto import Random
import util
+import packet
rng = Random.new().read
if sys.argv[1] == "generate":
- RSAkey = RSA.generate(1024, rng)
- print json.dumps(util.key_to_tuple(RSAkey))
+ print packet.PrivateKey.generate(rng).to_json()
elif sys.argv[1] == "info":
- RSApubkey = util.tuple_to_key(json.loads(open(sys.argv[2]).read())).publickey()
- print util.key_to_address(RSApubkey)
+ private_key = packet.PrivateKey.from_json(open(sys.argv[2]).read())
+
+ print private_key.get_address()
elif sys.argv[1] == "encode":
- RSAkey = util.tuple_to_key(json.loads(open(sys.argv[2]).read()))
- if not RSAkey.has_private():
- print "not a private key"
- sys.exit(1)
- RSApubkey = RSAkey.publickey()
-
- data = open(sys.argv[3]).read()
+ private_key = packet.PrivateKey.from_json(open(sys.argv[2]).read())
+ zone_file = open(sys.argv[3]).read()
- packet = {'pubkey': util.key_to_tuple(RSApubkey), 'data': data, 'data_hash_signed': RSAkey.sign(hashlib.sha1(data).digest(), rng)}
- print json.dumps(packet)
+ print private_key.encode(zone_file, rng).to_json()
elif sys.argv[1] == "decode":
- packet = json.loads(open(sys.argv[2]).read())
- RSApubkey = util.tuple_to_key(packet['pubkey'])
- data = packet['data']
- data_hash_signed = packet['data_hash_signed']
-
- address = sys.argv[3]
+ pkt = packet.Packet.from_json(open(sys.argv[2]).read())
- print "pubkey matches:", util.key_to_address(RSApubkey) == address
- print "data valid:", RSApubkey.verify(hashlib.sha1(data).digest(), data_hash_signed)
- print "data:", repr(data)
+ print pkt.get_address()
+ print
+ print pkt.get_zone_file(),
View
2  util.py
@@ -1,7 +1,6 @@
import hashlib
from Crypto.PublicKey import RSA
-from Crypto import Random
def int_to_string(i, alphabet):
res = []
@@ -20,7 +19,6 @@ def string_to_int(s, alphabet):
place_value *= len(alphabet)
return acc
-
def key_to_name(k):
hash = int(hashlib.sha1(k.exportKey()).hexdigest(), 16)
return int_to_string(hash, alphabet)
Please sign in to comment.
Something went wrong with that request. Please try again.