Beispiel #1
0
        public async Task DuplicateSignaturesAreReduced()
        {
            await using var client = _network.NewClient();
            var(_, privateKey)     = Generator.KeyPair();
            var invoice = new Invoice(new Proto.TransactionBody
            {
                TransactionID = new Proto.TransactionID(client.CreateNewTxId()),
                Memo          = Generator.String(20, 30)
            });
            var signatory = new Signatory(CustomSigner);

            await(signatory as ISignatory).SignAsync(invoice);
            var signedTransaction = invoice.GenerateSignedTransactionFromSignatures(0);
            var signatureMap      = signedTransaction.SigMap;

            Assert.Single(signatureMap.SigPair);
            Assert.Empty(signatureMap.SigPair[0].PubKeyPrefix);

            Task CustomSigner(IInvoice invoice)
            {
                for (int i = 0; i < Generator.Integer(3, 5); i++)
                {
                    var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(privateKey);
                    var prefix     = signingKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).ToArray();
                    var signature  = SignatureAlgorithm.Ed25519.Sign(signingKey, invoice.TxBytes.Span);
                    invoice.AddSignature(KeyType.Ed25519, prefix, signature);
                }
                return(Task.CompletedTask);
            }
        }
Beispiel #2
0
        public async Task SignatureMapNoWithOneSignatureAndTrimLimitInlucdesPrefix()
        {
            await using var client = _network.NewClient();
            var(_, privateKey)     = Generator.KeyPair();
            var invoice = new Invoice(new Proto.TransactionBody
            {
                TransactionID = new Proto.TransactionID(client.CreateNewTxId()),
                Memo          = Generator.String(20, 30)
            });
            var signatory = new Signatory(CustomSigner);

            await(signatory as ISignatory).SignAsync(invoice);
            var trimLimit         = Generator.Integer(5, 10);
            var signedTransaction = invoice.GenerateSignedTransactionFromSignatures(trimLimit);
            var signatureMap      = signedTransaction.SigMap;

            Assert.Single(signatureMap.SigPair);
            Assert.Equal(trimLimit, signatureMap.SigPair[0].PubKeyPrefix.Length);

            Task CustomSigner(IInvoice invoice)
            {
                var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(privateKey);
                var prefix     = signingKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).ToArray();
                var signature  = SignatureAlgorithm.Ed25519.Sign(signingKey, invoice.TxBytes.Span);

                invoice.AddSignature(KeyType.Ed25519, prefix, signature);
                return(Task.CompletedTask);
            }
        }
Beispiel #3
0
        public async Task PrefixTrimAccountsForShortPrefixes()
        {
            var sigCount = Generator.Integer(5, 10);
            var prefix   = Encoding.ASCII.GetBytes(Generator.Code(sigCount + 10));

            await using var client = _network.NewClient();
            var invoice = new Invoice(new Proto.TransactionBody
            {
                TransactionID = new Proto.TransactionID(client.CreateNewTxId()),
                Memo          = Generator.String(20, 30)
            });

            await(new Signatory(CustomSigner) as ISignatory).SignAsync(invoice);
            var signedTransaction = invoice.GenerateSignedTransactionFromSignatures(sigCount - 3);
            var signatureMap      = signedTransaction.SigMap;

            Assert.Equal(sigCount, signatureMap.SigPair.Count);
            for (int i = 0; i < signatureMap.SigPair.Count; i++)
            {
                Assert.Equal(i + 1, signatureMap.SigPair[i].PubKeyPrefix.Length);
            }
            Task CustomSigner(IInvoice invoice)
            {
                var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(Generator.KeyPair().privateKey);
                var signature  = SignatureAlgorithm.Ed25519.Sign(signingKey, invoice.TxBytes.Span);

                for (int i = 0; i < sigCount; i++)
                {
                    var thumbprint = prefix.Take(1 + i).ToArray();
                    invoice.AddSignature(KeyType.Ed25519, thumbprint, signature);
                }
                return(Task.CompletedTask);
            }
        }
Beispiel #4
0
        public async Task CanEmbedMessagesInTheSignatureItself()
        {
            var(_, privateKey) = Generator.KeyPair();
            var randomBytes = Generator.SHA384Hash();

            await using var fx = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 0);

            await AssertHg.CryptoBalanceAsync(fx, 0);

            var transferAmount = Generator.Integer(10, 100);
            var receipt        = await fx.Client.TransferAsync(_network.Payer, fx.Record.Address, transferAmount, ctx =>
            {
                ctx.Signatory = new Signatory(_network.PrivateKey, new Signatory(CustomSigner));
            });

            Assert.Equal(ResponseCode.Success, receipt.Status);
            await AssertHg.CryptoBalanceAsync(fx, transferAmount);

            Task CustomSigner(IInvoice invoice)
            {
                var message    = Encoding.ASCII.GetBytes("This is an Embedded Message");
                var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(privateKey);

                invoice.AddSignature(KeyType.Ed25519, message, message);
                return(Task.CompletedTask);
            }
        }
