package org.awesomeapp.messenger.crypto.otr;
import org.awesomeapp.messenger.model.Address;
import org.awesomeapp.messenger.model.Message;
import org.awesomeapp.messenger.plugin.xmpp.XmppAddress;
import org.awesomeapp.messenger.provider.Imps;
import org.awesomeapp.messenger.service.adapters.ChatSessionAdapter;
import org.awesomeapp.messenger.service.adapters.ChatSessionManagerAdapter;
import org.awesomeapp.messenger.service.adapters.ImConnectionAdapter;
import org.awesomeapp.messenger.service.RemoteImService;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Hashtable;
import net.java.otr4j.OtrEngineHost;
import net.java.otr4j.OtrKeyManager;
import net.java.otr4j.OtrPolicy;
import net.java.otr4j.session.SessionID;
import android.content.Context;
/*
* OtrEngineHostImpl is the connects this app and the OtrEngine
* http://code.google.com/p/otr4j/wiki/QuickStart
*/
public class OtrEngineHostImpl implements OtrEngineHost {
private OtrPolicy mPolicy;
private OtrAndroidKeyManagerImpl mOtrKeyManager;
private Context mContext;
private Hashtable<SessionID, String> mSessionResources;
private RemoteImService mImService;
public OtrEngineHostImpl(OtrPolicy policy, Context context, OtrAndroidKeyManagerImpl otrKeyManager, RemoteImService imService) throws IOException {
mPolicy = policy;
mContext = context;
mSessionResources = new Hashtable<SessionID, String>();
mOtrKeyManager = otrKeyManager;
mImService = imService;
}
public void putSessionResource(SessionID session, String resource) {
mSessionResources.put(session, resource);
}
public void removeSessionResource(SessionID session) {
mSessionResources.remove(session);
}
public Address appendSessionResource(SessionID session, Address to) {
String resource = mSessionResources.get(session);
if (resource != null)
return new XmppAddress(to.getBareAddress() + '/' + resource);
else
return to;
}
public ImConnectionAdapter findConnection(SessionID session) {
return mImService.getConnection(Address.stripResource(session.getLocalUserId()));
}
public OtrKeyManager getKeyManager() {
return mOtrKeyManager;
}
public void storeRemoteKey(SessionID sessionID, PublicKey remoteKey) {
mOtrKeyManager.savePublicKey(sessionID, remoteKey);
}
public boolean isRemoteKeyVerified(String userId, String fingerprint) {
return mOtrKeyManager.isVerified(userId, fingerprint);
}
public boolean isRemoteKeyVerified(SessionID sessionID) {
return mOtrKeyManager.isVerified(sessionID);
}
public String getLocalKeyFingerprint(SessionID sessionID) {
return mOtrKeyManager.getLocalFingerprint(sessionID);
}
public String getLocalKeyFingerprint(String userId) {
return mOtrKeyManager.getLocalFingerprint(userId);
}
public String getRemoteKeyFingerprint(SessionID sessionID) {
return mOtrKeyManager.getRemoteFingerprint(sessionID);
}
public String getRemoteKeyFingerprint(String userId) {
return mOtrKeyManager.getRemoteFingerprint(userId);
}
public ArrayList<String> getRemoteKeyFingerprints(String userId) {
return mOtrKeyManager.getRemoteKeyFingerprints(userId);
}
public boolean hasRemoteKeyFingerprint (String userid)
{
return mOtrKeyManager.hasRemoteFingerprint(userid);
}
public KeyPair getKeyPair(SessionID sessionID) {
KeyPair kp = null;
kp = mOtrKeyManager.loadLocalKeyPair(sessionID);
if (kp == null) {
mOtrKeyManager.generateLocalKeyPair(sessionID);
kp = mOtrKeyManager.loadLocalKeyPair(sessionID);
}
return kp;
}
public OtrPolicy getSessionPolicy(SessionID sessionID) {
return mPolicy;
}
public void setSessionPolicy(OtrPolicy policy) {
mPolicy = policy;
}
public void injectMessage(SessionID sessionID, String text) {
OtrDebugLogger.log(sessionID.toString() + ": injecting message: " + text);
ImConnectionAdapter connection = findConnection(sessionID);
if (connection != null)
{
ChatSessionManagerAdapter chatSessionManagerAdapter = (ChatSessionManagerAdapter) connection
.getChatSessionManager();
ChatSessionAdapter chatSessionAdapter = (ChatSessionAdapter) chatSessionManagerAdapter
.getChatSession(sessionID.getRemoteUserId());
if (chatSessionAdapter != null)
{
String body = text;
if (body == null)
body = ""; //don't allow null messages, only empty ones!
Message msg = new Message(body);
Address to = new XmppAddress(sessionID.getRemoteUserId());
msg.setTo(to);
if (!to.getAddress().contains("/")) {
//always send OTR messages to a resource
msg.setTo(appendSessionResource(sessionID, to));
}
boolean verified = mOtrKeyManager.isVerified(sessionID);
if (verified) {
msg.setType(Imps.MessageType.OUTGOING_ENCRYPTED_VERIFIED);
} else {
msg.setType(Imps.MessageType.OUTGOING_ENCRYPTED);
}
// msg ID is set by plugin
chatSessionManagerAdapter.getChatSessionManager().sendMessageAsync(chatSessionAdapter.getAdaptee(), msg);
}
else {
OtrDebugLogger.log(sessionID.toString() + ": could not find chatSession");
}
}
else
{
OtrDebugLogger.log(sessionID.toString() + ": could not find ImConnection");
}
}
public void showError(SessionID sessionID, String error) {
OtrDebugLogger.log(sessionID.toString() + ": ERROR=" + error);
// Toast.makeText(mContext, "ERROR: " + error, Toast.LENGTH_SHORT).show();
}
public void showWarning(SessionID sessionID, String warning) {
OtrDebugLogger.log(sessionID.toString() + ": WARNING=" + warning);
}
}