/// <summary>
        /// Creates a new instance of activity information from the activity.
        /// </summary>
        /// <returns>New instance of the ActivityInformation structure.</returns>
        public ActivityInformation ToActivityInformation()
        {
            GpsLocation         activityLocation = this.GetLocation();
            ActivityInformation res = new ActivityInformation()
            {
                Version              = new SemVer(this.Version).ToByteString(),
                Id                   = this.ActivityId,
                OwnerPublicKey       = ProtocolHelper.ByteArrayToByteString(this.OwnerPublicKey),
                ProfileServerContact = new ServerContactInfo()
                {
                    IpAddress   = ProtocolHelper.ByteArrayToByteString(this.OwnerProfileServerIpAddress),
                    NetworkId   = ProtocolHelper.ByteArrayToByteString(this.OwnerProfileServerId),
                    PrimaryPort = this.OwnerProfileServerPrimaryPort,
                },
                Type           = this.Type != null ? this.Type : "",
                Latitude       = activityLocation.GetLocationTypeLatitude(),
                Longitude      = activityLocation.GetLocationTypeLongitude(),
                Precision      = this.PrecisionRadius,
                StartTime      = ProtocolHelper.DateTimeToUnixTimestampMs(this.StartTime),
                ExpirationTime = ProtocolHelper.DateTimeToUnixTimestampMs(this.ExpirationTime),
                ExtraData      = this.ExtraData != null ? this.ExtraData : ""
            };

            return(res);
        }
Exemple #2
0
        /// <summary>
        /// Returns location network node information.
        /// </summary>
        /// <param name="LocPort">Port of the associated LOC server.</param>
        /// <returns>NodeInfo structure describing the server in location network.</returns>
        public Iop.Locnet.NodeInfo GetNodeInfo(int LocPort)
        {
            Iop.Locnet.NodeInfo res = new Iop.Locnet.NodeInfo()
            {
                NodeId   = ProtocolHelper.ByteArrayToByteString(new byte[0]),
                Location = new Iop.Locnet.GpsLocation()
                {
                    Latitude  = location.GetLocationTypeLatitude(),
                    Longitude = location.GetLocationTypeLongitude()
                },
                Contact = new Iop.Locnet.NodeContact()
                {
                    IpAddress  = ProtocolHelper.ByteArrayToByteString(ipAddress.GetAddressBytes()),
                    NodePort   = (uint)LocPort,
                    ClientPort = (uint)LocPort
                },
            };

            Iop.Locnet.ServiceInfo serviceInfo = new Iop.Locnet.ServiceInfo()
            {
                Type        = Iop.Locnet.ServiceType.Profile,
                Port        = (uint)primaryPort,
                ServiceData = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(keys.PublicKey))
            };

            res.Services.Add(serviceInfo);
            return(res);
        }
Exemple #3
0
        /// <summary>
        /// Returns network profile information about the client's identity.
        /// </summary>
        /// <param name="IncludeThumbnailImage">If true, the returned profile information will include thumbnail image.</param>
        /// <returns>network profile information about the client's identity.</returns>
        public IdentityNetworkProfileInformation GetIdentityNetworkProfileInformation(bool IncludeThumbnailImage)
        {
            log.Trace("(IncludeThumbnailImage:{0})", IncludeThumbnailImage);

            IdentityNetworkProfileInformation res = new IdentityNetworkProfileInformation()
            {
                IdentityPublicKey = ProtocolHelper.ByteArrayToByteString(keys.PublicKey),
                IsHosted          = false,
                IsOnline          = false,
                Latitude          = location.GetLocationTypeLatitude(),
                Longitude         = location.GetLocationTypeLongitude(),
                Name      = name != null ? name : "",
                Type      = type != null ? type : "",
                Version   = version.ToByteString(),
                ExtraData = extraData != null ? extraData : ""
            };

            if (IncludeThumbnailImage && (thumbnailImage != null))
            {
                res.ThumbnailImage = ProtocolHelper.ByteArrayToByteString(thumbnailImage);
            }
            else
            {
                res.ThumbnailImage = ProtocolHelper.ByteArrayToByteString(new byte[0]);
            }

            log.Trace("(-)");
            return(res);
        }
Exemple #4
0
        /// <summary>
        /// Returns NodeInfo structure of the profile server.
        /// </summary>
        /// <returns>NodeInfo structure of the profile server.</returns>
        public Iop.Locnet.NodeInfo GetNodeInfo()
        {
            log.Trace("()");

            Iop.Locnet.NodeInfo res = null;
            lock (internalLock)
            {
                res = new Iop.Locnet.NodeInfo()
                {
                    NodeId  = ProtocolHelper.ByteArrayToByteString(new byte[0]),
                    Contact = new Iop.Locnet.NodeContact()
                    {
                        IpAddress  = ProtocolHelper.ByteArrayToByteString(ipAddress.GetAddressBytes()),
                        ClientPort = (uint)locPort,
                        NodePort   = (uint)locPort
                    },
                    Location = nodeLocation,
                };

                Iop.Locnet.ServiceInfo serviceInfo = new Iop.Locnet.ServiceInfo()
                {
                    Type        = Iop.Locnet.ServiceType.Profile,
                    Port        = (uint)primaryInterfacePort,
                    ServiceData = ProtocolHelper.ByteArrayToByteString(networkId)
                };
                res.Services.Add(serviceInfo);
            }

            log.Trace("(-)");
            return(res);
        }
Exemple #5
0
        /// <summary>
        /// Creates instance of profile server from snapshot.
        /// </summary>
        /// <param name="Snapshot">Profile server snapshot.</param>
        /// <returns>New profile server instance.</returns>
        public static ProfileServer CreateFromSnapshot(ProfileServerSnapshot Snapshot)
        {
            ProfileServer res = new ProfileServer(Snapshot.Name, new GpsLocation(Snapshot.LocationLatitude, Snapshot.LocationLongitude), Snapshot.BasePort);

            res.availableIdentitySlots         = Snapshot.AvailableIdentitySlots;
            res.clientAppServiceInterfacePort  = Snapshot.ClientAppServiceInterfacePort;
            res.clientCustomerInterfacePort    = Snapshot.ClientCustomerInterfacePort;
            res.clientNonCustomerInterfacePort = Snapshot.ClientNonCustomerInterfacePort;
            res.ipAddress                   = IPAddress.Parse(Snapshot.IpAddress);
            res.locPort                     = Snapshot.LocPort;
            res.networkId                   = Crypto.FromHex(Snapshot.NetworkId);
            res.primaryInterfacePort        = Snapshot.PrimaryInterfacePort;
            res.serverNeighborInterfacePort = Snapshot.ServerNeighborInterfacePort;
            res.instanceDirectory           = res.GetInstanceDirectoryName();
            res.locServer                   = new LocServer(res);

            byte[] ipBytes = res.ipAddress.GetAddressBytes();
            Iop.Locnet.NodeContact contact = new Iop.Locnet.NodeContact()
            {
                IpAddress  = ProtocolHelper.ByteArrayToByteString(ipBytes),
                ClientPort = (uint)res.locPort,
                NodePort   = (uint)res.locPort
            };

            return(res);
        }