Beispiel #5
0
        public async Task UnrelatedPublicKeysCanSignUnrelatedMessage()
        {
            var(_, privateKey) = Generator.KeyPair();
            await using var fx = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 0);

            await AssertHg.CryptoBalanceAsync(fx, 0);

            var transferAmount = Generator.Integer(10, 100);
            var receipt        = await fx.Client.TransferAsync(_network.Payer, fx.Record.Address, transferAmount, ctx =>
            {
                ctx.Signatory = new Signatory(_network.PrivateKey, new Signatory(CustomSigner));
            });

            Assert.Equal(ResponseCode.Success, receipt.Status);
            await AssertHg.CryptoBalanceAsync(fx, transferAmount);

            Task CustomSigner(IInvoice invoice)
            {
                var randomBytes = Generator.SHA384Hash();
                var signingKey  = TestKeys.ImportPrivateEd25519KeyFromBytes(privateKey);
                var prefix      = signingKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).TakeLast(32).Take(6).ToArray();
                var signature   = SignatureAlgorithm.Ed25519.Sign(signingKey, randomBytes.Span);

                invoice.AddSignature(KeyType.Ed25519, prefix, signature);
                return(Task.CompletedTask);
            }
        }
 // Arrange
 static void Configure(AppleAuthenticationOptions options)
 {
     options.ClientId = "my-client-id";
     options.ClientSecretExpiresAfter = TimeSpan.FromMinutes(1);
     options.KeyId      = "my-key-id";
     options.TeamId     = "my-team-id";
     options.PrivateKey = (_, cancellationToken) => TestKeys.GetPrivateKeyAsync(cancellationToken);
 }
        public async Task TestValidators80DutiesForEpochZeroHaveExactlyOneProposerPerSlot()
        {
            // Arrange
            IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true);

            testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>());
            testServiceCollection.AddSingleton <IEth1DataProvider>(Substitute.For <IEth1DataProvider>());
            testServiceCollection.AddSingleton <IOperationPool>(Substitute.For <IOperationPool>());
            ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider();
            BeaconState     state      = TestState.PrepareTestState(testServiceProvider);
            ForkChoice      forkChoice = testServiceProvider.GetService <ForkChoice>();

            // Get genesis store initialise MemoryStoreProvider with the state
            _ = forkChoice.GetGenesisStore(state);

            TimeParameters timeParameters     = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            int            numberOfValidators = state.Validators.Count;

            Console.WriteLine("Number of validators: {0}", numberOfValidators);
            BlsPublicKey[] publicKeys  = TestKeys.PublicKeys(timeParameters).ToArray();
            byte[][]       privateKeys = TestKeys.PrivateKeys(timeParameters).ToArray();
            for (int index = 0; index < numberOfValidators; index++)
            {
                Console.WriteLine("[{0}] priv:{1} pub:{2}", index, "0x" + BitConverter.ToString(privateKeys[index]).Replace("-", ""), publicKeys[index]);
            }

            // Act
            Epoch          targetEpoch         = new Epoch(0);
            var            validatorPublicKeys = publicKeys.Take(numberOfValidators);
            IBeaconNodeApi beaconNode          = testServiceProvider.GetService <IBeaconNodeApi>();

            beaconNode.ShouldBeOfType(typeof(BeaconNodeFacade));
            var validatorDuties = await beaconNode.ValidatorDutiesAsync(validatorPublicKeys, targetEpoch);

            for (var index = 0; index < validatorDuties.Count; index++)
            {
                ValidatorDuty validatorDuty = validatorDuties[index];
                Console.WriteLine("Index [{0}], Epoch {1}, Validator {2}, : attestation slot {3}, shard {4}, proposal slot {5}",
                                  index, targetEpoch, validatorDuty.ValidatorPublicKey, validatorDuty.AttestationSlot,
                                  (ulong)validatorDuty.AttestationShard, validatorDuty.BlockProposalSlot);
            }

            // Assert
            Dictionary <Slot, IGrouping <Slot, ValidatorDuty> > groupsByProposalSlot = validatorDuties
                                                                                       .GroupBy(x => x.BlockProposalSlot)
                                                                                       .ToDictionary(x => x.Key, x => x);

            groupsByProposalSlot[new Slot(0)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(1)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(2)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(3)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(4)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(5)].Count().ShouldBe(1);
            //groupsByProposalSlot[new Slot(6)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(7)].Count().ShouldBe(1);
            //groupsByProposalSlot[Slot.None].Count().ShouldBe(numberOfValidators - 7);
        }
Beispiel #8
0
 public static TheoryData <IoTHubDeviceInfo> Serialize_Deserialize_Composition_Should_Preserve_Information_TheoryData() => TheoryDataFactory.From(
     from networkSessionKey in new[] { (NetworkSessionKey?)null, TestKeys.CreateNetworkSessionKey(3) }
     select new IoTHubDeviceInfo
 {
     DevAddr    = new DevAddr(1),
     DevEUI     = new DevEui(2),
     GatewayId  = "foo",
     NwkSKey    = networkSessionKey,
     PrimaryKey = TestKeys.CreateAppKey(4).ToString()
 });
        public async Task TestValidators80DutiesForEpochOneHaveExactlyOneProposerPerSlot()
        {
            // Arrange
            IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true);

            testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>());
            testServiceCollection.AddSingleton <IEth1DataProvider>(Substitute.For <IEth1DataProvider>());
            testServiceCollection.AddSingleton <IOperationPool>(Substitute.For <IOperationPool>());
            ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider();
            BeaconState     state      = TestState.PrepareTestState(testServiceProvider);
            ForkChoice      forkChoice = testServiceProvider.GetService <ForkChoice>();

            // Get genesis store initialise MemoryStoreProvider with the state
            _ = forkChoice.GetGenesisStore(state);

            TimeParameters timeParameters     = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            int            numberOfValidators = state.Validators.Count;

            Console.WriteLine("Number of validators: {0}", numberOfValidators);
            BlsPublicKey[] publicKeys = TestKeys.PublicKeys(timeParameters).ToArray();

            // Act
            Epoch targetEpoch = new Epoch(1);
            IEnumerable <BlsPublicKey> validatorPublicKeys = publicKeys.Take(numberOfValidators);
            IBeaconNodeApi             beaconNode          = testServiceProvider.GetService <IBeaconNodeApi>();

            beaconNode.ShouldBeOfType(typeof(BeaconNodeFacade));

            int validatorDutyIndex = 0;
            List <ValidatorDuty> validatorDuties = new List <ValidatorDuty>();

            await foreach (ValidatorDuty validatorDuty in beaconNode.ValidatorDutiesAsync(validatorPublicKeys, targetEpoch, CancellationToken.None))
            {
                validatorDuties.Add(validatorDuty);
                Console.WriteLine("Index [{0}], Epoch {1}, Validator {2}, : attestation slot {3}, shard {4}, proposal slot {5}",
                                  validatorDutyIndex, targetEpoch, validatorDuty.ValidatorPublicKey, validatorDuty.AttestationSlot,
                                  (ulong)validatorDuty.AttestationShard, validatorDuty.BlockProposalSlot);
                validatorDutyIndex++;
            }

            // Assert
            Dictionary <Slot, IGrouping <Slot, ValidatorDuty> > groupsByProposalSlot = validatorDuties
                                                                                       .GroupBy(x => x.BlockProposalSlot)
                                                                                       .ToDictionary(x => x.Key, x => x);

            groupsByProposalSlot[new Slot(8)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(9)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(10)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(11)].Count().ShouldBe(1);
            //groupsByProposalSlot[new Slot(12)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(13)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(14)].Count().ShouldBe(1);
            groupsByProposalSlot[new Slot(15)].Count().ShouldBe(1);
            //groupsByProposalSlot[Slot.None].Count().ShouldBe(numberOfValidators - 8);
        }
