示例#1
0
        public async Task RpcServer_Can_Handle_SignMessageRequest(string message)
        {
            var sender       = PeerIdHelper.GetPeerId("sender");
            var peerSettings = Substitute.For <IPeerSettings>();

            peerSettings.PeerId.Returns(sender);
            var signMessageRequest = new SignMessageRequest
            {
                Message        = message.ToUtf8ByteString(),
                SigningContext = new SigningContext()
            };
            var protocolMessage =
                signMessageRequest.ToProtocolMessage(sender);

            await TaskHelper.WaitForAsync(
                () => _keySigner.KeyStore.KeyStoreDecrypt(KeyRegistryTypes.DefaultKey) != null,
                TimeSpan.FromSeconds(2));

            var messageStream =
                MessageStreamHelper.CreateStreamWithMessage(_fakeContext, _testScheduler, protocolMessage);
            var handler =
                new SignMessageRequestObserver(peerSettings, _logger, _keySigner);

            handler.StartObserving(messageStream);

            _testScheduler.Start();

            var receivedCalls = _fakeContext.Channel.ReceivedCalls().ToList();

            _logger.DidNotReceiveWithAnyArgs().Error((Exception) default, default);
        public void RpcServer_Can_Handle_SignMessageRequest(string message)
        {
            var sender       = PeerIdHelper.GetPeerId("sender");
            var peerSettings = Substitute.For <IPeerSettings>();

            peerSettings.PeerId.Returns(sender);
            var signMessageRequest = new SignMessageRequest
            {
                Message        = message.ToUtf8ByteString(),
                SigningContext = new SigningContext()
            };
            var protocolMessage =
                signMessageRequest.ToProtocolMessage(sender);

            var messageStream =
                MessageStreamHelper.CreateStreamWithMessage(_fakeContext, _testScheduler, protocolMessage);
            var handler =
                new SignMessageRequestObserver(peerSettings, _logger, _keySigner);

            handler.StartObserving(messageStream);

            _testScheduler.Start();

            var receivedCalls = _fakeContext.Channel.ReceivedCalls().ToList();

            receivedCalls.Count.Should().Be(1);

            var sentResponseDto     = (IMessageDto <ProtocolMessage>)receivedCalls.Single().GetArguments().Single();
            var signResponseMessage = sentResponseDto.Content.FromProtocolMessage <SignMessageResponse>();

            signResponseMessage.OriginalMessage.Should().Equal(message);
            signResponseMessage.Signature.Should().NotBeEmpty();
            signResponseMessage.PublicKey.Should().NotBeEmpty();
        }
        public async Task <PubKey> JoinFederationAsync(JoinFederationRequestModel request, CancellationToken cancellationToken)
        {
            // Get the address pub key hash.
            var   address    = BitcoinAddress.Create(request.CollateralAddress, this.counterChainSettings.CounterChainNetwork);
            KeyId addressKey = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(address.ScriptPubKey);

            // Get mining key.
            var keyTool  = new KeyTool(this.settings.DataFolder);
            Key minerKey = keyTool.LoadPrivateKey();

            if (minerKey == null)
            {
                throw new Exception($"The private key file ({KeyTool.KeyFileDefaultName}) has not been configured.");
            }

            var expectedCollateralAmount = CollateralFederationMember.GetCollateralAmountForPubKey(this.network, minerKey.PubKey);

            Money collateralAmount = new Money(expectedCollateralAmount, MoneyUnit.BTC);

            var joinRequest = new JoinFederationRequest(minerKey.PubKey, collateralAmount, addressKey);

            // Populate the RemovalEventId.
            var collateralFederationMember = new CollateralFederationMember(minerKey.PubKey, false, joinRequest.CollateralAmount, request.CollateralAddress);

            byte[] federationMemberBytes = (this.network.Consensus.ConsensusFactory as CollateralPoAConsensusFactory).SerializeFederationMember(collateralFederationMember);
            var    votingManager         = this.fullNode.NodeService <VotingManager>();
            Poll   poll = votingManager.GetFinishedPolls().FirstOrDefault(x => x.IsExecuted &&
                                                                          x.VotingData.Key == VoteKey.KickFederationMember && x.VotingData.Data.SequenceEqual(federationMemberBytes));

            joinRequest.RemovalEventId = (poll == null) ? Guid.Empty : new Guid(poll.PollExecutedBlockData.Hash.ToBytes().TakeLast(16).ToArray());

            // Get the signature by calling the counter-chain "signmessage" API.
            var signMessageRequest = new SignMessageRequest()
            {
                Message         = joinRequest.SignatureMessage,
                WalletName      = request.CollateralWalletName,
                Password        = request.CollateralWalletPassword,
                ExternalAddress = request.CollateralAddress
            };

            var    walletClient = new WalletClient(this.loggerFactory, this.httpClientFactory, $"http://{this.counterChainSettings.CounterChainApiHost}", this.counterChainSettings.CounterChainApiPort);
            string signature    = await walletClient.SignMessageAsync(signMessageRequest, cancellationToken);

            if (signature == null)
            {
                throw new Exception("Operation was cancelled during call to counter-chain to sign the collateral address.");
            }

            joinRequest.AddSignature(signature);

            var         walletTransactionHandler = this.fullNode.NodeService <IWalletTransactionHandler>();
            var         encoder = new JoinFederationRequestEncoder(this.loggerFactory);
            Transaction trx     = JoinFederationRequestBuilder.BuildTransaction(walletTransactionHandler, this.network, joinRequest, encoder, request.WalletName, request.WalletAccount, request.WalletPassword);

            var walletService = this.fullNode.NodeService <IWalletService>();
            await walletService.SendTransaction(new SendTransactionRequest(trx.ToHex()), cancellationToken);

            return(minerKey.PubKey);
        }
示例#4
0
        public async Task <string> SignMessage(string msg)
        {
            var request = new SignMessageRequest()
            {
                Msg = ByteString.CopyFromUtf8(msg)
            };
            var response = await lndClient.SignMessageAsync(request);

            return(response.Signature);
        }
 public async Task <IActionResult> SignMessage([FromBody] SignMessageRequest request,
                                               CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await this.ExecuteAsAsync(request, cancellationToken, (req, token) =>
     {
         string signature =
             this.walletManager.SignMessage(req.Password, req.WalletName, req.ExternalAddress, req.Message);
         return this.Json(signature);
     }));
 }
        public async void TestSignAndVerifyUsingBIP39Key()
        {
            var vlt = await TestUtil.InitVaultWithOrgToken();

            var vault = await vlt.CreateVault(new provide.Model.Vault.Vault
            {
                Name = "test vault"
            });

            var orgName  = "test org";
            var hdWallet = await vlt.CreateVaultKey(vault.Id.ToString(), new Key
            {
                Type        = "asymmetric",
                Usage       = "sign/verify",
                Spec        = "BIP39",
                Name        = $"{orgName} BIP39 keypair",
                Description = $"{orgName} BIP39 keypair"
            });

            var message = "02a285b1a277f7602dc115a3bf627a8b7603a4a1be9a72b3ab0284878afe443d"; // secp256k1 signing requests must send 32-byte `message` (ie hash the data first...)

            var hdWalletReqOptions = new Dictionary <string, object>
            {
                { "coin", 60 }, // ETH
            };

            // sign and assert
            var signReq = new SignMessageRequest
            {
                Message = message,
                Options = new Dictionary <string, object>
                {
                    { "hdwallet", hdWalletReqOptions }
                }
            };
            var signedMessage = await vlt.SignMessage(vault.Id.ToString(), hdWallet.Id.ToString(), signReq);

            Assert.NotNull(signedMessage.Signature);
            Assert.NotEmpty(signedMessage.Signature);

            // verify and assert
            var verificationReq = new SignatureVerificationRequest
            {
                Message   = message,
                Signature = signedMessage.Signature,
                Options   = new Dictionary <string, object>
                {
                    { "hdwallet", hdWalletReqOptions }
                }
            };
            var verifiedMessage = await vlt.VerifySignature(vault.Id.ToString(), hdWallet.Id.ToString(), verificationReq);

            Assert.True(verifiedMessage.Verified);
        }
