1678 lines
58 KiB
Go
1678 lines
58 KiB
Go
|
|
||
|
// sendRequests provides functions for making requests to Seekia hosts
|
||
|
// Each function provides a way to send a server request to a host through an active connection
|
||
|
// This package is imported by queryHosts.
|
||
|
// queryHosts is a higher level package which provides functions to split requests up, to save retrieved data, and more
|
||
|
|
||
|
package sendRequests
|
||
|
|
||
|
//TODO: Add if request successful, remove host from unreachable list
|
||
|
|
||
|
//TODO: Verify that input does not exceed maximum size for request of that type
|
||
|
|
||
|
//TODO: Add ability to handle busy responses
|
||
|
// If host is busy, we will keep track of that in a new package and not try to recontact them for a while
|
||
|
|
||
|
import "seekia/internal/byteRange"
|
||
|
import "seekia/internal/encoding"
|
||
|
import "seekia/internal/helpers"
|
||
|
import "seekia/internal/identity"
|
||
|
import "seekia/internal/messaging/readMessages"
|
||
|
import "seekia/internal/moderation/readReports"
|
||
|
import "seekia/internal/moderation/readReviews"
|
||
|
import "seekia/internal/network/maliciousHosts"
|
||
|
import "seekia/internal/network/mateCriteria"
|
||
|
import "seekia/internal/network/peerClient"
|
||
|
import "seekia/internal/network/serverRequest"
|
||
|
import "seekia/internal/network/serverResponse"
|
||
|
import "seekia/internal/parameters/readParameters"
|
||
|
import "seekia/internal/profiles/readProfiles"
|
||
|
import "seekia/internal/readContent"
|
||
|
|
||
|
import "bytes"
|
||
|
import "errors"
|
||
|
import "slices"
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successsful
|
||
|
// -map[string]int64: Map of ParametersType -> Parameters broadcast time
|
||
|
// -error
|
||
|
func GetParametersInfoFromHost(connectionIdentifier [21]byte, hostIdentityHash [16]byte, networkType byte)(bool, map[string]int64, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetParametersInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetParametersInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetParametersInfo(hostIdentityHash, connectionKey, networkType)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, parametersInfoMap, err := serverResponse.ReadServerResponse_GetParametersInfo(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Host sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, parametersInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][]byte: List of parameters
|
||
|
// -error
|
||
|
func GetParametersFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
parametersTypesToRetrieveList []string)(bool, [][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetParametersFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetParametersFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetParameters(hostIdentityHash, connectionKey, networkType, parametersTypesToRetrieveList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, parametersList, err := serverResponse.ReadServerResponse_GetParameters(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, parametersBytes := range parametersList{
|
||
|
|
||
|
ableToRead, _, parametersNetworkType, _, parametersType, _, _, err := readParameters.ReadParameters(false, parametersBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
return false, errors.New("ReadServerResponse_GetParameters not verifying network parameters")
|
||
|
}
|
||
|
|
||
|
if (parametersNetworkType != networkType){
|
||
|
// We did not request parameters for this networkType.
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
isExpected := slices.Contains(parametersTypesToRetrieveList, parametersType)
|
||
|
if (isExpected == false){
|
||
|
// We did not request this parameters type. Response is malformed.
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, parametersList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[]serverResponse.ProfileInfoStruct: Profiles info map list
|
||
|
// -error
|
||
|
func GetProfilesInfoFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
profileTypeToRetrieve string,
|
||
|
rangeStart [16]byte,
|
||
|
rangeEnd [16]byte,
|
||
|
identityHashesList [][16]byte,
|
||
|
criteria []byte,
|
||
|
getNewestProfilesOnly bool,
|
||
|
getViewableProfilesOnly bool)(bool, []serverResponse.ProfileInfoStruct, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetProfilesInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetProfilesInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableProfileVersionsList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetProfilesInfo(hostIdentityHash, connectionKey, networkType, acceptableProfileVersionsList, profileTypeToRetrieve, rangeStart, rangeEnd, identityHashesList, criteria, getNewestProfilesOnly, getViewableProfilesOnly)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, profileInfoObjectsList, err := serverResponse.ReadServerResponse_GetProfilesInfo(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
// Now we verify received profile identity hashes fulfill request filters
|
||
|
|
||
|
// We use map to make sure that only 1 profile hash per identity is returned (if getNewestProfilesOnly == true)
|
||
|
// Map structure: Identity Hash -> Nothing
|
||
|
identitiesMap := make(map[[16]byte]struct{})
|
||
|
|
||
|
for _, profileInfoObject := range profileInfoObjectsList{
|
||
|
|
||
|
receivedProfileAuthor := profileInfoObject.ProfileAuthor
|
||
|
|
||
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(receivedProfileAuthor)
|
||
|
if (err != nil){
|
||
|
receivedProfileAuthorHex := encoding.EncodeBytesToHexString(receivedProfileAuthor[:])
|
||
|
return false, errors.New("ReadServerResponse_GetProfilesInfo not verifying profileInfoObject receivedProfileAuthor: " + receivedProfileAuthorHex)
|
||
|
}
|
||
|
|
||
|
if (identityType != profileTypeToRetrieve){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(identityHashesList) != 0){
|
||
|
identityIsInRequestedList := slices.Contains(identityHashesList, receivedProfileAuthor)
|
||
|
if (identityIsInRequestedList == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, receivedProfileAuthor)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (isWithinRange == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (getNewestProfilesOnly == true){
|
||
|
|
||
|
_, exists := identitiesMap[receivedProfileAuthor]
|
||
|
if (exists == true){
|
||
|
// We received two profiles with the same author in a getNewestProfilesOnly response.
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
identitiesMap[receivedProfileAuthor] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, profileInfoObjectsList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][]byte: List of profiles
|
||
|
// -error
|
||
|
func GetProfilesFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
profileTypeToRetrieve string,
|
||
|
profileHashesList [][28]byte,
|
||
|
expectedProfileIdentityHashesMap map[[28]byte][16]byte, // Profile Hash -> Profile Identity hash
|
||
|
expectedProfileBroadcastTimesMap map[[28]byte]int64, // Profile Hash -> Profile Broadcast Time
|
||
|
expectedCriteria []byte)(bool, [][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetProfilesFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetProfilesFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetProfiles(hostIdentityHash, connectionKey, networkType, profileTypeToRetrieve, profileHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, profilesList, err := serverResponse.ReadServerResponse_GetProfiles(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(profilesList) > len(profileHashesList)){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, profileBytes := range profilesList{
|
||
|
|
||
|
ableToRead, profileHash, profileVersion, profileNetworkType, profileIdentityHash, profileBroadcastTime, _, rawProfileMap, err := readProfiles.ReadProfileAndHash(false, profileBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
return false, errors.New("ReadServerResponse_GetProfiles not verifying received profile is valid.")
|
||
|
}
|
||
|
profileHashIsExpected := slices.Contains(profileHashesList, profileHash)
|
||
|
if (profileHashIsExpected == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
if (profileNetworkType != networkType){
|
||
|
// The host must have sent us a different networkType profile when we requested profilesInfo
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
expectedProfileIdentityHash, profileExists := expectedProfileIdentityHashesMap[profileHash]
|
||
|
if (profileExists == false){
|
||
|
return false, errors.New("ExpectedProfileIdentityHashesMap missing entry for profile contained in ProfileHashesList")
|
||
|
}
|
||
|
if (profileIdentityHash != expectedProfileIdentityHash){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
expectedProfileBroadcastTime, exists := expectedProfileBroadcastTimesMap[profileHash]
|
||
|
if (exists == false){
|
||
|
return false, errors.New("expectedProfileBroadcastTimesMap missing entry for profile contained in ProfileHashesList")
|
||
|
}
|
||
|
if (profileBroadcastTime != expectedProfileBroadcastTime){
|
||
|
// Profile is does not fulfill the expected BroadcastTime
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (expectedCriteria != nil){
|
||
|
|
||
|
criteriaIsValid, fulfillsCriteria, err := mateCriteria.CheckIfMateProfileFulfillsCriteria(false, profileVersion, rawProfileMap, expectedCriteria)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (criteriaIsValid == false){
|
||
|
return false, errors.New("GetProfilesFromHost called with invalid expectedCriteria")
|
||
|
}
|
||
|
if (fulfillsCriteria == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, profilesList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][26]byte: Received message hashes list
|
||
|
// -error
|
||
|
func GetMessageHashesListFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
rangeStart [10]byte,
|
||
|
rangeEnd [10]byte,
|
||
|
inboxesToRetrieveList [][10]byte,
|
||
|
getViewableMessagesOnly bool,
|
||
|
getDecryptableMessagesOnly bool)(bool, [][26]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetMessageHashesListFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetMessageHashesListFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableMessageVersionsList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageHashesList(hostIdentityHash, connectionKey, networkType, acceptableMessageVersionsList, rangeStart, rangeEnd, inboxesToRetrieveList, getViewableMessagesOnly, getDecryptableMessagesOnly)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, messageHashesList_Received, err := serverResponse.ReadServerResponse_GetMessageHashesList(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, messageHashesList_Received, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][]byte: List of messages
|
||
|
// -error
|
||
|
func GetMessagesFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
messageHashesList [][26]byte,
|
||
|
expectedInboxRangeStart [10]byte,
|
||
|
expectedInboxRangeEnd [10]byte,
|
||
|
expectedInboxesList [][10]byte)(bool, [][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetMessagesFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetMessagesFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessages(hostIdentityHash, connectionKey, networkType, messageHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, messagesList, err := serverResponse.ReadServerResponse_GetMessages(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, messageBytes := range messagesList{
|
||
|
|
||
|
ableToRead, messageHash, _, messageNetworkType, messageInbox, _, _, _, _, _, _, err := readMessages.ReadChatMessagePublicDataAndHash(false, messageBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
return false, errors.New("ReadServerResponse_GetMessages not verifying each message.")
|
||
|
}
|
||
|
|
||
|
isExpected := slices.Contains(messageHashesList, messageHash)
|
||
|
if (isExpected == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
if (messageNetworkType != networkType){
|
||
|
// Host must have sent us a different networkType messageHash when we got messageHashesList response
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(expectedInboxesList) != 0){
|
||
|
|
||
|
messageInboxIsExpected := slices.Contains(expectedInboxesList, messageInbox)
|
||
|
if (messageInboxIsExpected == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
} else {
|
||
|
|
||
|
inboxIsWithinRange, err := byteRange.CheckIfInboxIsWithinRange(expectedInboxRangeStart, expectedInboxRangeEnd, messageInbox)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (inboxIsWithinRange == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, messagesList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -map[[29]byte][]byte: Received reviews info map (Review Hash -> Reviewed Hash)
|
||
|
// -error
|
||
|
func GetIdentityReviewsInfoFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
identityTypeToRetrieve string,
|
||
|
rangeStart [16]byte,
|
||
|
rangeEnd [16]byte,
|
||
|
reviewedIdentityHashesList [][16]byte,
|
||
|
reviewersList [][16]byte)(bool, map[[29]byte][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetIdentityReviewsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetIdentityReviewsInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableReviewVersionList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetIdentityReviewsInfo(hostIdentityHash, connectionKey, networkType, acceptableReviewVersionList, identityTypeToRetrieve, rangeStart, rangeEnd, reviewedIdentityHashesList, reviewersList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsInfoMap, err := serverResponse.ReadServerResponse_GetIdentityReviewsInfo(responseBytes, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
// Now we verify received reviews info map fulfills request filters
|
||
|
|
||
|
for _, reviewedHash := range reviewsInfoMap{
|
||
|
|
||
|
// reviewedHash is either Profile hash or identity hash or attribute hash
|
||
|
|
||
|
reviewedHashType, err := helpers.GetReviewedTypeFromReviewedHash(reviewedHash)
|
||
|
if (err != nil) {
|
||
|
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
|
||
|
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedHashHex)
|
||
|
}
|
||
|
|
||
|
if (reviewedHashType != "Identity" && reviewedHashType != "Profile" && reviewedHashType != "Attribute"){
|
||
|
// Must be a message hash. Host is malicious.
|
||
|
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
|
||
|
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedHashHex)
|
||
|
}
|
||
|
|
||
|
if (reviewedHashType == "Identity"){
|
||
|
|
||
|
if (len(reviewedHash) != 16){
|
||
|
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
|
||
|
return false, errors.New("GetReviewedTypeFromReviewedHash returning Identity for different length reviewedHash: " + reviewedHashHex)
|
||
|
}
|
||
|
|
||
|
reviewedIdentityHash := [16]byte(reviewedHash)
|
||
|
|
||
|
if (len(reviewedIdentityHashesList) == 0){
|
||
|
|
||
|
// We only need to verify identityType if a reviewedHashesList was not requested
|
||
|
|
||
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(reviewedIdentityHash)
|
||
|
if (err != nil){
|
||
|
reviewedIdentityHashHex := encoding.EncodeBytesToHexString(reviewedIdentityHash[:])
|
||
|
return false, errors.New("GetReviewedTypeFromReviewedHash fails to verify identity hash: " + reviewedIdentityHashHex)
|
||
|
}
|
||
|
|
||
|
if (identityType != identityTypeToRetrieve){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, reviewedIdentityHash)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (isWithinRange == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(reviewedIdentityHashesList) != 0){
|
||
|
|
||
|
identityHashIsInRequestedList := slices.Contains(reviewedIdentityHashesList, reviewedIdentityHash)
|
||
|
if (identityHashIsInRequestedList == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
continue
|
||
|
|
||
|
} else if (reviewedHashType == "Profile"){
|
||
|
|
||
|
if (len(reviewedHash) != 28){
|
||
|
reviewedHashHex := encoding.EncodeBytesToHexString(reviewedHash)
|
||
|
return false, errors.New("GetReviewedTypeFromReviewedHash returning Profile for different length reviewedHash: " + reviewedHashHex)
|
||
|
}
|
||
|
|
||
|
reviewedProfileHash := [28]byte(reviewedHash)
|
||
|
|
||
|
if (len(reviewedIdentityHashesList) == 0){
|
||
|
|
||
|
// We only need to verify profileType if a reviewedIdentityHashesList was not requested
|
||
|
|
||
|
profileType, isDisabled, err := readProfiles.ReadProfileHashMetadata(reviewedProfileHash)
|
||
|
if (err != nil) {
|
||
|
reviewedProfileHashHex := encoding.EncodeBytesToHexString(reviewedProfileHash[:])
|
||
|
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: " + reviewedProfileHashHex)
|
||
|
}
|
||
|
if (isDisabled == true){
|
||
|
return false, errors.New("ReadServerResponse_GetReviewsInfo not verifying reviewsInfoMap reviewedHash: Profile hash is disabled.")
|
||
|
}
|
||
|
if (profileType != identityTypeToRetrieve){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reviewsInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -map[[29]byte][26]byte: Received reviews info map (Review Hash -> Reviewed Message Hash)
|
||
|
// -error
|
||
|
func GetMessageReviewsInfoFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
rangeStart [10]byte,
|
||
|
rangeEnd [10]byte,
|
||
|
reviewedMessageHashesList [][26]byte,
|
||
|
reviewersList [][16]byte)(bool, map[[29]byte][26]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetMessageReviewsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetMessageReviewsInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableReviewVersionList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageReviewsInfo(hostIdentityHash, connectionKey, networkType, acceptableReviewVersionList, rangeStart, rangeEnd, reviewedMessageHashesList, reviewersList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsInfoMap, err := serverResponse.ReadServerResponse_GetMessageReviewsInfo(responseBytes, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
// Now we verify received reviews info map fulfills request filters
|
||
|
|
||
|
for _, reviewedHash := range reviewsInfoMap{
|
||
|
|
||
|
// reviewedHash is a message hash
|
||
|
|
||
|
if (len(reviewedMessageHashesList) != 0){
|
||
|
|
||
|
messageHashIsInRequestedList := slices.Contains(reviewedMessageHashesList, reviewedHash)
|
||
|
if (messageHashIsInRequestedList == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reviewsInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][]byte: Retrieved list of reviews
|
||
|
// -error
|
||
|
func GetReviewsFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
reviewHashesList [][29]byte,
|
||
|
expectedReviewsInfoMap map[[29]byte][]byte, // Review Hash -> Reviewed Hash
|
||
|
expectedReviewersList [][16]byte)(bool, [][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetReviewsFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetReviewsFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetReviews(hostIdentityHash, connectionKey, networkType, reviewHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reviewsList, err := serverResponse.ReadServerResponse_GetReviews(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, reviewBytes := range reviewsList{
|
||
|
|
||
|
ableToRead, reviewHash, _, reviewNetworkType, authorIdentityHash, _, _, reviewReviewedHash, _, _, err := readReviews.ReadReviewAndHash(false, reviewBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
return false, errors.New("ReadServerResponse_GetReviews not verifying each review")
|
||
|
}
|
||
|
if (reviewNetworkType != networkType){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(expectedReviewersList) != 0){
|
||
|
|
||
|
isExpectedReviewer := slices.Contains(expectedReviewersList, authorIdentityHash)
|
||
|
if (isExpectedReviewer == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
expectedReviewedHash, exists := expectedReviewsInfoMap[reviewHash]
|
||
|
if (exists == false) {
|
||
|
// We received an unexpected reviewHash
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
areEqual := bytes.Equal(reviewReviewedHash, expectedReviewedHash)
|
||
|
if (areEqual == false){
|
||
|
// We received an unexpected reviewedHash for expected reviewHash
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reviewsList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -map[[30]byte][]byte: Reports info map (Report Hash -> Reported Hash)
|
||
|
// -error
|
||
|
func GetIdentityReportsInfoFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
identityTypeToRetrieve string,
|
||
|
rangeStart [16]byte,
|
||
|
rangeEnd [16]byte,
|
||
|
reportedIdentityHashesList [][16]byte)(bool, map[[30]byte][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetIdentityReportsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetIdentityReportsInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableReportVersionsList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetIdentityReportsInfo(hostIdentityHash, connectionKey, networkType, acceptableReportVersionsList, identityTypeToRetrieve, rangeStart, rangeEnd, reportedIdentityHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsInfoMap, err := serverResponse.ReadServerResponse_GetIdentityReportsInfo(responseBytes, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
// Now we verify received reports info map fulfills request filters
|
||
|
|
||
|
for _, reportedHash := range reportsInfoMap{
|
||
|
|
||
|
// reportedHash is either Profile hash or identity hash or Attribute hash
|
||
|
|
||
|
reportedType, err := helpers.GetReportedTypeFromReportedHash(reportedHash)
|
||
|
if (err != nil){
|
||
|
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
|
||
|
return false, errors.New("ReadServerResponse_GetReportsInfo not verifying reportedHash: " + reportedHashHex)
|
||
|
}
|
||
|
|
||
|
if (reportedType != "Identity" && reportedType != "Profile" && reportedType != "Attribute"){
|
||
|
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
|
||
|
return false, errors.New("ReadServerResponse_GetReportsInfo not verifying reportedHash: " + reportedHashHex)
|
||
|
}
|
||
|
|
||
|
if (reportedType == "Identity"){
|
||
|
|
||
|
if (len(reportedHash) != 16){
|
||
|
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
|
||
|
return false, errors.New("GetReportedTypeFromReportedHash returning Identity for different length reportedHash: " + reportedHashHex)
|
||
|
}
|
||
|
|
||
|
reportedIdentityHash := [16]byte(reportedHash)
|
||
|
|
||
|
if (len(reportedIdentityHashesList) == 0){
|
||
|
|
||
|
identityType, err := identity.GetIdentityTypeFromIdentityHash(reportedIdentityHash)
|
||
|
if (err != nil){
|
||
|
reportedIdentityHashHex := encoding.EncodeBytesToHexString(reportedIdentityHash[:])
|
||
|
return false, errors.New("GetReportedTypeFromReportedHash not verifying identityHash: " + reportedIdentityHashHex)
|
||
|
}
|
||
|
|
||
|
if (identityType != identityTypeToRetrieve){
|
||
|
// We only need to verify identityType if a reportedHashesList was not requested
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
isWithinRange, err := byteRange.CheckIfIdentityHashIsWithinRange(rangeStart, rangeEnd, reportedIdentityHash)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (isWithinRange == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (len(reportedIdentityHashesList) != 0){
|
||
|
identityHashIsInRequestedList := slices.Contains(reportedIdentityHashesList, reportedIdentityHash)
|
||
|
if (identityHashIsInRequestedList == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
continue
|
||
|
}
|
||
|
if (reportedType == "Profile"){
|
||
|
|
||
|
if (len(reportedHash) != 28){
|
||
|
reportedHashHex := encoding.EncodeBytesToHexString(reportedHash)
|
||
|
return false, errors.New("GetReportedTypeFromReportedHash returning Profile for different length reportedHash: " + reportedHashHex)
|
||
|
}
|
||
|
|
||
|
reportedProfileHash := [28]byte(reportedHash)
|
||
|
|
||
|
if (len(reportedIdentityHashesList) == 0){
|
||
|
|
||
|
// We only need to verify profileType if a reportedHashesList was not requested
|
||
|
|
||
|
profileType, isDisabled, err := readProfiles.ReadProfileHashMetadata(reportedProfileHash)
|
||
|
if (err != nil) {
|
||
|
return false, errors.New("GetReportedTypeFromReportedHash not verifying profileHash")
|
||
|
}
|
||
|
if (isDisabled == true){
|
||
|
return false, errors.New("GetReportedTypeFromReportedHash not verifying profileHash is not disabled.")
|
||
|
}
|
||
|
|
||
|
if (profileType != identityTypeToRetrieve){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reportsInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -map[[30]byte][26]byte: Reports info map (Report Hash -> Reported Message Hash)
|
||
|
// -error
|
||
|
func GetMessageReportsInfoFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
rangeStart [10]byte,
|
||
|
rangeEnd [10]byte,
|
||
|
reportedMessageHashesList [][26]byte)(bool, map[[30]byte][26]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetMessageReportsInfoFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetMessageReportsInfoFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
acceptableReportVersionsList := []int{1}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetMessageReportsInfo(hostIdentityHash, connectionKey, networkType, acceptableReportVersionsList, rangeStart, rangeEnd, reportedMessageHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseBytes, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsInfoMap, err := serverResponse.ReadServerResponse_GetMessageReportsInfo(responseBytes, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
// Now we verify received reports info map fulfills request filters
|
||
|
|
||
|
for _, reportedHash := range reportsInfoMap{
|
||
|
|
||
|
// reportedHash is a message hash
|
||
|
|
||
|
if (len(reportedMessageHashesList) != 0){
|
||
|
|
||
|
messageHashIsInRequestedList := slices.Contains(reportedMessageHashesList, reportedHash)
|
||
|
if (messageHashIsInRequestedList == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil){ return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reportsInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Download successful (could be unsuccessful because host keys not found, host is malicious, internet connection down, and more)
|
||
|
// -[][]byte: Retrieved list of reports
|
||
|
// -error
|
||
|
func GetReportsFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
reportHashesList [][30]byte,
|
||
|
expectedReportsInfoMap map[[30]byte][]byte)(bool, [][]byte, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("GetReportsFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("GetReportsFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetReports(hostIdentityHash, connectionKey, networkType, reportHashesList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, reportsList, err := serverResponse.ReadServerResponse_GetReports(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, reportBytes := range reportsList{
|
||
|
|
||
|
ableToRead, reportHash, _, reportNetworkType, _, _, reportReportedHash, _, err := readReports.ReadReportAndHash(false, reportBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
// Report is invalid, peer must be malicious.
|
||
|
return false, nil
|
||
|
}
|
||
|
if (reportNetworkType != networkType){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
expectedReportedHash, exists := expectedReportsInfoMap[reportHash]
|
||
|
if (exists == false) {
|
||
|
// We received an unexpected reportHash
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
areEqual := bytes.Equal(reportReportedHash, expectedReportedHash)
|
||
|
if (areEqual == false){
|
||
|
// We received an unexpected reportedHash for expected reportHash
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, reportsList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Outputs:
|
||
|
// -bool: Successful download
|
||
|
// -[]serverResponse.DepositStruct
|
||
|
// -[]string: List of addresses with no deposits
|
||
|
// -error
|
||
|
func GetAddressDepositsFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
cryptocurrency string,
|
||
|
cryptoAddressesList []string)(bool, []serverResponse.DepositStruct, []string, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, nil, errors.New("GetAddressDepositsFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, nil, errors.New("GetAddressDepositsFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetAddressDeposits(hostIdentityHash, connectionKey, networkType, cryptocurrency, cryptoAddressesList)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, addressDepositObjectsList, err := serverResponse.ReadServerResponse_GetAddressDeposits(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
// This map will store all addresses which have deposits
|
||
|
addressesWithDepositsMap := make(map[string]struct{})
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, depositObject := range addressDepositObjectsList{
|
||
|
|
||
|
depositAddress := depositObject.Address
|
||
|
|
||
|
addressExists := slices.Contains(cryptoAddressesList, depositAddress)
|
||
|
if (addressExists == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
addressesWithDepositsMap[depositAddress] = struct{}{}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Host sent invalid response, they must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
addressesWithoutDepositsList := make([]string, 0)
|
||
|
|
||
|
for _, cryptoAddress := range cryptoAddressesList{
|
||
|
|
||
|
_, exists := addressesWithDepositsMap[cryptoAddress]
|
||
|
if (exists == false){
|
||
|
addressesWithoutDepositsList = append(addressesWithoutDepositsList, cryptoAddress)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, addressDepositObjectsList, addressesWithoutDepositsList, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Inputs:
|
||
|
// -[21]byte: Connection Identifier
|
||
|
// -[16]byte: Host Identity Hash
|
||
|
// -byte: Network Type
|
||
|
// -[][16]byte: Identity hashes to retrieve viewable statuses for
|
||
|
// -[][28]byte: Profiles hashes to retrieve viewable statuses for
|
||
|
//Outputs:
|
||
|
// -bool: Successful download
|
||
|
// -map[[16]byte]bool: Identity Hash Statuses Map (Identity Hash -> true/false) (true = viewable, false = unviewable)
|
||
|
// -map[[28]byte]bool: Profile Hash Statuses Map (Profile Hash -> true/false) (true = viewable, false = unviewable)
|
||
|
// -error
|
||
|
func GetViewableStatusesFromHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
identityHashesList [][16]byte,
|
||
|
profileHashesList [][28]byte)(bool, map[[16]byte]bool, map[[28]byte]bool, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, nil, errors.New("GetViewableStatusesFromHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, nil, errors.New("GetViewableStatusesFromHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_GetViewableStatuses(hostIdentityHash, connectionKey, networkType, identityHashesList, profileHashesList)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, identityHashStatusesMap, profileHashStatusesMap, err := serverResponse.ReadServerResponse_GetViewableStatuses(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for identityHash, _ := range identityHashStatusesMap{
|
||
|
|
||
|
isRequestedIdentityHash := slices.Contains(identityHashesList, identityHash)
|
||
|
if (isRequestedIdentityHash == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for profileHash, _ := range profileHashStatusesMap{
|
||
|
|
||
|
isRequestedProfileHash := slices.Contains(profileHashesList, profileHash)
|
||
|
if (isRequestedProfileHash == false){
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, nil, err }
|
||
|
|
||
|
return false, nil, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, identityHashStatusesMap, profileHashStatusesMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
//Inputs:
|
||
|
// -[21]byte: Connection Identifier
|
||
|
// -[16]byte: Host Identity Hash
|
||
|
// -byte: Network Type
|
||
|
// -string: Content Type ("Profile"/"Message"/"Review"/"Report"/"Parameters")
|
||
|
// -[][]byte: Contents list
|
||
|
//Outputs:
|
||
|
// -bool: Successful download
|
||
|
// -map[string]bool: Received Content Accepted Info Map (Content Hash -> true/false)
|
||
|
// -error
|
||
|
func BroadcastContentToHost(
|
||
|
connectionIdentifier [21]byte,
|
||
|
hostIdentityHash [16]byte,
|
||
|
networkType byte,
|
||
|
contentType string,
|
||
|
contentList [][]byte)(bool, map[string]bool, error){
|
||
|
|
||
|
connectionExists, connectionHostIdentityHash, connectionKey, connectionNetworkType, err := peerClient.GetConnectionMetadata(connectionIdentifier)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (connectionExists == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
if (connectionHostIdentityHash != hostIdentityHash){
|
||
|
return false, nil, errors.New("BroadcastContentToHost called with hostIdentityHash which does not match connection metadata.")
|
||
|
}
|
||
|
if (connectionNetworkType != networkType){
|
||
|
return false, nil, errors.New("BroadcastContentToHost called with networkType which does not match connection metadata.")
|
||
|
}
|
||
|
|
||
|
requestBytes, requestIdentifier, err := serverRequest.CreateServerRequest_BroadcastContent(hostIdentityHash, connectionKey, networkType, contentType, contentList)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
requestSuccessful, responseData, err := peerClient.SendRequestThroughConnection(connectionIdentifier, requestBytes)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (requestSuccessful == false){
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
ableToRead, requestIdentifier_Received, hostIdentityHash_Received, contentAcceptedInfoMap, err := serverResponse.ReadServerResponse_BroadcastContent(responseData, connectionKey)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (ableToRead == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
// Now we check to make sure response is valid based on input request information
|
||
|
|
||
|
checkIfResponseIsValid := func()(bool, error){
|
||
|
|
||
|
if (requestIdentifier != requestIdentifier_Received){
|
||
|
// Host sent invalid response, must be malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
if (hostIdentityHash != hostIdentityHash_Received){
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
for _, contentBytes := range contentList{
|
||
|
|
||
|
ableToRead, contentHash, err := readContent.GetContentHashFromContentBytes(false, contentType, contentBytes)
|
||
|
if (err != nil) { return false, err }
|
||
|
if (ableToRead == false){
|
||
|
return false, errors.New("CreateServerRequest_BroadcastContent not verifying content is valid.")
|
||
|
}
|
||
|
|
||
|
_, exists := contentAcceptedInfoMap[string(contentHash)]
|
||
|
if (exists == false){
|
||
|
// Host did not tell us if they accepted the content
|
||
|
// Host is malicious
|
||
|
return false, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
responseIsValid, err := checkIfResponseIsValid()
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
if (responseIsValid == false){
|
||
|
// Peer sent invalid response, must be malicious
|
||
|
|
||
|
err := maliciousHosts.AddHostToMaliciousHostsList(hostIdentityHash)
|
||
|
if (err != nil) { return false, nil, err }
|
||
|
|
||
|
return false, nil, nil
|
||
|
}
|
||
|
|
||
|
return true, contentAcceptedInfoMap, nil
|
||
|
}
|
||
|
|
||
|
|
||
|
|