blob: 8db424285bf959d7c2c25d565393800a78c7ccbf [file] [log] [blame]
philoLbd28e132015-04-16 23:54:21 -07001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
3# Copyright (C) 2014-2015 Regents of the University of California.
4# Author: Jeff Thompson <jefft0@remap.ucla.edu>
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU Lesser General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18# A copy of the GNU Lesser General Public License is in the file COPYING.
19
20
21import time
Teng Liang52f43c32015-05-20 17:06:20 -070022import json
philoLbd28e132015-04-16 23:54:21 -070023from pyndn import Name
24from pyndn import Data
25from pyndn import Face
Teng Liang50429402015-05-22 16:01:17 -070026from pyndn.key_locator import KeyLocator, KeyLocatorType
27
philoLbd28e132015-04-16 23:54:21 -070028from pyndn.security import KeyChain
philo5d4724e2014-11-10 19:34:05 +000029from base_node import BaseNode
Teng Liang50429402015-05-22 16:01:17 -070030from pyndn.security import SecurityException
31from pyndn.util import Blob
philoLbd28e132015-04-16 23:54:21 -070032
33def dump(*list):
34 result = ""
35 for element in list:
36 result += (element if type(element) is str else repr(element)) + " "
37 print(result)
38
philo5d4724e2014-11-10 19:34:05 +000039class Controller(BaseNode):
Teng Lianga0b49372015-05-15 05:30:27 -070040 def __init__(self,configFileName):
41 super(Controller, self).__init__(configFileName=configFileName)
philoLbd28e132015-04-16 23:54:21 -070042 self._responseCount = 0
Teng Liang50429402015-05-22 16:01:17 -070043 self._symmetricKey = "symmetricKeyForBootstrapping"
44 self._prefix = "/home/controller/id999"
philoLbd28e132015-04-16 23:54:21 -070045
46 def onInterest(self, prefix, interest, transport, registeredPrefixId):
47 self._responseCount += 1
Teng Liang50429402015-05-22 16:01:17 -070048
49 interestName = interest.getName()
50
51 #for bootstrap interest
52 if(interestName.toUri().startswith(self._bootstrapPrefix) and interest.getKeyLocator().getKeyData().toRawStr() == self._symmetricKey):
53 dump("Reveived bootstrap interest")
54 self.onBootstrapInterest(prefix, interest, transport, registeredPrefixId)
55
56 elif ("KEY" in interestName.toUri() and "ID-CERT" in interestName.toUri()):
57 dump("Reveived certificate request interest")
58 self.onCertificateRequest(prefix, interest, transport, registeredPrefixId)
59
60 def onBootstrapInterest(self, prefix, interest, transport, registeredPrefixId):
Teng Lianga0b49372015-05-15 05:30:27 -070061
62 interestName = interest.getName()
Teng Liang50429402015-05-22 16:01:17 -070063 deviceParameters = json.loads(interestName.get(3).getValue().toRawStr())
64 deviceNewIdentity = Name("/home")
Teng Liang52f43c32015-05-20 17:06:20 -070065
Teng Liang50429402015-05-22 16:01:17 -070066 #create new identity for device
67 deviceNewIdentity.append(deviceParameters["category"])
68 deviceNewIdentity.append(deviceParameters["id"])
Teng Liang52f43c32015-05-20 17:06:20 -070069
Teng Liang50429402015-05-22 16:01:17 -070070 #generate content
71 content = {}
72 content["deviceNewIdentity"] = deviceNewIdentity.toUri()
73 content["controllerIdentity"] = self._prefix
Teng Liang52f43c32015-05-20 17:06:20 -070074
Teng Liang50429402015-05-22 16:01:17 -070075 #get public key of controller
76 pKeyName = self._identityManager.getDefaultKeyNameForIdentity(self._identityManager.getDefaultIdentity())
77 pKey = self._identityManager.getPublicKey(pKeyName)
78
79 pKeyInfo = content["controllerPublicKey"] = {}
80 pKeyInfo["keyName"] = pKeyName.toUri()
81 pKeyInfo["keyType"] = pKey.getKeyType()
82 pKeyInfo["publicKeyDer"] = pKey.getKeyDer().toRawStr()
83 dump("Sent content : ",content)
84
85 #TODO generate signature for data
86
87 #generate data package
88 data = Data(interestName)
89 data.setContent(json.dumps(content,encoding="latin-1"))
90 #data.setSignature(signature)
91 encodedData = data.wireEncode()
92 transport.send(encodedData.toBuffer())
93
94
95 def onCertificateRequest(self, prefix, interest, transport, registeredPrefixId):
96 interestName = interest.getName()
97 dump("interest name : ",interestName)
98
99 keyName = interestName[:3]
100 keyId = interestName.get(4)
101 keyName.append(keyId)
102 keyInfo = json.loads(interestName.get(5).getValue().toRawStr(),encoding="latin-1")
103 keyType = keyInfo['keyType']
104 keyDer = Blob().fromRawStr(keyInfo['keyDer'])
105
106 dump("keyname: ",keyName)
107 dump("keyType ",keyInfo['keyType'])
108 dump("keyDer string",keyInfo['keyDer'])
109 dump("keyDer",keyDer)
110
111 #device and controller are on one mechine, so it needs to be done.
112 self._identityManager.setDefaultIdentity(Name(self._prefix))
113 try:
114 self._identityStorage.addKey(keyName, keyType, keyDer)
115 except SecurityException:
116 dump("The public key for device already exists ")
117
118 signedCertificate = self._identityManager._generateCertificateForKey(keyName)
119 self._keyChain.sign(signedCertificate, self._identityManager.getDefaultCertificateName())
120 self._identityManager.addCertificate(signedCertificate)
121
Teng Liang52f43c32015-05-20 17:06:20 -0700122
Teng Lianga0b49372015-05-15 05:30:27 -0700123
Teng Liang50429402015-05-22 16:01:17 -0700124 encodedData = signedCertificate.wireEncode()
125 transport.send(encodedData.toBuffer())
philoLbd28e132015-04-16 23:54:21 -0700126
Teng Liang50429402015-05-22 16:01:17 -0700127
128
philoLbd28e132015-04-16 23:54:21 -0700129 def onRegisterFailed(self, prefix):
130 self._responseCount += 1
131 dump("Register failed for prefix", prefix.toUri())
132
Teng Lianga0b49372015-05-15 05:30:27 -0700133 def beforeLoopStart(self):
134 identityName = Name(self._prefix)
Teng Liang52f43c32015-05-20 17:06:20 -0700135
136 defaultIdentityExists = True
Teng Lianga0b49372015-05-15 05:30:27 -0700137 try:
138 defaultIdentityName = self._identityManager.getDefaultIdentity()
Teng Lianga0b49372015-05-15 05:30:27 -0700139 except:
Teng Liang52f43c32015-05-20 17:06:20 -0700140 defaultIdentityExists = False
Teng Lianga0b49372015-05-15 05:30:27 -0700141
142
143 #dump(self._identityManager.getDefaultKeyNameForIdentity(self._prefix))
Teng Liang52f43c32015-05-20 17:06:20 -0700144 if not defaultIdentityExists or self._identityManager.getDefaultIdentity() != identityName:
Teng Lianga0b49372015-05-15 05:30:27 -0700145 #make one
Teng Liang52f43c32015-05-20 17:06:20 -0700146 dump("Set default identity: ",identityName)
147 #self._identityManager.createIdentityAndCertificate(identityName)
148 self._identityStorage.addIdentity(identityName)
Teng Lianga0b49372015-05-15 05:30:27 -0700149 self._identityManager.setDefaultIdentity(identityName)
Teng Liang52f43c32015-05-20 17:06:20 -0700150
151 try:
Teng Liang50429402015-05-22 16:01:17 -0700152 self._identityManager.getDefaultKeyNameForIdentity(identityName)
153 except SecurityException:
Teng Liang52f43c32015-05-20 17:06:20 -0700154 newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(self._prefix), isKsk=True)
155 newCert = self._identityManager.selfSign(newKey)
Teng Liang50429402015-05-22 16:01:17 -0700156 dump("generated new KSK certificate ", newCert)
Teng Liang52f43c32015-05-20 17:06:20 -0700157 self._identityManager.addCertificateAsIdentityDefault(newCert)
Teng Lianga0b49372015-05-15 05:30:27 -0700158
159
philo5d4724e2014-11-10 19:34:05 +0000160if __name__ == '__main__':
161
philoLbd28e132015-04-16 23:54:21 -0700162 # The default Face will connect using a Unix socket, or to "localhost".
163 face = Face()
164
165 # Use the system default key chain and certificate name to sign commands.
philo5d4724e2014-11-10 19:34:05 +0000166
Teng Lianga0b49372015-05-15 05:30:27 -0700167 controller = Controller("default.conf")
168 controller.beforeLoopStart()
169
Teng Liang52f43c32015-05-20 17:06:20 -0700170 face.setCommandSigningInfo(controller.getKeyChain(), controller._keyChain.getDefaultCertificateName())
philoLbd28e132015-04-16 23:54:21 -0700171
172 # Also use the default certificate name to sign data packets.
philo5d4724e2014-11-10 19:34:05 +0000173
philoLbd28e132015-04-16 23:54:21 -0700174 prefix = Name("/home/")
Teng Lianga0b49372015-05-15 05:30:27 -0700175 dump("Register prefix", prefix)
176
philoLbd28e132015-04-16 23:54:21 -0700177 face.registerPrefix(prefix, controller.onInterest, controller.onRegisterFailed)
178
Teng Lianga0b49372015-05-15 05:30:27 -0700179
philoLbd28e132015-04-16 23:54:21 -0700180 while controller._responseCount < 100:
181 face.processEvents()
182 # We need to sleep for a few milliseconds so we don't use 100% of the CPU.
183 time.sleep(0.01)
184
185 face.shutdown()
186