@Nullable @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Utils.Log("MessageFragment onCreateView called"); View view = inflater.inflate(R.layout.fragment_messages, container, false); messageList = (ListView) view.findViewById(R.id.messages_list); messages = dbManager.getMessages(conversation.getUsername()); adapter = new MessagesAdapter( getActivity(), messages, dbManager.getUsername(), conversation.getUsername(), conversationPass); messageList.setAdapter(adapter); messageList.setOnItemLongClickListener(messageLongClicked); if (savedInstanceState == null) { messageList.setSelection(adapter.getCount() - 6); } sendMessage = (Button) view.findViewById(R.id.btn_message_send); sendMessage.setOnClickListener(sendClicked); messageText = (MaterialEditText) view.findViewById(R.id.user_message_text); return view; }
@Override public void onSaveInstanceState(Bundle outState) { outState.putString("username", conversation.getUsername()); outState.putInt("_id", conversation.getId()); outState.putInt("unreadMessages", conversation.getUnreadMessages()); super.onSaveInstanceState(outState); }
@Override public void onClick(View view) { Utils.Log("Send clicked"); // If the message field is not empty if (!messageText.getText().toString().isEmpty()) { final Message message = new Message(); message.setSender(username); message.setRecipient(conversation.getUsername()); // If DHKE was completed and a key exists if (!dbManager.getAESKey(conversation.getUsername()).isEmpty()) { String signature = ""; String key = dbManager.getAESKey(conversation.getUsername()); byte[] iv = Crypto.GenerateRandomIV(); final String plainText = messageText.getText().toString(); final String cipherText = Crypto.AESencrypt(key, plainText, iv); final String base64IV = Base64.encodeToString(iv, Base64.NO_WRAP); try { PrivateKey RSAKeySign = Crypto.RSAStringToPrivateKey(dbManager.getRSAKeySignaturePrivate()); signature = Base64.encodeToString( Crypto.RSASign(Base64.decode(cipherText, Base64.NO_WRAP), RSAKeySign), Base64.NO_WRAP); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } message.setMessage(cipherText); message.setIv(base64IV); message.setSignature(signature); new HttpHandler() { @Override public HttpUriRequest getHttpRequestMethod() { HttpPost httpPost = new HttpPost(Utils.SERVER_SEND_MESSAGE); List<NameValuePair> nameValuePairs = new ArrayList<>(); nameValuePairs.add(new BasicNameValuePair("sender", message.getSender())); nameValuePairs.add(new BasicNameValuePair("recipient", message.getRecipient())); nameValuePairs.add(new BasicNameValuePair("message", message.getMessage())); nameValuePairs.add(new BasicNameValuePair("iv", message.getIv())); nameValuePairs.add(new BasicNameValuePair("signature", message.getSignature())); try { httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return httpPost; } @Override public void onResponse(String result) { Utils.Log("HttpResult: " + result); if (conversation.isEncrypted().equals("true")) { message.setMessage( Crypto.AESencrypt( conversationPass, plainText, Base64.decode(message.getIv(), Base64.NO_WRAP))); message.setEncrypted(true); dbManager.addMessage(message); message.setEncrypted(false); message.setMessage(plainText); messages.add(message); adapter.notifyDataSetChanged(); } else { message.setMessage(plainText); message.setEncrypted(false); dbManager.addMessage(message); messages.add(message); adapter.notifyDataSetChanged(); } messageList.setSelection(messages.size() + 1); } }.execute(); messageText.setText(""); } // DHKE was not complete yet, store messages unencrypted temporarily // and then encrypt and send them once the exchange is complete else { message.setEncrypted(false); message.setMessage(messageText.getText().toString()); message.setIv(Base64.encodeToString(Crypto.GenerateRandomIV(), Base64.NO_WRAP)); dbManager.addMessage(message); messages.add(message); adapter.notifyDataSetChanged(); messageList.setSelection(adapter.getCount() - 1); messageText.setText(""); } } }