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

Thu, 26 Dec 2024 17:19:15 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 26 Dec 2024 17:19:15 +0100
changeset 3
25a32e2dfde5
parent 1
42d0d099492b
child 4
856befba7674
permissions
-rw-r--r--

update status in contact list and conversations

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