public async Task HandleAsync() { try { var nodeKey = request.Keys; ConnectData connectData = request.GetConnectData(nodeKey.SignPublicKey, NodeData.Instance.NodeKeys.Password, NodeData.Instance.NodeKeys.PrivateKey); nodeConnection.Node = connectData.Node; nodeConnection.Node.StartDay = nodeConnection.Node.StartDay.ToUniversalTime(); var nodeJson = ObjectSerializer.ObjectToJson(nodeConnection.Node); bool isValid = Encryptor.CheckSign( connectData.LicensorSign, LicensorClient.Instance.GetSignPublicKey(), Encoding.UTF8.GetBytes(nodeJson), NodeData.Instance.NodeKeys.Password); if (!isValid) { NodeWebSocketCommunicationManager.SendResponse( new ResultNodeResponse(request.RequestId, ErrorCode.AuthorizationProblem, "Wrong sign for node data."), nodeConnection); } LicenseVm license = connectData.License; long currentTime = DateTime.UtcNow.ToUnixTime(); if (!license.IsLicenseValid(currentTime, LicensorClient.Instance.GetSignPublicKey(), NodeData.Instance.NodeKeys.Password, out _)) { var licenseFromLicensor = await LicensorClient.Instance.GetLicenseAsync(nodeConnection.Node.Id).ConfigureAwait(false); if (!licenseFromLicensor.IsLicenseValid(currentTime, LicensorClient.Instance.GetSignPublicKey(), NodeData.Instance.NodeKeys.Password, out var errorMessage)) { var isBlockchainLicenseValid = await BlockchainReadService.IsNodeLicenseValidAsync(nodeConnection.Node.Id, currentTime).ConfigureAwait(false); if (!isBlockchainLicenseValid) { NodeWebSocketCommunicationManager.SendResponse( new ResultNodeResponse(request.RequestId, ErrorCode.AuthorizationProblem, errorMessage), nodeConnection); } } } nodeConnection.Uri = new Uri($"wss://{nodeConnection.Node.Domains.FirstOrDefault()}:{nodeConnection.Node.NodesPort}"); ConnectData responseConnectData = new ConnectData { Node = NodeSettings.Configs.Node, LicensorSign = NodeSettings.Configs.LicensorSign.Sign, License = NodeSettings.Configs.License }; byte[] encryptedData = Encryptor.SymmetricDataEncrypt( ObjectSerializer.ObjectToByteArray(responseConnectData), NodeData.Instance.NodeKeys.SignPrivateKey, connectData.SymmetricKey, MessageDataType.Binary, NodeData.Instance.NodeKeys.Password); await NodeWebSocketCommunicationManager.SendResponseAsync(new NodesInformationResponse(request.RequestId, encryptedData), nodeConnection).ConfigureAwait(false); nodeConnection.PublicKey = nodeKey.PublicKey; nodeConnection.SymmetricKey = connectData.SymmetricKey; nodeConnection.Node.NodeKey.EncPublicKey = nodeKey.PublicKey; nodeConnection.PublicKeyExpirationTime = nodeKey.ExpirationTime; nodeConnection.PublicKeyId = nodeKey.KeyId; nodeConnection.SignPublicKey = nodeKey.SignPublicKey; nodesService.CreateOrUpdateNodeInformationAsync(nodeConnection.Node); connectionsService.AddOrUpdateNodeConnection(nodeConnection.Node.Id, nodeConnection); await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); await nodeNoticeService.SendPendingMessagesAsync(nodeConnection.Node.Id).ConfigureAwait(false); } catch (Exception ex) { Logger.WriteLog(ex); NodeWebSocketCommunicationManager.SendResponse(new ResultNodeResponse(request.RequestId, ErrorCode.UnknownError, ex.Message), nodeConnection); } }
public async void SendConnectRequestAsync(NodeConnection nodeConnection) { NodeKeysDto publicKey = null; try { if (nodeConnection.Node == null || nodeConnection.Node.NodeKey == null || nodeConnection.Node.NodeKey.EncPublicKey.IsNullOrEmpty() || nodeConnection.Node.NodeKey.SignPublicKey.IsNullOrEmpty() || nodeConnection.Node.NodeKey.ExpiredAt < DateTime.UtcNow.ToUnixTime()) { publicKey = await GetNodePublicKeyAsync(nodeConnection).ConfigureAwait(false); } if (publicKey == null) { publicKey = new NodeKeysDto { ExpirationTime = nodeConnection.Node.NodeKey.ExpiredAt, KeyId = nodeConnection.Node.NodeKey.KeyId, PublicKey = nodeConnection.Node.NodeKey.EncPublicKey, SignPublicKey = nodeConnection.Node.NodeKey.SignPublicKey }; } byte[] symmetricKey; byte[] encryptedKey = null; if (nodeConnection.IsEncryptedConnection) { symmetricKey = nodeConnection.SymmetricKey; } else { symmetricKey = Encryptor.GetSymmetricKey(256, RandomExtensions.NextInt64(), uint.MaxValue, NodeData.Instance.NodeKeys.Password); } encryptedKey = Encryptor.AsymmetricDataEncrypt( symmetricKey, publicKey.PublicKey, NodeData.Instance.NodeKeys.SignPrivateKey, NodeData.Instance.NodeKeys.Password); ConnectData connectData = new ConnectData { License = NodeSettings.Configs.License, LicensorSign = NodeSettings.Configs.LicensorSign.Sign, Node = NodeSettings.Configs.Node, SymmetricKey = symmetricKey }; byte[] encryptedRequestData = Encryptor.SymmetricDataEncrypt( ObjectSerializer.ObjectToByteArray(connectData), NodeData.Instance.NodeKeys.SignPrivateKey, symmetricKey, MessageDataType.Binary, NodeData.Instance.NodeKeys.Password); NodeRequest request = new ConnectNodeRequest(encryptedKey, encryptedRequestData, NodeData.Instance.PublicKeys); SendRequest(nodeConnection, request); NodeResponse response = await GetResponseAsync(request, (int)TimeSpan.FromSeconds(30).TotalMilliseconds).ConfigureAwait(false); if (response is NodesInformationResponse informationResponse) { ConnectData responseData = informationResponse.GetConnectData(symmetricKey, publicKey.SignPublicKey, NodeData.Instance.NodeKeys.Password); responseData.Node.StartDay = responseData.Node.StartDay.ToUniversalTime(); var nodeJson = ObjectSerializer.ObjectToJson(responseData.Node); var isValid = Encryptor.CheckSign( responseData.LicensorSign, LicensorClient.Instance.GetSignPublicKey(), Encoding.UTF8.GetBytes(nodeJson), NodeData.Instance.NodeKeys.Password); if (!isValid) { return; } LicenseVm license = responseData.License; long currentTime = DateTime.UtcNow.ToUnixTime(); if (license.ExpiredAt <= currentTime) { return; } foreach (LicenseSegmentVm segment in license.LicenseSegments) { if (segment.StartAt <= currentTime && segment.LicensorSign != null && segment.LicensorSign.Sign != null) { var jsonData = ObjectSerializer.ObjectToJson(segment.GetSignObject()); bool isSegmentValid = Encryptor.CheckSign( segment.LicensorSign.Sign, LicensorClient.Instance.GetSignPublicKey(), Encoding.UTF8.GetBytes(jsonData), NodeData.Instance.NodeKeys.Password); if (!isSegmentValid) { return; } } } nodeConnection.Node = responseData.Node; nodeConnection.Uri = new Uri($"wss://{responseData.Node.Domains.FirstOrDefault()}:{responseData.Node.NodesPort}"); nodeConnection.PublicKey = publicKey.PublicKey; nodeConnection.SymmetricKey = symmetricKey; nodeConnection.PublicKeyId = publicKey.KeyId; nodeConnection.PublicKeyExpirationTime = publicKey.ExpirationTime; nodeConnection.SignPublicKey = publicKey.SignPublicKey; nodesService.CreateOrUpdateNodeInformationAsync(responseData.Node); connectionsService.AddOrUpdateNodeConnection(nodeConnection.Node.Id, nodeConnection); await nodeNoticeService.SendPendingMessagesAsync(nodeConnection.Node.Id).ConfigureAwait(false); } else if (response is ResultNodeResponse resultResponse) { if (nodeConnection?.Uri != null) { Console.WriteLine($"Node URI: {nodeConnection.Uri.AbsoluteUri} Message: {resultResponse.Message}"); } else { Console.WriteLine(resultResponse.Message); } } } catch (Exception ex) { if (publicKey != null) { Console.WriteLine($"PublicKey Id:{publicKey.KeyId}, Expired at: {publicKey.ExpirationTime.ToDateTime().ToString()}, Generated at: {publicKey.GenerationTime.ToDateTime().ToString()}, NodeId:{publicKey.NodeId}"); } Logger.WriteLog(ex); nodeConnection.NodeWebSocket.Abort(); } }