Beispiel #10
0
        public async Task When_StationEui_Missing_Should_Fail()
        {
            var devAddr   = new DevAddr(0x023637F8);
            var appSKey   = TestKeys.CreateAppSessionKey(0xABC0200000000000, 0x09);
            var nwkSKey   = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var simDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, deviceClassType: 'c', gatewayID: ServerGatewayID));
            var devEUI    = simDevice.DevEUI;

            simDevice.SetupJoin(appSKey, nwkSKey, devAddr);

            this.deviceApi.Setup(x => x.GetPrimaryKeyByEuiAsync(devEUI))
            .ReturnsAsync("123");

            var twin = simDevice.CreateOTAATwin(
                desiredProperties: new Dictionary <string, object>
            {
                { TwinProperty.RX2DataRate, "10" }
            },
                reportedProperties: new Dictionary <string, object>
            {
                { TwinProperty.RX2DataRate, 10 },
                { TwinProperty.Region, LoRaRegionType.US915.ToString() },
                // OTAA device, already joined
                { TwinProperty.DevAddr, devAddr.ToString() },
                { TwinProperty.AppSKey, appSKey.ToString() },
                { TwinProperty.NwkSKey, nwkSKey.ToString() },
            });

            this.deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            var c2dToDeviceMessage = new ReceivedLoRaCloudToDeviceMessage()
            {
                Payload   = "hello",
                DevEUI    = devEUI,
                Fport     = TestPort,
                MessageId = Guid.NewGuid().ToString(),
            };

            var target = new DefaultClassCDevicesMessageSender(
                this.serverConfiguration,
                this.loRaDeviceRegistry,
                this.downstreamMessageSender.Object,
                this.frameCounterStrategyProvider,
                NullLogger <DefaultClassCDevicesMessageSender> .Instance,
                TestMeter.Instance);

            Assert.False(await target.SendAsync(c2dToDeviceMessage));

            this.downstreamMessageSender.VerifyAll();
            this.deviceApi.VerifyAll();
            this.deviceClient.VerifyAll();
        }
Beispiel #11
0
        public async Task When_Initialized_With_Class_C_And_Custom_RX2DR_Should_Have_Correct_Properties()
        {
            var networkSessionKey = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var appSessionKey     = TestKeys.CreateAppSessionKey(0xABCD200000000000, 0x09);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "AppEUI", new JoinEui(0xABCD1234).ToString() },
                { "AppKey", "ABCD2000000000000000000000000009" },
                { "ClassType", "C" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "http://mydecoder" },
                { "RX2DataRate", "10" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "FCntDown", 9 },
                { "FCntUp", 100 },
                { "DevEUI", "ABC0200000000009" },
                { "NetId", "010000" },
                { "DevNonce", "C872" },
                { "RX2DataRate", 10 },
                { "Region", "US915" },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            using var loRaDevice = CreateDefaultDevice();
            await loRaDevice.InitializeAsync(this.configuration);

            Assert.Equal(LoRaDeviceClassType.C, loRaDevice.ClassType);
            Assert.Equal("mygateway", loRaDevice.GatewayID);
            Assert.Equal(9u, loRaDevice.FCntDown);
            Assert.Equal(100u, loRaDevice.FCntUp);
            Assert.Equal(DR10, loRaDevice.ReportedRX2DataRate.Value);
            Assert.Equal(DR10, loRaDevice.DesiredRX2DataRate.Value);
            Assert.Equal(appSessionKey, loRaDevice.AppSKey);
            Assert.Equal(networkSessionKey, loRaDevice.NwkSKey);
            Assert.Equal(LoRaRegionType.US915, loRaDevice.LoRaRegion);
            Assert.False(loRaDevice.IsABP);
        }
Beispiel #12
0
        public async Task When_Initialized_With_PreferredGateway_And_Region_Should_Get_Properties(
            [CombinatorialValues("EU868", "3132", "eu868", "US915", "us915", "eu")] string regionValue)
        {
            var networkSessionKey = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var appSessionKey     = TestKeys.CreateAppSessionKey(0xABCD200000000000, 0x09);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "FCntDown", 10 },
                { "FCntUp", 20 },
                { "PreferredGatewayID", "gateway1" },
                { "Region", regionValue }
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            using var loRaDevice = CreateDefaultDevice();
            await loRaDevice.InitializeAsync(this.configuration);

            if (string.Equals(LoRaRegionType.EU868.ToString(), regionValue, StringComparison.OrdinalIgnoreCase))
            {
                Assert.Equal(LoRaRegionType.EU868, loRaDevice.LoRaRegion);
            }
            else if (string.Equals(LoRaRegionType.US915.ToString(), regionValue, StringComparison.OrdinalIgnoreCase))
            {
                Assert.Equal(LoRaRegionType.US915, loRaDevice.LoRaRegion);
            }
            else
            {
                Assert.Equal(LoRaRegionType.NotSet, loRaDevice.LoRaRegion);
            }
        }
Beispiel #13
0
        public async Task When_Initialized_ABP_Device_Should_Have_All_Properties()
        {
            var networkSessionKey = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var appSessionKey     = TestKeys.CreateAppSessionKey(0xABCD200000000000, 0x09);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "GatewayID", this.configuration.GatewayID },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            using var loRaDevice = CreateDefaultDevice();

            await loRaDevice.InitializeAsync(this.configuration);

            Assert.Null(loRaDevice.AppEui);
            Assert.Null(loRaDevice.AppKey);
            Assert.Equal(this.configuration.GatewayID, loRaDevice.GatewayID);
            Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder);
            Assert.True(loRaDevice.IsABP);
            Assert.True(loRaDevice.IsOurDevice);
            Assert.Equal(0U, loRaDevice.FCntDown);
            Assert.Equal(0U, loRaDevice.LastSavedFCntDown);
            Assert.Equal(0U, loRaDevice.FCntUp);
            Assert.Equal(0U, loRaDevice.LastSavedFCntUp);
            Assert.False(loRaDevice.HasFrameCountChanges);
            Assert.Equal(networkSessionKey, loRaDevice.NwkSKey);
            Assert.Equal(appSessionKey, loRaDevice.AppSKey);
            Assert.Null(loRaDevice.DevNonce);
            Assert.Equal(new DevAddr(0x0000aabb), loRaDevice.DevAddr);
            Assert.Null(loRaDevice.ReportedDwellTimeSetting);
        }
