using System.Security.Cryptography; using System.Text; using PCC.App.Security; using PCC.App.Tpm; using PCC.Common.AssemblyInject.Interfaces; using PCC.Common.EventBus; using PCC.DevShared.Configuration; namespace PCC.DevServer; internal class DevServerApp( PccDevConfigManagerBase configManager, IPeerInfoProvider peerInfoProvider, TrustedPeerManager tpm, IEventBus eventBus, ILogger logger) : IAssemblyInjectSyncInitStarStop { private ILocalPeerInfo? _local; private IRemotePeerInfo? _remote; public void Init() { logger.LogInformation("init"); eventBus.Subscript(OnListenerStatusChanged); eventBus.Subscript(OnInboundAccepted); eventBus.Subscript(OnInboundStatusChanged); eventBus.Subscript(OnInboundConnectionError); eventBus.Subscript(OnInboundRx); eventBus.Subscript(OnInboundTx); } public void Start() { logger.LogInformation("starting..."); if (configManager.Instance.MyKeyPrivate == null || configManager.Instance.MyKeyPublic == null) { logger.LogInformation("Generating 8192bit RSA key... be patient, may take up to 30 seconds..."); var (myPub, myPri) = RsaUtility.GeneratePKCS1(8192); configManager.Instance.MyKeyPrivate = Convert.ToBase64String(myPri, Base64FormattingOptions.None); configManager.Instance.MyKeyPublic = Convert.ToBase64String(myPub, Base64FormattingOptions.None); configManager.Save(); logger.LogInformation("RSA key generated and saved. Please fill conf and RESTART."); } _local = peerInfoProvider.PeerInfo.FirstOrDefault(); if (_local != null) { _remote = _local.TrustedRemotePeers.FirstOrDefault(); } } private void OnInboundTx(TPM_EVT_INBOUND_TX obj) { logger.LogInformation($"IB Tx L{obj.LocalPeerId} R{obj.RemotePeerId} {Encoding.UTF8.GetString(obj.payload.Span)}"); } private void OnInboundRx(TPM_EVT_INBOUND_RX obj) { logger.LogInformation($"IB Rx L{obj.LocalPeerId} R{obj.RemotePeerId} {Encoding.UTF8.GetString(obj.payload.Span)}"); tpm.SendToPeer(_local.PeerId, obj.RemotePeerId, SHA256.HashData(obj.payload.Span)); } private void OnInboundConnectionError(TPM_EVT_INBOUND_CON_ERROR obj) { logger.LogError(obj.Exception, $"IB ERR L{obj.LocalPeerId} R{obj.RemotePeerId} C{obj.ConnectionId}"); } private void OnInboundStatusChanged(TPM_EVT_INBOUND_CON_STATUS_CHANGED obj) { switch (obj.Status) { case TPM_EVT_INBOUND_CON_STATUS.HANDSHAKE_FAIL_NOT_TRUSTED: case TPM_EVT_INBOUND_CON_STATUS.SECURE_ALERT_REPLAY_ATTACK_DETECT: logger.LogError($"IB ST {obj.Status} L{obj.LocalPeerId} R{obj.RemotePeerId} C{obj.ConnectionId}"); break; default: case TPM_EVT_INBOUND_CON_STATUS.INVALID: case TPM_EVT_INBOUND_CON_STATUS.SECURE_WARN_TIMESTAMP_SKEW: logger.LogWarning($"IB ST {obj.Status} L{obj.LocalPeerId} R{obj.RemotePeerId} C{obj.ConnectionId}"); break; case TPM_EVT_INBOUND_CON_STATUS.HANDSHAKE_OK: case TPM_EVT_INBOUND_CON_STATUS.DISCONNECTED: logger.LogInformation($"IB ST {obj.Status} L{obj.LocalPeerId} R{obj.RemotePeerId} C{obj.ConnectionId}"); break; } } private void OnInboundAccepted(TPM_EVT_INBOUND_CON_ACCEPTED obj) { logger.LogInformation($"Inbound accepted {obj.RemoteEndpoint} {obj.ConnectionId}"); } private void OnListenerStatusChanged(TPM_EVT_LISTENER_STATUS_CHANGED obj) { logger.LogInformation($"Listener {obj.Status} {obj.Exception?.Message}"); } public void Stop() { } }