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); } }