Exemple #6
0
        /// <summary>
        /// Creates CAN IPNS record object to point to a CAN object of the given hash with the given sequence number.
        /// </summary>
        /// <param name="Hash">Hash of the CAN object to point IPNS record to.</param>
        /// <param name="SequenceNumber">Sequence number of the IPNS record.</param>
        /// <param name="ExpirationTimeSeconds">Expiration time of the newly created record in seconds.</param>
        /// <returns>Valid signed CAN IPNS record object, ready to be sent to CAN server.</returns>
        public static CanIpnsEntry CreateIpnsRecord(byte[] Hash, UInt64 SequenceNumber, int ExpirationTimeSeconds)
        {
            log.Trace("(Hash:'{0}',SequenceNumber:{1},ExpirationTimeSeconds:{2})", Hash.ToBase58(), SequenceNumber, ExpirationTimeSeconds);

            string validityString = DateTime.UtcNow.AddMonths(1).ToString(Rfc3339DateTimeFormat, DateTimeFormatInfo.InvariantInfo);

            byte[] validityBytes = Encoding.UTF8.GetBytes(validityString);

            UInt64 ttlNanoSec = (UInt64)(TimeSpan.FromSeconds(ExpirationTimeSeconds).TotalMilliseconds) * (UInt64)1000000;

            string valueString = CanApi.CreateIpfsPathFromHash(Hash);

            byte[] valueBytes = Encoding.UTF8.GetBytes(valueString);

            CanIpnsEntry res = new CanIpnsEntry()
            {
                Sequence     = SequenceNumber,
                ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                Ttl          = ttlNanoSec,
                Validity     = ProtocolHelper.ByteArrayToByteString(validityBytes),
                Value        = ProtocolHelper.ByteArrayToByteString(valueBytes)
            };

            res.Signature = ProtocolHelper.ByteArrayToByteString(CreateIpnsRecordSignature(res));

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Creates SignedActivityInformation representation of the activity.
        /// </summary>
        /// <returns>SignedActivityInformation structure describing the activity.</returns>
        public SignedActivityInformation ToSignedActivityInformation()
        {
            SignedActivityInformation res = new SignedActivityInformation()
            {
                Activity  = this.ToActivityInformation(),
                Signature = ProtocolHelper.ByteArrayToByteString(this.Signature != null ? this.Signature : new byte[0])
            };

            return(res);
        }
        /// <summary>
        /// Constructs ServerContactInfo representation of the server's contact information.
        /// </summary>
        /// <returns>ServerContactInfo structure or null if the function fails.</returns>
        public ServerContactInfo GetServerContactInfo()
        {
            log.Trace("()");

            ServerContactInfo res = new ServerContactInfo();

            res.NetworkId   = ProtocolHelper.ByteArrayToByteString(this.NetworkId);
            res.PrimaryPort = (uint)this.PrimaryPort;
            res.IpAddress   = ProtocolHelper.ByteArrayToByteString(this.IpAddress);

            log.Trace("(-)");
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp          = (IPAddress)ArgumentValues["Server IP"];
            int       ClNonCustomerPort = (int)ArgumentValues["clNonCustomer Port"];

            log.Trace("(ServerIp:'{0}',ClNonCustomerPort:{1})", ServerIp, ClNonCustomerPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                await client.ConnectAsync(ServerIp, ClNonCustomerPort, true);

                bool startConversationOk = await client.StartConversationAsync();

                Message requestMessage = mb.CreateVerifyIdentityRequest(client.Challenge);

                // Invalidate signature.
                byte[] signature = requestMessage.Request.ConversationRequest.Signature.ToByteArray();
                signature[0] ^= 0x12;
                requestMessage.Request.ConversationRequest.Signature = ProtocolHelper.ByteArrayToByteString(signature);

                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk             = responseMessage.Id == requestMessage.Id;
                bool statusOk         = responseMessage.Response.Status == Status.ErrorInvalidSignature;
                bool verifyIdentityOk = idOk && statusOk;

                // Step 1 Acceptance
                Passed = startConversationOk && verifyIdentityOk;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #10
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress NodeIp            = (IPAddress)ArgumentValues["Node IP"];
            int       ClNonCustomerPort = (int)ArgumentValues["clNonCustomer Port"];

            log.Trace("(NodeIp:'{0}',ClNonCustomerPort:{1})", NodeIp, ClNonCustomerPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                await client.ConnectAsync(NodeIp, ClNonCustomerPort, true);

                Message    requestMessage = client.CreateStartConversationRequest();
                ByteString myKey          = requestMessage.Request.ConversationRequest.Start.PublicKey;
                byte[]     badChallenge   = new byte[4];
                Crypto.Rng.GetBytes(badChallenge);
                requestMessage.Request.ConversationRequest.Start                 = new StartConversationRequest();
                requestMessage.Request.ConversationRequest.Start.PublicKey       = myKey;
                requestMessage.Request.ConversationRequest.Start.ClientChallenge = ProtocolHelper.ByteArrayToByteString(badChallenge);
                requestMessage.Request.ConversationRequest.Start.SupportedVersions.Add(ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 0, 0 }));

                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                // Step 1 Acceptance
                bool idOk      = responseMessage.Id == requestMessage.Id;
                bool statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "clientChallenge";

                Passed = idOk && statusOk && detailsOk;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #11
0
        /// <summary>
        /// Converts public key to CAN ID format.
        /// </summary>
        /// <param name="PublicKey">Ed25519 public key.</param>
        /// <returns>CAN ID that corresponds to the the public.</returns>
        public static byte[] PublicKeyToId(byte[] PublicKey)
        {
            CanCryptoKey key = new CanCryptoKey()
            {
                Type = CanCryptoKey.Types.KeyType.Ed25519,
                Data = ProtocolHelper.ByteArrayToByteString(PublicKey)
            };

            byte[] hash = Crypto.Sha256(key.ToByteArray());

            byte[] res = new byte[2 + hash.Length];
            res[0] = 0x12; // SHA256 hash prefix
            res[1] = (byte)hash.Length;
            Array.Copy(hash, 0, res, 2, hash.Length);
            return(res);
        }
        public override bool Init()
        {
            log.Info("()");

            bool res = false;

            try
            {
                canIpnsLastSequenceNumber = Config.Configuration.CanIpnsLastSequenceNumber;
                api = new CanApi(Config.Configuration.CanEndPoint, ShutdownSignaling);

                // Construct profile server's contact information CAN object.
                canContactInformation = new CanProfileServerContact()
                {
                    PublicKey   = ProtocolHelper.ByteArrayToByteString(Config.Configuration.Keys.PublicKey),
                    IpAddress   = ProtocolHelper.ByteArrayToByteString(Config.Configuration.ExternalServerAddress.GetAddressBytes()),
                    PrimaryPort = (uint)Config.Configuration.ServerRoles.GetRolePort((uint)ServerRole.Primary)
                };


                initThread = new Thread(new ThreadStart(InitThread));
                initThread.Start();

                RegisterCronJobs();

                res         = true;
                Initialized = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            if (!res)
            {
                ShutdownSignaling.SignalShutdown();

                if ((initThread != null) && !initThreadFinished.WaitOne(25000))
                {
                    log.Error("Init thread did not terminated in 25 seconds.");
                }
            }

            log.Info("(-):{0}", res);
            return(res);
        }
Exemple #13
0
        public override bool Init()
        {
            log.Info("()");

            bool res = false;

            try
            {
                canApi = (CanApi)Base.ComponentDictionary["Network.ContentAddressNetwork.CanApi"];

                // Construct profile server's contact information CAN object.
                canContactInformation = new CanProfileServerContact()
                {
                    PublicKey   = ProtocolHelper.ByteArrayToByteString(Base.Configuration.Keys.PublicKey),
                    IpAddress   = ProtocolHelper.ByteArrayToByteString(Base.Configuration.ServerInterface.GetAddressBytes()),
                    PrimaryPort = (uint)Base.Configuration.ServerRoles.GetRolePort(ServerRole.Primary)
                };


                initThread = new Thread(new ThreadStart(InitThread));
                initThread.Start();

                res         = true;
                Initialized = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            if (!res)
            {
                ShutdownSignaling.SignalShutdown();

                if ((initThread != null) && !initThreadFinished.WaitOne(25000))
                {
                    log.Error("Init thread did not terminated in 25 seconds.");
                }
            }

            log.Info("(-):{0}", res);
            return(res);
        }
Exemple #14
0
        /// <summary>
        /// Calculates expected search query results from the given profile server and its neighbors.
        /// </summary>
        /// <param name="NameFilter">Name filter of the search query, or null if name filtering is not required.</param>
        /// <param name="TypeFilter">Type filter of the search query, or null if type filtering is not required.</param>
        /// <param name="LocationFilter">Location filter of the search query, or null if location filtering is not required.</param>
        /// <param name="Radius">If <paramref name="LocationFilter"/> is not null, this is the radius of the target area.</param>
        /// <param name="IncludeHostedOnly">If set to true, the search results should only include profiles hosted on the queried profile server.</param>
        /// <param name="IncludeImages">If set to true, the search results should include images.</param>
        /// <param name="ExpectedCoveredServers">If the function succeeds, this is filled with list of covered servers that the search query should return.</param>
        /// <param name="LocalServerResultsCount">If the function succeeds, this is filled with the number of search results obtained from the local server.</param>
        /// <returns>List of profiles that match the given criteria or null if the function fails.</returns>
        public List <IdentityNetworkProfileInformation> GetExpectedSearchResults(string NameFilter, string TypeFilter, GpsLocation LocationFilter, int Radius, bool IncludeHostedOnly, bool IncludeImages, out List <byte[]> ExpectedCoveredServers, out int LocalServerResultsCount)
        {
            log.Trace("(NameFilter:'{0}',TypeFilter:'{1}',LocationFilter:'{2}',Radius:{3},IncludeHostedOnly:{4},IncludeImages:{5})", NameFilter, TypeFilter, LocationFilter, Radius, IncludeHostedOnly, IncludeImages);

            List <IdentityNetworkProfileInformation> res = new List <IdentityNetworkProfileInformation>();

            ExpectedCoveredServers = new List <byte[]>();
            ExpectedCoveredServers.Add(networkId);

            List <IdentityNetworkProfileInformation> localResults = SearchQuery(NameFilter, TypeFilter, LocationFilter, Radius, IncludeImages);

            LocalServerResultsCount = localResults.Count;

            foreach (IdentityNetworkProfileInformation localResult in localResults)
            {
                localResult.IsHosted = true;
                localResult.IsOnline = false;
            }

            res.AddRange(localResults);

            if (!IncludeHostedOnly)
            {
                List <ProfileServer> neighbors = LocServer.GetNeighbors();
                foreach (ProfileServer neighbor in neighbors)
                {
                    ByteString neighborId = ProtocolHelper.ByteArrayToByteString(neighbor.GetNetworkId());
                    ExpectedCoveredServers.Add(neighborId.ToByteArray());
                    List <IdentityNetworkProfileInformation> neighborResults = neighbor.SearchQuery(NameFilter, TypeFilter, LocationFilter, Radius, IncludeImages);
                    foreach (IdentityNetworkProfileInformation neighborResult in neighborResults)
                    {
                        neighborResult.IsHosted = false;
                        neighborResult.HostingServerNetworkId = neighborId;
                    }

                    res.AddRange(neighborResults);
                }
            }

            log.Trace("(-):*.Count={0}", res.Count);
            return(res);
        }
        /// <summary>
        /// Creates SignedProfileInformation representation of the identity's profile.
        /// </summary>
        /// <returns>SignedProfileInformation structure describing the profile.</returns>
        public SignedProfileInformation ToSignedProfileInformation()
        {
            GpsLocation location         = this.GetInitialLocation();
            SignedProfileInformation res = new SignedProfileInformation()
            {
                Profile = new ProfileInformation()
                {
                    Version            = new SemVer(this.Version).ToByteString(),
                    PublicKey          = ProtocolHelper.ByteArrayToByteString(this.PublicKey),
                    Type               = this.Type,
                    Name               = this.Name,
                    ExtraData          = this.ExtraData,
                    Latitude           = location.GetLocationTypeLatitude(),
                    Longitude          = location.GetLocationTypeLongitude(),
                    ProfileImageHash   = ProtocolHelper.ByteArrayToByteString(this.ProfileImage != null ? this.ProfileImage : new byte[0]),
                    ThumbnailImageHash = ProtocolHelper.ByteArrayToByteString(this.ThumbnailImage != null ? this.ThumbnailImage: new byte[0])
                },
                Signature = ProtocolHelper.ByteArrayToByteString(this.Signature != null ? this.Signature : new byte[0])
            };

            return(res);
        }
        /// <summary>
        /// Performs a single round of initialization process with the target profile server.
        /// </summary>
        /// <param name="UpdateItems">Update items to send during the initialization process to the target profile server.</param>
        /// <param name="ProfileServer">Simulated profile server instance.</param>
        /// <param name="LocServer">Simulated LOC server instance.</param>
        /// <param name="ErrorDetails">Expected error details returned as a response to update request.</param>
        /// <returns>true if the function succeeds, false otherwise.</returns>
        public async Task <bool> PerformInitializationProcessWithUpdateItemsAsync(List <SharedProfileUpdateItem> UpdateItems, ProfileServer ProfileServer, LocServer LocServer, string ErrorDetails)
        {
            log.Trace("()");

            // Announce new neighbor.
            Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
            {
                AddedNodeInfo = ProfileServer.GetNodeInfo(LocServer.Port)
            };

            bool addNeighborOk = await LocServer.SendChangeNotification(change);

            // Wait for start of neighborhood initialization process.
            IncomingServerMessage incomingServerMessage = await ProfileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);

            Message requestMessage = await ProfileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, UpdateItems);

            incomingServerMessage = await ProfileServer.WaitForResponse(ServerRole.ServerNeighbor, requestMessage);

            bool statusOk  = incomingServerMessage.IncomingMessage.Response.Status == Status.ErrorInvalidValue;
            bool detailsOk = incomingServerMessage.IncomingMessage.Response.Details == ErrorDetails;
            bool updateOk  = statusOk && detailsOk;

            // Announce new neighbor.
            change = new Iop.Locnet.NeighbourhoodChange()
            {
                RemovedNodeId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(ProfileServer.Keys.PublicKey))
            };

            bool deleteNeighborOk = await LocServer.SendChangeNotification(change);

            bool res = addNeighborOk && updateOk && deleteNeighborOk;

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       CanPort     = (int)ArgumentValues["CAN Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},CanPort:{2})", ServerIp, PrimaryPort, CanPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool hostingOk = await client.EstablishHostingAsync("Test");

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                bool checkInOk = await client.CheckInAsync();

                bool step1Ok = listPortsOk && hostingOk && checkInOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                byte[]             serverId   = Crypto.Sha256(client.ServerKey);
                List <CanKeyValue> clientData = new List <CanKeyValue>()
                {
                    new CanKeyValue()
                    {
                        Key = "key1", StringValue = "value 1"
                    },
                    new CanKeyValue()
                    {
                        Key = "key2", Uint32Value = 2
                    },
                    new CanKeyValue()
                    {
                        Key = "key3", BoolValue = true
                    },
                    new CanKeyValue()
                    {
                        Key = "key4", BinaryValue = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 2, 3 })
                    },
                };

                CanIdentityData identityData1 = new CanIdentityData()
                {
                    HostingServerId = ProtocolHelper.ByteArrayToByteString(serverId)
                };
                identityData1.KeyValueList.AddRange(clientData);

                Message requestMessage = mb.CreateCanStoreDataRequest(identityData1);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk           = responseMessage.Id == requestMessage.Id;
                bool statusOk       = responseMessage.Response.Status == Status.Ok;
                bool canStoreDataOk = idOk && statusOk;

                byte[] objectHash1 = responseMessage.Response.ConversationResponse.CanStoreData.Hash.ToByteArray();


                string objectPath1 = client.CreateIpfsPathFromHash(objectHash1);
                log.Trace("Object path 1 is '{0}'.", objectPath1);

                string       validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                CanIpnsEntry ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath1)),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 1,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                bool canPublishIpnsRecordOk = idOk && statusOk;



                // Step 2 Acceptance
                bool step2Ok = canStoreDataOk && canPublishIpnsRecordOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");
                IPEndPoint canEndPoint = new IPEndPoint(ServerIp, CanPort);
                byte[]     clientCanId = client.CanPublicKeyToId(client.GetIdentityKeys().PublicKey);
                string     ipnsPath    = client.CreateIpnsPathFromHash(clientCanId);

                ProtocolClient.CanIpnsResolveResult canIpnsResolveResult = await client.CanIpnsResolve(canEndPoint, ipnsPath);

                string canObjectPath = canIpnsResolveResult.Path;
                bool   objectPathOk  = canObjectPath == objectPath1;
                bool   resolveOk     = canIpnsResolveResult.Success && objectPathOk;

                ProtocolClient.CanCatResult canCatResult = await client.CanGetObject(canEndPoint, canObjectPath);

                byte[] receivedData = canCatResult.Data;
                byte[] expectedData = identityData1.ToByteArray();
                bool   dataOk       = StructuralComparisons.StructuralComparer.Compare(receivedData, expectedData) == 0;
                bool   catOk        = canCatResult.Success && dataOk;

                // Step 3 Acceptance
                bool step3Ok = resolveOk && catOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                ipnsRecord.Sequence  = 2;
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                canPublishIpnsRecordOk = idOk && statusOk;


                canIpnsResolveResult = await client.CanIpnsResolve(canEndPoint, ipnsPath);

                canObjectPath = canIpnsResolveResult.Path;
                objectPathOk  = canObjectPath == objectPath1;
                resolveOk     = canIpnsResolveResult.Success && objectPathOk;

                // Step 4 Acceptance
                bool step4Ok = canPublishIpnsRecordOk && resolveOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");


                // Step 5
                log.Trace("Step 5");

                byte[] valX = new byte[50000];
                for (int i = 0; i < valX.Length; i++)
                {
                    valX[i] = 0x30;
                }

                clientData = new List <CanKeyValue>()
                {
                    new CanKeyValue()
                    {
                        Key = "key1", StringValue = "value 1"
                    },
                    new CanKeyValue()
                    {
                        Key = "key2", Uint32Value = 3
                    },
                    new CanKeyValue()
                    {
                        Key = "key3", BoolValue = false
                    },
                    new CanKeyValue()
                    {
                        Key = "keyX", BinaryValue = ProtocolHelper.ByteArrayToByteString(valX)
                    },
                };

                CanIdentityData identityData2 = new CanIdentityData()
                {
                    HostingServerId = ProtocolHelper.ByteArrayToByteString(serverId)
                };
                identityData2.KeyValueList.AddRange(clientData);


                requestMessage = mb.CreateCanStoreDataRequest(identityData2);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk           = responseMessage.Id == requestMessage.Id;
                statusOk       = responseMessage.Response.Status == Status.Ok;
                canStoreDataOk = idOk && statusOk;

                byte[] objectHash2 = responseMessage.Response.ConversationResponse.CanStoreData.Hash.ToByteArray();


                string objectPath2 = client.CreateIpfsPathFromHash(objectHash2);
                log.Trace("Object path 2 is '{0}'.", objectPath2);

                ipnsRecord.Sequence  = 3;
                ipnsRecord.Value     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath2));
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                canPublishIpnsRecordOk = idOk && statusOk;


                // Step 5 Acceptance
                bool step5Ok = canStoreDataOk && canPublishIpnsRecordOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");


                // Step 6
                log.Trace("Step 6");

                await Task.Delay(10000);

                canIpnsResolveResult = await client.CanIpnsResolve(canEndPoint, ipnsPath);

                canObjectPath = canIpnsResolveResult.Path;
                objectPathOk  = canObjectPath == objectPath2;
                resolveOk     = canIpnsResolveResult.Success && objectPathOk;

                canCatResult = await client.CanGetObject(canEndPoint, canObjectPath);

                receivedData = canCatResult.Data;
                expectedData = identityData2.ToByteArray();
                dataOk       = StructuralComparisons.StructuralComparer.Compare(receivedData, expectedData) == 0;
                catOk        = canCatResult.Success && dataOk;

                // Step 6 Acceptance
                bool step6Ok = resolveOk && catOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");


                // Step 7
                log.Trace("Step 7");

                requestMessage = mb.CreateCanStoreDataRequest(null);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk           = responseMessage.Id == requestMessage.Id;
                statusOk       = responseMessage.Response.Status == Status.Ok;
                canStoreDataOk = idOk && statusOk;

                ProtocolClient.CanDeleteResult canDeleteResult = await client.CanDeleteObject(canEndPoint, canObjectPath);

                bool pinsOk   = (canDeleteResult.Pins == null) || (canDeleteResult.Pins.Length == 0);
                bool deleteOk = canDeleteResult.Success && pinsOk;

                // Step 7 Acceptance
                bool step7Ok = canStoreDataOk && deleteOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");

                canDeleteResult = await client.CanDeleteObject(canEndPoint, objectPath1);

                pinsOk   = (canDeleteResult.Pins == null) || (canDeleteResult.Pins.Length == 0);
                deleteOk = canDeleteResult.Success && pinsOk;

                // Step 8 Acceptance
                bool step8Ok = deleteOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();


            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2})", ServerIp, PrimaryPort, BasePort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));
                byte[] testImageData2          = File.ReadAllBytes(Path.Combine("images", TestName + "b.png"));

                int profileIndex = 1;
                int profileCount = 50;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }


                profileServer = new ProfileServer("TestServer", ServerIp, BasePort, client.GetIdentityKeys());
                bool serverStartOk = profileServer.Start();

                bool step1Ok = listPortsOk && profileInitializationOk && serverStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool neighborhoodInitializationProcessOk = await client.NeighborhoodInitializationProcessAsync(profileServer.PrimaryPort, profileServer.ServerNeighborPort, TestProfiles);

                client.CloseConnection();

                bool step2Ok = neighborhoodInitializationProcessOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                // Step 3
                log.Trace("Step 3");

                // Add 15 more identities.
                Dictionary <string, ProtocolClient> newProfiles = new Dictionary <string, ProtocolClient>(StringComparer.Ordinal);
                profileInitializationOk = true;
                profileCount            = 15;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                        newProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }

                log.Trace("Waiting 20 seconds ...");
                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                bool error = false;
                List <IncomingServerMessage> psMessages = profileServer.GetMessageList();
                List <SharedProfileAddItem>  addUpdates = new List <SharedProfileAddItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                            {
                                SharedProfileAddItem addItem = updateItem.Add;
                                addUpdates.Add(addItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                bool receivedUpdatesOk = !error;

                bool updatesOk = client.CheckProfileListMatchAddItems(newProfiles, addUpdates);

                bool step3Ok = profileInitializationOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                // Cancel 15 identities.
                HashSet <byte[]> cancelledProfiles  = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default);
                bool             profileCancelingOk = true;
                profileCount = 15;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    if (await profileClient.CancelHostingAgreementAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Remove(keys[index]);
                        cancelledProfiles.Add(profileClient.GetIdentityId());
                    }
                    else
                    {
                        profileCancelingOk = false;
                        break;
                    }
                }

                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                psMessages = profileServer.GetMessageList();
                List <SharedProfileDeleteItem> deleteUpdates = new List <SharedProfileDeleteItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Delete)
                            {
                                SharedProfileDeleteItem deleteItem = updateItem.Delete;
                                deleteUpdates.Add(deleteItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                receivedUpdatesOk = !error;

                updatesOk = client.CheckProfileListMatchDeleteItems(cancelledProfiles, deleteUpdates);

                bool step4Ok = profileCancelingOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");



                // Step 5
                log.Trace("Step 5");

                // Change 25 profiles.
                Dictionary <byte[], SharedProfileChangeItem> changedProfiles = new Dictionary <byte[], SharedProfileChangeItem>(StructuralEqualityComparer <byte[]> .Default);
                bool profileChangingOk = true;
                profileCount = 25;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];
                    if (changedProfiles.ContainsKey(profileClient.GetIdentityId()))
                    {
                        // Do not take one client twice.
                        i--;
                        continue;
                    }

                    SharedProfileChangeItem changeItem = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(profileClient.GetIdentityId()),
                        SetName           = Rng.NextDouble() < 0.20,
                        SetLocation       = Rng.NextDouble() < 0.20,
                        SetExtraData      = Rng.NextDouble() < 0.20,
                        SetThumbnailImage = Rng.NextDouble() < 0.20,
                        SetVersion        = false,
                    };

                    // Make sure we change at least one thing.
                    if (!changeItem.SetName && !changeItem.SetLocation && !changeItem.SetThumbnailImage)
                    {
                        changeItem.SetExtraData = true;
                    }

                    if (changeItem.SetName)
                    {
                        log.Trace("Changing name of identity name '{0}'.", profileClient.Profile.Name);
                        TestProfiles.Remove(profileClient.Profile.Name);

                        profileClient.Profile.Name += "-change";
                        changeItem.Name             = profileClient.Profile.Name;
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }

                    if (changeItem.SetLocation)
                    {
                        log.Trace("Changing location of identity name '{0}'.", profileClient.Profile.Name);
                        if (Rng.NextDouble() < 0.30)
                        {
                            profileClient.Profile.Location.Latitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        else if (Rng.NextDouble() < 0.30)
                        {
                            profileClient.Profile.Location.Longitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        else
                        {
                            profileClient.Profile.Location.Latitude  = profileClient.Profile.Location.Latitude / 2 + 1;
                            profileClient.Profile.Location.Longitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        changeItem.Latitude  = profileClient.Profile.Location.GetLocationTypeLatitude();
                        changeItem.Longitude = profileClient.Profile.Location.GetLocationTypeLongitude();
                    }

                    if (changeItem.SetExtraData)
                    {
                        log.Trace("Changing extra data of identity name '{0}'.", profileClient.Profile.Name);
                        if (!string.IsNullOrEmpty(profileClient.Profile.ExtraData))
                        {
                            profileClient.Profile.ExtraData = profileClient.Profile.ExtraData.Substring(0, Math.Min(10, profileClient.Profile.ExtraData.Length)) + "-change";
                        }
                        else
                        {
                            profileClient.Profile.ExtraData = "new value";
                        }
                        changeItem.ExtraData = profileClient.Profile.ExtraData;
                    }

                    if (changeItem.SetThumbnailImage)
                    {
                        log.Trace("Changing profile image of identity name '{0}'.", profileClient.Profile.Name);
                        profileClient.Profile.ProfileImage   = testImageData2;
                        profileClient.Profile.ThumbnailImage = testImageData2;
                        changeItem.ThumbnailImage            = ProtocolHelper.ByteArrayToByteString(testImageData2);
                    }

                    changedProfiles.Add(profileClient.GetIdentityId(), changeItem);

                    await profileClient.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                    bool ccheckInOk = await profileClient.CheckInAsync();

                    Message clientRequest = profileClient.MessageBuilder.CreateUpdateProfileRequest(null, changeItem.SetName ? changeItem.Name : null, changeItem.SetThumbnailImage ? profileClient.Profile.ProfileImage : null, changeItem.SetLocation ? profileClient.Profile.Location : null, changeItem.SetExtraData ? changeItem.ExtraData : null);
                    await profileClient.SendMessageAsync(clientRequest);

                    Message clientResponse = await profileClient.ReceiveMessageAsync();

                    bool cidOk     = clientResponse.Id == clientRequest.Id;
                    bool cstatusOk = clientResponse.Response.Status == Status.Ok;

                    profileClient.CloseConnection();

                    bool changeOk = ccheckInOk && cidOk && cstatusOk;

                    if (!changeOk)
                    {
                        profileChangingOk = false;
                        break;
                    }
                }

                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                psMessages = profileServer.GetMessageList();
                List <SharedProfileChangeItem> changeUpdates = new List <SharedProfileChangeItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Change)
                            {
                                SharedProfileChangeItem changeItem = updateItem.Change;
                                changeUpdates.Add(changeItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                receivedUpdatesOk = !error;

                updatesOk = client.CheckProfileListMatchChangeItems(changedProfiles, changeUpdates);

                bool step5Ok = profileChangingOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                // Step 6
                log.Trace("Step 6");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client.VerifyIdentityAsync();

                Message request = mb.CreateStopNeighborhoodUpdatesRequest();
                await client.SendMessageAsync(request);

                Message response = await client.ReceiveMessageAsync();

                bool idOk          = response.Id == request.Id;
                bool statusOk      = response.Response.Status == Status.Ok;
                bool stopUpdatesOk = idOk && statusOk;

                client.CloseConnection();

                bool step6Ok = verifyIdentityOk && stopUpdatesOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");



                // Step 7
                log.Trace("Step 7");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                bool addProfilesOk = !error;


                // Cancel 5 identities.
                error        = false;
                profileCount = 5;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    if (!await profileClient.CancelHostingAgreementAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to cancel hosting agreement of client name '{0}'.", profileClient.Profile.Name);
                        error = true;
                        break;
                    }

                    TestProfiles.Remove(keys[index]);
                }

                bool cancelProfilesOk = !error;



                // Change 5 profiles.
                error        = false;
                profileCount = 5;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    SharedProfileChangeItem changeItem = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(profileClient.GetIdentityId()),
                        SetExtraData      = true,
                        ExtraData         = "last change",
                        SetVersion        = false,
                        SetLocation       = false,
                        SetName           = false,
                        SetThumbnailImage = false,
                    };

                    profileClient.Profile.ExtraData = changeItem.ExtraData;

                    await profileClient.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                    bool checkInOk = await profileClient.CheckInAsync();

                    Message clientRequest = profileClient.MessageBuilder.CreateUpdateProfileRequest(null, null, null, null, changeItem.ExtraData);
                    await profileClient.SendMessageAsync(clientRequest);

                    Message clientResponse = await profileClient.ReceiveMessageAsync();

                    bool cidOk     = clientResponse.Id == clientRequest.Id;
                    bool cstatusOk = clientResponse.Response.Status == Status.Ok;

                    profileClient.CloseConnection();

                    bool changeOk = checkInOk && cidOk && cstatusOk;

                    if (!changeOk)
                    {
                        log.Trace("Failed to change profile of client name '{0}'.", profileClient.Profile.Name);
                        error = true;
                        break;
                    }
                }

                bool changeProfileOk = !error;

                await Task.Delay(20000);

                // Meanwhile we expect NO update messages to arrive on our simulated profile server.
                error      = false;
                psMessages = profileServer.GetMessageList();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        error = true;
                        break;
                    }
                }
                bool noNewUpdatesOk = !error;


                bool step7Ok = addProfilesOk && cancelProfilesOk && changeProfileOk && noNewUpdatesOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                request = mb.CreateStartNeighborhoodInitializationRequest((uint)profileServer.PrimaryPort, (uint)profileServer.ServerNeighborPort);
                await client.SendMessageAsync(request);

                response = await client.ReceiveMessageAsync();

                idOk     = response.Id == request.Id;
                statusOk = response.Response.Status == Status.Ok;
                bool startNeighborhoodInitializationOk = idOk && statusOk;

                bool step8Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");



                // Step 9
                log.Trace("Step 9");

                // Add 5 more identities.
                // These identities may or may not be included in the current initialization process in progress.
                List <ProtocolClient> newClients = new List <ProtocolClient>();
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    newClients.Add(profileClient);
                }

                addProfilesOk = !error;

                bool step9Ok = addProfilesOk;

                log.Trace("Step 9: {0}", step9Ok ? "PASSED" : "FAILED");



                // Step 10
                log.Trace("Step 10");


                // Wait for update request.
                Message serverRequestMessage  = null;
                Message clientResponseMessage = null;
                bool    typeOk = false;

                List <SharedProfileAddItem> receivedItems = new List <SharedProfileAddItem>();

                error = false;
                while (receivedItems.Count < TestProfiles.Count)
                {
                    serverRequestMessage = await client.ReceiveMessageAsync();

                    typeOk = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                             serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                             serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate;

                    clientResponseMessage = mb.CreateNeighborhoodSharedProfileUpdateResponse(serverRequestMessage);
                    await client.SendMessageAsync(clientResponseMessage);


                    if (!typeOk)
                    {
                        break;
                    }

                    foreach (SharedProfileUpdateItem updateItem in serverRequestMessage.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                    {
                        if (updateItem.ActionTypeCase != SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                        {
                            log.Trace("Received invalid update item action type '{0}'.", updateItem.ActionTypeCase);
                            error = true;
                            break;
                        }

                        receivedItems.Add(updateItem.Add);
                    }

                    if (error)
                    {
                        break;
                    }
                }

                log.Trace("Received {0} profiles from target profile server.", receivedItems.Count);

                bool receivedProfilesOk = false;
                if (!error)
                {
                    // As we do not know if new identities made it to the initialization process, we just try all possible combinations.
                    // First possibility is that no new clients were present in the process.
                    if (client.CheckProfileListMatchAddItems(TestProfiles, receivedItems))
                    {
                        receivedProfilesOk = true;
                    }

                    for (int i = 0; i < newClients.Count; i++)
                    {
                        ProtocolClient newClient = newClients[i];
                        TestProfiles.Add(newClient.Profile.Name, newClient);

                        // Other possibilities are that one or more clients were present in the process.
                        if (!receivedProfilesOk)
                        {
                            if (client.CheckProfileListMatchAddItems(TestProfiles, receivedItems))
                            {
                                receivedProfilesOk = true;
                            }
                        }
                    }
                }

                bool step10Ok = receivedProfilesOk;

                log.Trace("Step 10: {0}", step10Ok ? "PASSED" : "FAILED");



                // Step 11
                log.Trace("Step 11");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                addProfilesOk = !error;

                bool step11Ok = addProfilesOk;

                log.Trace("Step 11: {0}", step11Ok ? "PASSED" : "FAILED");



                // Step 12
                log.Trace("Step 12");

                client.CloseConnection();
                bool step12Ok = true;

                log.Trace("Step 12: {0}", step12Ok ? "PASSED" : "FAILED");



                // Step 13
                log.Trace("Step 13");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                addProfilesOk = !error;

                await Task.Delay(20000);

                // Meanwhile we expect NO update messages to arrive on our simulated profile server.
                error      = false;
                psMessages = profileServer.GetMessageList();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        error = true;
                        break;
                    }
                }
                noNewUpdatesOk = !error;

                bool step13Ok = addProfilesOk && noNewUpdatesOk;

                log.Trace("Step 13: {0}", step13Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok && step9Ok && step10Ok && step11Ok && step12Ok && step13Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #19
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];
            int       LocPort     = (int)ArgumentValues["LOC Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2},LocPort:{3})", ServerIp, PrimaryPort, BasePort, LocPort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;
            LocServer      locServer     = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                // Create identities.
                int    profileNumber = 0;
                byte[] imageData     = File.ReadAllBytes(Path.Combine("images", TestName + ".png"));

                Dictionary <string, ProtocolClient> expectedLastClients = new Dictionary <string, ProtocolClient>(StringComparer.Ordinal);
                List <string> excessClientNames = new List <string>();
                for (int i = 0; i < 20050; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    if (i >= 19990)
                    {
                        protocolClient.Profile.Type = "last";
                        if (i < 20000)
                        {
                            expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);
                        }
                        else
                        {
                            excessClientNames.Add(protocolClient.Profile.Name);
                        }
                    }
                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                }


                // Start simulated profile server.
                profileServer = new ProfileServer("TestProfileServer", ServerIp, BasePort, client.GetIdentityKeys(), new GpsLocation(1, 2));
                bool profileServerStartOk = profileServer.Start();

                // Start simulated LOC server.
                locServer = new LocServer("TestLocServer", ServerIp, LocPort);
                bool locServerStartOk = locServer.Start();

                await locServer.WaitForProfileServerConnectionAsync();

                bool step1Ok = profileServerStartOk && locServerStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");


                // Step 2
                log.Trace("Step 2");

                // Announce new neighbor.
                Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
                {
                    AddedNodeInfo = profileServer.GetNodeInfo(LocPort)
                };

                bool changeNotificationOk = await locServer.SendChangeNotification(change);

                // Wait for start of neighborhood initialization process.
                IncomingServerMessage incomingServerMessage = await profileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);


                // Send update.
                bool statusOk     = false;
                bool updateOk     = true;
                int  profilesSent = 0;
                List <ProtocolClient> allProfiles    = new List <ProtocolClient>(TestProfiles.Values);
                List <ProtocolClient> profilesToSend = allProfiles.GetRange(0, 19990);
                while (profilesToSend.Count > 0)
                {
                    int batchSize = Math.Min(Rng.Next(100, 150), profilesToSend.Count);

                    List <SharedProfileUpdateItem> updateItems = new List <SharedProfileUpdateItem>();
                    foreach (ProtocolClient pc in profilesToSend.GetRange(0, batchSize))
                    {
                        updateItems.Add(pc.GetSharedProfileUpdateAddItem());
                    }

                    profilesToSend.RemoveRange(0, batchSize);

                    Message updateRequest = await profileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, updateItems);

                    profilesSent         += batchSize;
                    incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, updateRequest);

                    statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                    bool batchOk = (updateRequest != null) && statusOk;
                    if (!batchOk)
                    {
                        updateOk = false;
                        break;
                    }
                }


                // Finish neighborhood initialization process.
                Message finishRequest = await profileServer.SendFinishNeighborhoodInitializationRequest(incomingServerMessage.Client);

                incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, finishRequest);

                statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                bool finishOk = (finishRequest != null) && statusOk;


                bool step2Ok = changeNotificationOk && updateOk && finishOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client.VerifyIdentityAsync();

                List <SharedProfileUpdateItem> badUpdateItems = new List <SharedProfileUpdateItem>();
                foreach (ProtocolClient pc in allProfiles.GetRange(19990, 60))
                {
                    badUpdateItems.Add(pc.GetSharedProfileUpdateAddItem());
                }


                Message requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(badUpdateItems);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "10.add";

                bool badUpdateOk = idOk && statusOk && detailsOk;
                client.CloseConnection();

                // Step 3 Acceptance
                bool step3Ok = verifyIdentityOk && badUpdateOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool startConversationOk = await client.StartConversationAsync();

                HashSet <byte[]> expectedCoveredServers = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default)
                {
                    client.GetIdentityId(), Crypto.Sha256(client.ServerKey)
                };

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 100, 100);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                bool totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == 10;
                bool maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 100;
                bool profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == 10;
                bool resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), true);

                bool queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 4 Acceptance
                bool step4Ok = startConversationOk && queryOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");



                // Step 5
                log.Trace("Step 5");

                // Make TestProfiles reflect the status on the target profile server.
                foreach (string excessClientName in excessClientNames)
                {
                    TestProfiles[excessClientName].Dispose();
                    TestProfiles.Remove(excessClientName);
                }

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                // Select 140 profiles for deletion.
                List <SharedProfileUpdateItem> deleteUpdateItems = new List <SharedProfileUpdateItem>();
                while (deleteUpdateItems.Count < 140)
                {
                    int            index = Rng.Next(TestProfiles.Count);
                    ProtocolClient pc    = TestProfiles.ElementAt(index).Value;
                    deleteUpdateItems.Add(pc.GetSharedProfileUpdateDeleteItem());

                    if (expectedLastClients.ContainsKey(pc.Profile.Name))
                    {
                        expectedLastClients.Remove(pc.Profile.Name);
                    }

                    TestProfiles.Remove(pc.Profile.Name);
                    pc.Dispose();
                }

                // Send delete update.
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(deleteUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                bool deleteUpdateOk = idOk && statusOk;


                // Generate 160 new identities.
                badUpdateItems.Clear();
                excessClientNames.Clear();
                for (int i = 0; i < 160; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    protocolClient.Profile.Type = "last";

                    if (TestProfiles.Count < 20000)
                    {
                        expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);
                    }
                    else
                    {
                        excessClientNames.Add(protocolClient.Profile.Name);
                    }

                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                    badUpdateItems.Add(protocolClient.GetSharedProfileUpdateAddItem());
                }


                // Add the new profiles to the profile server.
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(badUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "140.add";

                badUpdateOk = idOk && statusOk && detailsOk;
                client.CloseConnection();

                // Step 5 Acceptance
                bool step5Ok = verifyIdentityOk && deleteUpdateOk && badUpdateOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                // Step 6
                log.Trace("Step 6");

                // Make TestProfiles reflect the status on the target profile server.
                foreach (string excessClientName in excessClientNames)
                {
                    TestProfiles[excessClientName].Dispose();
                    TestProfiles.Remove(excessClientName);
                }

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                startConversationOk = await client.StartConversationAsync();

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 1000, 1000, false, false);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == expectedLastClients.Count;
                maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == expectedLastClients.Count;
                resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 6 Acceptance
                bool step6Ok = startConversationOk && queryOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");



                // Step 7
                log.Trace("Step 7");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                // Select 40 profiles for deletion.
                deleteUpdateItems = new List <SharedProfileUpdateItem>();
                while (deleteUpdateItems.Count < 40)
                {
                    int            index = Rng.Next(TestProfiles.Count);
                    ProtocolClient pc    = TestProfiles.ElementAt(index).Value;
                    deleteUpdateItems.Add(pc.GetSharedProfileUpdateDeleteItem());

                    if (expectedLastClients.ContainsKey(pc.Profile.Name))
                    {
                        expectedLastClients.Remove(pc.Profile.Name);
                    }

                    TestProfiles.Remove(pc.Profile.Name);
                    pc.Dispose();
                }

                // Select 40 profiles for change, but avoid updating one profile twice in a single update message, which is forbidden.
                HashSet <int> usedIndexes = new HashSet <int>();
                List <SharedProfileUpdateItem> changeUpdateItems = new List <SharedProfileUpdateItem>();
                while (changeUpdateItems.Count < 40)
                {
                    int index = Rng.Next(TestProfiles.Count);

                    if (usedIndexes.Contains(index))
                    {
                        continue;
                    }
                    usedIndexes.Add(index);

                    ProtocolClient pc = TestProfiles.ElementAt(index).Value;
                    pc.Profile.ExtraData = "1234567890";
                    SharedProfileUpdateItem changeUpdateItem = new SharedProfileUpdateItem()
                    {
                        Change = new SharedProfileChangeItem()
                        {
                            IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(pc.GetIdentityId()),
                            SetExtraData      = true,
                            ExtraData         = pc.Profile.ExtraData
                        }
                    };
                    changeUpdateItems.Add(changeUpdateItem);
                }

                // Generate 40 new identities.
                List <SharedProfileUpdateItem> addUpdateItems = new List <SharedProfileUpdateItem>();
                for (int i = 0; i < 40; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    protocolClient.Profile.Type = "last";

                    expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);

                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                    addUpdateItems.Add(protocolClient.GetSharedProfileUpdateAddItem());
                }


                // Send all the updates as one.
                List <SharedProfileUpdateItem> newUpdateItems = new List <SharedProfileUpdateItem>();
                newUpdateItems.AddRange(deleteUpdateItems);
                newUpdateItems.AddRange(changeUpdateItems);
                newUpdateItems.AddRange(addUpdateItems);
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(newUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                bool newUpdateOk = idOk && statusOk;
                client.CloseConnection();

                // Step 7 Acceptance
                bool step7Ok = verifyIdentityOk && newUpdateOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                startConversationOk = await client.StartConversationAsync();

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 1000, 1000, false, false);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == expectedLastClients.Count;
                maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == expectedLastClients.Count;
                resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 8 Acceptance
                bool step8Ok = startConversationOk && queryOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }
            if (locServer != null)
            {
                locServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #20
0
        /// <summary>
        /// Checks whether AddRelatedIdentityRequest request is valid.
        /// </summary>
        /// <param name="Client">Client that sent the request.</param>
        /// <param name="AddRelatedIdentityRequest">Client's request message to validate.</param>
        /// <param name="MessageBuilder">Client's network message builder.</param>
        /// <param name="RequestMessage">Full request message from client.</param>
        /// <param name="ErrorResponse">If the function fails, this is filled with error response message that is ready to be sent to the client.</param>
        /// <returns>true if the profile update request can be applied, false otherwise.</returns>
        public static bool ValidateAddRelatedIdentityRequest(IncomingClient Client, AddRelatedIdentityRequest AddRelatedIdentityRequest, PsMessageBuilder MessageBuilder, PsProtocolMessage RequestMessage, out PsProtocolMessage ErrorResponse)
        {
            log.Trace("()");

            bool res = false;

            ErrorResponse = null;
            string details = null;

            if (AddRelatedIdentityRequest == null)
            {
                AddRelatedIdentityRequest = new AddRelatedIdentityRequest();
            }
            if (AddRelatedIdentityRequest.CardApplication == null)
            {
                AddRelatedIdentityRequest.CardApplication = new CardApplicationInformation();
            }
            if (AddRelatedIdentityRequest.SignedCard == null)
            {
                AddRelatedIdentityRequest.SignedCard = new SignedRelationshipCard();
            }
            if (AddRelatedIdentityRequest.SignedCard.Card == null)
            {
                AddRelatedIdentityRequest.SignedCard.Card = new RelationshipCard();
            }

            CardApplicationInformation cardApplication = AddRelatedIdentityRequest.CardApplication;
            SignedRelationshipCard     signedCard      = AddRelatedIdentityRequest.SignedCard;
            RelationshipCard           card            = signedCard.Card;

            byte[] applicationId = cardApplication.ApplicationId.ToByteArray();
            byte[] cardId        = card.CardId.ToByteArray();

            if ((applicationId.Length == 0) || (applicationId.Length > RelatedIdentity.CardIdentifierLength))
            {
                log.Debug("Card application ID is invalid.");
                details = "cardApplication.applicationId";
            }

            if (details == null)
            {
                byte[] appCardId = cardApplication.CardId.ToByteArray();
                if (!ByteArrayComparer.Equals(cardId, appCardId))
                {
                    log.Debug("Card IDs in application card and relationship card do not match.");
                    details = "cardApplication.cardId";
                }
            }

            if (details == null)
            {
                if (card.ValidFrom > card.ValidTo)
                {
                    log.Debug("Card validFrom field is greater than validTo field.");
                    details = "signedCard.card.validFrom";
                }
                else
                {
                    DateTime?cardValidFrom = ProtocolHelper.UnixTimestampMsToDateTime(card.ValidFrom);
                    DateTime?cardValidTo   = ProtocolHelper.UnixTimestampMsToDateTime(card.ValidTo);
                    if (cardValidFrom == null)
                    {
                        log.Debug("Card validFrom value '{0}' is not a valid timestamp.", card.ValidFrom);
                        details = "signedCard.card.validFrom";
                    }
                    else if (cardValidTo == null)
                    {
                        log.Debug("Card validTo value '{0}' is not a valid timestamp.", card.ValidTo);
                        details = "signedCard.card.validTo";
                    }
                }
            }

            if (details == null)
            {
                byte[] issuerPublicKey = card.IssuerPublicKey.ToByteArray();
                bool   pubKeyValid     = (0 < issuerPublicKey.Length) && (issuerPublicKey.Length <= ProtocolHelper.MaxPublicKeyLengthBytes);
                if (!pubKeyValid)
                {
                    log.Debug("Issuer public key has invalid length {0} bytes.", issuerPublicKey.Length);
                    details = "signedCard.card.issuerPublicKey";
                }
            }

            if (details == null)
            {
                byte[] recipientPublicKey = card.RecipientPublicKey.ToByteArray();
                if (!ByteArrayComparer.Equals(recipientPublicKey, Client.PublicKey))
                {
                    log.Debug("Caller is not recipient of the card.");
                    details = "signedCard.card.recipientPublicKey";
                }
            }

            if (details == null)
            {
                if (!Client.MessageBuilder.VerifySignedConversationRequestBodyPart(RequestMessage, cardApplication.ToByteArray(), Client.PublicKey))
                {
                    log.Debug("Caller is not recipient of the card.");
                    ErrorResponse = Client.MessageBuilder.CreateErrorInvalidSignatureResponse(RequestMessage);
                    details       = "";
                }
            }

            if (details == null)
            {
                SemVer cardVersion = new SemVer(card.Version);
                if (!cardVersion.Equals(SemVer.V100))
                {
                    log.Debug("Card version is invalid or not supported.");
                    details = "signedCard.card.version";
                }
            }

            if (details == null)
            {
                if (Encoding.UTF8.GetByteCount(card.Type) > PsMessageBuilder.MaxRelationshipCardTypeLengthBytes)
                {
                    log.Debug("Card type is too long.");
                    details = "signedCard.card.type";
                }
            }

            if (details == null)
            {
                RelationshipCard emptyIdCard = new RelationshipCard()
                {
                    CardId             = ProtocolHelper.ByteArrayToByteString(new byte[RelatedIdentity.CardIdentifierLength]),
                    Version            = card.Version,
                    IssuerPublicKey    = card.IssuerPublicKey,
                    RecipientPublicKey = card.RecipientPublicKey,
                    Type      = card.Type,
                    ValidFrom = card.ValidFrom,
                    ValidTo   = card.ValidTo
                };

                byte[] hash = Crypto.Sha256(emptyIdCard.ToByteArray());
                if (!ByteArrayComparer.Equals(hash, cardId))
                {
                    log.Debug("Card ID '{0}' does not match its hash '{1}'.", cardId.ToHex(64), hash.ToHex());
                    details = "signedCard.card.cardId";
                }
            }

            if (details == null)
            {
                byte[] issuerSignature = signedCard.IssuerSignature.ToByteArray();
                byte[] issuerPublicKey = card.IssuerPublicKey.ToByteArray();
                if (!Ed25519.Verify(issuerSignature, cardId, issuerPublicKey))
                {
                    log.Debug("Issuer signature is invalid.");
                    details = "signedCard.issuerSignature";
                }
            }

            if (details == null)
            {
                res = true;
            }
            else
            {
                if (ErrorResponse == null)
                {
                    ErrorResponse = MessageBuilder.CreateErrorInvalidValueResponse(RequestMessage, details);
                }
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();
            ProtocolClient issuer = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                // Establish hosting agreement for primary client.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool establishHostingOk = await client.EstablishHostingAsync("Primary");

                client.CloseConnection();

                // Check in primary client.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                bool checkInOk = await client.CheckInAsync();

                // Step 1 Acceptance
                bool step1Ok = listPortsOk && establishHostingOk && checkInOk;

                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");

                byte[]   primaryPubKey            = client.GetIdentityKeys().PublicKey;
                string   type                     = "Card Type A";
                DateTime validFrom                = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                DateTime validTo                  = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                SignedRelationshipCard signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                byte[] applicationId = new byte[] { 1 };
                CardApplicationInformation cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                byte[] signature = new byte[16];
                for (int i = 0; i < signature.Length; i++)
                {
                    signature[i] = 0x40;
                }

                Message requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                requestMessage.Request.ConversationRequest.Signature = ProtocolHelper.ByteArrayToByteString(signature);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = responseMessage.Response.Status == Status.ErrorInvalidSignature;

                bool req1Ok = idOk && statusOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 2 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                signature      = requestMessage.Request.ConversationRequest.Signature.ToByteArray();
                signature[0]  ^= 0x12;
                requestMessage.Request.ConversationRequest.Signature = ProtocolHelper.ByteArrayToByteString(signature);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorInvalidSignature;

                bool req2Ok = idOk && statusOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 3 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                bool req3Ok = idOk && statusOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 3 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorAlreadyExists;

                bool req4Ok = idOk && statusOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 4 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                byte[] hash = new byte[16];
                for (int i = 0; i < hash.Length; i++)
                {
                    hash[i] = 0x40;
                }

                cardApplication.CardId = ProtocolHelper.ByteArrayToByteString(hash);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "cardApplication.cardId";

                bool req5Ok = idOk && statusOk && detailsOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 5 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                hash     = cardApplication.CardId.ToByteArray();
                hash[0] ^= 0x12;
                cardApplication.CardId = ProtocolHelper.ByteArrayToByteString(hash);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "cardApplication.cardId";

                bool req6Ok = idOk && statusOk && detailsOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "cardApplication.applicationId";

                bool req7Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId = new byte[40];
                for (int i = 0; i < applicationId.Length; i++)
                {
                    applicationId[i] = 0x40;
                }

                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "cardApplication.applicationId";

                bool req8Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                byte[] issuerPubKey = new byte[10];
                Array.Copy(signedCard.Card.IssuerPublicKey.ToByteArray(), issuerPubKey, issuerPubKey.Length);
                signedCard.Card.IssuerPublicKey = ProtocolHelper.ByteArrayToByteString(issuerPubKey);


                RelationshipCard card = new RelationshipCard()
                {
                    CardId             = ProtocolHelper.ByteArrayToByteString(new byte[32]),
                    Version            = SemVer.V100.ToByteString(),
                    IssuerPublicKey    = signedCard.Card.IssuerPublicKey,
                    RecipientPublicKey = signedCard.Card.RecipientPublicKey,
                    Type      = signedCard.Card.Type,
                    ValidFrom = signedCard.Card.ValidFrom,
                    ValidTo   = signedCard.Card.ValidTo,
                };

                byte[] cardDataToHash = card.ToByteArray();
                byte[] cardId         = Crypto.Sha256(cardDataToHash);
                signedCard.Card.CardId = ProtocolHelper.ByteArrayToByteString(cardId);



                applicationId   = new byte[] { 6 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.issuerSignature";

                bool req9Ok = idOk && statusOk && detailsOk;



                type             = "Card Type A";
                validFrom        = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo          = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard       = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                issuerPubKey     = signedCard.Card.IssuerPublicKey.ToByteArray();
                issuerPubKey[0] ^= 0x12;
                signedCard.Card.IssuerPublicKey = ProtocolHelper.ByteArrayToByteString(issuerPubKey);


                card = new RelationshipCard()
                {
                    CardId             = ProtocolHelper.ByteArrayToByteString(new byte[32]),
                    Version            = SemVer.V100.ToByteString(),
                    IssuerPublicKey    = signedCard.Card.IssuerPublicKey,
                    RecipientPublicKey = signedCard.Card.RecipientPublicKey,
                    Type      = signedCard.Card.Type,
                    ValidFrom = signedCard.Card.ValidFrom,
                    ValidTo   = signedCard.Card.ValidTo,
                };

                cardDataToHash         = card.ToByteArray();
                cardId                 = Crypto.Sha256(cardDataToHash);
                signedCard.Card.CardId = ProtocolHelper.ByteArrayToByteString(cardId);


                applicationId   = new byte[] { 7 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.issuerSignature";

                bool req10Ok = idOk && statusOk && detailsOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                byte[] issuerSignature = new byte[20];
                Array.Copy(signedCard.IssuerSignature.ToByteArray(), issuerSignature, issuerSignature.Length);
                signedCard.IssuerSignature = ProtocolHelper.ByteArrayToByteString(issuerSignature);


                applicationId   = new byte[] { 8 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.issuerSignature";

                bool req11Ok = idOk && statusOk && detailsOk;


                type                       = "Card Type A";
                validFrom                  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo                    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard                 = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                issuerSignature            = signedCard.IssuerSignature.ToByteArray();
                issuerSignature[0]        ^= 0x12;
                signedCard.IssuerSignature = ProtocolHelper.ByteArrayToByteString(issuerSignature);


                applicationId   = new byte[] { 9 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.issuerSignature";

                bool req12Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                cardId     = new byte[20];
                Array.Copy(signedCard.Card.CardId.ToByteArray(), cardId, cardId.Length);
                signedCard.Card.CardId = ProtocolHelper.ByteArrayToByteString(cardId);


                applicationId   = new byte[] { 10 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.cardId";

                bool req13Ok = idOk && statusOk && detailsOk;


                type                   = "Card Type A";
                validFrom              = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo                = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard             = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                cardId                 = signedCard.Card.CardId.ToByteArray();
                cardId[0]             ^= 0x12;
                signedCard.Card.CardId = ProtocolHelper.ByteArrayToByteString(cardId);


                applicationId   = new byte[] { 11 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.cardId";

                bool req14Ok = idOk && statusOk && detailsOk;


                type      = "Card Type A";
                validFrom = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo   = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                byte[] rcptPubKey = new byte[20];
                Array.Copy(signedCard.Card.RecipientPublicKey.ToByteArray(), rcptPubKey, rcptPubKey.Length);
                signedCard = issuer.IssueRelationshipCard(rcptPubKey, type, validFrom, validTo);


                applicationId   = new byte[] { 12 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.recipientPublicKey";

                bool req15Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                rcptPubKey = new byte[primaryPubKey.Length];
                Array.Copy(primaryPubKey, rcptPubKey, rcptPubKey.Length);
                rcptPubKey[0] ^= 0x12;
                signedCard     = issuer.IssueRelationshipCard(rcptPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 13 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.recipientPublicKey";

                bool req16Ok = idOk && statusOk && detailsOk;



                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(1479220555000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 14 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.validFrom";

                bool req17Ok = idOk && statusOk && detailsOk;



                type       = new string('a', 70);
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 15 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.type";

                bool req18Ok = idOk && statusOk && detailsOk;


                type       = new string('ɐ', 35);
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 16 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.type";

                bool req19Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(new byte[] { 0, 0, 0 }, primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 17 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.version";

                bool req20Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(new byte[] { 1, 0 }, primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 18 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.version";

                bool req21Ok = idOk && statusOk && detailsOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = issuer.IssueRelationshipCard(new byte[] { 1, 0, 0, 0 }, primaryPubKey, type, validFrom, validTo);

                applicationId   = new byte[] { 19 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.version";

                bool req22Ok = idOk && statusOk && detailsOk;


                type      = "Card Type A";
                validFrom = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo   = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                byte[] badPubKey = new byte[130];
                for (int i = 0; i < badPubKey.Length; i++)
                {
                    badPubKey[i] = 0x40;
                }

                RelationshipCard badIssuerKeyCard = new RelationshipCard()
                {
                    CardId             = ProtocolHelper.ByteArrayToByteString(new byte[32]),
                    Version            = SemVer.V100.ToByteString(),
                    IssuerPublicKey    = ProtocolHelper.ByteArrayToByteString(badPubKey),
                    RecipientPublicKey = ProtocolHelper.ByteArrayToByteString(primaryPubKey),
                    Type      = type,
                    ValidFrom = ProtocolHelper.DateTimeToUnixTimestampMs(validFrom),
                    ValidTo   = ProtocolHelper.DateTimeToUnixTimestampMs(validTo)
                };

                signedCard = issuer.IssueRelationshipCard(badIssuerKeyCard);

                applicationId   = new byte[] { 20 };
                cardApplication = client.CreateRelationshipCardApplication(applicationId, signedCard);

                requestMessage = mb.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "signedCard.card.issuerPublicKey";

                bool req23Ok = idOk && statusOk && detailsOk;



                // Step 2 Acceptance
                bool step2Ok = req1Ok && req2Ok && req3Ok && req4Ok && req5Ok && req6Ok && req7Ok && req8Ok && req9Ok && req10Ok &&
                               req11Ok && req12Ok && req13Ok && req14Ok && req15Ok && req16Ok && req17Ok && req18Ok && req19Ok && req20Ok &&
                               req21Ok && req22Ok && req23Ok;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                applicationId  = new byte[] { 21 };
                requestMessage = mb.CreateRemoveRelatedIdentityRequest(applicationId);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorNotFound;
                bool removeOk = idOk && statusOk;


                type           = new string('a', 70);
                requestMessage = mb.CreateGetIdentityRelationshipsInformationRequest(client.GetIdentityId(), true, type, null);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "type";

                req1Ok = idOk && statusOk && detailsOk;


                type           = new string('ɐ', 35);
                requestMessage = mb.CreateGetIdentityRelationshipsInformationRequest(client.GetIdentityId(), true, type, null);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "type";

                req2Ok = idOk && statusOk && detailsOk;


                // Step 3 Acceptance
                bool step3Ok = removeOk && req1Ok && req2Ok;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok;


                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();
            issuer.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #22
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool hostingOk = await client.EstablishHostingAsync("Test");

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                bool checkInOk = await client.CheckInAsync();

                bool step1Ok = listPortsOk && hostingOk && checkInOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                byte[] serverId = new byte[5] {
                    0x40, 0x40, 0x40, 0x40, 0x40
                };
                List <CanKeyValue> clientData = new List <CanKeyValue>()
                {
                    new CanKeyValue()
                    {
                        Key = "key1", StringValue = "value 1"
                    },
                    new CanKeyValue()
                    {
                        Key = "key2", Uint32Value = 2
                    },
                    new CanKeyValue()
                    {
                        Key = "key3", BoolValue = true
                    },
                    new CanKeyValue()
                    {
                        Key = "key4", BinaryValue = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 2, 3 })
                    },
                };

                CanIdentityData identityData1 = new CanIdentityData()
                {
                    HostingServerId = ProtocolHelper.ByteArrayToByteString(serverId)
                };
                identityData1.KeyValueList.AddRange(clientData);

                Message requestMessage = mb.CreateCanStoreDataRequest(identityData1);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk      = responseMessage.Id == requestMessage.Id;
                bool statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "data.hostingServerId";

                // Step 2 Acceptance
                bool step2Ok = idOk && statusOk && detailsOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();


            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #23
0
        /// <summary>
        /// Refreshes profile server's IPNS record in CAN.
        /// </summary>
        /// <param name="IpnsRecord">IPNS record to refresh.</param>
        /// <param name="PublicKey">Public key of the IPNS record owner.</param>
        /// <returns>Structure describing whether the function succeeded and response provided by CAN server.</returns>
        public async Task <CanRefreshIpnsResult> RefreshIpnsRecord(CanIpnsEntry IpnsRecord, byte[] PublicKey)
        {
            log.Trace("(PublicKey:'{0}')", PublicKey.ToHex());

            string ipnsRecordEncoded = IpnsRecord.ToByteArray().ToBase64UrlPad(true);

            CanCryptoKey cryptoKey = new CanCryptoKey()
            {
                Type = CanCryptoKey.Types.KeyType.Ed25519,
                Data = ProtocolHelper.ByteArrayToByteString(PublicKey)
            };
            string keyEncoded = Base58Encoding.Encoder.Encode(cryptoKey.ToByteArray());

            log.Debug("Encoding public key: {0}", keyEncoded);

            NameValueCollection args = new NameValueCollection();

            args.Add("arg", ipnsRecordEncoded);
            args.Add("key", keyEncoded);

            CanApiResult apiResult = await SendRequest("name/upload", args);

            CanRefreshIpnsResult res = CanRefreshIpnsResult.FromApiResult(apiResult);

            if (res.Success)
            {
                res.IsCanError = false;

                // Check that the ID, path and sequence number match what we expect.
                string canId = CanApi.PublicKeyToId(PublicKey).ToBase58();
                if (res.Details.Peer == canId)
                {
                    string path = Encoding.UTF8.GetString(IpnsRecord.Value.ToByteArray());
                    if (res.Details.NewPath == path)
                    {
                        if (res.Details.NewSeq == IpnsRecord.Sequence)
                        {
                            // All OK.
                        }
                        else
                        {
                            log.Warn("CAN sequence is {0}, received {1}.", IpnsRecord.Sequence, res.Details.NewSeq);
                            res.Success = false;
                            res.Message = "CAN path in response does not match expected value.";
                        }
                    }
                    else
                    {
                        log.Warn("CAN path is '{0}', received '{1}'.", path, res.Details.NewPath);
                        res.Success = false;
                        res.Message = "CAN path in response does not match expected value.";
                    }
                }
                else
                {
                    log.Warn("CAN ID is '{0}', received '{1}'.", canId, res.Details.Peer);
                    res.Success = false;
                    res.Message = "CAN ID in response does not match expected value.";
                }
            }

            if (res.Success)
            {
                log.Trace("(-):*.Success={0}", res.Success);
            }
            else
            {
                log.Trace("(-):*.Success={0},*.IsCanError={1},*.Message='{2}'", res.Success, res.IsCanError, res.Message);
            }
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp          = (IPAddress)ArgumentValues["Server IP"];
            int       ClNonCustomerPort = (int)ArgumentValues["clNonCustomer Port"];
            int       ClCustomerPort    = (int)ArgumentValues["clCustomer Port"];

            log.Trace("(ServerIp:'{0}',ClNonCustomerPort:{1},ClCustomerPort:{2})", ServerIp, ClNonCustomerPort, ClCustomerPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                await client.ConnectAsync(ServerIp, ClNonCustomerPort, true);

                bool establishHostingOk = await client.EstablishHostingAsync();

                // Step 1 Acceptance
                bool step1Ok = establishHostingOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");

                client.CloseConnection();


                // Step 2
                log.Trace("Step 2");
                await client.ConnectAsync(ServerIp, ClCustomerPort, true);

                bool startConversationOk = await client.StartConversationAsync();

                Message requestMessage = mb.CreateCheckInRequest(client.Challenge);
                // Invalidate the signature.
                byte[] signature = requestMessage.Request.ConversationRequest.Signature.ToByteArray();
                byte[] sig32     = new byte[32];
                Array.Copy(signature, sig32, sig32.Length);
                requestMessage.Request.ConversationRequest.Signature = ProtocolHelper.ByteArrayToByteString(sig32);

                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk      = responseMessage.Id == requestMessage.Id;
                bool statusOk  = responseMessage.Response.Status == Status.ErrorInvalidSignature;
                bool checkInOk = idOk && statusOk;

                // Step 2 Acceptance
                bool step2Ok = startConversationOk && checkInOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");

                Passed = step1Ok && step2Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #25
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                byte[]  payload        = Encoding.UTF8.GetBytes("Hello");
                Message requestMessage = mb.CreatePingRequest(payload);
                requestMessage.Request.SingleRequest.Version = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 0 });

                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = responseMessage.Response.Status == Status.ErrorProtocolViolation;

                // We should be disconnected by now, so sending or receiving should throw.
                bool disconnectedOk = false;
                requestMessage = mb.CreatePingRequest(payload);

                try
                {
                    await client.SendMessageAsync(requestMessage);

                    await client.ReceiveMessageAsync();
                }
                catch
                {
                    log.Trace("Expected exception occurred.");
                    disconnectedOk = true;
                }

                // Step 1 Acceptance
                Passed = idOk && statusOk && disconnectedOk;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Announces server's primary server role interface to the LOC server.
        /// </summary>
        /// <param name="PrimaryPort">Primary port of the server.</param>
        /// <param name="Type">Type of the server.</param>
        /// <param name="Location">Optionally, an empty GpsLocation instance that will be filled with location information received from the LOC server if the function succeeds.</param>
        /// <returns>true if the function succeeds, false otherwise.</returns>
        public async Task <bool> RegisterPrimaryServerRoleAsync(int PrimaryPort, ServiceType Type, IopProtocol.GpsLocation Location = null)
        {
            log.Info("(PrimaryPort:{0})", PrimaryPort);

            bool res = false;

            ServiceInfo serviceInfo = new ServiceInfo()
            {
                Port        = (uint)PrimaryPort,
                Type        = Type,
                ServiceData = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(((KeysEd25519)config.Settings["Keys"]).PublicKey))
            };

            LocProtocolMessage request = MessageBuilder.CreateRegisterServiceRequest(serviceInfo);

            if (await SendMessageAsync(request))
            {
                LocProtocolMessage response = await ReceiveMessageAsync(shutdownSignaling.ShutdownCancellationTokenSource.Token);

                if (response != null)
                {
                    res = (response.Id == request.Id) &&
                          (response.MessageTypeCase == Message.MessageTypeOneofCase.Response) &&
                          (response.Response.Status == Status.Ok) &&
                          (response.Response.ResponseTypeCase == Response.ResponseTypeOneofCase.LocalService) &&
                          (response.Response.LocalService.LocalServiceResponseTypeCase == LocalServiceResponse.LocalServiceResponseTypeOneofCase.RegisterService);

                    if (res)
                    {
                        if (Location != null)
                        {
                            IopProtocol.GpsLocation location = new IopProtocol.GpsLocation(response.Response.LocalService.RegisterService.Location.Latitude, response.Response.LocalService.RegisterService.Location.Longitude);
                            Location.Latitude  = location.Latitude;
                            Location.Longitude = location.Longitude;
                            if (Location.IsValid())
                            {
                                res = true;
                            }
                            else
                            {
                                log.Error("Registration failed, LOC server provided invalid location information [{0}].", location);
                            }
                        }
                        else
                        {
                            res = true;
                        }

                        if (res)
                        {
                            log.Debug("Primary interface has been registered successfully on LOC server{0}.", Location != null ? string.Format(", server location set is [{0}]", Location) : "");
                        }
                    }
                    else
                    {
                        log.Error("Registration failed, response status is {0}.", response.Response != null ? response.Response.Status.ToString() : "n/a");
                    }
                }
                else
                {
                    log.Error("Invalid message received from LOC server.");
                }
            }
            else
            {
                log.Error("Unable to send register server request to LOC server.");
            }

            log.Info("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];
            int       LocPort     = (int)ArgumentValues["LOC Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2},LocPort:{3})", ServerIp, PrimaryPort, BasePort, LocPort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;
            LocServer      locServer     = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                // Create identities.
                ProfilePublicKeys = new List <byte[]>();
                for (int i = 0; i < ProfileNames.Count; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    ProfilePublicKeys.Add(protocolClient.GetIdentityKeys().PublicKey);
                    protocolClient.Dispose();
                }


                // Start simulated profile server.
                profileServer = new ProfileServer("TestProfileServer", ServerIp, BasePort, client.GetIdentityKeys(), new GpsLocation(1, 2));
                bool profileServerStartOk = profileServer.Start();

                // Start simulated LOC server.
                locServer = new LocServer("TestLocServer", ServerIp, LocPort);
                bool locServerStartOk = locServer.Start();

                await locServer.WaitForProfileServerConnectionAsync();

                bool step1Ok = profileServerStartOk && locServerStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");


                // Step 2
                log.Trace("Step 2");

                // Initialize the original set of update messages update.
                List <SharedProfileUpdateItem> originalAddUpdateItems = new List <SharedProfileUpdateItem>();
                for (int i = 0; i < ProfileNames.Count; i++)
                {
                    SharedProfileUpdateItem updateItem = new SharedProfileUpdateItem()
                    {
                        Add = new SharedProfileAddItem()
                        {
                            Version           = SemVer.V100.ToByteString(),
                            Name              = ProfileNames[i],
                            Type              = ProfileTypes[i],
                            ExtraData         = ProfileExtraData[i] != null ? ProfileExtraData[i] : "",
                            Latitude          = ProfileLocations[i].GetLocationTypeLatitude(),
                            Longitude         = ProfileLocations[i].GetLocationTypeLongitude(),
                            IdentityPublicKey = ProtocolHelper.ByteArrayToByteString(ProfilePublicKeys[i]),
                            SetThumbnailImage = ProfileImages[i] != null,
                            ThumbnailImage    = ProtocolHelper.ByteArrayToByteString(ProfileImages[i] != null ? File.ReadAllBytes(ProfileImages[i]) : new byte[0])
                        }
                    };

                    originalAddUpdateItems.Add(updateItem);
                }



                // Neighborhood initialization process.

                // Announce new neighbor.
                Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
                {
                    AddedNodeInfo = profileServer.GetNodeInfo(LocPort)
                };

                bool addNeighborOk = await locServer.SendChangeNotification(change);


                // Wait for start of neighborhood initialization process.
                IncomingServerMessage incomingServerMessage = await profileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);

                List <SharedProfileUpdateItem> updateItems = new List <SharedProfileUpdateItem>();
                updateItems.Add(originalAddUpdateItems[0]);
                updateItems.Add(originalAddUpdateItems[1]);
                updateItems.Add(originalAddUpdateItems[5]);
                updateItems.Add(originalAddUpdateItems[6]);

                SharedProfileUpdateItem changeItem0 = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[0].Add.IdentityPublicKey.ToByteArray())),
                    }
                };

                SharedProfileUpdateItem changeItem1 = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[1].Add.IdentityPublicKey.ToByteArray())),
                        SetName           = true,
                        Name = "X"
                    }
                };

                List <SharedProfileUpdateItem> originalUpdateItems = new List <SharedProfileUpdateItem>();
                originalUpdateItems.Add(changeItem1);
                originalUpdateItems.Add(originalAddUpdateItems[2]);
                originalUpdateItems.Add(originalAddUpdateItems[3]);
                originalUpdateItems.Add(originalAddUpdateItems[4]);

                Message requestMessage = await profileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, updateItems);

                incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, requestMessage);

                bool statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                bool updateOk = statusOk;


                // Finish neighborhood initialization process.
                Message finishRequest = await profileServer.SendFinishNeighborhoodInitializationRequest(incomingServerMessage.Client);

                incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, finishRequest);

                statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                bool finishOk = (finishRequest != null) && statusOk;

                bool step2Ok = addNeighborOk && updateOk && finishOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client.VerifyIdentityAsync();

                updateItems                = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]             = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Version = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 0 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.version");

                bool step3Ok = verifyIdentityOk && updateOk;
                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");


                // Step 4
                log.Trace("Step 4");

                updateItems                = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]             = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Version = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 0, 0 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.version");

                bool step4Ok = verifyIdentityOk && updateOk;
                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");


                // Step 5
                log.Trace("Step 5");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.IdentityPublicKey = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(new string ('a', 300)));

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.identityPublicKey");

                bool step5Ok = updateOk;
                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");


                // Step 6
                log.Trace("Step 6");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.IdentityPublicKey = originalAddUpdateItems[0].Add.IdentityPublicKey;

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.identityPublicKey");

                bool step6Ok = updateOk;
                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");


                // Step 7
                log.Trace("Step 7");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Name = new string('a', 70);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.name");

                bool step7Ok = updateOk;
                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");


                // Step 8
                log.Trace("Step 8");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Name = new string('ɐ', 50);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.name");

                bool step8Ok = updateOk;
                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");


                // Step 9
                log.Trace("Step 9");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Type = new string('a', 70);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.type");

                bool step9Ok = updateOk;
                log.Trace("Step 9: {0}", step9Ok ? "PASSED" : "FAILED");


                // Step 10
                log.Trace("Step 10");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Type = new string('ɐ', 50);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.type");

                bool step10Ok = updateOk;
                log.Trace("Step 10: {0}", step10Ok ? "PASSED" : "FAILED");


                // Step 11
                log.Trace("Step 11");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Type = "";

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.type");

                bool step11Ok = updateOk;
                log.Trace("Step 11: {0}", step11Ok ? "PASSED" : "FAILED");


                // Step 12
                log.Trace("Step 12");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.SetThumbnailImage = true;
                updateItems[1].Add.ThumbnailImage    = ProtocolHelper.ByteArrayToByteString(new byte[0]);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.thumbnailImage");

                bool step12Ok = updateOk;
                log.Trace("Step 12: {0}", step12Ok ? "PASSED" : "FAILED");


                // Step 13
                log.Trace("Step 13");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.SetThumbnailImage = true;
                updateItems[1].Add.ThumbnailImage    = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 1, 2 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.thumbnailImage");

                bool step13Ok = updateOk;
                log.Trace("Step 13: {0}", step13Ok ? "PASSED" : "FAILED");


                // Step 14
                log.Trace("Step 14");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Latitude = 987654321;

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.latitude");

                bool step14Ok = updateOk;
                log.Trace("Step 14: {0}", step14Ok ? "PASSED" : "FAILED");


                // Step 15
                log.Trace("Step 15");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Longitude = 987654321;

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.longitude");

                bool step15Ok = updateOk;
                log.Trace("Step 15: {0}", step15Ok ? "PASSED" : "FAILED");


                // Step 16
                log.Trace("Step 16");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.ExtraData = new string('a', 270);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.extraData");

                bool step16Ok = updateOk;
                log.Trace("Step 16: {0}", step16Ok ? "PASSED" : "FAILED");


                // Step 17
                log.Trace("Step 17");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.ExtraData = new string('ɐ', 150);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.extraData");

                bool step17Ok = updateOk;
                log.Trace("Step 17: {0}", step17Ok ? "PASSED" : "FAILED");


                // Step 18
                log.Trace("Step 18");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[0].Add.IdentityPublicKey.ToByteArray())),
                    }
                };

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.set*");

                bool step18Ok = updateOk;
                log.Trace("Step 18: {0}", step18Ok ? "PASSED" : "FAILED");



                // Step 19
                log.Trace("Step 19");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 1, 2 }),
                        SetName           = true,
                        Name = "X"
                    }
                };

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.identityNetworkId");

                bool step19Ok = updateOk;
                log.Trace("Step 19: {0}", step19Ok ? "PASSED" : "FAILED");


                // Step 20
                log.Trace("Step 20");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[0] = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[0].Add.IdentityPublicKey.ToByteArray())),
                        SetName           = true,
                        Name = "X"
                    }
                };
                updateItems[1] = new SharedProfileUpdateItem()
                {
                    Delete = new SharedProfileDeleteItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[0].Add.IdentityPublicKey.ToByteArray())),
                    }
                };

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.delete.identityNetworkId");

                bool step20Ok = updateOk;
                log.Trace("Step 20: {0}", step20Ok ? "PASSED" : "FAILED");


                // Step 21
                log.Trace("Step 21");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[0] = new SharedProfileUpdateItem(originalAddUpdateItems[2]);
                updateItems[1] = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[2].Add.IdentityPublicKey.ToByteArray())),
                        SetName           = true,
                        Name = "X"
                    }
                };

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.identityNetworkId");

                bool step21Ok = updateOk;
                log.Trace("Step 21: {0}", step21Ok ? "PASSED" : "FAILED");


                // Step 22
                log.Trace("Step 22");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[0] = new SharedProfileUpdateItem()
                {
                    Change = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(Crypto.Sha256(originalAddUpdateItems[2].Add.IdentityPublicKey.ToByteArray())),
                        SetName           = true,
                        Name = "X"
                    }
                };
                updateItems[1] = new SharedProfileUpdateItem(originalAddUpdateItems[2]);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.identityPublicKey");

                bool step22Ok = updateOk;
                log.Trace("Step 22: {0}", step22Ok ? "PASSED" : "FAILED");


                // Step 23
                log.Trace("Step 23");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetVersion = true;
                updateItems[1].Change.Version    = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 0 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.version");

                bool step23Ok = updateOk;
                log.Trace("Step 23: {0}", step23Ok ? "PASSED" : "FAILED");


                // Step 24
                log.Trace("Step 24");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetVersion = true;
                updateItems[1].Change.Version    = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 0, 0 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.version");

                bool step24Ok = updateOk;
                log.Trace("Step 24: {0}", step24Ok ? "PASSED" : "FAILED");


                // Step 25
                log.Trace("Step 25");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetName = true;
                updateItems[1].Change.Name    = new string('a', 70);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.name");

                bool step25Ok = updateOk;
                log.Trace("Step 25: {0}", step25Ok ? "PASSED" : "FAILED");


                // Step 26
                log.Trace("Step 26");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetName = true;
                updateItems[1].Change.Name    = new string('ɐ', 50);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.name");

                bool step26Ok = updateOk;
                log.Trace("Step 26: {0}", step26Ok ? "PASSED" : "FAILED");


                // Step 27
                log.Trace("Step 27");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetThumbnailImage = true;
                updateItems[1].Change.ThumbnailImage    = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(new string((char)0x40, 6000)));

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.thumbnailImage");

                bool step27Ok = updateOk;
                log.Trace("Step 27: {0}", step27Ok ? "PASSED" : "FAILED");


                // Step 28
                log.Trace("Step 28");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetThumbnailImage = true;
                updateItems[1].Change.ThumbnailImage    = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 1, 2 });

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.thumbnailImage");

                bool step28Ok = updateOk;
                log.Trace("Step 28: {0}", step28Ok ? "PASSED" : "FAILED");


                // Step 29
                log.Trace("Step 29");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetLocation = true;
                updateItems[1].Change.Latitude    = 987654321;
                updateItems[1].Change.Longitude   = 0;

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.latitude");

                bool step29Ok = updateOk;
                log.Trace("Step 29: {0}", step29Ok ? "PASSED" : "FAILED");


                // Step 30
                log.Trace("Step 30");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetLocation = true;
                updateItems[1].Change.Latitude    = 0;
                updateItems[1].Change.Longitude   = 987654321;

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.longitude");

                bool step30Ok = updateOk;
                log.Trace("Step 30: {0}", step30Ok ? "PASSED" : "FAILED");


                // Step 31
                log.Trace("Step 31");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetExtraData = true;
                updateItems[1].Change.ExtraData    = new string('a', 270);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.extraData");

                bool step31Ok = updateOk;
                log.Trace("Step 31: {0}", step31Ok ? "PASSED" : "FAILED");


                // Step 32
                log.Trace("Step 32");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetExtraData = true;
                updateItems[1].Change.ExtraData    = new string('ɐ', 150);

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.extraData");

                bool step32Ok = updateOk;
                log.Trace("Step 32: {0}", step32Ok ? "PASSED" : "FAILED");


                // Step 33
                log.Trace("Step 33");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem()
                {
                    Delete = new SharedProfileDeleteItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(new byte[] { 0, 1, 2 })
                    }
                };

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.delete.identityNetworkId");

                bool step33Ok = updateOk;
                log.Trace("Step 33: {0}", step33Ok ? "PASSED" : "FAILED");


                // Step 34
                log.Trace("Step 34");

                updateItems             = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1]          = new SharedProfileUpdateItem(updateItems[1]);
                updateItems[1].Add.Name = "";

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.add.name");

                bool step34Ok = updateOk;
                log.Trace("Step 34: {0}", step34Ok ? "PASSED" : "FAILED");


                // Step 35
                log.Trace("Step 35");

                updateItems    = new List <SharedProfileUpdateItem>(originalUpdateItems);
                updateItems[1] = new SharedProfileUpdateItem(changeItem0);
                updateItems[1].Change.SetName = true;
                updateItems[1].Change.Name    = "";

                updateOk = await PerformNeighborhoodUpdateAsync(updateItems, client, "1.change.name");

                bool step35Ok = updateOk;
                log.Trace("Step 35: {0}", step35Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok && step9Ok && step10Ok &&
                         step11Ok && step12Ok && step13Ok && step14Ok && step15Ok && step16Ok && step17Ok && step18Ok && step19Ok && step20Ok &&
                         step21Ok && step22Ok && step23Ok && step24Ok && step25Ok && step26Ok && step27Ok && step28Ok && step29Ok && step30Ok &&
                         step31Ok && step32Ok && step33Ok && step34Ok && step35Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }
            if (locServer != null)
            {
                locServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Removes servers from the profile server's neighborhood.
        /// </summary>
        /// <param name="NeighborhoodList">List of servers to cancel neighbor connection with..</param>
        /// <returns>true if the function succeeds, false otherwise.</returns>
        public bool CancelNeighborhood(List <ProfileServer> NeighborhoodList)
        {
            log.Trace("(NeighborhoodList.Count:{0})", NeighborhoodList.Count);

            List <NeighbourhoodChange> changes = new List <NeighbourhoodChange>();
            bool res = false;

            lock (neighborsLock)
            {
                foreach (ProfileServer ps in NeighborhoodList)
                {
                    // Do not process your own profile server.
                    if (ps.Name == profileServer.Name)
                    {
                        continue;
                    }

                    ps.Lock();
                    if (ps.IsInitialized())
                    {
                        // Ignore servers that are not in the neighborhood.
                        if (neighbors.ContainsKey(ps.Name))
                        {
                            neighbors.Remove(ps.Name);
                            log.Trace("Profile server '{0}' removed from the neighborhood of server '{1}'.", ps.Name, profileServer.Name);

                            // This neighbor server already runs, so we know its profile
                            // we can inform our profile server about it.
                            NeighbourhoodChange change = new NeighbourhoodChange();
                            change.RemovedNodeId = ProtocolHelper.ByteArrayToByteString(ps.GetNetworkId());
                            changes.Add(change);
                        }
                    }
                    else
                    {
                        // This neighbor server does not run yet, so we do not have its profile.
                        // We will uninstall a possibly installed event.
                        log.Debug("Profile server '{0}' is not initialized yet, uninstalling notification for server '{1}'.", ps.Name, profileServer.Name);
                        ps.UninstallInitializationNeighborhoodNotification(profileServer);
                    }
                    ps.Unlock();
                }
            }

            if ((connectedProfileServer != null) && connectedProfileServerWantsUpdates)
            {
                // If our profile server is running already, removing servers to its neighborhood
                // ends with sending update notification to the profile server.
                if (changes.Count > 0)
                {
                    log.Debug("Sending {0} neighborhood changes to profile server '{1}'.", changes.Count, profileServer.Name);
                    LocProtocolMessage message = connectedProfileServerMessageBuilder.CreateNeighbourhoodChangedNotificationRequest(changes);
                    res = SendMessageAsync(connectedProfileServer, message).Result;
                }
                else
                {
                    log.Debug("No neighborhood changes to send to profile server '{0}'.", profileServer.Name);
                    res = true;
                }
            }
            else
            {
                // Our profile server is not started/connected yet, which means we just modified its neighborhood,
                // and the information about its neighborhood will be send to it once it sends us GetNeighbourNodesByDistanceLocalRequest.
                log.Debug("Profile server '{0}' is not connected or not fully initialized yet, can't send changes.", profileServer.Name);
                res = true;
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool hostingOk = await client.EstablishHostingAsync("Test");

                client.CloseConnection();

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                bool checkInOk = await client.CheckInAsync();

                bool step1Ok = listPortsOk && hostingOk && checkInOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");

                string       validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                CanIpnsEntry ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes("/ipfs/QmaRvpLT4RgBDVY6cQKwqQGQNtbM31KSqh8TxvQgFoEUus")),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 1,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                Message requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = (responseMessage.Response.Status == Status.ErrorNotFound) || ((responseMessage.Response.Status == Status.ErrorInvalidValue) && (responseMessage.Response.Details == "record.value"));
                bool canPublishIpnsRecordOk = idOk && statusOk;

                // Step 2 Acceptance
                bool step2Ok = canPublishIpnsRecordOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");
                byte[]             serverId   = Crypto.Sha256(client.ServerKey);
                List <CanKeyValue> clientData = new List <CanKeyValue>()
                {
                    new CanKeyValue()
                    {
                        Key = "key1", StringValue = "value 1"
                    },
                    new CanKeyValue()
                    {
                        Key = "key2", Uint32Value = 2
                    },
                    new CanKeyValue()
                    {
                        Key = "key3", BoolValue = true
                    },
                    new CanKeyValue()
                    {
                        Key = "key4", BinaryValue = ProtocolHelper.ByteArrayToByteString(new byte[] { 1, 2, 3 })
                    },
                };

                CanIdentityData identityData1 = new CanIdentityData()
                {
                    HostingServerId = ProtocolHelper.ByteArrayToByteString(serverId)
                };
                identityData1.KeyValueList.AddRange(clientData);

                requestMessage = mb.CreateCanStoreDataRequest(identityData1);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                bool canStoreDataOk = idOk && statusOk;

                byte[] objectHash1 = responseMessage.Response.ConversationResponse.CanStoreData.Hash.ToByteArray();


                string objectPath1 = client.CreateIpfsPathFromHash(objectHash1);
                log.Trace("Object path 1 is '{0}'.", objectPath1);

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(null);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "record";
                canPublishIpnsRecordOk = idOk && statusOk && detailsOk;


                // Step 3 Acceptance
                bool step3Ok = canStoreDataOk && canPublishIpnsRecordOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");


                validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes("ipfabc")),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 1,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "record.value";
                canPublishIpnsRecordOk = idOk && statusOk && detailsOk;

                // Step 4 Acceptance
                bool step4Ok = canPublishIpnsRecordOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");


                // Step 5
                log.Trace("Step 5");

                validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath1)),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 1,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                canPublishIpnsRecordOk = idOk && statusOk;

                // Step 5 Acceptance
                bool step5Ok = canPublishIpnsRecordOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                // Step 6
                log.Trace("Step 6");

                validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath1)),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 1,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorRejected;
                detailsOk = !string.IsNullOrEmpty(responseMessage.Response.Details);
                canPublishIpnsRecordOk = idOk && statusOk && detailsOk;

                // Step 6 Acceptance
                bool step6Ok = canPublishIpnsRecordOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");


                // Step 7
                log.Trace("Step 7");

                validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath1)),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 2,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(new byte[] { 0x40, 0x40, 0x40, 0x40, 0x40 });

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorRejected;
                detailsOk = !string.IsNullOrEmpty(responseMessage.Response.Details);
                canPublishIpnsRecordOk = idOk && statusOk && detailsOk;

                // Step 7 Acceptance
                bool step7Ok = canPublishIpnsRecordOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");


                requestMessage = mb.CreateCanStoreDataRequest(null);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk           = responseMessage.Id == requestMessage.Id;
                statusOk       = responseMessage.Response.Status == Status.Ok;
                canStoreDataOk = idOk && statusOk;


                validityString = DateTime.UtcNow.AddMonths(1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", DateTimeFormatInfo.InvariantInfo);
                ipnsRecord     = new CanIpnsEntry()
                {
                    Value        = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(objectPath1)),
                    ValidityType = CanIpnsEntry.Types.ValidityType.Eol,
                    Validity     = ProtocolHelper.ByteArrayToByteString(Encoding.UTF8.GetBytes(validityString)),
                    Sequence     = 3,
                    Ttl          = 6000000000,
                };
                ipnsRecord.Signature = ProtocolHelper.ByteArrayToByteString(client.CreateIpnsRecordSignature(ipnsRecord));

                requestMessage = mb.CreateCanPublishIpnsRecordRequest(ipnsRecord);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorNotFound;
                canPublishIpnsRecordOk = idOk && statusOk;

                // Step 8 Acceptance
                bool step8Ok = canStoreDataOk && canPublishIpnsRecordOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();


            log.Trace("(-):{0}", res);
            return(res);
        }
