// Called when receiving S2 data from clients
        public static void receiveData(byte[] bytes, RemoteEndpoint endpoint)
        {
            Logging.info(string.Format("Receiving S2 data "));

            StreamMessage message = new StreamMessage(bytes);

            if (message.data == null)
            {
                Logging.error(string.Format("Null message data."));
                return;
            }

            // Extract the Spixi message
            SpixiMessage spixi_message = new SpixiMessage(message.data);

            switch (spixi_message.type)
            {
            case SpixiMessageCode.chat:
            {
                // Add the message to the friend list
                FriendList.addMessage(message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.getNick:
            {
                // Send the nickname to the sender as requested
                handleGetNick(message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.nick:
            {
                // Set the nickname for the corresponding address
                FriendList.setNickname(message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.requestAdd:
            {
                // Friend request
                handleRequestAdd(message.sender);
            }
            break;

            case SpixiMessageCode.acceptAdd:
            {
                // Friend accepted request
                handleAcceptAdd(message.sender);
            }
            break;

            case SpixiMessageCode.requestFunds:
            {
                // Friend requested funds
                handleRequestFunds(message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;
            }
        }
Exemple #2
0
        // Called when an encryption key is received from the S2 server, as per step 4 of the WhitePaper

        /*private static void sendRsaEncryptedMessage(StreamMessage msg, string key, RemoteEndpoint endpoint)
         * {
         * // TODO TODO use transaction code for S2
         *  using (MemoryStream m = new MemoryStream())
         *  {
         *      using (BinaryWriter writer = new BinaryWriter(m))
         *      {
         *          writer.Write(msg.getID());
         *          writer.Write(msg.recipientAddress);
         *          writer.Write(msg.transactionID);
         *      }
         *  }
         *  Console.WriteLine("Sending encrypted message with key {0}", key);
         *
         *          using (MemoryStream m = new MemoryStream())
         *          {
         *              using (BinaryWriter writer = new BinaryWriter(m))
         *              {
         *                  writer.Write(msg.getID());
         *                  writer.Write(msg.recipientAddress);
         *                  writer.Write(msg.transactionID);
         *
         *                  byte[] encrypted_message = CryptoManager.lib.encryptDataS2(msg.data, key);
         *                  int encrypted_count = encrypted_message.Count();
         *
         *                  writer.Write(encrypted_count);
         *                  writer.Write(encrypted_message);
         *
         *                  byte[] ba = ProtocolMessage.prepareProtocolMessage(ProtocolMessageCode.s2data, m.ToArray());
         *                  socket.Send(ba, SocketFlags.None);
         *
         *
         *                  // Update the DLT transaction as well
         *                  Transaction transaction = new Transaction(0, msg.recipientAddress, Node.walletStorage.address);
         *                  transaction.id = msg.transactionID;
         *                  //transaction.data = Encoding.UTF8.GetString(checksum);
         *                  //ProtocolMessage.broadcastProtocolMessage(ProtocolMessageCode.updateTransaction, transaction.getBytes());
         *
         *              }
         *          }
         * }*/

        // Called when receiving S2 data from clients
        public static void receiveData(byte[] bytes, RemoteEndpoint endpoint)
        {
            StreamMessage message = new StreamMessage(bytes);

            if (message.data == null)
            {
                Logging.error(string.Format("Null message data."));
                return;
            }

            Logging.info("Received S2 data from {0} for {1}", Base58Check.Base58CheckEncoding.EncodePlain(message.sender), Base58Check.Base58CheckEncoding.EncodePlain(message.recipient));

            Friend friend = null;

            // decrypt the message if necessary
            // TODO TODO TODO add message receive queue for when the keys aren't available yet
            if (message.encryptionType != StreamMessageEncryptionCode.none)
            {
                byte[] aes_key    = null;
                byte[] chacha_key = null;

                friend = FriendList.getFriend(message.sender);
                if (friend != null)
                {
                    aes_key    = friend.aesKey;
                    chacha_key = friend.chachaKey;
                }
                if (!message.decrypt(Node.walletStorage.getPrimaryPrivateKey(), aes_key, chacha_key))
                {
                    Logging.error("Could not decrypt message from {0}", Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress));
                    return;
                }
            }

            // Extract the Spixi message
            SpixiMessage spixi_message = new SpixiMessage(message.data);

            switch (spixi_message.type)
            {
            case SpixiMessageCode.chat:
            {
                // Add the message to the friend list
                FriendList.addMessage(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.getNick:
            {
                // Send the nickname to the sender as requested
                handleGetNick(message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.nick:
            {
                // Set the nickname for the corresponding address
                if (spixi_message.data != null)
                {
                    FriendList.setNickname(message.sender, Encoding.UTF8.GetString(spixi_message.data));
                }
                else
                {
                    FriendList.setNickname(message.sender, Base58Check.Base58CheckEncoding.EncodePlain(message.sender));
                }
            }
            break;

            case SpixiMessageCode.requestAdd:
            {
                // Friend request
                handleRequestAdd(spixi_message.id, message.sender, spixi_message.data);
            }
            break;

            case SpixiMessageCode.acceptAdd:
            {
                // Friend accepted request
                handleAcceptAdd(message.sender, spixi_message.data);
            }
            break;

            case SpixiMessageCode.sentFunds:
            {
                // Friend requested funds
                handleSentFunds(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.requestFunds:
            {
                // Friend requested funds
                handleRequestFunds(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.requestFundsResponse:
            {
                handleRequestFundsResponse(spixi_message.id, message.sender, Encoding.UTF8.GetString(spixi_message.data));
            }
            break;

            case SpixiMessageCode.keys:
            {
                handleReceivedKeys(message.sender, spixi_message.data);
            }
            break;

            case SpixiMessageCode.msgReceived:
            {
                handleMsgReceived(message.sender, spixi_message);
                // don't send confirmation back, so just return
                return;
            }

            case SpixiMessageCode.msgRead:
            {
                handleMsgRead(message.sender, spixi_message);
                // don't send confirmation back, so just return
                return;
            }

            case SpixiMessageCode.fileHeader:
            {
                handleFileHeader(message.sender, spixi_message);
            }
            break;
            }

            if (friend == null)
            {
                friend = FriendList.getFriend(message.sender);
            }

            if (friend == null)
            {
                Logging.error("Cannot send received confirmation, friend is null");
                return;
            }

            // Send received confirmation
            StreamMessage msg_received = new StreamMessage();

            msg_received.type           = StreamMessageCode.info;
            msg_received.sender         = IxianHandler.getWalletStorage().getPrimaryAddress();
            msg_received.recipient      = message.sender;
            msg_received.data           = new SpixiMessage(spixi_message.id, SpixiMessageCode.msgReceived, null).getBytes();
            msg_received.transaction    = new byte[1];
            msg_received.sigdata        = new byte[1];
            msg_received.encryptionType = StreamMessageEncryptionCode.none;

            sendMessage(friend, msg_received, true);
        }