Esempio n. 1
0
        public async Task <string> CreateSessionAndSendSessionRequestAsync(string counterPartyVaspId)
        {
            var session = new Session
            {
                Id    = Guid.NewGuid().ToString("N"),
                Type  = SessionType.Originator,
                State = SessionState.Created,
                CounterPartyVaspId = counterPartyVaspId,
                CreationDateTime   = DateTime.UtcNow,
                EcdhPrivateKey     = ECDH_Key.GenerateKey().PrivateKey,
            };

            _sessions[session.Id] = session;

            var whisperConnection = await _transportService.CreateConnectionAsync(session.CounterPartyVaspId);

            session.ConnectionId = whisperConnection;

            var messageKey = await _vaspCodesService.GetMessageKeyAsync(session.CounterPartyVaspId.Substring(4));

            session.TempAesMessageKey = ECDH_Key.ImportKey(_privateMessageKey).GenerateSharedSecretHex(messageKey);

            await SendMessageAsync(
                session,
                MessageType.SessionRequest,
                Instruction.Invite,
                ECDH_Key.ImportKey(session.EcdhPrivateKey).PublicKey,
                new SessionRequest());

            return(session.Id);
        }
Esempio n. 2
0
        private async Task HandleSessionRequestAsync(
            string connectionId,
            string sessionId,
            string senderVaspId,
            string ecdhPkA)
        {
            var key = ECDH_Key.GenerateKey();

            var session = new Session
            {
                Id    = sessionId,
                Type  = SessionType.Beneficiary,
                State = SessionState.Invited,
                CounterPartyVaspId = senderVaspId,
                ConnectionId       = connectionId,
                CreationDateTime   = DateTime.UtcNow,
                EcdhPrivateKey     = key.PrivateKey,
                TempAesMessageKey  = ECDH_Key.ImportKey(_privateMessageKey)
                                     .GenerateSharedSecretHex(await _vaspCodesService.GetMessageKeyAsync(senderVaspId.Substring(4)))
            };

            if (!string.IsNullOrWhiteSpace(ecdhPkA))
            {
                session.EstablishedAesMessageKey = key.GenerateSharedSecretHex(ecdhPkA);
            }

            _sessions[sessionId] = session;

            await TriggerAsyncEvent(BeneficiarySessionCreated, new BeneficiarySessionCreatedEvent
            {
                SessionId          = sessionId,
                CounterPartyVaspId = session.CounterPartyVaspId
            });
        }
        public async Task <string> CreateConnectionAsync(string counterPartyVaspId)
        {
            var counterPartyVaspCode = counterPartyVaspId.Substring(4, 8);
            var vaspTransportKey     = await _vaspCodesService.GetTransportKeyAsync(counterPartyVaspCode);

            if (vaspTransportKey == null)
            {
                throw new InvalidOperationException($"Couldn't get TransportKey for vasp code {counterPartyVaspCode}");
            }

            var sessionKey   = ECDH_Key.GenerateKey();
            var topic        = TopicGenerator.GenerateConnectionTopic();
            var privateKeyId = await _whisperRpc.RegisterKeyPairAsync(sessionKey.PrivateKey);

            var filter = await _whisperRpc.CreateMessageFilterAsync(topic, privateKeyId);

            _activeTopics.Add(topic);

            var connection = new Connection
            {
                Id                 = Guid.NewGuid().ToString("N"),
                Filter             = filter,
                InboundTopic       = topic,
                Status             = ConnectionStatus.Active,
                CounterPartyVaspId = counterPartyVaspId,
                PrivateKey         = sessionKey.PrivateKey,
            };

            _connections[connection.Id] = connection;

            return(connection.Id);
        }
Esempio n. 4
0
        public void GenerateHandshakeKeyForVaspSmartContractTest()
        {
            ECDH_Key alice       = ECDH_Key.GenerateKey();
            ECDH_Key importValid = ECDH_Key.ImportKey(alice.PrivateKey);

            Assert.Equal(alice.PrivateKey, importValid.PrivateKey);
            Assert.Equal(alice.PublicKey, importValid.PublicKey);
        }
Esempio n. 5
0
        public void SharedSecretECDHGenerationTest()
        {
            ECDH_Key alice = ECDH_Key.GenerateKey();
            ECDH_Key bob   = ECDH_Key.GenerateKey();

            var shared1 = alice.GenerateSharedSecretHex(bob.PublicKey);
            var shared2 = bob.GenerateSharedSecretHex(alice.PublicKey);

            Assert.Equal(shared1, shared2);
        }