Exemple #30
0
    /// <summary>
    /// Implementation of the test itself.
    /// </summary>
    /// <returns>true if the test passes, false otherwise.</returns>
    public override async Task<bool> RunAsync()
    {
      IPAddress ServerIp = (IPAddress)ArgumentValues["Server IP"];
      int ClNonCustomerPort = (int)ArgumentValues["clNonCustomer Port"];
      log.Trace("(ServerIp:'{0}',ClNonCustomerPort:{1})", ServerIp, ClNonCustomerPort);

      bool res = false;
      Passed = false;

      ProtocolClient client = new ProtocolClient();
      try
      {
        MessageBuilder mb = client.MessageBuilder;

        // Step 1
        await client.ConnectAsync(ServerIp, ClNonCustomerPort, true);

        Message requestMessage = client.CreateStartConversationRequest();
        byte[] badPubKey = new byte[0];
        requestMessage.Request.ConversationRequest.Start.PublicKey = ProtocolHelper.ByteArrayToByteString(badPubKey);
        await client.SendMessageAsync(requestMessage);
        Message responseMessage = await client.ReceiveMessageAsync();

        bool idOk = responseMessage.Id == requestMessage.Id;
        bool statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
        bool detailsOk = responseMessage.Response.Details == "publicKey";

        bool start1Ok = idOk && statusOk && detailsOk;


        requestMessage = client.CreateStartConversationRequest();
        badPubKey = new byte[130];
        for (int i = 0; i < badPubKey.Length; i++)
          badPubKey[i] = 0x40;

        requestMessage.Request.ConversationRequest.Start.PublicKey = ProtocolHelper.ByteArrayToByteString(badPubKey);
        await client.SendMessageAsync(requestMessage);
        responseMessage = await client.ReceiveMessageAsync();

        idOk = responseMessage.Id == requestMessage.Id;
        statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
        detailsOk = responseMessage.Response.Details == "publicKey";

        bool start2Ok = idOk && statusOk && detailsOk;

        // Step 1 Acceptance
        bool step1Ok = start1Ok && start2Ok;


        Passed = step1Ok;

        res = true;
      }
      catch (Exception e)
      {
        log.Error("Exception occurred: {0}", e.ToString());
      }
      client.Dispose();

      log.Trace("(-):{0}", res);
      return res;
    }