Beispiel #14
0
        public async Task When_Initialized_New_OTAA_Device_Should_Have_All_Properties()
        {
            var appKey  = TestKeys.CreateAppKey(0xABC0200000000000, 0x09);
            var joinEui = new JoinEui(0xABC0200000000009);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "AppEUI", joinEui.ToString() },
                { "AppKey", appKey.ToString() },
                { "GatewayID", "mygateway" },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            using var connectionManager = new SingleDeviceConnectionManager(this.loRaDeviceClient.Object);
            using var loRaDevice        = new LoRaDevice(null, new DevEui(0xabc0200000000009), connectionManager);
            await loRaDevice.InitializeAsync(this.configuration);

            Assert.Equal(joinEui, loRaDevice.AppEui);
            Assert.Equal(appKey, loRaDevice.AppKey);
            Assert.Equal("mygateway", loRaDevice.GatewayID);
            Assert.Equal("DecoderValueSensor", loRaDevice.SensorDecoder);
            Assert.Equal(0U, loRaDevice.FCntDown);
            Assert.Equal(0U, loRaDevice.LastSavedFCntDown);
            Assert.Equal(0U, loRaDevice.FCntUp);
            Assert.Equal(0U, loRaDevice.LastSavedFCntUp);
            Assert.False(loRaDevice.HasFrameCountChanges);
            Assert.Null(loRaDevice.AppSKey);
            Assert.Null(loRaDevice.NwkSKey);
            Assert.Null(loRaDevice.DevAddr);
            Assert.Null(loRaDevice.DevNonce);
            Assert.Null(loRaDevice.NetId);
            Assert.False(loRaDevice.IsABP);
            Assert.False(loRaDevice.IsOurDevice);
            Assert.Null(loRaDevice.ReportedDwellTimeSetting);
        }
        public async Task When_Mic_Check_Fails_Join_Process_Should_Fail()
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, gatewayID: ServerConfiguration.GatewayID));
            var wrongAppKey     = TestKeys.CreateAppKey(0x3000000, 0x30000);

            var joinRequest = simulatedDevice.CreateJoinRequest(wrongAppKey);

            using var loRaDevice = CreateLoRaDevice(simulatedDevice);
            loRaDevice.SetFcntDown(10);
            loRaDevice.SetFcntUp(20);

            var devEui = simulatedDevice.LoRaDevice.DevEui;

            var loRaDeviceRegistryMock = new Mock <ILoRaDeviceRegistry>(MockBehavior.Strict);

            loRaDeviceRegistryMock.Setup(x => x.RegisterDeviceInitializer(It.IsNotNull <ILoRaDeviceInitializer>()));
            loRaDeviceRegistryMock.Setup(x => x.GetDeviceForJoinRequestAsync(devEui, joinRequest.DevNonce))
            .ReturnsAsync(() => loRaDevice);

            // Send to message processor
            using var messageProcessor = new MessageDispatcher(
                      ServerConfiguration,
                      loRaDeviceRegistryMock.Object,
                      FrameCounterUpdateStrategyProvider);

            using var request = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), joinRequest);
            messageProcessor.DispatchRequest(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.Null(request.ResponseDownlink);

            // Device frame counts were not modified
            Assert.Equal(10U, loRaDevice.FCntDown);
            Assert.Equal(20U, loRaDevice.FCntUp);

            // Twin property were updated
            LoRaDeviceClient.VerifyAll();
            LoRaDeviceApi.VerifyAll();
            loRaDeviceRegistryMock.VerifyAll();

            loRaDeviceRegistryMock.Setup(dr => dr.Dispose());
            LoRaDeviceClient.Setup(ldc => ldc.Dispose());
        }
Beispiel #16
0
        public async Task When_Initialized_ABP_Device_Has_Fcnt_Should_Have_Non_Zero_Fcnt_Values()
        {
            var networkSessionKey = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var appSessionKey     = TestKeys.CreateAppSessionKey(0xABCD200000000000, 0x09);

            var twin = TestUtils.CreateTwin(
                desired: new Dictionary <string, object>
            {
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "GatewayID", this.configuration.GatewayID },
                { "SensorDecoder", "DecoderValueSensor" },
                { "$version", 1 },
            },
                reported: new Dictionary <string, object>
            {
                { "$version", 1 },
                { "NwkSKey", networkSessionKey.ToString() },
                { "AppSKey", appSessionKey.ToString() },
                { "DevAddr", "0000AABB" },
                { "FCntDown", 10 },
                { "FCntUp", 20 },
            });

            this.loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            using var loRaDevice = CreateDefaultDevice();

            await loRaDevice.InitializeAsync(this.configuration);

            Assert.True(loRaDevice.IsOurDevice);
            Assert.Equal(10U, loRaDevice.FCntDown);
            Assert.Equal(10U, loRaDevice.LastSavedFCntDown);
            Assert.Equal(20U, loRaDevice.FCntUp);
            Assert.Equal(20U, loRaDevice.LastSavedFCntUp);
            Assert.Empty(loRaDevice.PreferredGatewayID);
            Assert.Equal(LoRaRegionType.NotSet, loRaDevice.LoRaRegion);
            Assert.False(loRaDevice.HasFrameCountChanges);
        }
Beispiel #17
0
        public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID)
        {
            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();
            var simulatedDevice1  = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            using var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, connectionManager.Object);

            var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: ServerConfiguration.GatewayID));

            simulatedDevice2.LoRaDevice.DeviceID = new DevEui(2).ToString();
            simulatedDevice2.LoRaDevice.NwkSKey  = TestKeys.CreateNetworkSessionKey(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
            using var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, connectionManager.Object);

            DeviceCache.Register(loraDevice1);
            DeviceCache.Register(loraDevice2);

            var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234");

            var apiService = new Mock <LoRaDeviceAPIServiceBase>();

            using var request = WaitableLoRaRequest.Create(payload);
            var requestHandler = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);

            requestHandler.Setup(x => x.ProcessRequestAsync(request, loraDevice1))
            .ReturnsAsync(new LoRaDeviceRequestProcessResult(loraDevice1, request));
            loraDevice1.SetRequestHandler(requestHandler.Object);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache);
            target.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingSucceeded);

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();

            requestHandler.VerifyAll();
        }
        public void InvalidSignature()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider();
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            TimeParameters      timeParameters      = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            // move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
            ulong move    = timeParameters.SlotsPerEpoch * (ulong)timeParameters.PersistentCommitteePeriod;
            ulong newSlot = state.Slot + move;

            state.SetSlot((Slot)newSlot);

            Epoch          currentEpoch   = beaconStateAccessor.GetCurrentEpoch(state);
            ValidatorIndex validatorIndex = beaconStateAccessor.GetActiveValidatorIndices(state, currentEpoch)[0];
            Validator      validator      = state.Validators[(int)(ulong)validatorIndex];
            var            privateKey     = TestKeys.PublicKeyToPrivateKey(validator.PublicKey, timeParameters);

            VoluntaryExit voluntaryExit = TestVoluntaryExit.BuildVoluntaryExit(testServiceProvider, state, currentEpoch, validatorIndex, privateKey, signed: false);

            RunVoluntaryExitProcessing(testServiceProvider, state, voluntaryExit, expectValid: false);
        }
