blob: 4fa3540d0972762db3a0b7e0ffc9b47f965073b6 [file] [log] [blame]
Teng Liang938be582015-07-15 16:25:26 -07001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
3# Copyright (C) 2014 Regents of the University of California.
4# Author: Teng Liang <philoliang2011@gmail.com>
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 General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18# A copy of the GNU General Public License is in the file COPYING.
19
20"""
21This module defines Device class, which contains core modules of end device, including device discovery protocol, syncronization protocol, and access control manager.
22"""
23
24
25import time
26import json
27from pyndn import Name, Face, Interest, Data
28from pyndn.threadsafe_face import ThreadsafeFace
29from pyndn import KeyLocator, KeyLocatorType
30from base_node import BaseNode
31from hmac_helper import HmacHelper
32from pyndn.security.security_exception import SecurityException
33from pyndn.util import Blob
34try:
35 import asyncio
36except ImportError:
37 import trollius as asyncio
38
39def dump(*list):
40 result = ""
41 for element in list:
42 result += (element if type(element) is str else repr(element)) + " "
43 print(result)
44
45class Device(BaseNode):
46 def __init__(self,configFileName=None):
47 super(Device, self).__init__(configFileName)
48
49 self._deviceSerial = self.getSerial()
50 self._callbackCount = 0
51 self._symKey = "symmetricKeyForBootstrapping"
52 self._category = "sensors"
53 self._id = "T9273659"
54 self._hmacHelper = HmacHelper(self._symKey)
55
56
57 def expressBootstrapInterest(self):
58
59 #generate bootstrap name /home/controller/bootstrap/<device-parameters>
60 bootstrapName = Name(self._bootstrapPrefix)
61
62 deviceParameters = {}
63 deviceParameters["category"] = self._category
64 deviceParameters["id"] = self._id
65 bootstrapName.append(json.dumps(deviceParameters))
66
67 bootstrapInterest = Interest(bootstrapName)
68 bootstrapInterest.setInterestLifetimeMilliseconds(3000)
69 self._hmacHelper.signInterest(bootstrapInterest)
70
71 dump("Express bootstrap interest : ",bootstrapInterest.toUri())
72 self.face.expressInterest(bootstrapInterest, self.onBootstrapData, self.onTimeout)
73
74 def onBootstrapData(self, interest, data):
75 dump("Bootstrap data received.")
76
77 if (self._hmacHelper.verifyData(data)):
78 self.log.info("Bootstrap data is verified")
79 content = json.loads(data.getContent().toRawStr(), encoding="latin-1")
80 deviceNewIdentity = Name(content["deviceNewIdentity"])
81 controllerIdentity = Name(content["controllerIdentity"])
82 controllerPublicKeyInfo = content["controllerPublicKey"]
83
84 self.face.registerPrefix(content["deviceNewIdentity"],self.onInterest,self.onRegisterFailed)
85 #set new identity as default and generate default key-pair with KSK Certificate
86 self._identityStorage.addIdentity(deviceNewIdentity)
87 self._identityManager.setDefaultIdentity(deviceNewIdentity)
88 try:
89 self._identityManager.getDefaultKeyNameForIdentity(deviceNewIdentity)
90 except SecurityException:
91 #generate new key-pair and certificate for new identity
92 dump("Install new identity as default\nGenerate new key-pair and self signed certificate")
93 newKey = self._identityManager.generateRSAKeyPairAsDefault(Name(deviceNewIdentity), isKsk=True)
94 newCert = self._identityManager.selfSign(newKey)
95 self._identityManager.addCertificateAsIdentityDefault(newCert)
96
97 #add controller's identity and public key
98 keyType = controllerPublicKeyInfo["keyType"]
99 keyName = Name(controllerPublicKeyInfo["keyName"])
100 keyDer = Blob().fromRawStr(controllerPublicKeyInfo["publicKeyDer"])
101 dump("Controller's KeyType: ",keyType)
102 dump("Controller's keyName: ",keyName)
103 dump("Controller public key der : ",keyDer)
104
105 self._identityStorage.addIdentity(controllerIdentity)
106 try:
107 self._identityStorage.addKey(keyName, keyType, keyDer)
108 dump("Controller's identity, key and certificate installled.")
109 except SecurityException:
110 dump("Controller's identity, key, certificate already exists.")
111
112 #express an certificate request interest
113 defaultKeyName = self._identityManager.getDefaultKeyNameForIdentity(self._keyChain.getDefaultIdentity() )
114 self.requestCertificate(defaultKeyName)
115 else:
116 self.log.info("Bootstrap data is not verified")
117
118
119
120
121 def beforeLoopStart(self):
122 #self.face.registerPrefix('/home', self.onInterest, self.onRegisterFailed)
123 self.expressBootstrapInterest()
124
125 def onTimeout(self, interest):
126 self._callbackCount += 1
127 dump("Time out for interest", interest.getName().toUri())
128
129 def onInterest():
130 pass
131 def onRegisterFailed():
132 pass
133
134# def requestCertificate(self, keyIdentity):
135 """
136 We compose a command interest with our public key info so the controller
137 can sign us a certificate that can be used with other nodes in the network.
138 Name format : /home/<device-category>/KEY/<device-id>/<key-id>/<publickey>/ID-CERT/<version-number>
139 """
140""" certificateRequestName = self._keyChain.getDefaultIdentity()
141 deviceIdComponent = certificateRequestName.get(-1)
142 keyIdComponent = keyIdentity.get(-1)
143
144 certificateRequestName = certificateRequestName
145 certificateRequestName.append("KEY")
146 #certificateRequestName.append(deviceIdComponent)
147 certificateRequestName.append(keyIdComponent)
148
149 key = self._identityManager.getPublicKey(keyIdentity)
150 keyInfo = {}
151 keyInfo["keyType"] = key.getKeyType()
152 keyInfo["keyDer"] = key.getKeyDer().toRawStr()
153
154 certificateRequestName.append(json.dumps(keyInfo, encoding="latin-1"))
155
156 certificateRequestName.append("ID-CERT")
157
158 certificateRequest = Interest(certificateRequestName)
159 certificateRequest.setInterestLifetimeMilliseconds(5000)
160 self._hmacHelper.signInterest(certificateRequest)
161
162 dump("Sending certificate request : ",certificateRequestName)
163
164 self.face.expressInterest(certificateRequest, self.onCertificateData, self.onTimeout)
165 #TODO use symmetric key to sign
166
167 def onCertificateData(self, interest, data):
168 dump("OnCertificateData : ",data)
169"""
170
171if __name__ == '__main__':
172
173 device = Device()
174 device.start()
175
176
177