modified: controller.py
modified: end-device.py
new file: test_get_async_threadsafe.py
diff --git a/controller.py b/controller.py
index 64d4119..d41bb1d 100644
--- a/controller.py
+++ b/controller.py
@@ -20,16 +20,16 @@
import time
import json
-from pyndn import Name
-from pyndn import Data
-from pyndn import Face
+from pyndn import Name, Face, Interest, Data
from pyndn.key_locator import KeyLocator, KeyLocatorType
+from hmac_helper import HmacHelper
from pyndn.security import KeyChain
from base_node import BaseNode
from pyndn.security import SecurityException
from pyndn.util import Blob
+
def dump(*list):
result = ""
for element in list:
@@ -43,14 +43,19 @@
self._symmetricKey = "symmetricKeyForBootstrapping"
self._prefix = "/home"
self._identity = "/home/controller/id999"
+ self._hmacHelper = HmacHelper(self._symmetricKey)
+
+ def setFace(self,face):
+ self.face = face
def onInterest(self, prefix, interest, transport, registeredPrefixId):
self._responseCount += 1
-
interestName = interest.getName()
+ dump("received interest : ",interestName.toUri())
#for bootstrap interest
- if(interestName.toUri().startswith(self._bootstrapPrefix) and interest.getKeyLocator().getKeyData().toRawStr() == self._symmetricKey):
+ #if(interestName.toUri().startswith(self._bootstrapPrefix) and interest.getKeyLocator().getKeyData().toRawStr() == self._symmetricKey):
+ if(interestName.toUri().startswith(self._bootstrapPrefix) and self._hmacHelper.verifyInterest(interest)):
dump("Reveived bootstrap interest")
self.onBootstrapInterest(prefix, interest, transport, registeredPrefixId)
@@ -59,69 +64,87 @@
self.onCertificateRequest(prefix, interest, transport, registeredPrefixId)
def onBootstrapInterest(self, prefix, interest, transport, registeredPrefixId):
+ if (self._hmacHelper.verifyInterest(interest)):
+ self.log.info("Bootstrap interest verified")
+ interestName = interest.getName()
+ deviceParameters = json.loads(interestName.get(3).getValue().toRawStr())
+ deviceNewIdentity = Name("/home")
+
+ #create new identity for device
+ deviceNewIdentity.append(deviceParameters["category"])
+ deviceNewIdentity.append(deviceParameters["id"])
+
+ #generate content
+ content = {}
+ content["deviceNewIdentity"] = deviceNewIdentity.toUri()
+ content["controllerIdentity"] = self._identity
+
+ #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)
+ self._hmacHelper.signData(data)
+
+ #encodedData = data.wireEncode()
+ #transport.send(encodedData.toBuffer())
+ self.sendData(data,transport,sign=False)
+ else:
+ self.log.info("Bootstrap interest not verified")
- interestName = interest.getName()
- deviceParameters = json.loads(interestName.get(3).getValue().toRawStr())
- deviceNewIdentity = Name("/home")
-
- #create new identity for device
- deviceNewIdentity.append(deviceParameters["category"])
- deviceNewIdentity.append(deviceParameters["id"])
-
- #generate content
- content = {}
- content["deviceNewIdentity"] = deviceNewIdentity.toUri()
- content["controllerIdentity"] = self._identity
-
- #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)
+ if (self._hmacHelper.verifyInterest(interest)):
+ self.log.info("certificate request interest verified")
+ 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._identity))
+ 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)
+ #self._hmacHelper.signData()
+
+ #encodedData = signedCertificate.wireEncode()
+ #transport.send(encodedData.toBuffer())
+ self.sendData(signedCertificate,transport,sign=False)
+
+ self.log.info("Certificate sent back : {}".format(signedCertificate.__str__))
+ print(signedCertificate)
+ else:
+ self.log.info("certificate request interest not verified")
- 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._identity))
- 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)
-
- encodedData = signedCertificate.wireEncode()
- transport.send(encodedData.toBuffer())
def onRegisterFailed(self, prefix):
@@ -154,28 +177,34 @@
dump("generated new KSK certificate ", newCert)
self._identityManager.addCertificateAsIdentityDefault(newCert)
-
+ #self.face.setCommandSigningInfo(self._keyChain, self.getDefaultCertificateName())
#self.face.registerPrefix(self._prefix, self.onInterest, self.onRegisterFailed)
+
+
if __name__ == '__main__':
controller = Controller("default.conf")
+ #controller.start()
controller.beforeLoopStart()
+
face = Face()
- face.setCommandSigningInfo(controller._keyChain, controller._keyChain.getDefaultCertificateName())
- dump("Register prefix : ", controller._prefix)
- face.registerPrefix(controller._prefix, controller.onInterest, controller.onRegisterFailed)
+ controller.setFace(face)
+ face.setCommandSigningInfo(controller._keyChain, controller.getDefaultCertificateName())
+ face.registerPrefix(controller._prefix, controller.onInterest, controller.onRegisterFailed)
+ dump("Register prefix : ",controller._prefix)
while True:
face.processEvents()
- # We need to sleep for a few milliseconds so we don't use 100% of the CPU.
- time.sleep(0.01)
+ time.sleep(0.05)
face.shutdown()
+
+
diff --git a/end-device.py b/end-device.py
index fb97a23..a77dc47 100644
--- a/end-device.py
+++ b/end-device.py
@@ -22,6 +22,7 @@
from pyndn import Name, Face, Interest, Data, ThreadsafeFace
from pyndn import KeyLocator, KeyLocatorType
from base_node import BaseNode
+from hmac_helper import HmacHelper
from pyndn.security.security_exception import SecurityException
from pyndn.util import Blob
try:
@@ -44,6 +45,7 @@
self._symKey = "symmetricKeyForBootstrapping"
self._category = "sensors"
self._id = "T9273659"
+ self._hmacHelper = HmacHelper(self._symKey)
def expressBootstrapInterest(self):
@@ -53,59 +55,73 @@
deviceParameters = {}
deviceParameters["category"] = self._category
- deviceParameters["id"] = self._deviceSerial
+ deviceParameters["id"] = self._id
bootstrapName.append(json.dumps(deviceParameters))
bootstrapInterest = Interest(bootstrapName)
bootstrapInterest.setInterestLifetimeMilliseconds(5000)
- bootstrapKeyLocator = KeyLocator()
- bootstrapKeyLocator.setType(KeyLocatorType.KEY_LOCATOR_DIGEST)
- bootstrapKeyLocator.setKeyData(self._symKey)
- bootstrapInterest.setKeyLocator(bootstrapKeyLocator)
+ #bootstrapKeyLocator = KeyLocator()
+ #bootstrapKeyLocator.setType(KeyLocatorType.KEY_LOCATOR_DIGEST)
+ #bootstrapKeyLocator.setKeyData(self._symKey)
+ #bootstrapInterest.setKeyLocator(bootstrapKeyLocator)
+ self._hmacHelper.signInterest(bootstrapInterest)
dump("Express bootstrap interest : ",bootstrapInterest.toUri())
self.face.expressInterest(bootstrapInterest, self.onBootstrapData, self.onTimeout)
+ def onInterest():
+ pass
+ def onRegisterFailed():
+ pass
def onBootstrapData(self, interest, data):
dump("Bootstrap 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("Install new identity as default\nGenerate new key-pair and self signed certificate")
- newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(deviceNewIdentity), isKsk=True)
- newCert = self._identityManager.selfSign(newKey)
- self._identityManager.addCertificateAsIdentityDefault(newCert)
+ if (self._hmacHelper.verifyData(data)):
+ self.log.info("Bootstrap data is verified")
+ content = json.loads(data.getContent().toRawStr(), encoding="latin-1")
+ deviceNewIdentity = Name(content["deviceNewIdentity"])
+ controllerIdentity = Name(content["controllerIdentity"])
+ controllerPublicKeyInfo = content["controllerPublicKey"]
+
+ self.face.registerPrefix(content["deviceNewIdentity"],self.onInterest,self.onRegisterFailed)
+ #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("Install new identity as default\nGenerate 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("Controller's KeyType: ",keyType)
+ dump("Controller's 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)
+ else:
+ self.log.info("Bootstrap data is not verified")
- #add controller's identity and public key
- keyType = controllerPublicKeyInfo["keyType"]
- keyName = Name(controllerPublicKeyInfo["keyName"])
- keyDer = Blob().fromRawStr(controllerPublicKeyInfo["publicKeyDer"])
- dump("Controller's KeyType: ",keyType)
- dump("Controller's 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):
+ #self.face.registerPrefix('/', self.onInterest, self.onRegisterFailed)
self.expressBootstrapInterest()
def onTimeout(self, interest):
@@ -135,10 +151,14 @@
certificateRequestName.append(json.dumps(keyInfo, encoding="latin-1"))
certificateRequestName.append("ID-CERT")
+
+ certificateRequest = Interest(certificateRequestName)
+ certificateRequest.setInterestLifetimeMilliseconds(5000)
+ self._hmacHelper.signInterest(certificateRequest)
dump("Sending certificate request : ",certificateRequestName)
- self.face.expressInterest(Interest(certificateRequestName), self.onCertificateData, self.onTimeout)
+ self.face.expressInterest(certificateRequest, self.onCertificateData, self.onTimeout)
#TODO use symmetric key to sign
def onCertificateData(self, interest, data):
@@ -147,7 +167,7 @@
if __name__ == '__main__':
- device = Device("default.conf")
+ device = Device("tmp.conf")
device.start()
diff --git a/test_get_async_threadsafe.py b/test_get_async_threadsafe.py
new file mode 100644
index 0000000..fd1602e
--- /dev/null
+++ b/test_get_async_threadsafe.py
@@ -0,0 +1,73 @@
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (C) 2014-2015 Regents of the University of California.
+# Author: Jeff Thompson <jefft0@remap.ucla.edu>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# A copy of the GNU Lesser General Public License is in the file COPYING.
+
+try:
+ # Use builtin asyncio on Python 3.4+, or Tulip on Python 3.3
+ import asyncio
+except ImportError:
+ # Use Trollius on Python <= 3.2
+ import trollius as asyncio
+from pyndn import Name
+from pyndn import ThreadsafeFace
+
+def dump(*list):
+ result = ""
+ for element in list:
+ result += (element if type(element) is str else repr(element)) + " "
+ print(result)
+
+class Counter(object):
+ def __init__(self):
+ self._callbackCount = 0
+
+ def onData(self, interest, data):
+ self._callbackCount += 1
+ dump("Got data packet with name", data.getName().toUri())
+ # Use join to convert each byte to chr.
+ dump(data.getContent().toRawStr())
+
+ def onTimeout(self, interest):
+ self._callbackCount += 1
+ dump("Time out for interest", interest.getName().toUri())
+
+ def onInterest(self,prefix,interest,face,interestFilterId,filter):
+ self._callbackCount+=1
+ dump("Receive interest", interest.toUri())
+
+ def onRegisterFailed(self,prefix):
+ dump("Register failed for prefix")
+
+def main():
+ loop = asyncio.get_event_loop()
+ face = ThreadsafeFace(loop, "aleph.ndn.ucla.edu")
+
+ counter = Counter()
+ face.stopWhen(lambda: counter._callbackCount >= 10)
+
+ face.registerPrefix("/home",counter.onInterest,counter.onRegisterFailed)
+ #name1 = Name("/")
+ #dump("Express name ", name1.toUri())
+ # This call to exressIinterest is thread safe because face is a ThreadsafeFace.
+ #face.expressInterest(name1, counter.onData, counter.onTimeout)
+
+ # Run until stopWhen stops the loop.
+ loop.run_forever()
+ face.shutdown()
+
+main()