Beispiel #19
0
    public async Task PrefixTrimLimitIsRespected()
    {
        var prefix   = Encoding.ASCII.GetBytes(Generator.String(10, 20));
        var sigCount = Generator.Integer(5, 10);

        await using var client = _network.NewClient();
        var invoice = new Invoice(new Proto.TransactionBody
        {
            TransactionID = new Proto.TransactionID(client.CreateNewTxId()),
            Memo          = Generator.String(20, 30)
        }, prefix.Length + 10);

        await(new Signatory(CustomSigner) as ISignatory).SignAsync(invoice);
        var signedTransaction = invoice.GenerateSignedTransactionFromSignatures();
        var signatureMap      = signedTransaction.SigMap;

        Assert.Equal(sigCount, signatureMap.SigPair.Count);
        foreach (var sig in signatureMap.SigPair)
        {
            Assert.Equal(prefix.Length, sig.PubKeyPrefix.Length);
        }

        Task CustomSigner(IInvoice invoice)
        {
            var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(Generator.Ed25519KeyPair().privateKey);
            var signature  = SignatureAlgorithm.Ed25519.Sign(signingKey, invoice.TxBytes.Span);

            for (int i = 0; i < sigCount; i++)
            {
                var thumbprint = prefix.Clone() as byte[];
                thumbprint[thumbprint.Length - 1] = (byte)i;
                invoice.AddSignature(KeyType.Ed25519, thumbprint, signature);
            }
            return(Task.CompletedTask);
        }
    }
Beispiel #20
0
    public async Task AllowsDuplicateSignature()
    {
        await using var client = _network.NewClient();
        var payerKey     = TestKeys.ImportPrivateEd25519KeyFromBytes(_network.PrivateKey);
        var publicPrefix = payerKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).TakeLast(32).Take(6).ToArray();

        // Define Signing Method producing a duplicate signature
        Task CustomSigner(IInvoice invoice)
        {
            var goodSignature1 = SignatureAlgorithm.Ed25519.Sign(payerKey, invoice.TxBytes.Span);
            var goodSignature2 = SignatureAlgorithm.Ed25519.Sign(payerKey, invoice.TxBytes.Span);

            invoice.AddSignature(KeyType.Ed25519, publicPrefix, goodSignature1);
            invoice.AddSignature(KeyType.Ed25519, publicPrefix, goodSignature2);
            return(Task.CompletedTask);
        }

        var record = await client.TransferWithRecordAsync(_network.Payer, _network.Gateway, 100, ctx =>
        {
            ctx.Signatory = new Signatory(CustomSigner);
        });

        Assert.Equal(ResponseCode.Success, record.Status);
    }
