src/main/java/de/unixwork/im/OTR.java

changeset 1
42d0d099492b
child 4
856befba7674
--- /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<SessionID, KeyPair> 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");
+    }
+    
+}

mercurial