Skip to content

Commit 585a1e2

Browse files
committed
Migrate from libsignal-protocol-java to libsignal
1 parent de56468 commit 585a1e2

File tree

11 files changed

+172
-121
lines changed

11 files changed

+172
-121
lines changed

smack-omemo-signal/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dependencies {
1111
api project(":smack-im")
1212
api project(":smack-extensions")
1313
api project(":smack-omemo")
14-
implementation 'org.whispersystems:signal-protocol-java:2.8.1'
14+
implementation 'org.signal:libsignal-client:0.26.0'
1515

1616
// TODO: Migrate Junit4 tests to Junit5.
1717
testImplementation "org.junit.vintage:junit-vintage-engine:$junitVersion"

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalCachingOmemoStore.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
import org.jivesoftware.smackx.omemo.CachingOmemoStore;
2424
import org.jivesoftware.smackx.omemo.OmemoStore;
2525

26-
import org.whispersystems.libsignal.IdentityKey;
27-
import org.whispersystems.libsignal.IdentityKeyPair;
28-
import org.whispersystems.libsignal.SessionCipher;
29-
import org.whispersystems.libsignal.SignalProtocolAddress;
30-
import org.whispersystems.libsignal.ecc.ECPublicKey;
31-
import org.whispersystems.libsignal.state.PreKeyBundle;
32-
import org.whispersystems.libsignal.state.PreKeyRecord;
33-
import org.whispersystems.libsignal.state.SessionRecord;
34-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
26+
import org.signal.libsignal.protocol.IdentityKey;
27+
import org.signal.libsignal.protocol.IdentityKeyPair;
28+
import org.signal.libsignal.protocol.SessionCipher;
29+
import org.signal.libsignal.protocol.SignalProtocolAddress;
30+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
31+
import org.signal.libsignal.protocol.state.PreKeyBundle;
32+
import org.signal.libsignal.protocol.state.PreKeyRecord;
33+
import org.signal.libsignal.protocol.state.SessionRecord;
34+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
3535

3636
/**
3737
* Implementation of the CachingOmemoStore for smack-omemo-signal.

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalFileBasedOmemoStore.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
import org.jivesoftware.smackx.omemo.FileBasedOmemoStore;
2626
import org.jivesoftware.smackx.omemo.util.OmemoKeyUtil;
2727

28-
import org.whispersystems.libsignal.IdentityKey;
29-
import org.whispersystems.libsignal.IdentityKeyPair;
30-
import org.whispersystems.libsignal.SessionCipher;
31-
import org.whispersystems.libsignal.SignalProtocolAddress;
32-
import org.whispersystems.libsignal.ecc.ECPublicKey;
33-
import org.whispersystems.libsignal.state.PreKeyBundle;
34-
import org.whispersystems.libsignal.state.PreKeyRecord;
35-
import org.whispersystems.libsignal.state.SessionRecord;
36-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
28+
import org.signal.libsignal.protocol.IdentityKey;
29+
import org.signal.libsignal.protocol.IdentityKeyPair;
30+
import org.signal.libsignal.protocol.SessionCipher;
31+
import org.signal.libsignal.protocol.SignalProtocolAddress;
32+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
33+
import org.signal.libsignal.protocol.state.PreKeyBundle;
34+
import org.signal.libsignal.protocol.state.PreKeyRecord;
35+
import org.signal.libsignal.protocol.state.SessionRecord;
36+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
3737

3838
/**
3939
* Implementation of a FileBasedOmemoStore for the smack-omemo-signal module.

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoKeyUtil.java

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,27 @@
2020
*/
2121
package org.jivesoftware.smackx.omemo.signal;
2222

23-
import java.io.IOException;
24-
import java.util.List;
25-
import java.util.TreeMap;
26-
2723
import org.jivesoftware.smackx.omemo.element.OmemoBundleElement;
2824
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
2925
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
3026
import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint;
3127
import org.jivesoftware.smackx.omemo.util.OmemoKeyUtil;
28+
import org.signal.libsignal.protocol.IdentityKey;
29+
import org.signal.libsignal.protocol.IdentityKeyPair;
30+
import org.signal.libsignal.protocol.InvalidKeyException;
31+
import org.signal.libsignal.protocol.InvalidMessageException;
32+
import org.signal.libsignal.protocol.ecc.Curve;
33+
import org.signal.libsignal.protocol.ecc.ECKeyPair;
34+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
35+
import org.signal.libsignal.protocol.state.PreKeyBundle;
36+
import org.signal.libsignal.protocol.state.PreKeyRecord;
37+
import org.signal.libsignal.protocol.state.SessionRecord;
38+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
39+
import org.signal.libsignal.protocol.util.Medium;
3240

33-
import org.whispersystems.libsignal.IdentityKey;
34-
import org.whispersystems.libsignal.IdentityKeyPair;
35-
import org.whispersystems.libsignal.InvalidKeyException;
36-
import org.whispersystems.libsignal.ecc.Curve;
37-
import org.whispersystems.libsignal.ecc.ECPublicKey;
38-
import org.whispersystems.libsignal.state.PreKeyBundle;
39-
import org.whispersystems.libsignal.state.PreKeyRecord;
40-
import org.whispersystems.libsignal.state.SessionRecord;
41-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
42-
import org.whispersystems.libsignal.util.KeyHelper;
41+
import java.io.IOException;
42+
import java.util.List;
43+
import java.util.TreeMap;
4344

4445
/**
4546
* Concrete implementation of the KeyUtil for an implementation using the Signal library.
@@ -51,34 +52,58 @@ public class SignalOmemoKeyUtil extends OmemoKeyUtil<IdentityKeyPair, IdentityKe
5152

5253
@Override
5354
public IdentityKeyPair generateOmemoIdentityKeyPair() {
54-
return KeyHelper.generateIdentityKeyPair();
55+
return IdentityKeyPair.generate();
5556
}
5657

5758
@Override
5859
@SuppressWarnings("NonApiType")
5960
public TreeMap<Integer, PreKeyRecord> generateOmemoPreKeys(int currentPreKeyId, int count) {
60-
List<PreKeyRecord> preKeyRecords = KeyHelper.generatePreKeys(currentPreKeyId, count);
61+
List<PreKeyRecord> preKeyRecords = generatePreKeys(currentPreKeyId, count);
6162
TreeMap<Integer, PreKeyRecord> map = new TreeMap<>();
6263
for (PreKeyRecord p : preKeyRecords) {
6364
map.put(p.getId(), p);
6465
}
6566
return map;
6667
}
6768

69+
private static List<PreKeyRecord> generatePreKeys(int start, int count) {
70+
List<PreKeyRecord> results = new ArrayList<>(count);
71+
72+
start--;
73+
74+
for (int i=0;i<count;i++) {
75+
int pkIdx = ((start + i) % (Medium.MAX_VALUE-1)) + 1;
76+
results.add(new PreKeyRecord(pkIdx, Curve.generateKeyPair()));
77+
}
78+
79+
return results;
80+
}
81+
6882
@Override
6983
public SignedPreKeyRecord generateOmemoSignedPreKey(IdentityKeyPair identityKeyPair, int currentPreKeyId)
7084
throws CorruptedOmemoKeyException {
7185
try {
72-
return KeyHelper.generateSignedPreKey(identityKeyPair, currentPreKeyId);
86+
return generateSignedPreKey(identityKeyPair, currentPreKeyId);
7387
} catch (InvalidKeyException e) {
7488
throw new CorruptedOmemoKeyException(e);
7589
}
7690
}
7791

92+
private static SignedPreKeyRecord generateSignedPreKey(IdentityKeyPair identityKeyPair, int signedPreKeyId) throws InvalidKeyException {
93+
ECKeyPair keyPair = Curve.generateKeyPair();
94+
byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
95+
96+
return new SignedPreKeyRecord(signedPreKeyId, System.currentTimeMillis(), keyPair, signature);
97+
}
98+
7899
@Override
79100
public SignedPreKeyRecord signedPreKeyFromBytes(byte[] data) throws IOException {
80101
if (data == null) return null;
81-
return new SignedPreKeyRecord(data);
102+
try {
103+
return new SignedPreKeyRecord(data);
104+
} catch (InvalidMessageException e) {
105+
throw new IOException(e);
106+
}
82107
}
83108

84109
@Override
@@ -89,7 +114,11 @@ public byte[] signedPreKeyToBytes(SignedPreKeyRecord signedPreKeyRecord) {
89114
@Override
90115
public SessionRecord rawSessionFromBytes(byte[] data) throws IOException {
91116
if (data == null) return null;
92-
return new SessionRecord(data);
117+
try {
118+
return new SessionRecord(data);
119+
} catch (InvalidMessageException e) {
120+
throw new IOException(e);
121+
}
93122
}
94123

95124
@Override
@@ -100,11 +129,7 @@ public byte[] rawSessionToBytes(SessionRecord session) {
100129
@Override
101130
public IdentityKeyPair identityKeyPairFromBytes(byte[] data) throws CorruptedOmemoKeyException {
102131
if (data == null) return null;
103-
try {
104-
return new IdentityKeyPair(data);
105-
} catch (InvalidKeyException e) {
106-
throw new CorruptedOmemoKeyException(e);
107-
}
132+
return new IdentityKeyPair(data);
108133
}
109134

110135
@Override
@@ -135,7 +160,11 @@ public byte[] preKeyToBytes(PreKeyRecord preKeyRecord) {
135160
@Override
136161
public PreKeyRecord preKeyFromBytes(byte[] bytes) throws IOException {
137162
if (bytes == null) return null;
138-
return new PreKeyRecord(bytes);
163+
try {
164+
return new PreKeyRecord(bytes);
165+
} catch (InvalidMessageException e) {
166+
throw new IOException(e);
167+
}
139168
}
140169

141170
@Override
@@ -188,7 +217,11 @@ public byte[] preKeyPublicKeyForBundle(ECPublicKey preKey) {
188217

189218
@Override
190219
public byte[] preKeyForBundle(PreKeyRecord preKeyRecord) {
191-
return preKeyRecord.getKeyPair().getPublicKey().serialize();
220+
try {
221+
return preKeyRecord.getKeyPair().getPublicKey().serialize();
222+
} catch (InvalidKeyException e) {
223+
throw new RuntimeException(e);
224+
}
192225
}
193226

194227
@Override

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoRatchet.java

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,27 @@
3535
import org.jivesoftware.smackx.omemo.internal.CiphertextTuple;
3636
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
3737

38-
import org.whispersystems.libsignal.DuplicateMessageException;
39-
import org.whispersystems.libsignal.IdentityKey;
40-
import org.whispersystems.libsignal.IdentityKeyPair;
41-
import org.whispersystems.libsignal.InvalidKeyException;
42-
import org.whispersystems.libsignal.InvalidKeyIdException;
43-
import org.whispersystems.libsignal.InvalidMessageException;
44-
import org.whispersystems.libsignal.InvalidVersionException;
45-
import org.whispersystems.libsignal.LegacyMessageException;
46-
import org.whispersystems.libsignal.NoSessionException;
47-
import org.whispersystems.libsignal.SessionCipher;
48-
import org.whispersystems.libsignal.SignalProtocolAddress;
49-
import org.whispersystems.libsignal.UntrustedIdentityException;
50-
import org.whispersystems.libsignal.ecc.ECPublicKey;
51-
import org.whispersystems.libsignal.protocol.CiphertextMessage;
52-
import org.whispersystems.libsignal.protocol.PreKeySignalMessage;
53-
import org.whispersystems.libsignal.protocol.SignalMessage;
54-
import org.whispersystems.libsignal.state.PreKeyBundle;
55-
import org.whispersystems.libsignal.state.PreKeyRecord;
56-
import org.whispersystems.libsignal.state.SessionRecord;
57-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
38+
import org.signal.libsignal.protocol.DuplicateMessageException;
39+
import org.signal.libsignal.protocol.IdentityKey;
40+
import org.signal.libsignal.protocol.IdentityKeyPair;
41+
import org.signal.libsignal.protocol.InvalidKeyException;
42+
import org.signal.libsignal.protocol.InvalidKeyIdException;
43+
import org.signal.libsignal.protocol.InvalidMessageException;
44+
import org.signal.libsignal.protocol.InvalidVersionException;
45+
import org.signal.libsignal.protocol.LegacyMessageException;
46+
import org.signal.libsignal.protocol.NoSessionException;
47+
import org.signal.libsignal.protocol.SessionCipher;
48+
import org.signal.libsignal.protocol.SignalProtocolAddress;
49+
import org.signal.libsignal.protocol.UntrustedIdentityException;
50+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
51+
import org.signal.libsignal.protocol.message.CiphertextMessage;
52+
import org.signal.libsignal.protocol.message.PreKeySignalMessage;
53+
import org.signal.libsignal.protocol.message.SignalMessage;
54+
import org.signal.libsignal.protocol.state.PreKeyBundle;
55+
import org.signal.libsignal.protocol.state.PreKeyRecord;
56+
import org.signal.libsignal.protocol.state.SessionRecord;
57+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
58+
5859

5960
public class SignalOmemoRatchet
6061
extends OmemoRatchet<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord,
@@ -103,7 +104,7 @@ public byte[] doubleRatchetDecrypt(OmemoDevice sender, byte[] encryptedKey)
103104
catch (UntrustedIdentityException e) {
104105
throw new AssertionError("Signals trust management MUST be disabled.");
105106
}
106-
catch (LegacyMessageException | InvalidKeyException e) {
107+
catch (InvalidKeyException e) {
107108
throw new CryptoFailedException(e);
108109
}
109110
catch (InvalidKeyIdException e) {
@@ -134,7 +135,15 @@ public byte[] doubleRatchetDecrypt(OmemoDevice sender, byte[] encryptedKey)
134135
LOGGER.log(Level.INFO, "Decryption of SignalMessage from " + sender +
135136
" failed, since the message has been decrypted before.");
136137
return null;
138+
} catch (InvalidVersionException e) {
139+
throw new RuntimeException(e);
140+
} catch (InvalidKeyException e) {
141+
throw new RuntimeException(e);
137142
}
143+
} catch (LegacyMessageException e) {
144+
throw new RuntimeException(e);
145+
} catch (InvalidKeyException e) {
146+
throw new RuntimeException(e);
138147
}
139148

140149
return decryptedKey;
@@ -156,7 +165,7 @@ public CiphertextTuple doubleRatchetEncrypt(OmemoDevice recipient, byte[] messag
156165
}
157166

158167
private SessionCipher getCipher(OmemoDevice device) {
159-
return new SessionCipher(storeConnector, storeConnector, storeConnector, storeConnector,
168+
return new SessionCipher(storeConnector, storeConnector, storeConnector, null, storeConnector,
160169
SignalOmemoStoreConnector.asAddress(device));
161170
}
162171
}

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoService.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,19 @@
2828
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
2929
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
3030

31-
import org.whispersystems.libsignal.IdentityKey;
32-
import org.whispersystems.libsignal.IdentityKeyPair;
33-
import org.whispersystems.libsignal.SessionBuilder;
34-
import org.whispersystems.libsignal.SessionCipher;
35-
import org.whispersystems.libsignal.SignalProtocolAddress;
36-
import org.whispersystems.libsignal.UntrustedIdentityException;
37-
import org.whispersystems.libsignal.ecc.ECPublicKey;
38-
import org.whispersystems.libsignal.state.PreKeyBundle;
39-
import org.whispersystems.libsignal.state.PreKeyRecord;
40-
import org.whispersystems.libsignal.state.SessionRecord;
41-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
31+
32+
import org.signal.libsignal.protocol.IdentityKey;
33+
import org.signal.libsignal.protocol.IdentityKeyPair;
34+
import org.signal.libsignal.protocol.SessionBuilder;
35+
import org.signal.libsignal.protocol.SessionCipher;
36+
import org.signal.libsignal.protocol.SignalProtocolAddress;
37+
import org.signal.libsignal.protocol.UntrustedIdentityException;
38+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
39+
import org.signal.libsignal.protocol.state.PreKeyBundle;
40+
import org.signal.libsignal.protocol.state.PreKeyRecord;
41+
import org.signal.libsignal.protocol.state.SessionRecord;
42+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
43+
4244

4345
/**
4446
* Concrete implementation of the OmemoService using the Signal library.
@@ -103,7 +105,7 @@ protected void processBundle(OmemoManager omemoManager,
103105
try {
104106
builder.process(contactsBundle);
105107
LOGGER.log(Level.FINE, "Session built with " + contactsDevice);
106-
} catch (org.whispersystems.libsignal.InvalidKeyException e) {
108+
} catch (org.signal.libsignal.protocol.InvalidKeyException e) {
107109
throw new CorruptedOmemoKeyException(e);
108110
} catch (UntrustedIdentityException e) {
109111
// This should never happen.

smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoStore.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
import org.jivesoftware.smackx.omemo.OmemoStore;
2424
import org.jivesoftware.smackx.omemo.util.OmemoKeyUtil;
2525

26-
import org.whispersystems.libsignal.IdentityKey;
27-
import org.whispersystems.libsignal.IdentityKeyPair;
28-
import org.whispersystems.libsignal.SessionCipher;
29-
import org.whispersystems.libsignal.SignalProtocolAddress;
30-
import org.whispersystems.libsignal.ecc.ECPublicKey;
31-
import org.whispersystems.libsignal.state.PreKeyBundle;
32-
import org.whispersystems.libsignal.state.PreKeyRecord;
33-
import org.whispersystems.libsignal.state.SessionRecord;
34-
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
26+
import org.signal.libsignal.protocol.IdentityKey;
27+
import org.signal.libsignal.protocol.IdentityKeyPair;
28+
import org.signal.libsignal.protocol.SessionCipher;
29+
import org.signal.libsignal.protocol.SignalProtocolAddress;
30+
import org.signal.libsignal.protocol.ecc.ECPublicKey;
31+
import org.signal.libsignal.protocol.state.PreKeyBundle;
32+
import org.signal.libsignal.protocol.state.PreKeyRecord;
33+
import org.signal.libsignal.protocol.state.SessionRecord;
34+
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
3535

3636
/**
3737
* Implementation of the OmemoStore using the Signal library.

0 commit comments

Comments
 (0)