modified: base_node.py
modified: controller.py
modified: end-device.py
diff --git a/base_node.py b/base_node.py
index 728a107..387fce5 100644
--- a/base_node.py
+++ b/base_node.py
@@ -65,7 +65,7 @@
# waiting devices register this prefix and respond to discovery
# or configuration interest
- self._bootstrapPrefix = Name('/home/controller/bootstrap')
+ self._bootstrapPrefix = '/home/controller/bootstrap'
def getSerial(self):
"""
diff --git a/controller.py b/controller.py
index d42eca3..8db4242 100644
--- a/controller.py
+++ b/controller.py
@@ -23,9 +23,12 @@
from pyndn import Name
from pyndn import Data
from pyndn import Face
+from pyndn.key_locator import KeyLocator, KeyLocatorType
+
from pyndn.security import KeyChain
from base_node import BaseNode
-
+from pyndn.security import SecurityException
+from pyndn.util import Blob
def dump(*list):
result = ""
@@ -37,45 +40,92 @@
def __init__(self,configFileName):
super(Controller, self).__init__(configFileName=configFileName)
self._responseCount = 0
- self._symmetricKey = "symmetricKeyForBootStrapping"
- self._prefix = "/home/controller"
- self._bootStrapPrefix = "/home/controller/bootstrap"
+ self._symmetricKey = "symmetricKeyForBootstrapping"
+ self._prefix = "/home/controller/id999"
def onInterest(self, prefix, interest, transport, registeredPrefixId):
self._responseCount += 1
+
+ interestName = interest.getName()
+
+ #for bootstrap interest
+ if(interestName.toUri().startswith(self._bootstrapPrefix) and interest.getKeyLocator().getKeyData().toRawStr() == self._symmetricKey):
+ dump("Reveived bootstrap interest")
+ self.onBootstrapInterest(prefix, interest, transport, registeredPrefixId)
+
+ elif ("KEY" in interestName.toUri() and "ID-CERT" in interestName.toUri()):
+ dump("Reveived certificate request interest")
+ self.onCertificateRequest(prefix, interest, transport, registeredPrefixId)
+
+ def onBootstrapInterest(self, prefix, interest, transport, registeredPrefixId):
interestName = interest.getName()
- dump("Received interest ", interestName.toUri())
-
- if(interestName.toUri().startswith(self._bootStrapPrefix) and interest.getKeyLocator().getKeyData().toRawStr() == self._symmetricKey):
-
- deviceParameters = json.loads(interestName.get(3).getValue().toRawStr())
- deviceNewIdentity = Name("/home")
+ deviceParameters = json.loads(interestName.get(3).getValue().toRawStr())
+ deviceNewIdentity = Name("/home")
- #create new identity for device
- deviceNewIdentity.append(deviceParameters["category"])
- deviceNewIdentity.append(deviceParameters["id"])
- dump("New identity for device: ",deviceNewIdentity)
+ #create new identity for device
+ deviceNewIdentity.append(deviceParameters["category"])
+ deviceNewIdentity.append(deviceParameters["id"])
- #create key-pair and certificate for new identity
- self.
+ #generate content
+ content = {}
+ content["deviceNewIdentity"] = deviceNewIdentity.toUri()
+ content["controllerIdentity"] = self._prefix
- data = Data(interestName)
- content = {}
- content["deviceNewIdentity"] = deviceNewIdentity.toUri()
- content[]
- content["controllerPublicKey"] =
+ #get public key of controller
+ pKeyName = self._identityManager.getDefaultKeyNameForIdentity(self._identityManager.getDefaultIdentity())
+ pKey = self._identityManager.getPublicKey(pKeyName)
+
+ pKeyInfo = content["controllerPublicKey"] = {}
+ pKeyInfo["keyName"] = pKeyName.toUri()
+ pKeyInfo["keyType"] = pKey.getKeyType()
+ pKeyInfo["publicKeyDer"] = pKey.getKeyDer().toRawStr()
+ dump("Sent content : ",content)
+
+ #TODO generate signature for data
+
+ #generate data package
+ data = Data(interestName)
+ data.setContent(json.dumps(content,encoding="latin-1"))
+ #data.setSignature(signature)
+ encodedData = data.wireEncode()
+ transport.send(encodedData.toBuffer())
+
+
+ def onCertificateRequest(self, prefix, interest, transport, registeredPrefixId):
+ interestName = interest.getName()
+ dump("interest name : ",interestName)
+
+ keyName = interestName[:3]
+ keyId = interestName.get(4)
+ keyName.append(keyId)
+ keyInfo = json.loads(interestName.get(5).getValue().toRawStr(),encoding="latin-1")
+ keyType = keyInfo['keyType']
+ keyDer = Blob().fromRawStr(keyInfo['keyDer'])
+
+ dump("keyname: ",keyName)
+ dump("keyType ",keyInfo['keyType'])
+ dump("keyDer string",keyInfo['keyDer'])
+ dump("keyDer",keyDer)
+
+ #device and controller are on one mechine, so it needs to be done.
+ self._identityManager.setDefaultIdentity(Name(self._prefix))
+ try:
+ self._identityStorage.addKey(keyName, keyType, keyDer)
+ except SecurityException:
+ dump("The public key for device already exists ")
+
+ signedCertificate = self._identityManager._generateCertificateForKey(keyName)
+ self._keyChain.sign(signedCertificate, self._identityManager.getDefaultCertificateName())
+ self._identityManager.addCertificate(signedCertificate)
+
- #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())
+ encodedData = signedCertificate.wireEncode()
+ transport.send(encodedData.toBuffer())
-
+
+
def onRegisterFailed(self, prefix):
self._responseCount += 1
dump("Register failed for prefix", prefix.toUri())
@@ -99,11 +149,11 @@
self._identityManager.setDefaultIdentity(identityName)
try:
- getDefaultKeyNameForIdentity(identityName)
- except:
+ self._identityManager.getDefaultKeyNameForIdentity(identityName)
+ except SecurityException:
newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(self._prefix), isKsk=True)
newCert = self._identityManager.selfSign(newKey)
- dump("new certificate", newCert)
+ dump("generated new KSK certificate ", newCert)
self._identityManager.addCertificateAsIdentityDefault(newCert)
@@ -126,11 +176,6 @@
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()
diff --git a/end-device.py b/end-device.py
index 4754117..0f085e7 100644
--- a/end-device.py
+++ b/end-device.py
@@ -25,6 +25,7 @@
from pyndn import KeyLocator, KeyLocatorType
from base_node import BaseNode
from pyndn.security.security_exception import SecurityException
+from pyndn.util import Blob
def dump(*list):
@@ -34,18 +35,85 @@
print(result)
class Device(BaseNode):
- def __init__(self,configFileName):
+ def __init__(self,configFileName,face):
super(Device, self).__init__(configFileName=configFileName)
#self.deviceSerial = self.getSerial()
self._callbackCount = 0
+ self._face = face
def onData(self, interest, data):
self._callbackCount += 1
- dump("Got data packet with name", data.getName().toUri())
+ dump("Got data packet with name : ", data.getName().toUri())
# Use join to convert each byte to chr.
dump(data.getContent().toRawStr())
+ #haven't checked symmetric key digest yet
+ if (data.getName().toUri().startswith(self._bootstrapPrefix)):
+ self.onBootstrapData(interest, data)
+
+ def expressBootstrapInterest(self):
+ symKey = "symmetricKeyForBootstrapping"
+
+ #generate bootstrap name /home/controller/bootstrap/<device-parameters>
+ bootstrapName = Name(device._bootstrapPrefix)
+
+ deviceParameters = {}
+ deviceParameters["category"] = "sensors"
+ deviceParameters["id"] = "T123456789"
+ bootstrapName.append(json.dumps(deviceParameters))
+
+ bootstrapInterest = Interest(bootstrapName)
+
+ bootstrapInterest.setInterestLifetimeMilliseconds(5000)
+
+ bootstrapKeyLocator = KeyLocator()
+ bootstrapKeyLocator.setType(KeyLocatorType.KEY_LOCATOR_DIGEST)
+ bootstrapKeyLocator.setKeyData(symKey)
+ bootstrapInterest.setKeyLocator(bootstrapKeyLocator)
+
+ dump("Express interest :",bootstrapInterest.toUri())
+ self._face.expressInterest(bootstrapInterest, self.onBootstrapData, self.onTimeout)
+
+ def onBootstrapData(self, interest, data):
+ dump("Data received.")
+ content = json.loads(data.getContent().toRawStr(), encoding="latin-1")
+ deviceNewIdentity = Name(content["deviceNewIdentity"])
+ controllerIdentity = Name(content["controllerIdentity"])
+ controllerPublicKeyInfo = content["controllerPublicKey"]
+
+ #set new identity as default and generate default key-pair with KSK Certificate
+ self._identityStorage.addIdentity(deviceNewIdentity)
+ self._identityManager.setDefaultIdentity(deviceNewIdentity)
+ try:
+ self._identityManager.getDefaultKeyNameForIdentity(deviceNewIdentity)
+ except SecurityException:
+ #generate new key-pair and certificate for new identity
+ dump("Installed new identity as default\nGenerating new key-pair and self signed certificate...")
+ newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(deviceNewIdentity), isKsk=True)
+ newCert = self._identityManager.selfSign(newKey)
+ self._identityManager.addCertificateAsIdentityDefault(newCert)
+
+ #add controller's identity and public key
+ keyType = controllerPublicKeyInfo["keyType"]
+ keyName = Name(controllerPublicKeyInfo["keyName"])
+ keyDer = Blob().fromRawStr(controllerPublicKeyInfo["publicKeyDer"])
+ dump("KeyType: ",keyType)
+ dump("keyName: ",keyName)
+ dump("Controller public key der : ",keyDer)
+
+ self._identityStorage.addIdentity(controllerIdentity)
+ try:
+ self._identityStorage.addKey(keyName, keyType, keyDer)
+ dump("Controller's identity, key and certificate installled.")
+ except SecurityException:
+ dump("Controller's identity, key, certificate already exists.")
+
+ #express an certificate request interest
+ defaultKeyName = self._identityManager.getDefaultKeyNameForIdentity(self._keyChain.getDefaultIdentity() )
+ self.requestCertificate(defaultKeyName)
+
+
def beforeLoopStart(self):
pass
@@ -53,41 +121,48 @@
self._callbackCount += 1
dump("Time out for interest", interest.getName().toUri())
- def _sendCertificateRequest(self, keyIdentity):
+ def requestCertificate(self, keyIdentity):
"""
We compose a command interest with our public key info so the controller
can sign us a certificate that can be used with other nodes in the network.
- """
+ Name format : /home/<device-category>/KEY/<device-id>/<key-id>/<publickey>/ID-CERT/<version-number>
+ """
+ certificateRequestName = self._keyChain.getDefaultIdentity()
+ deviceIdComponent = certificateRequestName.get(-1)
+ keyIdComponent = keyIdentity.get(-1)
- #TODO: GENERATE A NEW PUBLIC/PRIVATE PAIR INSTEAD OF COPYING
+ certificateRequestName = certificateRequestName
+ certificateRequestName.append("KEY")
+ #certificateRequestName.append(deviceIdComponent)
+ certificateRequestName.append(keyIdComponent)
+
+ key = self._identityManager.getPublicKey(keyIdentity)
+ keyInfo = {}
+ keyInfo["keyType"] = key.getKeyType()
+ keyInfo["keyDer"] = key.getKeyDer().toRawStr()
+
+ certificateRequestName.append(json.dumps(keyInfo, encoding="latin-1"))
+
+ certificateRequestName.append("ID-CERT")
+
+ dump("Sending certificate request : ",certificateRequestName)
+
+ self._face.expressInterest(Interest(certificateRequestName), self.onCertificateData, self.onTimeout)
+ #TODO use symmetric key to sign
+
+ def onCertificateData(self, interest, data):
+ dump("OnCertificateData : ",data)
+
if __name__ == '__main__':
face = Face("")
- device = Device("default.conf")
+ device = Device("default.conf",face)
- symKey = "symmetricKeyForBootStrapping"
- bootStrapName = Name("/home/controller/bootstrap")
+ device.expressBootstrapInterest()
+ #device.requestCertificate(device._identityManager.getDefaultKeyNameForIdentity(device._keyChain.getDefaultIdentity() ))
- deviceParameters = {}
- deviceParameters["category"] = "sensors"
- deviceParameters["id"] = "T123456789"
- bootStrapName.append(json.dumps(deviceParameters))
-
- bootStrapInterest = Interest(bootStrapName)
-
- bootStrapInterest.setInterestLifetimeMilliseconds(5000)
-
- bootStrapKeyLocator = KeyLocator()
- bootStrapKeyLocator.setType(KeyLocatorType.KEY_LOCATOR_DIGEST)
- bootStrapKeyLocator.setKeyData(symKey)
- bootStrapInterest.setKeyLocator(bootStrapKeyLocator)
-
- dump("Express interest ",bootStrapInterest.toUri())
- face.expressInterest(bootStrapInterest, device.onData, device.onTimeout)
-
-
- while device._callbackCount < 100:
+ while device._callbackCount < 1000:
face.processEvents()
# We need to sleep for a few milliseconds so we don't use 100% of the CPU.
time.sleep(0.01)