def createDataMessage(self, message, flags=0, tlvs=None): # check MSGSTATE if self.theirKeyid == 0: raise InvalidParameterError if tlvs is None: tlvs = [] sess = self.sessionkeys[1][0] sess.sendctr.inc() logger.debug('create: enc={0!r} mac={1!r} ctr={2!r}' \ .format(sess.sendenc, sess.sendmac, sess.sendctr)) # plaintext + TLVS plainBuf = message + b'\0' + b''.join([ bytes(t) for t in tlvs]) encmsg = AESCTR(sess.sendenc, sess.sendctr).encrypt(plainBuf) msg = proto.DataMessage(flags, self.ourKeyid-1, self.theirKeyid, long_to_bytes(self.ourDHKey.pub), sess.sendctr.byteprefix(), encmsg, b'', b''.join(self.savedMacKeys)) self.savedMacKeys = [] msg.mac = SHA1HMAC(sess.sendmac, msg.getMacedData()) return msg
def handleDataMessage(self, msg): if self.saneKeyIds(msg) is False: raise InvalidParameterError sesskey = self.sessionkeys[self.ourKeyid - msg.rkeyid] \ [self.theirKeyid - msg.skeyid] logger.debug('sesskeys: {0!r}, our={1}, r={2}, their={3}, s={4}' \ .format(self.sessionkeys, self.ourKeyid, msg.rkeyid, self.theirKeyid, msg.skeyid)) if msg.mac != SHA1HMAC(sesskey.rcvmac, msg.getMacedData()): logger.error('HMACs don\'t match') raise InvalidParameterError sesskey.rcvmacused = True newCtrPrefix = bytes_to_long(msg.ctr) if newCtrPrefix <= sesskey.rcvctr.prefix: logger.error('CTR must increase (old %r, new %r)', sesskey.rcvctr.prefix, newCtrPrefix) raise InvalidParameterError sesskey.rcvctr.prefix = newCtrPrefix logger.debug('handle: enc={0!r} mac={1!r} ctr={2!r}' \ .format(sesskey.rcvenc, sesskey.rcvmac, sesskey.rcvctr)) plaintextData = AESCTR(sesskey.rcvenc, sesskey.rcvctr) \ .decrypt(msg.encmsg) if b'\0' in plaintextData: plaintext, tlvData = plaintextData.split(b'\0', 1) tlvs = proto.TLV.parse(tlvData) else: plaintext = plaintextData tlvs = [] if msg.rkeyid == self.ourKeyid: self.rotateDHKeys() if msg.skeyid == self.theirKeyid: self.rotateYKeys(bytes_to_long(msg.dhy)) return plaintext, tlvs