def handle_msg(self, msg): """ Verify that the published message was authorized, then decrypt it """ namespace, topic = parse_topic(msg.topic) proof, payload = unpack_payload(msg.payload) resp = self.agent.VerifyProof( wave3.VerifyProofParams(proofDER=proof, requiredRTreePolicy=wave3.RTreePolicy( namespace=namespace, statements=[ wave3.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource=topic, ) ]))) if resp.error.code != 0: print(resp.error) return None #raise Exception(resp.error) decrypt_msg = self.agent.DecryptMessage( wave3.DecryptMessageParams( perspective=self.perspective, ciphertext=payload, )) return json.loads(decrypt_msg.content)
def _grant_permission_to(self, entityhash, namespace, uripattern, permissions): """ hashes: entityhash, namespace uripattern: string permissions is a list of permissions """ # grants the permission to access the uri resp = self.agent.CreateAttestation( wave3.CreateAttestationParams( perspective=self.perspective, subjectHash=entityhash, publish=True, policy=wave3.Policy(rTreePolicy=wave3.RTreePolicy( namespace=namespace, indirections=5, statements=[ wave3.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=permissions, resource=uripattern, ) ])))) if resp.error.code != 0: raise Exception(resp.error.message) # grant permission to decrypt/encrypt resp = self.agent.CreateAttestation( wave3.CreateAttestationParams( perspective=self.perspective, subjectHash=entityhash, publish=True, policy=wave3.Policy(rTreePolicy=wave3.RTreePolicy( namespace=namespace, indirections=5, statements=[ wave3.RTreePolicyStatement( permissionSet=wave3.WaveBuiltinPSET, permissions=[wave3.WaveBuiltinE2EE], resource=uripattern, ) ])))) if resp.error.code != 0: raise Exception(resp.error.message)
agent.PublishEntity(wv.PublishEntityParams(DER=ent.PublicDER)) ent2 = agent.CreateEntity(wv.CreateEntityParams()) agent.PublishEntity(wv.PublishEntityParams(DER=ent2.PublicDER)) perspective = wv.Perspective(entitySecret=wv.EntitySecret(DER=ent.SecretDER)) att = agent.CreateAttestation( wv.CreateAttestationParams( perspective=perspective, subjectHash=ent2.hash, publish=True, policy=wv.Policy( rTreePolicy=wv.RTreePolicy(namespace=ent.hash, indirections=5, statements=[ wv.RTreePolicyStatement( permissionSet=ent.hash, permissions=["foo"], resource="foo/bar", ) ])))) ent2perspective = wv.Perspective(entitySecret=wv.EntitySecret( DER=ent2.SecretDER)) agent.ResyncPerspectiveGraph( wv.ResyncPerspectiveGraphParams(perspective=ent2perspective, )) for status in agent.WaitForSyncComplete( wv.SyncParams(perspective=ent2perspective)): print(status) proof = agent.BuildRTreeProof( wv.BuildRTreeProofParams(perspective=ent2perspective,
def on_message(self, client, userdata, msg): proof, payload = unpack_payload(msg.payload) if len(proof) == 0: return if msg.topic == self.nickname+"/smarthome/light/control": resp = self.agent.VerifyProof(wv.VerifyProofParams( proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/light/control", )] ) )) if resp.error.code != 0: print("home server received light control with invalid proof: ",resp.error.message) return # actuate light state when the light receives a direct message self.light_widget.state = json.loads(payload).get('state') == 'on' #self.notify("Light changed (remote) to {0}".format('on' if self.light_widget.state else 'off')) elif msg.topic == self.nickname+"/smarthome/thermostat/control": resp = self.agent.VerifyProof(wv.VerifyProofParams( proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/thermostat/control", )] ) )) if resp.error.code != 0: print("home server received thermostat control with invalid proof: ",resp.error.message) return # TODO integrate with gabe's widget here tstat_fields = json.loads(payload) #print('thermostat command', tstat_fields) if tstat_fields.get('hsp'): self.thermostat_widget.hsp = tstat_fields.get('hsp') self.notify("Thermostat heating setpoint changed to {0}".format(self.thermostat_widget.hsp)) if tstat_fields.get('csp'): self.thermostat_widget.csp = tstat_fields.get('csp') self.notify("Thermostat cooling setpoint changed to {0}".format(self.thermostat_widget.csp)) if tstat_fields.get('temperature'): self.thermostat_widget.temp = tstat_fields.get('temp') elif msg.topic == self.nickname+"/smarthome/notify": resp = self.agent.VerifyProof(wv.VerifyProofParams( proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/notify", )] ) )) if resp.error.code != 0: print("home server received notify with invalid proof: ",resp.error.message) return self.notify(json.loads(payload)) else: print("topic", msg.topic, "payload", payload)
def grant_permissions_to(self, enthash): # grant the ability to decrypt data that the thermostat publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/thermostat/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to decrypt data that the motion sensor publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/motion/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to decrypt data that the light publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/light/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to actuate the thermostat and the light and the notifications, and read the thermostat and light resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/thermostat/control", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/light/control", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/notify", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/thermostat/report", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/light/report", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/motion/report", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message)
def _make_device_entity(self, device): """ - makes entity - publishes entity - namespace grant to device entity read on <hash>/<device>/control - namespace grant to device entity write on <hash>/<device>/report """ device_entity, newlyCreated = createOrLoadEntity(self.agent, device) if newlyCreated: self.agent.PublishEntity(wv.PublishEntityParams(DER=device_entity.PublicDER)) device_perspective=wv.Perspective( entitySecret=wv.EntitySecret(DER=device_entity.SecretDER) ) # grant permission to encrypt on device URIs, read/write on report/control respectively encrypt_policy = wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, # TODO: need this? # visibilityURI=[bytes("smarthome","utf8"),bytes(device,"utf8")], statements=[ wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/{0}/+".format(device), ) ] )) msg_policy = wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[ wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/{0}/control".format(device), ), wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/{0}/report".format(device), ) ] )) if newlyCreated: r = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=device_entity.hash, publish=True, policy=msg_policy )) #print(r) #print('msg policy attested') r = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=device_entity.hash, publish=True, policy=encrypt_policy, )) #print(r) #print('encrypt policy attested') #print(encrypt_policy) encrypt_proof = self.agent.BuildRTreeProof(wv.BuildRTreeProofParams( perspective=device_perspective, namespace=encrypt_policy.rTreePolicy.namespace, resyncFirst=True, statements=encrypt_policy.rTreePolicy.statements, )) if encrypt_proof.error.code != 0: raise Exception(encrypt_proof.error) msg_proof = self.agent.BuildRTreeProof(wv.BuildRTreeProofParams( perspective=device_perspective, namespace=msg_policy.rTreePolicy.namespace, resyncFirst=True, statements=msg_policy.rTreePolicy.statements, )) if msg_proof.error.code != 0: raise Exception(msg_proof.error) return device_entity, encrypt_proof, msg_proof