Example #1
0
        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);
            }
        }
Example #2
0
        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();
            }
        }