Beispiel #21
0
        public async Task When_Queueing_To_Multiple_Devices_With_Same_DevAddr_Should_Queue_To_Device_Matching_Mic(string deviceGatewayID)
        {
            var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234");

            var loRaDeviceClient1 = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            loRaDeviceClient1.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simulatedDevice1.CreateABPTwin());

            using var connectionManager1 = new SingleDeviceConnectionManager(loRaDeviceClient1.Object);
            using var loraDevice1        = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, connectionManager1);
            var devAddr = loraDevice1.DevAddr.Value;

            var reqHandler1 = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);

            reqHandler1.Setup(x => x.ProcessRequestAsync(It.IsNotNull <LoRaRequest>(), loraDevice1))
            .ReturnsAsync(new LoRaDeviceRequestProcessResult(loraDevice1, null));
            loraDevice1.SetRequestHandler(reqHandler1.Object);

            var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            simulatedDevice2.LoRaDevice.DeviceID = new DevEui(2).ToString();
            simulatedDevice2.LoRaDevice.NwkSKey  = TestKeys.CreateNetworkSessionKey(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
            var loRaDeviceClient2 = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            loRaDeviceClient2.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simulatedDevice2.CreateABPTwin());
            using var connectionManager2 = new SingleDeviceConnectionManager(loRaDeviceClient2.Object);
            using var loraDevice2        = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, connectionManager2);

            // Api service: search devices async
            var iotHubDeviceInfo1 = new IoTHubDeviceInfo(devAddr, loraDevice1.DevEUI, string.Empty);
            var iotHubDeviceInfo2 = new IoTHubDeviceInfo(devAddr, loraDevice2.DevEUI, string.Empty);
            var apiService        = new Mock <LoRaDeviceAPIServiceBase>();

            apiService.Setup(x => x.SearchByDevAddrAsync(devAddr))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo[]
            {
                iotHubDeviceInfo2,
                iotHubDeviceInfo1,
            }));

            // Device factory: create 2 devices
            this.loraDeviceFactoryMock.Setup(x => x.CreateAndRegisterAsync(iotHubDeviceInfo1, It.IsAny <CancellationToken>())).ReturnsAsync(() => {
                DeviceCache.Register(loraDevice1);
                return(loraDevice1);
            });
            this.loraDeviceFactoryMock.Setup(x => x.CreateAndRegisterAsync(iotHubDeviceInfo2, It.IsAny <CancellationToken>())).ReturnsAsync(() => {
                DeviceCache.Register(loraDevice2);
                return(loraDevice2);
            });

            using var target  = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object, DeviceCache);
            using var request = WaitableLoRaRequest.Create(payload);
            target.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingSucceeded);

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();

            // Both devices are in cache
            Assert.Equal(2, DeviceCache.RegistrationCount(devAddr)); // 2 devices with same devAddr exist in cache

            // find device 1
            Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var actualCachedLoRaDevice1));
            Assert.Same(loraDevice1, actualCachedLoRaDevice1);
            Assert.True(loraDevice1.IsOurDevice);

            // find device 2
            Assert.True(DeviceCache.TryGetByDevEui(loraDevice2.DevEUI, out var actualCachedLoRaDevice2));
            Assert.Same(loraDevice2, actualCachedLoRaDevice2);
            Assert.True(loraDevice2.IsOurDevice);

            reqHandler1.VerifyAll();
        }
        // [InlineData(200, 500, 100, 100, 1)]
        public async Task When_Multiple_Devices_And_Conflicting_DevAddr_Send_Telemetry_Queue_Sends_Messages_To_IoTHub(
            int searchDelay,
            int getTwinDelay,
            int sendMessageDelay,
            int receiveDelay,
            int delayBetweenMessages)
        {
            const int messagePerDeviceCount = 10;
            const int payloadInitialFcnt    = 2;

            var device1     = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));
            var device1Twin = TestUtils.CreateABPTwin(device1);
            var device2     = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(2))
            {
                DevAddr = device1.DevAddr
            };
            var device2Twin = TestUtils.CreateABPTwin(device2);
            var device3     = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(3));

            device3.SetupJoin(TestKeys.CreateAppSessionKey(0x88), TestKeys.CreateNetworkSessionKey(0x88), new DevAddr(0x02000088));
            var device3Twin = TestUtils.CreateOTAATwin(device3);
            var device4     = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(4));
            var device4Twin = TestUtils.CreateABPTwin(device4);

            var device1And2Result = new IoTHubDeviceInfo[]
            {
                new IoTHubDeviceInfo(device1.DevAddr, device1.DevEUI, "1"),
                new IoTHubDeviceInfo(device2.DevAddr, device2.DevEUI, "2"),
            };

            LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(device1.DevAddr.Value))
            .ReturnsAsync(new SearchDevicesResult(device1And2Result), TimeSpan.FromMilliseconds(searchDelay));

            LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(device3.DevAddr.Value))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(device3.DevAddr, device3.DevEUI, "3").AsList()), TimeSpan.FromMilliseconds(searchDelay));

            LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(device4.DevAddr.Value))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(device4.DevAddr, device4.DevEUI, "3").AsList()), TimeSpan.FromMilliseconds(searchDelay));

            var deviceClient1          = new Mock <ILoRaDeviceClient>();
            var deviceClient1Telemetry = new List <LoRaDeviceTelemetry>();

            deviceClient1.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(device1Twin, TimeSpan.FromMilliseconds(getTwinDelay));
            deviceClient1.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .Callback <LoRaDeviceTelemetry, Dictionary <string, string> >((t, d) => deviceClient1Telemetry.Add(t))
            .ReturnsAsync(true, TimeSpan.FromMilliseconds(sendMessageDelay));
            deviceClient1.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>()))
            .ReturnsAsync(null, TimeSpan.FromMilliseconds(receiveDelay));
            deviceClient1.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);

            var deviceClient2          = new Mock <ILoRaDeviceClient>();
            var deviceClient2Telemetry = new List <LoRaDeviceTelemetry>();

            deviceClient2.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(device2Twin, TimeSpan.FromMilliseconds(getTwinDelay));
            deviceClient2.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .Callback <LoRaDeviceTelemetry, Dictionary <string, string> >((t, d) => deviceClient2Telemetry.Add(t))
            .ReturnsAsync(true, TimeSpan.FromMilliseconds(sendMessageDelay));
            deviceClient2.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>()))
            .ReturnsAsync(null, TimeSpan.FromMilliseconds(receiveDelay));
            deviceClient2.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);

            var deviceClient3          = new Mock <ILoRaDeviceClient>();
            var deviceClient3Telemetry = new List <LoRaDeviceTelemetry>();

            deviceClient3.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(device3Twin, TimeSpan.FromMilliseconds(getTwinDelay));
            deviceClient3.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .Callback <LoRaDeviceTelemetry, Dictionary <string, string> >((t, d) => deviceClient3Telemetry.Add(t))
            .ReturnsAsync(true, TimeSpan.FromMilliseconds(sendMessageDelay));
            deviceClient3.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>()))
            .ReturnsAsync(null, TimeSpan.FromMilliseconds(receiveDelay));
            deviceClient3.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);

            var deviceClient4          = new Mock <ILoRaDeviceClient>();
            var deviceClient4Telemetry = new List <LoRaDeviceTelemetry>();

            deviceClient4.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(device4Twin, TimeSpan.FromMilliseconds(getTwinDelay));
            deviceClient4.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null))
            .Callback <LoRaDeviceTelemetry, Dictionary <string, string> >((t, d) => deviceClient4Telemetry.Add(t))
            .ReturnsAsync(true, TimeSpan.FromMilliseconds(sendMessageDelay));
            deviceClient4.Setup(x => x.ReceiveAsync(It.IsNotNull <TimeSpan>()))
            .ReturnsAsync(null, TimeSpan.FromMilliseconds(receiveDelay));
            deviceClient4.Setup(x => x.UpdateReportedPropertiesAsync(It.IsAny <TwinCollection>(), It.IsAny <CancellationToken>())).ReturnsAsync(true);

            LoRaDeviceFactory.SetClient(device1.DevEUI, deviceClient1.Object);
            LoRaDeviceFactory.SetClient(device2.DevEUI, deviceClient2.Object);
            LoRaDeviceFactory.SetClient(device3.DevEUI, deviceClient3.Object);
            LoRaDeviceFactory.SetClient(device4.DevEUI, deviceClient4.Object);

            using var cache          = NewMemoryCache();
            using var deviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, DeviceCache);

            using var messageDispatcher = new MessageDispatcher(
                      ServerConfiguration,
                      deviceRegistry,
                      FrameCounterUpdateStrategyProvider);

            var device1Messages = await SendMessages(device1, messageDispatcher, payloadInitialFcnt, delayBetweenMessages, messagePerDeviceCount);

            var device2Messages = await SendMessages(device2, messageDispatcher, payloadInitialFcnt, delayBetweenMessages, messagePerDeviceCount);

            var device3Messages = await SendMessages(device3, messageDispatcher, payloadInitialFcnt, delayBetweenMessages, messagePerDeviceCount);

            var device4Messages = await SendMessages(device4, messageDispatcher, payloadInitialFcnt, delayBetweenMessages, messagePerDeviceCount);

            var allMessages = device1Messages
                              .Concat(device2Messages)
                              .Concat(device3Messages)
                              .Concat(device4Messages)
                              .ToList();

            Assert.Equal(messagePerDeviceCount * 4, allMessages.Count);

            await Task.WhenAll(allMessages.Select(x => x.WaitCompleteAsync()));

            Assert.All(allMessages, m => Assert.True(m.ProcessingSucceeded));

            var telemetries = new[]
            {
                deviceClient1Telemetry,
                deviceClient2Telemetry,
                deviceClient3Telemetry,
                deviceClient4Telemetry
            };

            foreach (var telemetry in telemetries)
            {
                Assert.Equal(messagePerDeviceCount, telemetry.Count);
                for (var i = 0; i < messagePerDeviceCount; ++i)
                {
                    Assert.Equal(payloadInitialFcnt + i, telemetry[i].Fcnt);
                }
            }

            deviceClient1.VerifyAll();
            deviceClient1.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Exactly(messagePerDeviceCount));
            deviceClient2.VerifyAll();
            deviceClient2.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Exactly(messagePerDeviceCount));
            deviceClient3.VerifyAll();
            deviceClient3.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Exactly(messagePerDeviceCount));
            deviceClient4.VerifyAll();
            deviceClient4.Verify(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null), Times.Exactly(messagePerDeviceCount));

            LoRaDeviceApi.VerifyAll();
        }
        public async Task When_Payload_Has_Invalid_Mic_Should_Not_Send_Messages(int searchDevicesDelayMs)
        {
            // Setup
            var wrongSKey       = TestKeys.CreateNetworkSessionKey(0xEEDDFF);
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));

            var searchResult = new SearchDevicesResult(new IoTHubDeviceInfo(simulatedDevice.DevAddr, simulatedDevice.DevEUI, "1321").AsList());

            if (searchDevicesDelayMs > 0)
            {
                LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(simulatedDevice.DevAddr.Value))
                .ReturnsAsync(searchResult, TimeSpan.FromMilliseconds(searchDevicesDelayMs));
            }
            else
            {
                LoRaDeviceApi.Setup(x => x.SearchByDevAddrAsync(simulatedDevice.DevAddr.Value))
                .ReturnsAsync(searchResult);
            }

            LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice));

            using var cache          = NewMemoryCache();
            using var deviceRegistry = new LoRaDeviceRegistry(ServerConfiguration, cache, LoRaDeviceApi.Object, LoRaDeviceFactory, DeviceCache);

            // Send to message processor
            using var messageProcessor = new MessageDispatcher(
                      ServerConfiguration,
                      deviceRegistry,
                      FrameCounterUpdateStrategyProvider);

            // Send request #1
            var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1", fcnt: 2, nwkSKey: wrongSKey);

            using var request1 = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), payload1);
            messageProcessor.DispatchRequest(request1);
            Assert.True(await request1.WaitCompleteAsync());
            Assert.Null(request1.ResponseDownlink);
            Assert.True(request1.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByMicCheck, request1.ProcessingFailedReason);

            await Task.Delay(2000);

            Assert.Equal(1, DeviceCache.RegistrationCount(simulatedDevice.DevAddr.Value));

            // Send request #2
            var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2", fcnt: 3, nwkSKey: wrongSKey);

            using var request2 = CreateWaitableRequest(TestUtils.GenerateTestRadioMetadata(), payload2);
            messageProcessor.DispatchRequest(request2);
            Assert.True(await request2.WaitCompleteAsync());
            Assert.Null(request2.ResponseDownlink);
            Assert.True(request2.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByMicCheck, request2.ProcessingFailedReason);
            Assert.Equal(1, DeviceCache.RegistrationCount(simulatedDevice.DevAddr.Value));

            LoRaDeviceApi.VerifyAll();
            LoRaDeviceClient.VerifyAll();

            LoRaDeviceApi.Verify(x => x.SearchByDevAddrAsync(simulatedDevice.DevAddr.Value), Times.Exactly(1));
        }
