private static void handleAcceptAdd(byte[] sender_wallet, byte[] aes_key) { // Retrieve the corresponding contact Friend friend = FriendList.getFriend(sender_wallet); if (friend == null) { byte[] pub_k = FriendList.findContactPubkey(sender_wallet); if (pub_k == null) { Console.WriteLine("Contact {0} not found in presence list!", Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet)); return; } friend = FriendList.addFriend(sender_wallet, pub_k, Base58Check.Base58CheckEncoding.EncodePlain(sender_wallet), aes_key, null, 0); } else { friend.aesKey = aes_key; } friend.handshakeStatus = 2; friend.generateKeys(); friend.sendKeys(2); requestNickname(friend); sendNickname(friend); FriendList.addMessage(null, friend.walletAddress, friend.nickname + " has accepted your friend request."); }
// 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; } }
// 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); }