| |
1 package de.unixwork.im; |
| |
2 |
| |
3 import java.security.KeyPair; |
| |
4 import java.security.KeyPairGenerator; |
| |
5 import java.security.MessageDigest; |
| |
6 import java.security.NoSuchAlgorithmException; |
| |
7 import java.security.PublicKey; |
| |
8 import java.util.HashMap; |
| |
9 import java.util.Map; |
| |
10 import java.util.logging.Level; |
| |
11 import java.util.logging.Logger; |
| |
12 import net.java.otr4j.OtrEngineHost; |
| |
13 import net.java.otr4j.OtrException; |
| |
14 import net.java.otr4j.OtrPolicy; |
| |
15 import net.java.otr4j.OtrPolicyImpl; |
| |
16 import net.java.otr4j.crypto.OtrCryptoEngineImpl; |
| |
17 import net.java.otr4j.crypto.OtrCryptoException; |
| |
18 import net.java.otr4j.session.FragmenterInstructions; |
| |
19 import net.java.otr4j.session.InstanceTag; |
| |
20 import net.java.otr4j.session.SessionID; |
| |
21 |
| |
22 public class OTR implements OtrEngineHost { |
| |
23 private final Xmpp xmpp; |
| |
24 |
| |
25 // Map to store key pairs for each session |
| |
26 private final Map<SessionID, KeyPair> keyPairCache = new HashMap<>(); |
| |
27 |
| |
28 public OTR(Xmpp xmpp) { |
| |
29 this.xmpp = xmpp; |
| |
30 } |
| |
31 |
| |
32 @Override |
| |
33 public void injectMessage(SessionID sid, String string) throws OtrException { |
| |
34 System.out.println("inject " + string); |
| |
35 xmpp.send(sid.getUserID(), string); |
| |
36 } |
| |
37 |
| |
38 @Override |
| |
39 public void unreadableMessageReceived(SessionID sid) throws OtrException { |
| |
40 // TODO: send error to App |
| |
41 } |
| |
42 |
| |
43 @Override |
| |
44 public void unencryptedMessageReceived(SessionID sid, String string) throws OtrException { |
| |
45 // TODO: send error to App |
| |
46 } |
| |
47 |
| |
48 @Override |
| |
49 public void showError(SessionID sid, String string) throws OtrException { |
| |
50 System.out.println("showError " + string); |
| |
51 } |
| |
52 |
| |
53 @Override |
| |
54 public void smpError(SessionID sid, int i, boolean bln) throws OtrException { |
| |
55 System.out.println("smpError"); |
| |
56 } |
| |
57 |
| |
58 @Override |
| |
59 public void smpAborted(SessionID sid) throws OtrException { |
| |
60 |
| |
61 } |
| |
62 |
| |
63 @Override |
| |
64 public void finishedSessionMessage(SessionID sid, String string) throws OtrException { |
| |
65 System.out.println("finishedSessionMessage: " + sid); |
| |
66 } |
| |
67 |
| |
68 @Override |
| |
69 public void requireEncryptedMessage(SessionID sid, String string) throws OtrException { |
| |
70 System.out.println("requireEncryptedMessage"); |
| |
71 } |
| |
72 |
| |
73 @Override |
| |
74 public OtrPolicy getSessionPolicy(SessionID sid) { |
| |
75 return new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ALLOW_V3 | OtrPolicy.OPPORTUNISTIC); |
| |
76 } |
| |
77 |
| |
78 @Override |
| |
79 public FragmenterInstructions getFragmenterInstructions(SessionID sid) { |
| |
80 return new FragmenterInstructions(4096, 131072); |
| |
81 } |
| |
82 |
| |
83 @Override |
| |
84 public KeyPair getLocalKeyPair(SessionID sid) throws OtrException { |
| |
85 // Check if a key pair already exists for the session |
| |
86 if (keyPairCache.containsKey(sid)) { |
| |
87 return keyPairCache.get(sid); |
| |
88 } |
| |
89 |
| |
90 // Generate a new key pair |
| |
91 KeyPair keyPair = generateKeyPair(); |
| |
92 |
| |
93 // Cache the key pair for this session |
| |
94 keyPairCache.put(sid, keyPair); |
| |
95 |
| |
96 return keyPair; |
| |
97 } |
| |
98 |
| |
99 // Helper method to generate a new key pair |
| |
100 private KeyPair generateKeyPair() { |
| |
101 try { |
| |
102 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA"); // Use DSA for OTR |
| |
103 keyPairGenerator.initialize(1024); // OTR uses 1024-bit keys |
| |
104 return keyPairGenerator.generateKeyPair(); |
| |
105 } catch (NoSuchAlgorithmException e) { |
| |
106 throw new RuntimeException("Error generating key pair", e); |
| |
107 } |
| |
108 } |
| |
109 |
| |
110 @Override |
| |
111 public byte[] getLocalFingerprintRaw(SessionID sid) { |
| |
112 // code from DummyClient: https://github.com/jitsi/otr4j/blob/master/src/test/java/net/java/otr4j/session/DummyClient.java |
| |
113 try { |
| |
114 return new OtrCryptoEngineImpl() |
| |
115 .getFingerprintRaw(getLocalKeyPair(sid) |
| |
116 .getPublic()); |
| |
117 } catch (OtrCryptoException e) { |
| |
118 e.printStackTrace(); |
| |
119 } catch (OtrException ex) { |
| |
120 Logger.getLogger(OTR.class.getName()).log(Level.SEVERE, null, ex); |
| |
121 } |
| |
122 return null; |
| |
123 } |
| |
124 |
| |
125 @Override |
| |
126 public void askForSecret(SessionID sid, InstanceTag it, String string) { |
| |
127 System.out.println("askForSecret " + sid); |
| |
128 } |
| |
129 |
| |
130 @Override |
| |
131 public void verify(SessionID sid, String string, boolean bln) { |
| |
132 System.out.println("verify"); |
| |
133 } |
| |
134 |
| |
135 @Override |
| |
136 public void unverify(SessionID sid, String string) { |
| |
137 System.out.println("unverify"); |
| |
138 } |
| |
139 |
| |
140 @Override |
| |
141 public String getReplyForUnreadableMessage(SessionID sid) { |
| |
142 return "Message unreadable"; |
| |
143 } |
| |
144 |
| |
145 @Override |
| |
146 public String getFallbackMessage(SessionID sid) { |
| |
147 return "error"; |
| |
148 } |
| |
149 |
| |
150 @Override |
| |
151 public void messageFromAnotherInstanceReceived(SessionID sid) { |
| |
152 System.out.println("messageFromAnotherInstanceReceived"); |
| |
153 } |
| |
154 |
| |
155 @Override |
| |
156 public void multipleInstancesDetected(SessionID sid) { |
| |
157 System.out.println("multipleInstancesDeteced"); |
| |
158 } |
| |
159 |
| |
160 } |