示例#7
0
        public async Task <string> Sign(Guid vaultId, Guid keyId, string message)
        {
            if (_logger.IsDebug)
            {
                _logger.Debug($"Signing a message with the key {keyId} from the vault {vaultId}");
            }
            SignMessageRequest request = new SignMessageRequest();

            request.Message = message;
            SignMessageResponse response = await _vaultService.SignMessage(
                vaultId.ToString(), keyId.ToString(), request);

            return(response.Signature);
        }
        public async void TestSignAndVerifyMessage()
        {
            var message = "02a285b1a277f7602dc115a3bf627a8b7603a4a1be9a72b3ab0284878afe443d"; // secp256k1 signing requests must send 32-byte `message` (ie hash the data first...)
            var token   = await TestUtil.CreateIdentForTestUser();

            var vlt = Vault.InitVault(token);

            provide.Model.Vault.Vault vault = await vlt.CreateVault(
                new provide.Model.Vault.Vault
            {
                Name = "TestVault"
            }
                );

            var generatedKey = await vlt.CreateVaultKey(
                vault.Id.ToString(),
                new Key
            {
                Type        = "asymmetric",
                Usage       = "sign/verify",
                Spec        = "secp256k1",
                Name        = "TestKey",
                Description = "Key used to test signing"
            }
                );

            // sign and assert
            var signReq = new SignMessageRequest
            {
                Message = message,
                Options = new Dictionary <string, object>()
            };
            var signedMessage = await vlt.SignMessage(vault.Id.ToString(), generatedKey.Id.ToString(), signReq);

            Assert.NotNull(signedMessage.Signature);
            Assert.NotEmpty(signedMessage.Signature);

            // verify and assert
            var verificationReq = new SignatureVerificationRequest
            {
                Message   = message,
                Signature = signedMessage.Signature,
                Options   = new Dictionary <string, object>()
            };
            var verifiedMessage = await vlt.VerifySignature(vault.Id.ToString(), generatedKey.Id.ToString(), verificationReq);

            Assert.True(verifiedMessage.Verified);
        }
