Exemple #1
0
    def send(self, addr, cSuite, nodeData):
        try:
            addrStr = sts_utility.addrToString(addr)
            if addrStr in STS.STSConnectionStates.keys():
                if STS.STSConnectionStates[addrStr]['phase'] == 2:
                    print('send data with the existing session')
                    ECDH_DATA_EX = self.constructSTSResponse(2, addr, nodeData)
                    self.sock.sendto(ECDH_DATA_EX, addr)
                    # self.receive()
                else:
                    self.terminate(addr)

            else:
                print('send data with the new session')
                # myCert, myCertStatus = sts_utility.decodeMyCertificate(self.sock, self.endpoint_address)
                # myEncrypKey, mySignKey = sts_utility.decodeSecretKey()
                if cSuite in [1, 2, 6]:
                    # print('sending ECDH')
                    myECDHPK, myECDHSK = pysodium.crypto_kx_keypair()
                    propose = self.generateProposeECDH(cSuite, myECDHPK,
                                                       self.mySignKey,
                                                       self.myCert,
                                                       self.myCertStatus)
                    STS.STSConnectionStates[addrStr] = {
                        'session_key': None,
                        'phase': 0,
                        'init': True,
                        'data': nodeData,
                        'keys': (myECDHPK, myECDHSK),
                        'cSuite': cSuite,
                        'time': int(time.time())
                    }
                    print('sending PROPOSE')
                    sts_utility.decodeSTSMessage(propose)
                    self.sock.sendto(propose, addr)
                elif cSuite in [3, 4, 5]:
                    propose = self.generateProposeECDH(cSuite, (0).to_bytes(
                        32, byteorder='big'), self.mySignKey, self.myCert,
                                                       self.myCertStatus)
                    STS.STSConnectionStates[addrStr] = {
                        'session_key': None,
                        'phase': 0,
                        'init': True,
                        'data': nodeData,
                        'keys': None,
                        'cSuite': cSuite,
                        'time': int(time.time())
                    }
                    print('sending PROPOSE')
                    sts_utility.decodeSTSMessage(propose)
                    self.sock.sendto(propose, addr)
                # while not STS.STSConnectionStates[addrStr]['phase'] == 2:
                #     self.receive()
                # ECDH_DATA_EX = self.constructSTSResponse(2, addr, nodeData)
                # self.sock.sendto(ECDH_DATA_EX, addr)
                # self.receive()
        except:
            return None
Exemple #2
0
 def sendBlake2bResp(self, data, addr, cSuite):
     addrStr = sts_utility.addrToString(addr)
     # myCert, myCertStatus = sts_utility.decodeMyCertificate(self.sock, self.endpoint_address)
     # myEncrypKey, mySignKey = sts_utility.decodeSecretKey()
     if cSuite in [1, 2]:
         # print('sending ECDH')
         myECDHPK, myECDHSK = pysodium.crypto_kx_keypair()
         propose = self.generateProposeECDH(cSuite, myECDHPK,
                                            self.mySignKey, self.myCert,
                                            self.myCertStatus)
         # STS.STSConnectionStates[addrStr] = {'session_key': None, 'phase': 0, 'init': True,
         #                                     'keys': (myECDHPK, myECDHSK),
         #                                     'cSuite': cSuite, 'time': int(time.time())}
         STS.STSConnectionStates[addrStr]['keys'] = (myECDHPK, myECDHSK)
         self.blake2b(data, addr, server=True)
         print('Sending Propose')
         sts_utility.decodeSTSMessage(propose)
         self.sock.sendto(propose, addr)
     elif cSuite == 0:
         myECDHPK, myECDHSK = pysodium.crypto_kx_keypair()
         STS.STSConnectionStates[addrStr]['keys'] = (myECDHPK, myECDHSK)
         propose = self.generateProposeECDH(1, myECDHPK, self.mySignKey,
                                            self.myCert, self.myCertStatus)
         self.sock.sendto(propose, addr)
Exemple #3
0
    def receive(self):
        # print(STS.STSConnectionStates)
        data, addr = self.sock.recvfrom(1500)
        print('received STS message')
        sts_utility.decodeSTSMessage(data)
        # TODO Clean STSConnectionStates
        # TODO VALIDATE SUITE DOWNGRADE
        addrStr = sts_utility.addrToString(addr)
        # Received propose
        # Reply propose for actual suite when 0/3 used
        try:
            if addr == self.endpoint_address:
                self.setCertificateStatus(data)

            elif data[0] == 0:
                # propose received as server
                # print(self.verifySTSResponse(data, addr))
                # CLIENT PROPOSE / MULTIPLE PROPOSE
                if addrStr in STS.STSConnectionStates.keys():
                    if self.verifyPropose(data, addr):
                        if STS.STSConnectionStates[addrStr]['phase'] != 0:
                            # pprint.pprint(STS.STSConnectionStates)
                            self.terminate(addr)
                        elif data[1] < STS.STSConnectionStates[addrStr][
                                'cSuite']:
                            self.terminate(addr)
                        elif STS.STSConnectionStates[addrStr]['phase'] == 0:
                            # TODO UPGRADE SUITE IS VALID, NEED TO FIX BELOW
                            # if STS.STSConnectionStates[addrStr]['cSuite'] in [1, 2] and data[1] in [3, 4, 5]:
                            #     self.terminate(addr)
                            if STS.STSConnectionStates[addrStr]['init']:
                                if STS.STSConnectionStates[addrStr][
                                        'cSuite'] in [1, 2]:
                                    # LOWER SUITE CHECKED BEFORE
                                    if STS.STSConnectionStates[addrStr][
                                            'cSuite'] != data[1]:
                                        data = STS.STSConnectionStates[
                                            addrStr]['data']
                                        STS.STSConnectionStates.pop(addrStr)
                                        self.send(addr, data[1], data)
                                        return None, None

                                elif STS.STSConnectionStates[addrStr][
                                        'cSuite'] == 3 and data[1] == 3:
                                    self.terminate(addr)
                            else:
                                if STS.STSConnectionStates[addrStr][
                                        'cSuite'] in [1, 2] and data[1] in [
                                            3, 4, 5
                                        ]:
                                    self.terminate(addr)
                                # if STS.STSConnectionStates[addrStr]['cSuite'] in [1 ,2]:
                                #     if STS.STSConnectionStates[addrStr]['cSuite'] != data[1]:
                                #         self.terminate(addr)

                        else:
                            STS.STSConnectionStates[addrStr]['cSuite'] = data[
                                1]
                            STS.STSConnectionStates[addrStr]['time'] = int(
                                time.time())
                    else:
                        print('=== VERIFICATION FAILED ===', addr)
                        self.terminate(addr)

                # SERVER RECEIVE
                else:
                    if self.verifyPropose(data, addr):
                        # if data[1] == 0:
                        # TODO PROPOSE EXPECTED SUITE

                        if addrStr not in STS.STSConnectionStates.keys():
                            STS.STSConnectionStates[addrStr] = {
                                'session_key': None,
                                'phase': data[0],
                                'init': False,
                                'keys': None,
                                'cSuite': data[1],
                                'time': int(time.time())
                            }
                    else:
                        print('=== VERIFICATION FAILED ===', addr)
                        self.terminate(addr)
                self.negotiate(data, addr)

            elif data[0] == 1:
                if addrStr not in STS.STSConnectionStates.keys():
                    self.terminate(addr)
                elif not self.deconstructSTSResponse(data, addr):
                    self.terminate(addr)
                else:
                    if STS.STSConnectionStates[addrStr]['init']:
                        if STS.STSConnectionStates[addrStr]['phase'] == 1:
                            STS.STSConnectionStates[addrStr]['phase'] = 2
                            ECDH_DATA_EX = self.constructSTSResponse(
                                2, addr,
                                STS.STSConnectionStates[addrStr]['data'])
                            self.sock.sendto(ECDH_DATA_EX, addr)
                        else:
                            self.terminate(addr)

                    else:
                        if STS.STSConnectionStates[addrStr][
                                'phase'] == 0 and STS.STSConnectionStates[
                                    addrStr]['cSuite'] in [1, 2]:
                            STS.STSConnectionStates[addrStr]['phase'] = 1
                            self.negotiate(data, addr)
                        elif STS.STSConnectionStates[addrStr][
                                'phase'] == 0 and STS.STSConnectionStates[
                                    addrStr]['cSuite'] in [4, 5]:
                            STS.STSConnectionStates[addrStr]['phase'] = 1
                            self.negotiate(data, addr)
                        else:
                            self.terminate(addr)

            elif data[0] == 2:
                # TODO VALID DATA EXCHANGE
                if addrStr not in STS.STSConnectionStates.keys():
                    self.terminate(addr)
                elif not self.deconstructSTSResponse(data, addr):
                    self.terminate(addr)
                else:
                    if addrStr in STS.STSConnectionStates.keys():
                        if STS.STSConnectionStates[addrStr]['init']:
                            if STS.STSConnectionStates[addrStr]['phase'] == 2:
                                data_ex_resp = self.deconstructSTSResponse(
                                    data, addr)
                                sts_utility.decodeDHTMessage(data_ex_resp)
                                return data_ex_resp, addr
                            else:
                                self.terminate(addr)
                        else:
                            if STS.STSConnectionStates[addrStr]['phase'] == 2:
                                date_ex_resp = self.deconstructSTSResponse(
                                    data, addr)
                                response = packet.pingResponse(date_ex_resp)
                                ECDH_DATA_EX = self.constructSTSResponse(
                                    2, addr, response)
                                self.sock.sendto(ECDH_DATA_EX, addr)
                    else:
                        self.terminate(addr)

            elif data[0] == 3:
                print('=== TERMINATE RECEIVED ===', addr)
                sts_utility.decodeSTSMessage(data)
                if addrStr in STS.STSConnectionStates.keys():
                    STS.STSConnectionStates.pop(addrStr)
        except:
            self.terminate(addr)
            return None, None

        return None, None
Exemple #4
0
    def negotiate(self, data, addr):
        addrStr = sts_utility.addrToString(addr)
        if addrStr in STS.STSConnectionStates.keys():
            # SERVER LOGIC
            if not STS.STSConnectionStates[addrStr]['init']:
                if STS.STSConnectionStates[addrStr]['cSuite'] in [
                        0, 1, 2
                ] and STS.STSConnectionStates[addrStr]['phase'] == 0:
                    self.sendBlake2bResp(
                        data, addr, STS.STSConnectionStates[addrStr]['cSuite'])
                elif STS.STSConnectionStates[addrStr]['cSuite'] in [
                        1, 2
                ] and STS.STSConnectionStates[addrStr]['phase'] == 1:
                    # TODO verify accept
                    # ACCEPT Verify
                    ECDH_AED_accept = self.constructSTSResponse(
                        1, addr, sts_utility.timestampPacked())
                    sts_utility.decodeSTSMessage(ECDH_AED_accept)
                    STS.STSConnectionStates[addrStr]['phase'] = 2
                    self.sock.sendto(ECDH_AED_accept, addr)
                    # self.receive()

                elif STS.STSConnectionStates[addrStr]['cSuite'] in [
                        3, 4, 5
                ] and STS.STSConnectionStates[addrStr]['phase'] == 0:
                    # print('=== GEN PROPOSE SALSA 4 ===')
                    # print(binascii.hexlify(proposeResp['C']['K_E']))
                    salsaMsg = self.salsa20poly1305(data, addr, server=True)
                    if not salsaMsg:
                        self.terminate(addr)
                    else:
                        sts_utility.decodeSTSMessage(salsaMsg)
                        # print(mySalsaSession)
                        self.sock.sendto(salsaMsg, addr)
                        # self.receive()

                elif STS.STSConnectionStates[addrStr]['cSuite'] in [
                        4, 5
                ] and STS.STSConnectionStates[addrStr]['phase'] == 1:
                    STS.STSConnectionStates[addrStr]['phase'] = 2
                    SALSA_AED_accept = self.constructSTSResponse(
                        1, addr, sts_utility.timestampPacked())
                    sts_utility.decodeSTSMessage(SALSA_AED_accept)
                    self.sock.sendto(SALSA_AED_accept, addr)
                    # self.receive()
                else:
                    self.terminate(addr)

            # CLIENT LOGIC
            else:
                if STS.STSConnectionStates[addrStr]['cSuite'] in [
                        1, 2
                ] and STS.STSConnectionStates[addrStr]['phase'] == 0:
                    if STS.STSConnectionStates[addrStr]['session_key'] is None:
                        self.blake2b(data, addr)
                        ECDH_AED_accept = self.constructSTSResponse(
                            1, addr, sts_utility.timestampPacked())
                        print('Sending Accept')
                        sts_utility.decodeSTSMessage(ECDH_AED_accept)
                        STS.STSConnectionStates[addrStr]['phase'] = 1
                        self.sock.sendto(ECDH_AED_accept, addr)
                        # self.receive()

                elif STS.STSConnectionStates[addrStr]['cSuite'] in [3, 4, 5]:
                    # print('=== GEN PROPOSE SALSA 4 ===')
                    # print(binascii.hexlify(proposeResp['C']['K_E']))
                    salsaMsg = self.salsa20poly1305(data, addr)
                    sts_utility.decodeSTSMessage(salsaMsg)
                    # print(mySalsaSession)
                    self.sock.sendto(salsaMsg, addr)
                    # self.receive()
                else:
                    self.terminate(addr)