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())
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
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