// serverRequest provides functions to create and read server requests // These are MessagePack encoded requests sent to Seekia hosts package serverRequest // Each encrypted request has a RequestTime and a RequestIdentifier // RequestTime ensures an attacker cannot replay a request and compare the response size to gain information // The host will reject any requests with a requestTime that is too old // RequestIdentifier is random for each request and ensures that the response is intended for the specific request // Otherwise, a man-in-the-middle attacker could replay old requests created during the same connection, to trick the requestor // For example, the requestor could make a GetProfilesInfo request, get a response A, and later make a different GetProfilesInfo request // The attacker could replay response A, and the requestor would wrongly designate the host as malicious (for providing invalid information) // Request Identifiers prevent this attack // Acceptable versions is a []int that describes the acceptable versions of profiles/messages/reviews/reports that the requestor can read // As new versions are created, different hosts and clients will only be able to read certain versions of content // This list allows hosts and clients who have not upgraded to newer versions to continue serving/downloading content on the network // See a description of each request and its purpose in Specification.md //TODO: Add GetFundedStatuses // Will be used to get the identity/profile IsFunded statuses from hosts // This will lessen the load on the credit account servers // We don't need this for messages, because we will always retrieve their fundedStatuses directly from the credits servers // Retrieving them from hosts is a privacy risk, and will take too long to retrieve individually import "seekia/internal/cryptography/chaPolyShrink" import "seekia/internal/encoding" import "seekia/internal/helpers" import "seekia/internal/readContent" import messagepack "github.com/vmihailenco/msgpack/v5" import "crypto/rand" import "time" import "errors" func getNewRequestIdentifier()([16]byte, error){ var identifierArray [16]byte _, err := rand.Read(identifierArray[:]) if (err != nil) { return [16]byte{}, err } return identifierArray, nil } func verifyAcceptableVersionsList(inputList []int)error{ // We use this map to detect duplicates versionsMap := make(map[int]struct{}) for _, versionInt := range inputList{ if (versionInt < 1 || versionInt > 500){ return errors.New("Acceptable versions list is invalid: Version int is not valid.") } _, exists := versionsMap[versionInt] if (exists == true){ return errors.New("Acceptable versions list is invalid: Duplicate exists.") } versionsMap[versionInt] = struct{}{} } return nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_EstablishConnectionKey(hostIdentityHash [16]byte, networkType byte, requestorNaclPublicKey [32]byte, requestorKyberPublicKey [1568]byte)([]byte, [16]byte, error){ requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } type requestContentStruct struct{ RequestVersion int RequestIdentifier [16]byte RequestType string RecipientHost [16]byte NetworkType byte RequestorNaclKey [32]byte RequestorKyberKey [1568]byte } requestContentObject := requestContentStruct{ RequestVersion: 1, RequestIdentifier: requestIdentifier, RequestType: "EstablishConnectionKey", RecipientHost: hostIdentityHash, NetworkType: networkType, RequestorNaclKey: requestorNaclPublicKey, RequestorKyberKey: requestorKyberPublicKey, } finalRequest, err := encoding.EncodeMessagePackBytes(requestContentObject) if (err != nil) { return nil, [16]byte{}, err } return finalRequest, requestIdentifier, nil } //Outputs: // -[16]byte: Host identity being requested from // -[16]byte: Request identifier // -byte: Network type // -[32]byte: Requestor Nacl Key // -[1568]byte: Requestor Kyber Key // -error func ReadServerRequest_EstablishConnectionKey(inputRequestBytes []byte)([16]byte, [16]byte, byte, [32]byte, [1568]byte, error){ //TODO: Verify everything type requestContentStruct struct{ RequestIdentifier [16]byte RequestType string RecipientHost [16]byte NetworkType byte RequestorNaclKey [32]byte RequestorKyberKey [1568]byte } var requestContentObject requestContentStruct err := encoding.DecodeMessagePackBytes(false, inputRequestBytes, &requestContentObject) if (err != nil) { return [16]byte{}, [16]byte{}, 0, [32]byte{}, [1568]byte{}, err } requestIdentifier := requestContentObject.RequestIdentifier requestType := requestContentObject.RequestType recipientHostIdentityHash := requestContentObject.RecipientHost networkType := requestContentObject.NetworkType requestorNaclKey := requestContentObject.RequestorNaclKey requestorKyberKey := requestContentObject.RequestorKyberKey if (requestType != "EstablishConnectionKey"){ return [16]byte{}, [16]byte{}, 0, [32]byte{}, [1568]byte{}, errors.New("Request is not EstablishConnectionKey") } return recipientHostIdentityHash, requestIdentifier, networkType, requestorNaclKey, requestorKyberKey, nil } //TODO: Deal with parameters versions somehow //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetParametersInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte)([]byte, [16]byte, error){ //TODO: Verify inputs requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetParametersInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetParameters(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, parametersTypesList []string)([]byte, [16]byte, error){ //TODO: Verify inputs if (len(parametersTypesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetParameters called with invalid parametersTypesList: Empty list") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte ParametersTypesList []string } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetParameters", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, ParametersTypesList: parametersTypesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]string: Parameters types list // -error func ReadDecryptedServerRequest_GetParameters(decryptedRequestBytes []byte)([]string, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string ParametersTypesList []string } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(false, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType parametersTypesList := decryptedRequestObject.ParametersTypesList if (requestVersion != 1){ return nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetParameters"){ return nil, errors.New("Invalid request: requestType not GetParameters") } //TODO: Verify everything return parametersTypesList, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetProfilesInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, profileTypeToRetrieve string, rangeStart [16]byte, rangeEnd [16]byte, identityHashesList [][16]byte, criteria []byte, getNewestOnly bool, getViewableOnly bool)([]byte, [16]byte, error){ //TODO: Verify inputs if (profileTypeToRetrieve != "Mate" && profileTypeToRetrieve != "Host" && profileTypeToRetrieve != "Moderator"){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetProfilesInfo called with invalid profileTypeToRetrieve: " + profileTypeToRetrieve) } err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int ProfileType string GetNewestOnly bool GetViewableOnly bool IdentityHashesList [][16]byte RangeStart [16]byte RangeEnd [16]byte Criteria []byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetProfilesInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, ProfileType: profileTypeToRetrieve, GetNewestOnly: getNewestOnly, GetViewableOnly: getViewableOnly, IdentityHashesList: identityHashesList, RangeStart: rangeStart, RangeEnd: rangeEnd, } if (profileTypeToRetrieve == "Mate"){ innerRequestObject.Criteria = criteria } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable versions list // -string: Profile Type To Retrieve // -[16]byte: Range Start // -[16]byte: Range End // -[][16]byte: Identity hashes list // -[]byte: Criteria // -bool: Get Newest profiles only // -bool: Get Viewable profiles only // -error func ReadDecryptedServerRequest_GetProfilesInfo(decryptedRequestBytes []byte)([]int, string, [16]byte, [16]byte, [][16]byte, []byte, bool, bool, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int ProfileType string IdentityHashesList [][16]byte RangeStart [16]byte RangeEnd [16]byte Criteria []byte GetNewestOnly bool GetViewableOnly bool } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(false, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, "", [16]byte{}, [16]byte{}, nil, nil, false, false, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions profileTypeToRetrieve := decryptedRequestObject.ProfileType identityHashesList := decryptedRequestObject.IdentityHashesList rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd getNewestOnly := decryptedRequestObject.GetNewestOnly getViewableOnly := decryptedRequestObject.GetViewableOnly if (requestVersion != 1){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, false, false, errors.New("Invalid request: Unknown requestVersion") } if (requestType != "GetProfilesInfo"){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, false, false, errors.New("Invalid request: requestType not GetProfilesInfo") } err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, false, false, err } //TODO: Verify everything getProfileCriteria := func()([]byte, error){ if (profileTypeToRetrieve != "Mate"){ return nil, nil } criteria := decryptedRequestObject.Criteria return criteria, nil } profileCriteria, err := getProfileCriteria() if (err != nil) { return nil, "", [16]byte{}, [16]byte{}, nil, nil, false, false, err } return acceptableVersionsList, profileTypeToRetrieve, rangeStart, rangeEnd, identityHashesList, profileCriteria, getNewestOnly, getViewableOnly, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetProfiles(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, profileTypeToRetrieve string, profileHashesList [][28]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (profileTypeToRetrieve != "Mate" && profileTypeToRetrieve != "Host" && profileTypeToRetrieve != "Moderator"){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetProfiles called with invalid profileTypeToRetrieve: " + profileTypeToRetrieve) } if (len(profileHashesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetProfiles called with empty profileHashesList.") } containsDuplicates, _ := helpers.CheckIfListContainsDuplicates(profileHashesList) if (containsDuplicates == true){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetProfiles called with profileHashesList containing duplicates.") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte ProfileType string ProfileHashesList [][28]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetProfiles", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, ProfileType: profileTypeToRetrieve, ProfileHashesList: profileHashesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -string: Profile Type To Retrieve // -[][28]byte: Profile hashes list // -error func ReadDecryptedServerRequest_GetProfiles(decryptedRequestBytes []byte)(string, [][28]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string ProfileType string ProfileHashesList [][28]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(false, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return "", nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType profileTypeToRetrieve := decryptedRequestObject.ProfileType profileHashesList := decryptedRequestObject.ProfileHashesList if (requestVersion != 1){ return "", nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetProfiles"){ return "", nil, errors.New("Invalid request: requestType not GetProfiles") } //TODO: Verify everything return profileTypeToRetrieve, profileHashesList, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetMessageHashesList(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, rangeStart [10]byte, rangeEnd [10]byte, inboxesList [][10]byte, getViewableOnly bool, getDecryptableOnly bool)([]byte, [16]byte, error){ //TODO: Verify inputs err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int GetViewableOnly bool GetDecryptableOnly bool RangeStart [10]byte RangeEnd [10]byte InboxesList [][10]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetMessageHashesList", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, GetViewableOnly: getViewableOnly, GetDecryptableOnly: getDecryptableOnly, RangeStart: rangeStart, RangeEnd: rangeEnd, InboxesList: inboxesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable versions list // -[10]byte: Inbox Range Start // -[10]byte: Inbox Range End // -[][10]byte: Inboxes list // -bool: Get Viewable messages only // -bool: Get Decryptable messages only // -error func ReadDecryptedServerRequest_GetMessageHashesList(decryptedRequestBytes []byte)([]int, [10]byte, [10]byte, [][10]byte, bool, bool, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int InboxesList [][10]byte RangeStart [10]byte RangeEnd [10]byte GetViewableOnly bool GetDecryptableOnly bool } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(false, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, [10]byte{}, [10]byte{}, nil, false, false, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions inboxesList := decryptedRequestObject.InboxesList rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd getViewableOnly := decryptedRequestObject.GetViewableOnly getDecryptableOnly := decryptedRequestObject.GetDecryptableOnly if (requestVersion != 1){ return nil, [10]byte{}, [10]byte{}, nil, false, false, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetMessageHashesList"){ return nil, [10]byte{}, [10]byte{}, nil, false, false, errors.New("Invalid request: requestType not GetMessageHashesList") } err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, [10]byte{}, [10]byte{}, nil, false, false, err } //TODO: Verify everything return acceptableVersionsList, rangeStart, rangeEnd, inboxesList, getViewableOnly, getDecryptableOnly, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetMessages(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, messageHashesList [][26]byte)([]byte, [16]byte, error){ //TODO: Verify inputs containsDuplicate, _ := helpers.CheckIfListContainsDuplicates(messageHashesList) if (containsDuplicate == true){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetMessages called with messageHashesList containing duplicates.") } if (len(messageHashesList) == 0){ return nil, [16]byte{}, errors.New("Invalid messageHashesList: Empty list") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte MessageHashesList [][26]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetMessages", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, MessageHashesList: messageHashesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[][26]byte: Message Hashes List // -error func ReadDecryptedServerRequest_GetMessages(decryptedRequestBytes []byte)([][26]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string MessageHashesList [][26]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType messageHashesList := decryptedRequestObject.MessageHashesList if (requestVersion != 1){ return nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetMessages"){ return nil, errors.New("Invalid request: requestType not GetMessages") } //TODO: Verify everything return messageHashesList, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetIdentityReviewsInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, identityTypeToRetrieve string, rangeStart [16]byte, rangeEnd [16]byte, reviewedIdentityHashesList [][16]byte, // A list of identity hashes reviewersList [][16]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (identityTypeToRetrieve != "Mate" && identityTypeToRetrieve != "Host" && identityTypeToRetrieve != "Moderator"){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetIdentityReviewsInfo called with invalid identityTypeToRetrieve: " + identityTypeToRetrieve) } err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int IdentityType string ReviewedIdentitiesList [][16]byte ReviewersList [][16]byte RangeStart [16]byte RangeEnd [16]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetIdentityReviewsInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, IdentityType: identityTypeToRetrieve, ReviewedIdentitiesList: reviewedIdentityHashesList, ReviewersList: reviewersList, RangeStart: rangeStart, RangeEnd: rangeEnd, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable review versions // -string: IdentityType // -[16]byte: Range Start // -[16]byte: Range End // -[][16]byte: Reviewed identity hashes list (If empty, ignore) // -[][16]byte: Reviewers list (identity hashes of reviewers) // -error func ReadDecryptedServerRequest_GetIdentityReviewsInfo(decryptedRequestBytes []byte)([]int, string, [16]byte, [16]byte, [][16]byte, [][16]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int ReviewedIdentitiesList [][16]byte ReviewersList [][16]byte IdentityType string RangeStart [16]byte RangeEnd [16]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, "", [16]byte{}, [16]byte{}, nil, nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions reviewedIdentityHashesList := decryptedRequestObject.ReviewedIdentitiesList reviewersList := decryptedRequestObject.ReviewersList identityType := decryptedRequestObject.IdentityType rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd if (requestVersion != 1){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetIdentityReviewsInfo"){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, errors.New("Invalid request: requestType not GetIdentityReviewsInfo") } err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, "", [16]byte{}, [16]byte{}, nil, nil, err } //TODO: Verify everything return acceptableVersionsList, identityType, rangeStart, rangeEnd, reviewedIdentityHashesList, reviewersList, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetMessageReviewsInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, rangeStart [10]byte, rangeEnd [10]byte, reviewedMessageHashesList [][26]byte, reviewersList [][16]byte)([]byte, [16]byte, error){ //TODO: Verify inputs err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int ReviewedMessagesList [][26]byte ReviewersList [][16]byte RangeStart [10]byte RangeEnd [10]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetMessageReviewsInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, ReviewedMessagesList: reviewedMessageHashesList, ReviewersList: reviewersList, RangeStart: rangeStart, RangeEnd: rangeEnd, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable review versions // -[10]byte: Range Start // -[10]byte: Range End // -[][26]byte: Reviewed hashes list (A list of message hashes) // -[][16]byte: Reviewers list (identity hashes of reviewers) // -error func ReadDecryptedServerRequest_GetMessageReviewsInfo(decryptedRequestBytes []byte)([]int, [10]byte, [10]byte, [][26]byte, [][16]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int ReviewedMessagesList [][26]byte ReviewersList [][16]byte RangeStart [10]byte RangeEnd [10]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, [10]byte{}, [10]byte{}, nil, nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions reviewedMessageHashesList := decryptedRequestObject.ReviewedMessagesList reviewersList := decryptedRequestObject.ReviewersList rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd if (requestVersion != 1){ return nil, [10]byte{}, [10]byte{}, nil, nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetMessageReviewsInfo"){ return nil, [10]byte{}, [10]byte{}, nil, nil, errors.New("Invalid request: requestType not GetMessageReviewsInfo") } err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, [10]byte{}, [10]byte{}, nil, nil, err } //TODO: Verify everything return acceptableVersionsList, rangeStart, rangeEnd, reviewedMessageHashesList, reviewersList, nil } //Outputs: // -[]byte: Request Bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetReviews(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, reviewHashesList [][29]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (len(reviewHashesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetReviews called with empty reviewHashesList") } containsDuplicate, _ := helpers.CheckIfListContainsDuplicates(reviewHashesList) if (containsDuplicate == true){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetReviews called with reviewHashesList containing duplicates.") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte ReviewHashesList [][29]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetReviews", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, ReviewHashesList: reviewHashesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[][29]byte: Review Hashes List // -error func ReadDecryptedServerRequest_GetReviews(decryptedRequestBytes []byte)([][29]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string ReviewHashesList [][29]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType reviewHashesList := decryptedRequestObject.ReviewHashesList if (requestVersion != 1){ return nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetReviews"){ return nil, errors.New("Invalid request: requestType not GetReviews") } //TODO: Verify review hashes list return reviewHashesList, nil } //Outputs: // -[]byte: Request bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetIdentityReportsInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, identityTypeToRetrieve string, rangeStart [16]byte, rangeEnd [16]byte, reportedIdentityHashesList [][16]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (identityTypeToRetrieve != "Mate" && identityTypeToRetrieve != "Host" && identityTypeToRetrieve != "Moderator"){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetIdentityReportsInfo called with invalid identityTypeToRetrieve: " + identityTypeToRetrieve) } err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int IdentityType string ReportedIdentitiesList [][16]byte RangeStart [16]byte RangeEnd [16]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetIdentityReportsInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, ReportedIdentitiesList: reportedIdentityHashesList, RangeStart: rangeStart, RangeEnd: rangeEnd, IdentityType: identityTypeToRetrieve, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable versions list // -string: IdentityType // -[16]byte: Range Start // -[16]byte: Range End // -[][16]byte: Reported identity hashes list // -error func ReadDecryptedServerRequest_GetIdentityReportsInfo(decryptedRequestBytes []byte)([]int, string, [16]byte, [16]byte, [][16]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int IdentityType string ReportedIdentitiesList [][16]byte RangeStart [16]byte RangeEnd [16]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, "", [16]byte{}, [16]byte{}, nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions identityTypeToRetrieve := decryptedRequestObject.IdentityType reportedIdentitiesList := decryptedRequestObject.ReportedIdentitiesList rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd if (requestVersion != 1){ return nil, "", [16]byte{}, [16]byte{}, nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetIdentityReportsInfo"){ return nil, "", [16]byte{}, [16]byte{}, nil, errors.New("Invalid request: requestType not GetIdentityReportsInfo: " + requestType) } //TODO: Verify everything err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, "", [16]byte{}, [16]byte{}, nil, err } return acceptableVersionsList, identityTypeToRetrieve, rangeStart, rangeEnd, reportedIdentitiesList, nil } //Outputs: // -[]byte: Request bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetMessageReportsInfo(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, acceptableVersionsList []int, rangeStart [10]byte, rangeEnd [10]byte, reportedMessageHashesList [][26]byte)([]byte, [16]byte, error){ //TODO: Verify inputs err := verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil) { return nil, [16]byte{}, err } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte AcceptableVersions []int ReportedMessagesList [][26]byte RangeStart [10]byte RangeEnd [10]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetMessageReportsInfo", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, AcceptableVersions: acceptableVersionsList, ReportedMessagesList: reportedMessageHashesList, RangeStart: rangeStart, RangeEnd: rangeEnd, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[]int: Acceptable versions list // -[10]byte: Range Start // -[10]byte: Range End // -[][26]byte: Reported message hashes list // -error func ReadDecryptedServerRequest_GetMessageReportsInfo(decryptedRequestBytes []byte)([]int, [10]byte, [10]byte, [][26]byte, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string AcceptableVersions []int ReportedMessagesList [][26]byte RangeStart [10]byte RangeEnd [10]byte } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, [10]byte{}, [10]byte{}, nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType acceptableVersionsList := decryptedRequestObject.AcceptableVersions reportedMessagesList := decryptedRequestObject.ReportedMessagesList rangeStart := decryptedRequestObject.RangeStart rangeEnd := decryptedRequestObject.RangeEnd if (requestVersion != 1){ return nil, [10]byte{}, [10]byte{}, nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetMessageReportsInfo"){ return nil, [10]byte{}, [10]byte{}, nil, errors.New("Invalid request: requestType not GetMessageReportsInfo: " + requestType) } //TODO: Verify everything err = verifyAcceptableVersionsList(acceptableVersionsList) if (err != nil){ return nil, [10]byte{}, [10]byte{}, nil, err } return acceptableVersionsList, rangeStart, rangeEnd, reportedMessagesList, nil } //Outputs: // -[]byte: Request bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetReports(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, reportHashesList [][30]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (reportHashesList == nil){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetReports called with nil reportHashesList") } if (len(reportHashesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetReports called with empty reportHashesList") } containsDuplicate, _ := helpers.CheckIfListContainsDuplicates(reportHashesList) if (containsDuplicate == true){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetReports called with reportHashesList containing duplicates.") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte ReportHashesList [][30]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetReports", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, ReportHashesList: reportHashesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[][30]byte: Report Hashes List // -error func ReadDecryptedServerRequest_GetReports(decryptedRequestBytes []byte)([][30]byte, error){ type innerRequestStruct struct{ RequestVersion int RequestType string ReportHashesList [][30]byte } var innerRequestObject innerRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &innerRequestObject) if (err != nil) { return nil, err } requestVersion := innerRequestObject.RequestVersion requestType := innerRequestObject.RequestType reportHashesList := innerRequestObject.ReportHashesList if (requestVersion != 1){ return nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetReports"){ return nil, errors.New("Invalid request: requestType not GetReports: " + requestType) } //TODO: Verify reportHashesList return reportHashesList, nil } //Outputs: // -[]byte: Request bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetAddressDeposits(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, cryptocurrencyName string, addressesList []string)([]byte, [16]byte, error){ //TODO: Verify inputs if (cryptocurrencyName != "Ethereum" && cryptocurrencyName != "Cardano"){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetAddressDeposits called with invalid cryptocurrencyName: " + cryptocurrencyName) } if (len(addressesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetAddressDeposits called with empty addressesList.") } containsDuplicates, _ := helpers.CheckIfListContainsDuplicates(addressesList) if (containsDuplicates == true){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetAddressDeposits called with addressesList containing duplicates.") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte Cryptocurrency string AddressesList []string } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetAddressDeposits", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, Cryptocurrency: cryptocurrencyName, AddressesList: addressesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -string: Cryptocurrency // -[]string: Addresses list // -error func ReadDecryptedServerRequest_GetAddressDeposits(decryptedRequestBytes []byte)(string, []string, error){ type decryptedRequestStruct struct{ RequestVersion int RequestType string Cryptocurrency string AddressesList []string } var decryptedRequestObject decryptedRequestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return "", nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType cryptocurrency := decryptedRequestObject.Cryptocurrency addressesList := decryptedRequestObject.AddressesList if (requestVersion != 1){ return "", nil, errors.New("Invalid request: Unknown requestVersion.") } if (requestType != "GetAddressDeposits"){ return "", nil, errors.New("Invalid request: requestType not GetAddressDeposits: " + requestType) } //TODO: Verify everything return cryptocurrency, addressesList, nil } // The reason we don't need a Messages option is because hosts will always use verifiedStickyStatuses when hosting messages // A user would never need to know the banned status of a message they have received // The message could not be banned unless the sender or recipient reported the message // The recipient will only care if the identity is banned, not the message //Outputs: // -[]byte: Request bytes // -[16]byte: Request identifier // -error func CreateServerRequest_GetViewableStatuses(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, identityHashesList [][16]byte, profileHashesList [][28]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (len(identityHashesList) == 0 && len(profileHashesList) == 0){ return nil, [16]byte{}, errors.New("CreateServerRequest_GetViewableStatuses called when identity hashes list and profile hashes list are both empty.") } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type innerRequestStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte IdentityHashesList [][16]byte ProfileHashesList [][28]byte } innerRequestObject := innerRequestStruct{ RequestVersion: 1, RequestType: "GetViewableStatuses", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, IdentityHashesList: identityHashesList, ProfileHashesList: profileHashesList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(innerRequestObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -[][16]byte: Identity Hashes List // -[][28]byte: Profile hashes list // -error func ReadDecryptedServerRequest_GetViewableStatuses(decryptedRequestBytes []byte)([][16]byte, [][28]byte, error){ type requestStruct struct{ RequestVersion int RequestType string IdentityHashesList [][16]byte ProfileHashesList [][28]byte } var decryptedRequestObject requestStruct err := encoding.DecodeMessagePackBytes(true, decryptedRequestBytes, &decryptedRequestObject) if (err != nil) { return nil, nil, err } requestVersion := decryptedRequestObject.RequestVersion requestType := decryptedRequestObject.RequestType identityHashesList := decryptedRequestObject.IdentityHashesList profileHashesList := decryptedRequestObject.ProfileHashesList if (requestVersion != 1){ return nil, nil, errors.New("Invalid request: Unknown request version.") } if (requestType != "GetViewableStatuses"){ return nil, nil, errors.New("Invalid request: requestType not GetViewableStatuses: " + requestType) } //TODO: Verify everything if (len(identityHashesList) == 0 && len(profileHashesList) == 0){ return nil, nil, errors.New("GetViewableStatuses request contains empty identityHashesList and profileHashesList") } return identityHashesList, profileHashesList, nil } //Outputs: // -[]byte: Final Request // -[16]byte: Request identifier // -error func CreateServerRequest_BroadcastContent(hostIdentityHash [16]byte, connectionKey [32]byte, networkType byte, contentType string, contentToBroadcastList [][]byte)([]byte, [16]byte, error){ //TODO: Verify inputs if (contentType != "Profile" && contentType != "Message" && contentType != "Review" && contentType != "Report" && contentType != "Parameters"){ return nil, [16]byte{}, errors.New("CreateServerRequest_BroadcastContent called with invalid contentType: " + contentType) } if (len(contentToBroadcastList) == 0){ return nil, [16]byte{}, errors.New("Empty contentToBroadcast list") } messagepackContentList := make([]messagepack.RawMessage, 0, len(contentToBroadcastList)) for _, contentBytes := range contentToBroadcastList{ messagepackContentList = append(messagepackContentList, contentBytes) } requestIdentifier, err := getNewRequestIdentifier() if (err != nil) { return nil, [16]byte{}, err } currentTime := time.Now().Unix() type requestContentStruct struct{ RequestVersion int RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte ContentType string ContentList []messagepack.RawMessage } requestContentObject := requestContentStruct{ RequestVersion: 1, RequestType: "BroadcastContent", RequestTime: currentTime, RequestIdentifier: requestIdentifier, RecipientHost: hostIdentityHash, NetworkType: networkType, ContentType: contentType, ContentList: messagepackContentList, } innerRequestBytes, err := encoding.EncodeMessagePackBytes(requestContentObject) if (err != nil) { return nil, [16]byte{}, err } finalEncryptedRequest, err := createEncryptedRequest(connectionKey, innerRequestBytes) if (err != nil) { return nil, [16]byte{}, err } return finalEncryptedRequest, requestIdentifier, nil } //Outputs: // -string: Content Type // -[][]byte: Content list // -error func ReadDecryptedServerRequest_BroadcastContent(decryptedMessagePackBytes []byte)(string, [][]byte, error){ type requestContentStruct struct{ RequestVersion int RequestType string ContentType string ContentList []messagepack.RawMessage } var requestContentObject requestContentStruct err := encoding.DecodeMessagePackBytes(true, decryptedMessagePackBytes, &requestContentObject) if (err != nil) { return "", nil, err } requestVersion := requestContentObject.RequestVersion requestType := requestContentObject.RequestType contentType := requestContentObject.ContentType messagepackContentList := requestContentObject.ContentList if (requestVersion != 1){ return "", nil, errors.New("Invalid request: Unknown request version.") } if (requestType != "BroadcastContent"){ return "", nil, errors.New("Invalid request: requestType not BroadcastContent: " + requestType) } if (contentType != "Profile" && contentType != "Message" && contentType != "Review" && contentType != "Report" && contentType != "Parameters"){ return "", nil, errors.New("Invalid BroadcastContent request: Invalid contentType: " + contentType) } //TODO: Verify everything // We use the map below to ensure we only received each piece of content once receivedContentHashesMap := make(map[string]struct{}) contentList := make([][]byte, 0, len(messagepackContentList)) for _, contentBytes := range messagepackContentList{ ableToRead, contentHash, err := readContent.GetContentHashFromContentBytes(true, contentType, contentBytes) if (err != nil) { return "", nil, err } if (ableToRead == false){ // Requestor sent invalid content. Requestor is malicious. return "", nil, errors.New("Invalid BroadcastContent request: Invalid " + contentType) } _, exists := receivedContentHashesMap[string(contentHash)] if (exists == true){ // We received a duplicate content hash. Requestor is malicious. return "", nil, errors.New("Invalid BroadcastContent request: received duplicate content hash") } receivedContentHashesMap[string(contentHash)] = struct{}{} contentList = append(contentList, contentBytes) } if (len(contentList) == 0){ return "", nil, errors.New("Invalid BroadcastContent request: Empty content list") } return contentType, contentList, nil } // This function will read the standard fields that are contained within all encrypted requests //Outputs: // -[16]byte: Request recipient host // -string: Request Type // -[16]byte: Request Identifier // -byte: Network Type // -error func ReadDecryptedServerRequest_StandardData(decryptedMessagePackBytes []byte)([16]byte, string, [16]byte, byte, error){ type standardRequestContentStruct struct{ RequestType string RequestTime int64 RequestIdentifier [16]byte RecipientHost [16]byte NetworkType byte } var standardRequestContentObject standardRequestContentStruct err := encoding.DecodeMessagePackBytes(true, decryptedMessagePackBytes, &standardRequestContentObject) if (err != nil) { return [16]byte{}, "", [16]byte{}, 0, err } //TODO: Verify everything requestType := standardRequestContentObject.RequestType recipientHost := standardRequestContentObject.RecipientHost requestIdentifier := standardRequestContentObject.RequestIdentifier requestTime := standardRequestContentObject.RequestTime networkType := standardRequestContentObject.NetworkType currentTime := time.Now().Unix() timePassed := currentTime - requestTime if (timePassed > 3600){ //Request has timed out, probably sent by malicious party return [16]byte{}, "", [16]byte{}, 0, errors.New(requestType + " Request has timed out.") } return recipientHost, requestType, requestIdentifier, networkType, nil } func createEncryptedRequest(connectionKey [32]byte, contentToEncrypt []byte)([]byte, error){ chaPolyNonce, err := helpers.GetNewRandom24ByteArray() if (err != nil) { return nil, err } cipheredContent, err := chaPolyShrink.EncryptChaPolyShrink(contentToEncrypt, connectionKey, chaPolyNonce, true, 1000, false, [32]byte{}) if (err != nil) { return nil, err } type encryptedRequestStruct struct{ ChaPolyNonce [24]byte CipheredContent []byte } encryptedRequestObject := encryptedRequestStruct{ ChaPolyNonce: chaPolyNonce, CipheredContent: cipheredContent, } encryptedRequestBytes, err := encoding.EncodeMessagePackBytes(encryptedRequestObject) if (err != nil) { return nil, err } return encryptedRequestBytes, nil } //Outputs: // -bool: Request is well formed and able to decrypt // -[]byte: Decrypted request messagePack // -error (decryption key inputs are malformed) func ReadEncryptedRequest(inputRequest []byte, connectionKey [32]byte)(bool, []byte, error){ //TODO: Verify everything type encryptedRequestStruct struct{ ChaPolyNonce [24]byte CipheredContent []byte } var encryptedRequestObject encryptedRequestStruct err := encoding.DecodeMessagePackBytes(false, inputRequest, &encryptedRequestObject) if (err != nil) { return false, nil, nil } chaPolyNonce := encryptedRequestObject.ChaPolyNonce cipheredContent := encryptedRequestObject.CipheredContent ableToDecrypt, decryptedBytes, err := chaPolyShrink.DecryptChaPolyShrink(cipheredContent, connectionKey, chaPolyNonce, false, [32]byte{}) if (err != nil) { return false, nil, nil } if (ableToDecrypt == false){ return false, nil, nil } return true, decryptedBytes, nil }