Exemplo n.º 1
0
        /// <summary>
        /// Verifies contents of list of relationships returned by the profile server against the expected list of cards.
        /// </summary>
        /// <param name="CardNumbers">Numbers of cards that are expected to be in the relationship list.</param>
        /// <param name="RelationshipList">Card list returned by the profile server.</param>
        /// <returns>true if the <paramref name="RelationshipList"/> contains cards specified by card numbers in <paramref name="CardNumbers"/>.</returns>
        public bool CheckRelationships(HashSet <int> CardNumbers, IEnumerable <IdentityRelationship> RelationshipList)
        {
            log.Trace("()");
            bool error = false;

            bool[] cardsOk = new bool[SignedCards.Count];
            foreach (IdentityRelationship relationship in RelationshipList)
            {
                CardApplicationInformation cardApplication = relationship.CardApplication;
                byte[] cardApplicationSignature            = relationship.CardApplicationSignature.ToByteArray();
                SignedRelationshipCard signedCard          = relationship.Card;
                RelationshipCard       card = signedCard.Card;
                byte[] cardId = card.CardId.ToByteArray();

                int cardIndex = -1;
                for (int i = 0; i < SignedCards.Count; i++)
                {
                    byte[] existingCardId = SignedCards[i].Card.CardId.ToByteArray();
                    if (!cardsOk[i] && (StructuralComparisons.StructuralComparer.Compare(existingCardId, cardId) == 0))
                    {
                        cardIndex = i;
                        break;
                    }
                }

                if (cardIndex != -1)
                {
                    if (CardNumbers.Contains(cardIndex + 1))
                    {
                        byte[] issuerPublicKey = card.IssuerPublicKey.ToByteArray();
                        byte[] cardSignature   = signedCard.IssuerSignature.ToByteArray();

                        bool cardSignatureOk = Ed25519.Verify(cardSignature, cardId, issuerPublicKey);
                        bool cardContentOk   = StructuralComparisons.StructuralComparer.Compare(SignedCards[cardIndex].ToByteArray(), signedCard.ToByteArray()) == 0;

                        bool cardOk = cardSignatureOk && cardContentOk;

                        byte[] recipientPublicKey     = card.RecipientPublicKey.ToByteArray();
                        bool   applicationSignatureOk = Ed25519.Verify(cardApplicationSignature, cardApplication.ToByteArray(), recipientPublicKey);
                        bool   applicationContentOk   = StructuralComparisons.StructuralComparer.Compare(CardApplications[cardIndex].ToByteArray(), cardApplication.ToByteArray()) == 0;
                        bool   applicationOk          = applicationSignatureOk && applicationContentOk;

                        if (!cardOk)
                        {
                            log.Trace("Card index {0} is corrupted.", cardIndex + 1);
                            error = true;
                            break;
                        }

                        if (!applicationOk)
                        {
                            log.Trace("Card application ID '{0}' for card index {1} is corrupted.", Crypto.ToHex(cardApplication.ApplicationId.ToByteArray()), cardIndex + 1);
                            error = true;
                            break;
                        }

                        cardsOk[cardIndex] = true;
                    }
                }
                else
                {
                    log.Trace("Card ID '{0}' not recognized.", Crypto.ToHex(cardId));
                    error = true;
                    break;
                }
            }

            foreach (int index in CardNumbers)
            {
                if (!cardsOk[index - 1])
                {
                    log.Trace("Card index {0} not retrieved.", index);
                    error = true;
                    break;
                }
            }

            bool res = !error;

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemplo n.º 2
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 clientPrimary   = new ProtocolClient();
            ProtocolClient clientSecondary = new ProtocolClient();

            try
            {
                MessageBuilder mbPrimary   = clientPrimary.MessageBuilder;
                MessageBuilder mbSecondary = clientSecondary.MessageBuilder;

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

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

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

                clientPrimary.CloseConnection();

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

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

                clientPrimary.CloseConnection();

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

                bool checkInOk = await clientPrimary.CheckInAsync();

                bool primaryOk = establishHostingOk && checkInOk;

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

                establishHostingOk = await clientSecondary.EstablishHostingAsync("Primary");

                clientSecondary.CloseConnection();

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

                checkInOk = await clientSecondary.CheckInAsync();

                bool secondaryOk = establishHostingOk && checkInOk;

                // Create card issuers.
                CardIssuers = new List <ProtocolClient>();
                for (int i = 0; i < IssuerCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    CardIssuers.Add(profileClient);
                }


                // Step 1 Acceptance
                bool step1Ok = listPortsOk && primaryOk && secondaryOk;

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



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

                SignedCards      = new List <SignedRelationshipCard>();
                CardApplications = new List <CardApplicationInformation>();

                // Just to make it easy to follow the test specification.
                ProtocolClient Identity1 = CardIssuers[0];
                ProtocolClient Identity2 = CardIssuers[1];
                ProtocolClient Identity3 = CardIssuers[2];
                ProtocolClient Identity4 = CardIssuers[3];
                ProtocolClient Identity5 = CardIssuers[4];

                log.Trace("Identity1 ID: {0}", Crypto.ToHex(Identity1.GetIdentityId()));
                log.Trace("Identity2 ID: {0}", Crypto.ToHex(Identity2.GetIdentityId()));
                log.Trace("Identity3 ID: {0}", Crypto.ToHex(Identity3.GetIdentityId()));
                log.Trace("Identity4 ID: {0}", Crypto.ToHex(Identity4.GetIdentityId()));
                log.Trace("Identity5 ID: {0}", Crypto.ToHex(Identity5.GetIdentityId()));


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

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

                Message requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                Message responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req1Ok = idOk && statusOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(1479220557000);
                signedCard = Identity1.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req2Ok = idOk && statusOk;


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

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req3Ok = idOk && statusOk;


                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(2479220555000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity2.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req4Ok = idOk && statusOk;


                type       = "Card Type B";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity3.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req5Ok = idOk && statusOk;


                type       = "Card Type B";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity4.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req6Ok = idOk && statusOk;


                type       = "Card Type C";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity4.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req7Ok = idOk && statusOk;


                type       = "Card Type C";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity4.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req8Ok = idOk && statusOk;


                type       = "Other";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity5.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

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

                requestMessage = mbPrimary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool req9Ok = idOk && statusOk;


                // Step 2 Acceptance
                bool step2Ok = req1Ok && req2Ok && req3Ok && req4Ok && req5Ok && req6Ok && req7Ok && req8Ok && req9Ok;

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


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

                byte[] secondaryPubKey = clientSecondary.GetIdentityKeys().PublicKey;
                type       = "Card Type A";
                validFrom  = ProtocolHelper.UnixTimestampMsToDateTime(1479220556000);
                validTo    = ProtocolHelper.UnixTimestampMsToDateTime(2479220556000);
                signedCard = Identity1.IssueRelationshipCard(secondaryPubKey, type, validFrom, validTo);
                SignedCards.Add(signedCard);

                applicationId   = new byte[] { 1 };
                cardApplication = clientSecondary.CreateRelationshipCardApplication(applicationId, signedCard);
                CardApplications.Add(cardApplication);

                requestMessage = mbSecondary.CreateAddRelatedIdentityRequest(cardApplication, signedCard);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

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

                bool req10Ok = idOk && statusOk;


                // Step 3 Acceptance
                bool step3Ok = req10Ok;

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


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

                byte[] primaryClientId = clientPrimary.GetIdentityId();
                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, null, null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;
                SemVer receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                bool   versionOk       = receivedVersion.Equals(SemVer.V100);

                HashSet <int> numberList = new HashSet <int>()
                {
                    1, 2, 3, 4, 5, 6, 7, 8, 9
                };
                bool relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req1Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, false, null, null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 3, 5, 6, 7, 8, 9
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req2Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "*", null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2, 3, 4, 5, 6, 7, 8, 9
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req3Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "**", null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2, 3, 4, 5, 6, 7, 8, 9
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req4Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "Card*", null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2, 3, 4, 5, 6, 7, 8
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req5Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "*Type A", null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2, 3, 4
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req6Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "*Type *", null);
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2, 3, 4, 5, 6, 7, 8
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req7Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, null, Identity1.GetIdentityId());
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 2
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req8Ok = idOk && statusOk && versionOk && relationshipsOk;


                requestMessage = mbSecondary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "*C", Identity4.GetIdentityId());
                await clientSecondary.SendMessageAsync(requestMessage);

                responseMessage = await clientSecondary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    7, 8
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req9Ok = idOk && statusOk && versionOk && relationshipsOk;


                // Step 4 Acceptance
                bool step4Ok = req1Ok && req2Ok && req3Ok && req4Ok && req5Ok && req6Ok && req7Ok && req8Ok && req9Ok;

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



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

                applicationId  = new byte[] { 2 };
                requestMessage = mbPrimary.CreateRemoveRelatedIdentityRequest(applicationId);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool removeRelation1Ok = idOk && statusOk;

                applicationId  = new byte[] { 4 };
                requestMessage = mbPrimary.CreateRemoveRelatedIdentityRequest(applicationId);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

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

                bool removeRelation2Ok = idOk && statusOk;



                requestMessage = mbPrimary.CreateGetIdentityRelationshipsInformationRequest(primaryClientId, true, "*Type a*", null);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                numberList = new HashSet <int>()
                {
                    1, 3
                };
                relationshipsOk = CheckRelationships(numberList, responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships);

                req1Ok = idOk && statusOk && versionOk && relationshipsOk;



                byte[] partId = new byte[10];
                Array.Copy(primaryClientId, partId, partId.Length);
                requestMessage = mbPrimary.CreateGetIdentityRelationshipsInformationRequest(partId, true, "*Type a*", null);
                await clientPrimary.SendMessageAsync(requestMessage);

                responseMessage = await clientPrimary.ReceiveMessageAsync();

                idOk            = responseMessage.Id == requestMessage.Id;
                statusOk        = responseMessage.Response.Status == Status.Ok;
                receivedVersion = new SemVer(responseMessage.Response.SingleResponse.Version);
                versionOk       = receivedVersion.Equals(SemVer.V100);

                relationshipsOk = responseMessage.Response.SingleResponse.GetIdentityRelationshipsInformation.Relationships.Count == 0;

                req1Ok = idOk && statusOk && versionOk && relationshipsOk;



                // Step 5 Acceptance
                bool step5Ok = removeRelation1Ok && removeRelation2Ok && req1Ok && req2Ok;

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


                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok;

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

            if (CardIssuers != null)
            {
                for (int i = 0; i < IssuerCount; i++)
                {
                    if (CardIssuers[i] != null)
                    {
                        CardIssuers[i].Dispose();
                    }
                }
            }


            log.Trace("(-):{0}", res);
            return(res);
        }
Exemplo n.º 3
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();
            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);

                bool reqOk = true;
                for (int i = 0; i < RequestCount; i++)
                {
                    SignedRelationshipCard signedCard = issuer.IssueRelationshipCard(primaryPubKey, type, validFrom, validTo);

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

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

                    Message responseMessage = await client.ReceiveMessageAsync();

                    bool idOk     = responseMessage.Id == requestMessage.Id;
                    bool statusOk = i < 100 ? (responseMessage.Response.Status == Status.Ok) : responseMessage.Response.Status == Status.ErrorQuotaExceeded;

                    reqOk = idOk && statusOk;
                    if (!reqOk)
                    {
                        break;
                    }
                }

                // Step 2 Acceptance
                bool step2Ok = reqOk;

                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();
            issuer.Dispose();

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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();
            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);
        }