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); }
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); }
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); }
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); }
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 }); }