Beispiel #24
0
        public async Task When_Has_Custom_RX2DR_Should_Send_Correctly()
        {
            var devAddr   = new DevAddr(0x023637F8);
            var appSKey   = TestKeys.CreateAppSessionKey(0xABC0200000000000, 0x09);
            var nwkSKey   = TestKeys.CreateNetworkSessionKey(0xABC0200000000000, 0x09);
            var simDevice = new SimulatedDevice(TestDeviceInfo.CreateOTAADevice(1, deviceClassType: 'c', gatewayID: ServerGatewayID));
            var devEUI    = simDevice.DevEUI;

            simDevice.SetupJoin(appSKey, nwkSKey, devAddr);

            this.deviceApi.Setup(x => x.GetPrimaryKeyByEuiAsync(devEUI))
            .ReturnsAsync("123");

            var twin = simDevice.CreateOTAATwin(
                desiredProperties: new Dictionary <string, object>
            {
                { TwinProperty.RX2DataRate, "10" }
            },
                reportedProperties: new Dictionary <string, object>
            {
                { TwinProperty.RX2DataRate, 10 },
                { TwinProperty.Region, LoRaRegionType.US915.ToString() },
                // OTAA device, already joined
                { TwinProperty.DevAddr, devAddr.ToString() },
                { TwinProperty.AppSKey, appSKey.ToString() },
                { TwinProperty.NwkSKey, nwkSKey.ToString() },
                { TwinProperty.LastProcessingStationEui, new StationEui(ulong.MaxValue).ToString() }
            });

            this.deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(twin);

            var c2dToDeviceMessage = new ReceivedLoRaCloudToDeviceMessage()
            {
                Payload   = "hello",
                DevEUI    = devEUI,
                Fport     = TestPort,
                MessageId = Guid.NewGuid().ToString(),
            };

            DownlinkMessage receivedDownlinkMessage = null;

            this.downstreamMessageSender.Setup(x => x.SendDownstreamAsync(It.IsNotNull <DownlinkMessage>()))
            .Returns(Task.CompletedTask)
            .Callback <DownlinkMessage>(d => receivedDownlinkMessage = d);

            var target = new DefaultClassCDevicesMessageSender(
                this.serverConfiguration,
                this.loRaDeviceRegistry,
                this.downstreamMessageSender.Object,
                this.frameCounterStrategyProvider,
                NullLogger <DefaultClassCDevicesMessageSender> .Instance,
                TestMeter.Instance);

            Assert.True(await target.SendAsync(c2dToDeviceMessage));

            this.downstreamMessageSender.Verify(x => x.SendDownstreamAsync(It.IsNotNull <DownlinkMessage>()), Times.Once());

            EnsureDownlinkIsCorrect(receivedDownlinkMessage, simDevice, c2dToDeviceMessage);
            Assert.Equal(DataRateIndex.DR10, receivedDownlinkMessage.Rx2.DataRate);
            Assert.Equal(Hertz.Mega(923.3), receivedDownlinkMessage.Rx2.Frequency);

            this.downstreamMessageSender.VerifyAll();
            this.deviceApi.VerifyAll();
            this.deviceClient.VerifyAll();
        }
