Mon, 30 Dec 2024 11:44:48 +0100
add minimally working otr
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 { System.out.println("smpAborted"); } @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 | OtrPolicy.ERROR_START_AKE); } @Override public FragmenterInstructions getFragmenterInstructions(SessionID sid) { return new FragmenterInstructions(16, 2048); } @Override public KeyPair getLocalKeyPair(SessionID sid) throws OtrException { System.out.println("getLocalKeyPair"); // 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) { System.out.println("getLocalFingerprintRaw"); // 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 ""; } @Override public void messageFromAnotherInstanceReceived(SessionID sid) { System.out.println("messageFromAnotherInstanceReceived"); } @Override public void multipleInstancesDetected(SessionID sid) { System.out.println("multipleInstancesDeteced"); } }