diff -r f3095cda599e -r 42d0d099492b src/main/java/de/unixwork/im/OTR.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/unixwork/im/OTR.java Thu Dec 26 12:29:05 2024 +0100 @@ -0,0 +1,160 @@ +package de.unixwork.im; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.java.otr4j.OtrEngineHost; +import net.java.otr4j.OtrException; +import net.java.otr4j.OtrPolicy; +import net.java.otr4j.OtrPolicyImpl; +import net.java.otr4j.crypto.OtrCryptoEngineImpl; +import net.java.otr4j.crypto.OtrCryptoException; +import net.java.otr4j.session.FragmenterInstructions; +import net.java.otr4j.session.InstanceTag; +import net.java.otr4j.session.SessionID; + +public class OTR implements OtrEngineHost { + private final Xmpp xmpp; + + // Map to store key pairs for each session + private final Map keyPairCache = new HashMap<>(); + + public OTR(Xmpp xmpp) { + this.xmpp = xmpp; + } + + @Override + public void injectMessage(SessionID sid, String string) throws OtrException { + System.out.println("inject " + string); + xmpp.send(sid.getUserID(), string); + } + + @Override + public void unreadableMessageReceived(SessionID sid) throws OtrException { + // TODO: send error to App + } + + @Override + public void unencryptedMessageReceived(SessionID sid, String string) throws OtrException { + // TODO: send error to App + } + + @Override + public void showError(SessionID sid, String string) throws OtrException { + System.out.println("showError " + string); + } + + @Override + public void smpError(SessionID sid, int i, boolean bln) throws OtrException { + System.out.println("smpError"); + } + + @Override + public void smpAborted(SessionID sid) throws OtrException { + + } + + @Override + public void finishedSessionMessage(SessionID sid, String string) throws OtrException { + System.out.println("finishedSessionMessage: " + sid); + } + + @Override + public void requireEncryptedMessage(SessionID sid, String string) throws OtrException { + System.out.println("requireEncryptedMessage"); + } + + @Override + public OtrPolicy getSessionPolicy(SessionID sid) { + return new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ALLOW_V3 | OtrPolicy.OPPORTUNISTIC); + } + + @Override + public FragmenterInstructions getFragmenterInstructions(SessionID sid) { + return new FragmenterInstructions(4096, 131072); + } + + @Override + public KeyPair getLocalKeyPair(SessionID sid) throws OtrException { + // Check if a key pair already exists for the session + if (keyPairCache.containsKey(sid)) { + return keyPairCache.get(sid); + } + + // Generate a new key pair + KeyPair keyPair = generateKeyPair(); + + // Cache the key pair for this session + keyPairCache.put(sid, keyPair); + + return keyPair; + } + + // Helper method to generate a new key pair + private KeyPair generateKeyPair() { + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA"); // Use DSA for OTR + keyPairGenerator.initialize(1024); // OTR uses 1024-bit keys + return keyPairGenerator.generateKeyPair(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Error generating key pair", e); + } + } + + @Override + public byte[] getLocalFingerprintRaw(SessionID sid) { + // code from DummyClient: https://github.com/jitsi/otr4j/blob/master/src/test/java/net/java/otr4j/session/DummyClient.java + try { + return new OtrCryptoEngineImpl() + .getFingerprintRaw(getLocalKeyPair(sid) + .getPublic()); + } catch (OtrCryptoException e) { + e.printStackTrace(); + } catch (OtrException ex) { + Logger.getLogger(OTR.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + + @Override + public void askForSecret(SessionID sid, InstanceTag it, String string) { + System.out.println("askForSecret " + sid); + } + + @Override + public void verify(SessionID sid, String string, boolean bln) { + System.out.println("verify"); + } + + @Override + public void unverify(SessionID sid, String string) { + System.out.println("unverify"); + } + + @Override + public String getReplyForUnreadableMessage(SessionID sid) { + return "Message unreadable"; + } + + @Override + public String getFallbackMessage(SessionID sid) { + return "error"; + } + + @Override + public void messageFromAnotherInstanceReceived(SessionID sid) { + System.out.println("messageFromAnotherInstanceReceived"); + } + + @Override + public void multipleInstancesDetected(SessionID sid) { + System.out.println("multipleInstancesDeteced"); + } + +}