| # -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| # |
| # Copyright (C) 2014 Regents of the University of California. |
| # Author: Teng Liang <philoliang2011@gmail.com> |
| # |
| # 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 General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| # A copy of the GNU General Public License is in the file COPYING. |
| |
| |
| import time |
| import json |
| 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: |
| result += (element if type(element) is str else repr(element)) + " " |
| print(result) |
| |
| class Controller(BaseNode): |
| def __init__(self,configFileName): |
| super(Controller, self).__init__(configFileName=configFileName) |
| self._responseCount = 0 |
| 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 self._hmacHelper.verifyInterest(interest)): |
| 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): |
| 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") |
| |
| |
| |
| |
| def onCertificateRequest(self, prefix, interest, transport, registeredPrefixId): |
| 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") |
| |
| |
| |
| def onRegisterFailed(self, prefix): |
| self._responseCount += 1 |
| dump("Register failed for prefix", prefix.toUri()) |
| |
| def beforeLoopStart(self): |
| identityName = Name(self._identity) |
| |
| defaultIdentityExists = True |
| try: |
| defaultIdentityName = self._identityManager.getDefaultIdentity() |
| except: |
| defaultIdentityExists = False |
| |
| if not defaultIdentityExists or self._identityManager.getDefaultIdentity() != identityName: |
| #make one |
| dump("Create identity and certificate for identity name: ",identityName) |
| self._keyChain.createIdentityAndCertificate(identityName) |
| self._identityManager.setDefaultIdentity(identityName) |
| |
| 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() |
| #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() |
| # time.sleep(0.05) |
| |
| # face.shutdown() |
| |
| |
| |
| |
| |
| |
| |