def init_self_connection(self): #Add myself to neighbors ownNeighborEntry = Neighbor() ownNeighborEntry.ipAddress = self.hostname ownNeighborEntry.encryptionKey = self.key ownNeighborEntry.encryptionIV = self.iv #Connect to own socket tempNeighborList = {} tempNeighborList[self.hostname] = ownNeighborEntry self.onAPJoined(tempNeighborList)
def sendFloodingMessage(self, message, max_ttl, msg_type='data', sub_type='std', key=str(), iv=str(), nodeID="255.255.255.255"): self.log.debug("sendFloodingMessage()") if len(key) != 16 or len(iv)!=16: key = self.key iv = self.iv lasthop = self.hostname else: self.log.debug("sendFloodingMessage, last hop key = old keys") lasthop = 'old_keys' #self.key_material[lasthop] = (key, iv) oldKeyNeighbor = Neighbor() oldKeyNeighbor.encryptionKey = key oldKeyNeighbor.encryptionIV = iv oldKeyNeighbor.pubKey = self.pubKey self.globalNeighborList[lasthop] = oldKeyNeighbor self.log.debug("SendFlooding to: nodeID: %s, msg_type=%s" %(nodeID, msg_type)) #Apply asymmetric encryption for unicast messages if nodeID != "255.255.255.255" and msg_type=="ctrl": #Apply enrcyption with public key of receiver if nodeID in self.globalNeighborList: self.log.debug('Additional public key encryption for unicast CTRL message to %s applied.' % (nodeID)) oaep = PKCS1_OAEP.new(self.globalNeighborList[nodeID].pubKey) asssymEncMessage = oaep.encrypt(message) message = asssymEncMessage else: self.log.error('Unicast Message to neighbor %s cannot be sent, neighbor is not available in neighbor list' % (nodeID)) self.sendingUserSpaceMessageEvent.set() return elif nodeID != "255.255.255.255" and msg_type=="data": if nodeID in self.globalNeighborList: self.log.debug('Additional symmetric key encryption for unicast STD message to %s applied.' % (nodeID)) aes = AES.new(self.globalNeighborList[nodeID].unicastSendKey, AES.MODE_CFB, self.globalNeighborList[nodeID].unicastSendIv) enc_message = aes.encrypt(message) # to base64 enc_message_b64 = base64.encodestring(enc_message) message = enc_message_b64 else: self.log.error('Unicast Message to neighbor %s cannot be sent, neighbor is not available in neighbor list' % (nodeID)) self.sendingUserSpaceMessageEvent.set() return #create signature: sig = self.security_helper.create_signature(message, self.rsaKey) # encrypt message aes = AES.new(key, AES.MODE_CFB, iv) enc_message = aes.encrypt(message) # to base64 enc_message_b64 = base64.encodestring(enc_message) if msg_type != "ctrl": self.log.debug('Source message: plain=%s, encrypted_B64=%s, rec:=%s' % (message, enc_message_b64, nodeID)) json_data = { 'host': self.hostname, 'lasthop': lasthop, 'id': self.local_id, 'rec': nodeID, 'ttl': max_ttl, 'msg_type' : msg_type, 'sub_type' : sub_type, 'msg': enc_message_b64, 'sig': sig } self.snd_socket.send_json(json_data) self.local_id = self.local_id + 1
def receiveMessage(self, myCallback): self.log.debug('receiveMessage') # Socket to talk to server context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect ("tcp://%s:%s" % (self.hostname, self.FWD_PORT)) socket.setsockopt(zmq.SUBSCRIBE, "") while True: json_data = socket.recv_json() if json_data['host'] == self.hostname: continue #decode encoded = base64.decodestring(json_data['msg']) aes = AES.new(self.key, AES.MODE_CFB, self.iv) plain = aes.decrypt(encoded) sig = json_data['sig'] if not self.security_helper.verify_signature(sig, plain, self.rsaKey): self.log.debug("Signature mismatch while checking own signature...") continue if json_data['rec'] != "255.255.255.255" and json_data['rec'] == self.hostname and json_data['msg_type'] == "ctrl": assymEncrMessage = plain plain = self.security_helper.decrypt_with_private_key(self.rsaKey, assymEncrMessage) self.log.debug('Received unicast CTRL message from: %s with subtype %s' % (json_data['host'], json_data['sub_type'])) elif json_data['rec'] != "255.255.255.255" and json_data['rec'] == self.hostname and json_data['msg_type'] == "data": if json_data['rec'] in self.globalNeighborList: plain_encoded = base64.decodestring(plain) if self.globalNeighborList[json_data['host']].unicastRecKey == str(): self.log.warn('Unicast Message from neighbor %s could not be decoded, no unicast key available' % (json_data['rec'])) continue aes = AES.new(self.globalNeighborList[json_data['host']].unicastRecKey, AES.MODE_CFB, self.globalNeighborList[json_data['host']].unicastRecIv) plain = aes.decrypt(plain_encoded) self.log.debug('Unicast Message from neighbor %s decoded' % (json_data['rec'])) self.log.debug('rx plain |%s|' % (plain)) self.processingNeighborMessageEvent.set() json_data['msg'] = unicode(plain, errors='ignore') #If the message is a control message if json_data['msg_type'] == 'ctrl': self.log.debug("Received CTRL Message") timestampKCM = int(time.time()) #if the message is a key change message if json_data['sub_type'] == 'kcm': self.log.debug("Received CTRL Message waiting for sendingUserSpaceMessageEvent") self.sendingUserSpaceMessageEvent.wait() self.log.debug("Received CTRL Message waiting for sendingUserCtrlMessageEvent") self.sendingUserCtrlMessageEvent.wait() self.log.debug("Received CTRL Message waiting for processingProbeRequestEvent") self.processingProbeRequestEvent.wait() self.log.debug("Received CTRL Message waiting for processingChangeKeysEvent") self.processingChangeKeysEvent.wait() self.log.debug("Received CTRL Message waiting for processingNeighborMessageEvent") self.processingNeighborMessageEvent.wait() self.log.debug("Received CTRL Message clearing processingNeighborUpdateEvent") self.processingNeighborUpdateEvent.clear() self.log.debug("Received CTRL Message running....") plain_splitted = json_data['msg'].split('|') freq = int(plain_splitted[0]) ssid = plain_splitted[1] ipAddress = plain_splitted[2] self.log.debug("Received key change message (KCM): ssid: %s, freq: %s " % (str(ssid), str(freq))) if (json_data["host"] in self.globalNeighborList): newNeighborEntry = Neighbor() newNeighborEntry.ipAddress = ipAddress newNeighborEntry.freq = freq newNeighborEntry.ssid = ssid newNeighborEntry.timestampLastKCM = timestampKCM self.globalNeighborList = self.parsing_helper.parse_existing_neighbor(newNeighborEntry, self.globalNeighborList) self.rescan_neighbor(freq, ssid, ipAddress, 10) self.processingNeighborUpdateEvent.set() #if the message is a request unicast key message elif json_data['sub_type'] == 'ruk': self.log.debug("Received request for unicast key (RUK) CTRL Message") #generate unicast symmetric key and send them back. if (json_data["host"] in self.globalNeighborList): if len(self.globalNeighborList[json_data["host"]].unicastRecKey)>2: retMsg = json.dumps({"key" : str(self.globalNeighborList[json_data["host"]].unicastRecKey.encode('hex')), "iv" : str(self.globalNeighborList[json_data["host"]].unicastRecIv.encode('hex'))}) self.sendCtrlToNeighbor(retMsg, "nuk", str(), str(), json_data["host"]) else: keys = self.security_helper.generateSymmetricKeys() retMsg = json.dumps({"key" : str(keys['keyHexStr']), "iv" : str(keys['ivHexStr'])}) self.sendCtrlToNeighbor(retMsg, "nuk", str(), str(), json_data["host"]) self.globalNeighborList[json_data["host"]].unicastRecKey = keys['key'] self.globalNeighborList[json_data["host"]].unicastRecIv = keys['iv'] else: self.log.warn("Unkown neighbor requested symmetric unicast keys") elif json_data['sub_type'] == 'nuk': self.log.debug("Received new unicast key (NUK) CTRL Message") if (json_data["host"] in self.globalNeighborList): nukMsg = json.loads(json_data['msg']) self.globalNeighborList[json_data["host"]].unicastSendKey = nukMsg["key"].decode('hex') self.globalNeighborList[json_data["host"]].unicastSendIv = nukMsg["iv"].decode('hex') self.globalNeighborList[json_data["host"]].waitingForUnicastKeys.set() else: myCallback(json_data)