Beispiel #25
0
 private static Dictionary <string, object> GetEssentialDesiredProperties() =>
 new Dictionary <string, object>
 {
     ["AppEUI"] = new JoinEui(0xABCD1234).ToString(),
     ["AppKey"] = TestKeys.CreateAppKey(1).ToString()
 };
        public async Task When_Device_Is_Not_In_Cache_And_Found_In_Api_Does_Not_Match_Mic_Should_Fail_Request(string deviceGatewayID)
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>();
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk");

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            // Will get device twin
            var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice));

            using var deviceCache = LoRaDeviceCacheDefault.CreateDefault();
            var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object, deviceCache, this.connectionManager);
            var target        = new DeviceLoaderSynchronizer(
                simulatedDevice.DevAddr.Value,
                apiService.Object,
                deviceFactory,
                new NetworkServerConfiguration(),
                deviceCache,
                null,
                NullLogger <DeviceLoaderSynchronizer> .Instance);

            _ = target.LoadAsync();

            var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", appSKey: simulatedDevice.AppSKey, nwkSKey: TestKeys.CreateNetworkSessionKey(0xEEAAFF));

            using var request = WaitableLoRaRequest.Create(payload);
            target.Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByMicCheck, request.ProcessingFailedReason);

            // Device was searched by DevAddr
            apiService.VerifyAll();
            loRaDeviceClient.VerifyAll();
        }
Beispiel #27
0
    public async Task InconsistentDuplicateSignatureRaisesError()
    {
        await using var client = _network.NewClient();
        var fakeKey1 = Key.Create(SignatureAlgorithm.Ed25519, new KeyCreationParameters {
            ExportPolicy = KeyExportPolicies.AllowPlaintextExport
        });
        var fakeKey2 = Key.Create(SignatureAlgorithm.Ed25519, new KeyCreationParameters {
            ExportPolicy = KeyExportPolicies.AllowPlaintextExport
        });
        var goodKey      = TestKeys.ImportPrivateEd25519KeyFromBytes(_network.PrivateKey);
        var publicPrefix = goodKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).TakeLast(32).Take(6).ToArray();

        // Define Defective Signing Method Bad Signature Last
        Task CustomSigner(IInvoice invoice)
        {
            var goodSignature = SignatureAlgorithm.Ed25519.Sign(goodKey, invoice.TxBytes.Span);
            var badSignature  = SignatureAlgorithm.Ed25519.Sign(fakeKey1, invoice.TxBytes.Span);

            invoice.AddSignature(KeyType.Ed25519, publicPrefix, goodSignature);
            invoice.AddSignature(KeyType.Ed25519, publicPrefix, badSignature);
            return(Task.CompletedTask);
        }

        var aex1 = await Assert.ThrowsAsync <ArgumentException>(async() =>
        {
            await client.TransferWithRecordAsync(_network.Payer, _network.Gateway, 100, ctx =>
            {
                ctx.Signatory = new Signatory(CustomSigner);
            });
        });

        Assert.StartsWith("Signature with Duplicate Prefix Identifier was provided, but did not have an Identical Signature.", aex1.Message);

        // Define Defective Signing Method Bad Signature First
        Task CustomSignerReverse(IInvoice invoice)
        {
            var goodSignature = SignatureAlgorithm.Ed25519.Sign(goodKey, invoice.TxBytes.Span);
            var badSignature  = SignatureAlgorithm.Ed25519.Sign(fakeKey1, invoice.TxBytes.Span);

            invoice.AddSignature(KeyType.Ed25519, publicPrefix, badSignature);
            invoice.AddSignature(KeyType.Ed25519, publicPrefix, goodSignature);
            return(Task.CompletedTask);
        }

        var aex2 = await Assert.ThrowsAsync <ArgumentException>(async() =>
        {
            await client.TransferWithRecordAsync(_network.Payer, _network.Gateway, 100, ctx =>
            {
                ctx.Signatory = new Signatory(CustomSignerReverse);
            });
        });

        Assert.StartsWith("Signature with Duplicate Prefix Identifier was provided, but did not have an Identical Signature.", aex2.Message);

        // Define Defective Signing Method Bad Two Bad Signatures
        Task CustomSignerBothBad(IInvoice invoice)
        {
            var badSignature1 = SignatureAlgorithm.Ed25519.Sign(fakeKey1, invoice.TxBytes.Span);
            var badSignature2 = SignatureAlgorithm.Ed25519.Sign(fakeKey2, invoice.TxBytes.Span);

            invoice.AddSignature(KeyType.Ed25519, publicPrefix, badSignature2);
            invoice.AddSignature(KeyType.Ed25519, publicPrefix, badSignature1);
            return(Task.CompletedTask);
        }

        // Inconsistent Key state should be checked before signatures are validated,
        // expecting an Argument exception and not a PreCheck exception.
        var aex3 = await Assert.ThrowsAsync <ArgumentException>(async() =>
        {
            await client.TransferWithRecordAsync(_network.Payer, _network.Gateway, 100, ctx =>
            {
                ctx.Signatory = new Signatory(CustomSignerBothBad);
            });
        });

        Assert.StartsWith("Signature with Duplicate Prefix Identifier was provided, but did not have an Identical Signature.", aex3.Message);
    }
Beispiel #28
0
 private static LoRaDevice CreateTestDevice()
 => new LoRaDevice(new DevAddr(0xffffffff), new DevEui(0), null)
 {
     NwkSKey = TestKeys.CreateNetworkSessionKey(0xAAAAAAAA)
 };