modified: base_node.py
modified: controller.py
new file: default.conf
modified: end-device.py
diff --git a/base_node.py b/base_node.py
index 76fb854..1325b4f 100644
--- a/base_node.py
+++ b/base_node.py
@@ -23,6 +23,7 @@
import random
from pyndn import Name, Face, Interest, Data, ThreadsafeFace
+from pyndn.security.policy import ConfigPolicyManager
from pyndn.security import KeyChain
from pyndn.security.identity import IdentityManager, BasicIdentityStorage
from pyndn.security.security_exception import SecurityException
@@ -42,19 +43,19 @@
This class contains methods/attributes common to both node and controller.
"""
- def __init__(self):
+ def __init__(self,configFileName):
"""
Initialize the network and security classes for the node
"""
super(BaseNode, self).__init__()
-
+
self._identityStorage = BasicIdentityStorage()
self._identityManager = IdentityManager(self._identityStorage)
-
+ self._policyManager = ConfigPolicyManager(configFileName)
# hopefully there is some private/public key pair available
- self._keyChain = KeyChain(self._identityManager)
+ self._keyChain = KeyChain(self._identityManager,self._policyManager)
self._registrationFailures = 0
self._prepareLogging()
diff --git a/controller.py b/controller.py
index 484751b..74177c3 100644
--- a/controller.py
+++ b/controller.py
@@ -33,29 +33,71 @@
print(result)
class Controller(BaseNode):
- def __init__(self):
- super(Controller, self).__init__()
+ def __init__(self,configFileName):
+ super(Controller, self).__init__(configFileName=configFileName)
self._responseCount = 0
+ self._symmetricKey = "symmetricKeyForBootStrapping"
+ self._prefix = "/home/controller"
def onInterest(self, prefix, interest, transport, registeredPrefixId):
self._responseCount += 1
-
- dump("interest ", interest.getName())
- dump("Uri ", interest.getName().toUri())
- # Make and sign a Data packet.
- #data = Data(interest.getName())
- content = "Echo " + interest.getName().toUri()
- #data.setContent(content)
- #self._keyChain.sign(data, self._certificateName)
- #encodedData = data.wireEncode()
+
+ interestName = interest.getName()
+ dump("Received interest ", interestName)
+
+ componentsString = []
+ for eachComponent in interestName._components:
+ componentsString.append(eachComponent.toEscapedString())
+ if (len(componentsString) >= 6 and componentsString[0] == "home" and componentsString[1] == "controller" and componentsString[2] == "bootstrap"):
+
+ newDeviceCategory = componentsString[3];
+ newDeviceId = componentsString[4];
+ signature = componentsString[5];
+
+ if (signature == self._symmetricKey):
+ #newDeviceIdentityName = Name("/home"+newDeviceCategory+newDeviceId)
+ content = "/home/"+newDeviceCategory+"/"+newDeviceId+"/"
+ #content = content + "/"
+ identityName = self._identityManager.getDefaultIdentity()
+ keyName = self._identityManager.getDefaultKeyNameForIdentity(identityName)
+ key = self._identityManager.getPublicKey(keyName)
+ content = content+key.getKeyDer().toHex()
+
+ dump("Send data : ",content)
+ data = Data(interest.getName())
+ data.setContent(content)
+ #self._keyChain.sign(data, self._certificateName)
+ encodedData = data.wireEncode()
#dump("Sent content", content)
- #transport.send(encodedData.toBuffer())
+ transport.send(encodedData.toBuffer())
def onRegisterFailed(self, prefix):
self._responseCount += 1
dump("Register failed for prefix", prefix.toUri())
+ def beforeLoopStart(self):
+ identityName = Name(self._prefix)
+ dump(identityName)
+ defaultIdentityExist = True
+ try:
+ defaultIdentityName = self._identityManager.getDefaultIdentity()
+ dump(self._identityManager.getDefaultIdentity())
+ dump(self._identityManager.getDefaultKeyNameForIdentity(defaultIdentityName))
+ except:
+ defaultIdentityExist = False
+
+
+ #dump(self._identityManager.getDefaultKeyNameForIdentity(self._prefix))
+ if not defaultIdentityExist or self._identityManager.getDefaultIdentity() != identityName:
+ #make one
+ self._identityManager.setDefaultIdentity(identityName)
+ self.log.warn("Generating controller key pair(this would take a while)......")
+ newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(self._prefix), isKsk=True)
+ newCert = self._identityManager.selfSign(newKey)
+ self._identityManager.addCertificateAsDefault(newCert)
+
+
if __name__ == '__main__':
# The default Face will connect using a Unix socket, or to "localhost".
@@ -63,15 +105,24 @@
# Use the system default key chain and certificate name to sign commands.
- controller = Controller()
+ controller = Controller("default.conf")
+ controller.beforeLoopStart()
+
face.setCommandSigningInfo(controller.getKeyChain(), controller.getDefaultCertificateName())
# Also use the default certificate name to sign data packets.
prefix = Name("/home/")
- dump("Register prefix", prefix.toUri())
+ dump("Register prefix", prefix)
+
face.registerPrefix(prefix, controller.onInterest, controller.onRegisterFailed)
+ identityName = controller._identityManager.getDefaultIdentity()
+ keyName = controller._identityManager.getDefaultKeyNameForIdentity(identityName)
+
+ key = controller._identityManager.getPublicKey(keyName)
+ dump("key : ",key.getKeyDer().toHex())
+
while controller._responseCount < 100:
face.processEvents()
# We need to sleep for a few milliseconds so we don't use 100% of the CPU.
diff --git a/default.conf b/default.conf
new file mode 100644
index 0000000..f131e97
--- /dev/null
+++ b/default.conf
@@ -0,0 +1,56 @@
+ validator
+ {
+ rule
+ {
+ id "Certificate Trust"
+ for "data"
+ filter
+ {
+ type "name"
+ regex "[^<KEY>]+<KEY><>*<ID-CERT>"
+ }
+ checker
+ {
+ type "customized"
+ sig-type "rsa-sha256"
+ key-locator
+ {
+ type "name"
+ name "/home"
+ relation "is-strict-prefix-of"
+ }
+ }
+ }
+ rule
+ {
+ id "All Other Data"
+ for "data"
+ checker
+ {
+ type "hierarchical"
+ sig-type "rsa-sha256"
+ }
+ }
+ rule
+ {
+ id "Command Interests"
+ for "interest"
+ filter
+ {
+ type "name"
+ name "/home/default"
+ relation "is-strict-prefix-of"
+ }
+ checker
+ {
+ type "customized"
+ sig-type "rsa-sha256"
+ key-locator
+ {
+ type "name"
+ name "/home"
+ relation "is-strict-prefix-of"
+ }
+ }
+ }
+ }
diff --git a/end-device.py b/end-device.py
index 26c1612..67fc150 100644
--- a/end-device.py
+++ b/end-device.py
@@ -29,10 +29,10 @@
print(result)
class Device(BaseNode):
- def __init__(self):
- super(Device, self).__init__()
+ def __init__(self,configFileName):
+ super(Device, self).__init__(configFileName=configFileName)
- self.deviceSerial = self.getSerial()
+ #self.deviceSerial = self.getSerial()
self._callbackCount = 0
def onData(self, interest, data):
@@ -41,6 +41,9 @@
# Use join to convert each byte to chr.
dump(data.getContent().toRawStr())
+ def beforeLoopStart(self):
+ pass
+
def onTimeout(self, interest):
self._callbackCount += 1
dump("Time out for interest", interest.getName().toUri())
@@ -48,11 +51,13 @@
if __name__ == '__main__':
face = Face("")
- device = Device()
-
- name1 = Name("/home/controller/bootstrap/publickey/category1/id")
- dump("Express name ", name1.toUri())
- face.expressInterest(name1, device.onData, device.onTimeout)
+ device = Device("default.conf")
+
+ symKey = "symmetricKeyForBootStrapping"
+ bootStrapName = Name("/home/controller/bootstrap/light/id1/"+symKey)
+ dump("Express name ",bootStrapName.toUri())
+
+ face.expressInterest(bootStrapName, device.onData, device.onTimeout)
while device._callbackCount < 10: