Example #1
0
    def blake2b(self, data, addr, server=False):
        # ECDH_AED_accept = None
        addrStr = sts_utility.addrToString(addr)
        proposeResp = sts_utility.deconstructPropose(data)
        # print(STS.STSConnectionStates)
        # if addrStr in STS.STSConnectionStates.keys():
        myECDHPK, myECDHSK = STS.STSConnectionStates[addrStr]['keys']
        # TODO verification
        scalarmult_q = pysodium.crypto_scalarmult_curve25519(
            myECDHSK, proposeResp['K'])
        genericHash = pysodium.crypto_generichash_init(outlen=64)
        genericHash = pysodium.crypto_generichash_update(
            genericHash, scalarmult_q)
        if not server:
            genericHash = pysodium.crypto_generichash_update(
                genericHash, myECDHPK)
            genericHash = pysodium.crypto_generichash_update(
                genericHash, proposeResp['K'])
        else:
            genericHash = pysodium.crypto_generichash_update(
                genericHash, proposeResp['K'])
            genericHash = pysodium.crypto_generichash_update(
                genericHash, myECDHPK)

        genericHash = pysodium.crypto_generichash_final(genericHash, outlen=64)

        STS.STSConnectionStates[addrStr]['session_key'] = genericHash
        # STS.STSConnectionStates[addrStr]['phase'] = 1
        STS.STSConnectionStates[addrStr]['time'] = int(time.time())
Example #2
0
    def verifyPropose(self, data, addr):
        propose_tuple = sts_utility.deconstructPropose(data)
        # 1. validate certificate
        # 2. validate cert status
        # 3. Message signature check
        # 4. Check capability

        # 1. Certificate Checks
        if propose_tuple['C']['I'] not in STS.CAcerts.keys():
            print('wrong issuer principal')
            return False
        for I, _ in STS.CAcerts.items():
            if propose_tuple['C']['I'] == I:
                ca_cert_tuple = STS.CAcerts[I]
        try:
            pysodium.crypto_sign_verify_detached(
                propose_tuple['C']['G'],
                propose_tuple['C_B'][:-64] + (0).to_bytes(64, byteorder='big'),
                ca_cert_tuple['K_S'])
        except:
            print('wrong certificate signature')
            return False

        # CA DEPTH
        if ca_cert_tuple['C'][0] == 0:
            print('wrong CA depth')
            return False

        if not self.subjectPrincipalCheck(addr, propose_tuple['C']):
            print('wrong subject principal')
            return False

        # 4. NODE CAPABILITIES
        if not (propose_tuple['C']['C'][1:4] == b'\x00\x00\x1f'
                or propose_tuple['C']['C'][1:4] == b'\x00\x00?'):
            print('wrong capabilities')
            return False

        # 2. Certificate Status check
        try:
            pysodium.crypto_sign_verify_detached(
                propose_tuple['S']['G'],
                propose_tuple['S_B'][:-64] + (0).to_bytes(64, byteorder='big'),
                ca_cert_tuple['K_S'])
        except:
            print('wrong status signature')
            return False

        if pysodium.crypto_generichash(propose_tuple['C_B'],
                                       outlen=64) != propose_tuple['S']['H']:
            print('wrong status HASH')
            return False

        if propose_tuple['S']['S'] != 1:
            print('wrong cert status validity')
            return False

        currTime = int(time.time())
        if propose_tuple['S']['F'] + propose_tuple['S']['U'] <= currTime:
            print('wrong cert status, validity expired')
            return False

        #  3. Message signature:
        try:
            pysodium.crypto_sign_verify_detached(
                propose_tuple['G'],
                data[:-64] + (0).to_bytes(64, byteorder='big'),
                propose_tuple['C']['K_S'])
        except:
            print('wrong propose message signature')
            return False

        return True
Example #3
0
    def salsa20poly1305(self, data, addr, server=False):
        salsaMsg = None
        addrStr = sts_utility.addrToString(addr)
        # myCert, myCertStatus = sts_utility.decodeMyCertificate(self.sock, self.endpoint_address)
        # myEncrypKey, mySignKey = sts_utility.decodeSecretKey()
        if not server:
            if STS.STSConnectionStates[addrStr]['cSuite'] == 3:
                mySalsaSession = pysodium.randombytes(32)
                proposeResp = sts_utility.deconstructPropose(data)
                salsaMsg = self.genProposeSalsa(proposeResp['P'],
                                                proposeResp['C']['K_E'],
                                                mySalsaSession,
                                                self.myEncrypKey,
                                                self.mySignKey, self.myCert,
                                                self.myCertStatus)
                STS.STSConnectionStates[addrStr][
                    'session_key'] = mySalsaSession
                STS.STSConnectionStates[addrStr]['cSuite'] = proposeResp['P']
                STS.STSConnectionStates[addrStr]['time'] = int(time.time())

            elif STS.STSConnectionStates[addrStr]['cSuite'] in [4, 5]:
                STS.STSConnectionStates[addrStr]['phase'] = 1
                salsaMsg = self.constructSTSResponse(
                    1, addr, sts_utility.timestampPacked())
        else:
            proposeReq = sts_utility.deconstructPropose(data)
            if STS.STSConnectionStates[addrStr][
                    'cSuite'] == 3 and STS.STSConnectionStates[addrStr][
                        'phase'] == 0:
                # mySalsaSession = pysodium.randombytes(32)

                salsaMsg = self.genProposeSalsa(4, proposeReq['C']['K_E'],
                                                (0).to_bytes(32,
                                                             byteorder='big'),
                                                self.myEncrypKey,
                                                self.mySignKey, self.myCert,
                                                self.myCertStatus)
                STS.STSConnectionStates[addrStr]['session_key'] = (0).to_bytes(
                    32, byteorder='big')
                STS.STSConnectionStates[addrStr]['cSuite'] = 4
                STS.STSConnectionStates[addrStr]['time'] = int(time.time())
            elif STS.STSConnectionStates[addrStr]['cSuite'] in [
                    4, 5
            ] and STS.STSConnectionStates[addrStr]['phase'] == 0:
                session_key = self.decryptSalsaSession(proposeReq,
                                                       self.myEncrypKey)
                if not session_key:
                    salsaMsg = self.genProposeSalsa(
                        STS.STSConnectionStates[addrStr]['cSuite'],
                        proposeReq['C']['K_E'], (0).to_bytes(32,
                                                             byteorder='big'),
                        self.myEncrypKey, self.mySignKey, self.myCert,
                        self.myCertStatus)
                    STS.STSConnectionStates[addrStr]['session_key'] = (
                        0).to_bytes(32, byteorder='big')
                    STS.STSConnectionStates[addrStr][
                        'cSuite'] = STS.STSConnectionStates[addrStr]['cSuite']
                    STS.STSConnectionStates[addrStr]['time'] = int(time.time())
                else:
                    STS.STSConnectionStates[addrStr][
                        'session_key'] = session_key
                    # STS.STSConnectionStates[addrStr]['phase'] = 1
                    salsaMsg = self.genProposeSalsa(
                        4, proposeReq['C']['K_E'],
                        (0).to_bytes(32, byteorder='big'), self.myEncrypKey,
                        self.mySignKey, self.myCert, self.myCertStatus)
                    STS.STSConnectionStates[addrStr]['cSuite'] = proposeReq[
                        'P']
                    # STS.STSConnectionStates[addrStr]['phase'] = 1
                    STS.STSConnectionStates[addrStr]['time'] = int(time.time())
            # elif STS.STSConnectionStates[addrStr]['cSuite'] in [4, 5] and STS.STSConnectionStates[addrStr][
            #     'phase'] == 1:
            #     STS.STSConnectionStates[addrStr]['phase'] = 2
            #     salsaMsg = self.constructSTSResponse(1, addr, sts_utility.timestampPacked())
            # salsaMsg = self.constructSTSResponse(1, addr, sts_utility.timestampPacked())

        return salsaMsg