Exemple #1
0
    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
Exemple #2
0
    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