/**
* Copyright (C) 2011 Adriano Monteiro Marques
*
* Author: Zubair Nabi <zn.zubairnabi@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
package org.umit.icm.mobile.p2p;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
import org.umit.icm.mobile.process.Constants;
import org.umit.icm.mobile.process.Globals;
import org.umit.icm.mobile.proto.MessageProtos.AgentData;
import org.umit.icm.mobile.utils.AESCrypto;
import org.umit.icm.mobile.utils.CryptoKeyReader;
import org.umit.icm.mobile.utils.RSACrypto;
import org.umit.icm.mobile.connectivity.TCPClient;
/**
* Provides sender functions for P2P messages.
*/
public class P2PCommunication {
/**
* Sends the byte[] message to the {@link AgentData} agentInfo.
* Uses symmetric key cryptography and opens a TCP connection to the peer
* using {@link TCPClient}.
*
*
@param agentInfo recipient peer data of type {@link AgentData}
*
@see CryptoKeyReader
*
@see AESCrypto
*
@see TCPClient
*/
public static void sendMessage(AgentData agentInfo, byte[] rawMessage, int messageID)
throws Exception {
byte [] cipherBytes;
byte [] totalBytes;
byte [] message;
byte [] completeMessage;
message = MessageBuilder.generateMessageWithoutLength(messageID, rawMessage);
if(Constants.P2P_ENCRYPTION == true) {
byte [] symmetricKey = CryptoKeyReader.getPeerSecretKey(
agentInfo.getAgentID());
cipherBytes = AESCrypto.encrypt(symmetricKey, message);
} else {
cipherBytes = message;
}
completeMessage = MessageBuilder.byteArrayAppend(
MessageBuilder.intToByteArray(cipherBytes.length),
cipherBytes);
Globals.tcpClient.openConnection(agentInfo.getAgentIP()
, agentInfo.getAgentPort());
Globals.tcpClient.writeLine(completeMessage);
byte[] messageSizeBytes = Globals.tcpClient.readBytes(4);
int messageSize = MessageBuilder.byteArrayToInt(messageSizeBytes);
byte[] totalBytesEncrypted = Globals.tcpClient.readBytes(messageSize);
if(Constants.P2P_ENCRYPTION == true) {
byte[] peerSecretKey = CryptoKeyReader.getPeerSecretKey(agentInfo.getAgentIP());
totalBytes = AESCrypto.decrypt(peerSecretKey, totalBytesEncrypted);
} else {
totalBytes = totalBytesEncrypted;
}
byte[] idBytes = MessageBuilder.getSubArray(totalBytes, 0, 3);
int id = MessageBuilder.byteArrayToInt(idBytes);
byte [] msgBytes = MessageBuilder.getSubArray(totalBytes, 4, messageSize - 1);
MessageTranslation.translateMessage(id, msgBytes, agentInfo);
Globals.tcpClient.closeConnection();
}
/**
* Sends the byte[] message to the {@link AgentData} agentInfo.
* Uses asymmetric key cryptography and opens a TCP connection to the peer
* using {@link TCPClient}.
*
*
@param agentInfo recipient peer data of type {@link AgentData}
*
@return byte[]
*
@see CryptoKeyReader
*
@see RSACrypto
*
@see TCPClient
*/
public static void sendMessagePublic(AgentData agentInfo, byte[] rawMessage, int messageID)
throws Exception {
byte [] cipherBytes;
byte [] totalBytes;
byte [] message;
byte [] completeMessage;
message = MessageBuilder.generateMessageWithoutLength(messageID, rawMessage);
if(Constants.P2P_ENCRYPTION == true) {
PrivateKey privateKey = CryptoKeyReader.getMyPrivateKey();
cipherBytes = RSACrypto.encryptPrivate(privateKey, message);
} else {
cipherBytes = message;
}
completeMessage = MessageBuilder.byteArrayAppend(
MessageBuilder.intToByteArray(cipherBytes.length),
cipherBytes);
Globals.tcpClient.openConnection(agentInfo.getAgentIP()
, agentInfo.getAgentPort());
Globals.tcpClient.writeLine(completeMessage);
byte[] messageSizeBytes = Globals.tcpClient.readBytes(4);
int messageSize = MessageBuilder.byteArrayToInt(messageSizeBytes);
byte[] totalBytesEncrypted = Globals.tcpClient.readBytes(messageSize);
if(Constants.P2P_ENCRYPTION == true) {
BigInteger mod = new BigInteger(agentInfo.getPublicKey().getMod());
BigInteger exp = new BigInteger(agentInfo.getPublicKey().getExp());
PublicKey peerPublicKey = RSACrypto.generatePublicKey(mod, exp);
totalBytes =
RSACrypto.decryptPublic(peerPublicKey, totalBytesEncrypted);
}
else {
totalBytes = totalBytesEncrypted;
}
byte[] idBytes = MessageBuilder.getSubArray(totalBytes, 0, 3);
int id = MessageBuilder.byteArrayToInt(idBytes);
byte [] msgBytes = MessageBuilder.getSubArray(totalBytes, 4, messageSize - 1);
MessageTranslation.translateMessage(id, msgBytes, agentInfo);
Globals.tcpClient.closeConnection();
}
}