示例#9
0
        /// <summary>
        /// Verify the signature of a message.
        /// </summary>
        /// <returns>If verification was successful it will return true.</returns>
        public async Task <SignMessageResult> SignMessage(SignMessageRequest signMessageRequest)
        {
            try
            {
                Guard.Null(signMessageRequest, nameof(signMessageRequest), "Sign Message Request Cannot Be NULL/Empty!");

                SignMessageResult response = await base.SendPostJSON <SignMessageResult>("/api/Wallet/signmessage", signMessageRequest);

                return(response);
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                return(new SignMessageResult());
            }
        }
示例#10
0
 /// <inheritdoc />
 public Task <string> SignMessageAsync(SignMessageRequest request, CancellationToken cancellation = default)
 {
     return(this.SendPostRequestAsync <SignMessageRequest, string>(request, "signmessage", cancellation));
 }
示例#11
0
        /// <summary>
        /// Verify the signature of a message.
        /// </summary>
        /// <returns>If verification was successful it will return true.</returns>
        public async Task <SignMessageResult> SignMessageAsync(SignMessageRequest signMessageRequest)
        {
            SignMessageResult response = await restClient.SignMessage(signMessageRequest);

            return(response);
        }
示例#12
0
        public async Task <PubKey> JoinFederationAsync(JoinFederationRequestModel request, CancellationToken cancellationToken)
        {
            // Wait until the node is synced before joining.
            if (this.initialBlockDownloadState.IsInitialBlockDownload())
            {
                throw new Exception($"Please wait until the node is synced with the network before attempting to join the federation.");
            }

            // First ensure that this collateral address isnt already present in the federation.
            if (this.federationManager.GetFederationMembers().IsCollateralAddressRegistered(request.CollateralAddress))
            {
                throw new Exception($"The provided collateral address '{request.CollateralAddress}' is already present in the federation.");
            }

            // Get the address pub key hash.
            BitcoinAddress address    = BitcoinAddress.Create(request.CollateralAddress, this.counterChainSettings.CounterChainNetwork);
            KeyId          addressKey = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(address.ScriptPubKey);

            // Get mining key.
            var keyTool  = new KeyTool(this.nodeSettings.DataFolder);
            Key minerKey = keyTool.LoadPrivateKey();

            if (minerKey == null)
            {
                throw new Exception($"The private key file ({KeyTool.KeyFileDefaultName}) has not been configured or is not present.");
            }

            var expectedCollateralAmount = CollateralFederationMember.GetCollateralAmountForPubKey(this.network, minerKey.PubKey);

            var joinRequest = new JoinFederationRequest(minerKey.PubKey, new Money(expectedCollateralAmount, MoneyUnit.BTC), addressKey);

            // Populate the RemovalEventId.
            SetLastRemovalEventId(joinRequest, GetFederationMemberBytes(joinRequest, this.network, this.counterChainSettings.CounterChainNetwork), this.votingManager);

            // Get the signature by calling the counter-chain "signmessage" API.
            var signMessageRequest = new SignMessageRequest()
            {
                Message         = joinRequest.SignatureMessage,
                WalletName      = request.CollateralWalletName,
                Password        = request.CollateralWalletPassword,
                ExternalAddress = request.CollateralAddress
            };

            var walletClient = new WalletClient(this.httpClientFactory, $"http://{this.counterChainSettings.CounterChainApiHost}", this.counterChainSettings.CounterChainApiPort);

            try
            {
                string signature = await walletClient.SignMessageAsync(signMessageRequest, cancellationToken);

                joinRequest.AddSignature(signature);
            }
            catch (Exception err)
            {
                throw new Exception($"The call to sign the join federation request failed: '{err.Message}'.");
            }

            IWalletTransactionHandler walletTransactionHandler = this.fullNode.NodeService <IWalletTransactionHandler>();
            var encoder = new JoinFederationRequestEncoder();
            JoinFederationRequestResult result = JoinFederationRequestBuilder.BuildTransaction(walletTransactionHandler, this.network, joinRequest, encoder, request.WalletName, request.WalletAccount, request.WalletPassword);

            if (result.Transaction == null)
            {
                throw new Exception(result.Errors);
            }

            IWalletService walletService = this.fullNode.NodeService <IWalletService>();
            await walletService.SendTransaction(new SendTransactionRequest(result.Transaction.ToHex()), cancellationToken);

            return(minerKey.PubKey);
        }
示例#13
0
        // SignMessage securely signs the given message
        public async Task <SignMessageResponse> SignMessage(string vaultID, string keyID, SignMessageRequest signReq)
        {
            var uri = $"vaults/{vaultID}/keys/{keyID}/sign";

            return(await this.Post <SignMessageResponse>(uri, signReq));
        }