Esempio n. 6
0
        public void GenerateHandshakeKeyForVaspSmartContractTest()
        {
            ECDH_Key alice       = ECDH_Key.GenerateKey();
            ECDH_Key importValid = ECDH_Key.ImportKey(alice.PrivateKey);

            Assert.Equal(alice.PrivateKey, importValid.PrivateKey);
            Assert.Equal(alice.PublicKey, importValid.PublicKey);

            testOutputHelper.WriteLine(alice.PrivateKey.HexToByteArray().Length.ToString());

            testOutputHelper.WriteLine(alice.PrivateKey);
            testOutputHelper.WriteLine(alice.PublicKey);
        }
        /// <summary>
        /// Create a session and send a request session message to beneficiary Vasp.
        /// </summary>
        /// <param name="originator">Information about a client who sends a transfer</param>
        /// <param name="beneficiaryVaan">Information about a receiver of the transfer</param>
        /// <returns>OriginatorSession through which transfer request and transfer dispatch should be requested.</returns>
        public async Task <OriginatorSession> CreateSessionAsync(
            Originator originator,
            VirtualAssetsAccountNumber beneficiaryVaan,
            IOriginatorVaspCallbacks _originatorVaspCallbacks)
        {
            string counterPartyVaspContractAddress = await _ensProvider.GetContractAddressByVaspCodeAsync(beneficiaryVaan.VaspCode);

            var contractInfo = await _ethereumRpc.GetVaspContractInfoAync(counterPartyVaspContractAddress);

            var sessionKey = ECDH_Key.GenerateKey();
            var sharedKey  = sessionKey.GenerateSharedSecretHex(contractInfo.HandshakeKey);

            var session = new OriginatorSession(
                originator,
                this._vaspContractInfo,
                this.VaspInfo,
                beneficiaryVaan,
                contractInfo.SigningKey,
                contractInfo.HandshakeKey,
                sharedKey,
                sessionKey.PublicKey,
                this._signatureKey,
                _whisperRpc,
                _transportClient,
                _signService,
                _originatorVaspCallbacks);

            if (_originatorSessionsDict.TryAdd(session.SessionId, session))
            {
                this.NotifySessionCreated(session);
                session.OnSessionTermination += this.ProcessSessionTermination;
                await session.StartAsync();

                return(session);
            }

            await session.TerminateAsync(TerminationMessage.TerminationMessageCode
                                         .SessionClosedTransferCancelledByOriginator);

            //TODO: process it as exception or retry
            return(null);
        }
        private async Task HandleInviteMessageAsync(OpenVaspPayload payload)
        {
            var senderVaspCode   = payload.SenderVaspId.Substring(4, 8);
            var vaspTransportKey = await _vaspCodesService.GetTransportKeyAsync(senderVaspCode);

            if (vaspTransportKey == null)
            {
                _logger?.LogError($"Transport key for vasp code {senderVaspCode} cannot be found during invitation processing");
                return;
            }

            _connections.TryGetValue(payload.ConnectionId, out var connection);
            if (connection != null)
            {
                bool isSameData = connection.CounterPartyVaspId == payload.SenderVaspId &&
                                  connection.OutboundTopic == payload.ReturnTopic;
                if (isSameData)
                {
                    _logger?.LogWarning(
                        $"Received invite for already existing connectionId {payload.ConnectionId} with the same data. Skipping.");

                    await AcknowledgeMessageAsync(
                        payload,
                        null,
                        payload.EcdhPk.DecompressPublicKey().ToHex(true));
                }
                else
                {
                    _logger?.LogWarning(
                        $"Received invite for already existing connectionId {payload.ConnectionId} with the different data:{Environment.NewLine}"
                        + $"SenderVaspId: {connection.CounterPartyVaspId} - {payload.SenderVaspId},{Environment.NewLine}"
                        + $"Topic: {connection.OutboundTopic} - {payload.ReturnTopic},{Environment.NewLine}");
                }
                return;
            }

            var topic        = TopicGenerator.GenerateConnectionTopic();
            var sessionKey   = ECDH_Key.GenerateKey();
            var sharedSecret = sessionKey.GenerateSharedSecretHex(payload.EcdhPk);

            var(filter, symKeyId) = await RegisterConnectionAsync(topic, sharedSecret);

            var newConnection = new Connection
            {
                Id                         = payload.ConnectionId,
                Filter                     = filter,
                InboundTopic               = topic,
                OutboundTopic              = payload.ReturnTopic,
                Status                     = ConnectionStatus.PartiallyActive,
                CounterPartyVaspId         = payload.SenderVaspId,
                SymKeyId                   = symKeyId,
                SharedPrivateEncryptionKey = sharedSecret,
                PrivateKey                 = sessionKey.PrivateKey,
                CounterPartyPublicKey      = payload.EcdhPk,
            };

            _connections[newConnection.Id] = newConnection;

            await AcknowledgeMessageAsync(
                payload,
                null,
                payload.EcdhPk.DecompressPublicKey().ToHex(true));

            var signingKey = await _vaspCodesService.GetSigningKeyAsync(senderVaspCode);

            await TriggerAsyncEvent(TransportMessageReceived,
                                    new TransportMessageEvent
            {
                ConnectionId = payload.ConnectionId,
                SenderVaspId = payload.SenderVaspId,
                Instruction  = payload.Instruction,
                Payload      = payload.OvMessage,
                Timestamp    = DateTime.UtcNow,
                SigningKey   = signingKey
            });
        }