mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-30 14:20:47 +00:00
Upgrade to libaxolotl 1.3.0, simplify some interfaces.
This commit is contained in:
parent
e5034134b3
commit
6d759bdc88
@ -1,7 +1,7 @@
|
||||
subprojects {
|
||||
ext.version_number = "1.0.0"
|
||||
ext.group_info = "org.whispersystems"
|
||||
ext.axolotl_version = "1.2.1"
|
||||
ext.axolotl_version = "1.3.0"
|
||||
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
allprojects {
|
||||
|
@ -19,6 +19,7 @@ package org.whispersystems.textsecure.api;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import org.whispersystems.libaxolotl.AxolotlAddress;
|
||||
import org.whispersystems.libaxolotl.InvalidKeyException;
|
||||
import org.whispersystems.libaxolotl.SessionBuilder;
|
||||
import org.whispersystems.libaxolotl.logging.Log;
|
||||
@ -81,19 +82,18 @@ public class TextSecureMessageSender {
|
||||
* @param trustStore The trust store containing the TextSecure server's signing TLS certificate.
|
||||
* @param user The TextSecure username (eg phone number).
|
||||
* @param password The TextSecure user's password.
|
||||
* @param userId The axolotl recipient id for the local TextSecure user.
|
||||
* @param store The AxolotlStore.
|
||||
* @param eventListener An optional event listener, which fires whenever sessions are
|
||||
* setup or torn down for a recipient.
|
||||
*/
|
||||
public TextSecureMessageSender(String url, TrustStore trustStore,
|
||||
String user, String password,
|
||||
long userId, AxolotlStore store,
|
||||
AxolotlStore store,
|
||||
Optional<EventListener> eventListener)
|
||||
{
|
||||
this.socket = new PushServiceSocket(url, trustStore, new StaticCredentialsProvider(user, password, null));
|
||||
this.store = store;
|
||||
this.syncAddress = new TextSecureAddress(userId, user, null);
|
||||
this.syncAddress = new TextSecureAddress(user);
|
||||
this.eventListener = eventListener;
|
||||
}
|
||||
|
||||
@ -129,10 +129,10 @@ public class TextSecureMessageSender {
|
||||
}
|
||||
|
||||
if (message.isEndSession()) {
|
||||
store.deleteAllSessions(recipient.getRecipientId());
|
||||
store.deleteAllSessions(recipient.getNumber());
|
||||
|
||||
if (eventListener.isPresent()) {
|
||||
eventListener.get().onSecurityEvent(recipient.getRecipientId());
|
||||
eventListener.get().onSecurityEvent(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,24 +308,27 @@ public class TextSecureMessageSender {
|
||||
messages.add(new OutgoingPushMessage(recipient, TextSecureAddress.DEFAULT_DEVICE_ID, masterBody));
|
||||
}
|
||||
|
||||
for (int deviceId : store.getSubDeviceSessions(recipient.getRecipientId())) {
|
||||
for (int deviceId : store.getSubDeviceSessions(recipient.getNumber())) {
|
||||
PushBody body = getEncryptedMessage(socket, recipient, deviceId, plaintext);
|
||||
messages.add(new OutgoingPushMessage(recipient, deviceId, body));
|
||||
}
|
||||
|
||||
return new OutgoingPushMessageList(recipient.getNumber(), timestamp, recipient.getRelay(), messages);
|
||||
return new OutgoingPushMessageList(recipient.getNumber(), timestamp, recipient.getRelay().orNull(), messages);
|
||||
}
|
||||
|
||||
private PushBody getEncryptedMessage(PushServiceSocket socket, TextSecureAddress recipient, int deviceId, byte[] plaintext)
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
if (!store.containsSession(recipient.getRecipientId(), deviceId)) {
|
||||
AxolotlAddress axolotlAddress = new AxolotlAddress(recipient.getNumber(), deviceId);
|
||||
|
||||
if (!store.containsSession(axolotlAddress)) {
|
||||
try {
|
||||
List<PreKeyBundle> preKeys = socket.getPreKeys(recipient, deviceId);
|
||||
|
||||
for (PreKeyBundle preKey : preKeys) {
|
||||
try {
|
||||
SessionBuilder sessionBuilder = new SessionBuilder(store, recipient.getRecipientId(), deviceId);
|
||||
AxolotlAddress preKeyAddress = new AxolotlAddress(recipient.getNumber(), preKey.getDeviceId());
|
||||
SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress);
|
||||
sessionBuilder.process(preKey);
|
||||
} catch (org.whispersystems.libaxolotl.UntrustedIdentityException e) {
|
||||
throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
|
||||
@ -333,14 +336,14 @@ public class TextSecureMessageSender {
|
||||
}
|
||||
|
||||
if (eventListener.isPresent()) {
|
||||
eventListener.get().onSecurityEvent(recipient.getRecipientId());
|
||||
eventListener.get().onSecurityEvent(recipient);
|
||||
}
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
TextSecureCipher cipher = new TextSecureCipher(store, recipient.getRecipientId(), deviceId);
|
||||
TextSecureCipher cipher = new TextSecureCipher(store, axolotlAddress);
|
||||
CiphertextMessage message = cipher.encrypt(plaintext);
|
||||
int remoteRegistrationId = cipher.getRemoteRegistrationId();
|
||||
|
||||
@ -359,14 +362,14 @@ public class TextSecureMessageSender {
|
||||
{
|
||||
try {
|
||||
for (int extraDeviceId : mismatchedDevices.getExtraDevices()) {
|
||||
store.deleteSession(recipient.getRecipientId(), extraDeviceId);
|
||||
store.deleteSession(new AxolotlAddress(recipient.getNumber(), extraDeviceId));
|
||||
}
|
||||
|
||||
for (int missingDeviceId : mismatchedDevices.getMissingDevices()) {
|
||||
PreKeyBundle preKey = socket.getPreKey(recipient, missingDeviceId);
|
||||
|
||||
try {
|
||||
SessionBuilder sessionBuilder = new SessionBuilder(store, recipient.getRecipientId(), missingDeviceId);
|
||||
SessionBuilder sessionBuilder = new SessionBuilder(store, new AxolotlAddress(recipient.getNumber(), missingDeviceId));
|
||||
sessionBuilder.process(preKey);
|
||||
} catch (org.whispersystems.libaxolotl.UntrustedIdentityException e) {
|
||||
throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
|
||||
@ -378,15 +381,13 @@ public class TextSecureMessageSender {
|
||||
}
|
||||
|
||||
private void handleStaleDevices(TextSecureAddress recipient, StaleDevices staleDevices) {
|
||||
long recipientId = recipient.getRecipientId();
|
||||
|
||||
for (int staleDeviceId : staleDevices.getStaleDevices()) {
|
||||
store.deleteSession(recipientId, staleDeviceId);
|
||||
store.deleteSession(new AxolotlAddress(recipient.getNumber(), staleDeviceId));
|
||||
}
|
||||
}
|
||||
|
||||
public static interface EventListener {
|
||||
public void onSecurityEvent(long recipientId);
|
||||
public void onSecurityEvent(TextSecureAddress address);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.whispersystems.textsecure.api.crypto;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import org.whispersystems.libaxolotl.AxolotlAddress;
|
||||
import org.whispersystems.libaxolotl.DuplicateMessageException;
|
||||
import org.whispersystems.libaxolotl.InvalidKeyException;
|
||||
import org.whispersystems.libaxolotl.InvalidKeyIdException;
|
||||
@ -53,8 +54,8 @@ public class TextSecureCipher {
|
||||
|
||||
private final SessionCipher sessionCipher;
|
||||
|
||||
public TextSecureCipher(AxolotlStore axolotlStore, long recipientId, int deviceId) {
|
||||
this.sessionCipher = new SessionCipher(axolotlStore, recipientId, deviceId);
|
||||
public TextSecureCipher(AxolotlStore axolotlStore, AxolotlAddress destination) {
|
||||
this.sessionCipher = new SessionCipher(axolotlStore, destination);
|
||||
}
|
||||
|
||||
public CiphertextMessage encrypt(byte[] unpaddedMessage) {
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package org.whispersystems.textsecure.api.push;
|
||||
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
|
||||
/**
|
||||
* A class representing a message destination or origin.
|
||||
*/
|
||||
@ -23,52 +25,48 @@ public class TextSecureAddress {
|
||||
|
||||
public static final int DEFAULT_DEVICE_ID = 1;
|
||||
|
||||
private final long recipientId;
|
||||
private final String e164number;
|
||||
private final String relay;
|
||||
private final Optional<String> relay;
|
||||
|
||||
/**
|
||||
* Construct a PushAddress.
|
||||
*
|
||||
* @param recipientId The axolotl recipient ID of this destination.
|
||||
* @param e164number The TextSecure username of this destination (eg e164 representation of a phone number).
|
||||
* @param relay The TextSecure federated server this user is registered with (if not your own server).
|
||||
*/
|
||||
public TextSecureAddress(long recipientId, String e164number, String relay) {
|
||||
this.recipientId = recipientId;
|
||||
public TextSecureAddress(String e164number, Optional<String> relay) {
|
||||
this.e164number = e164number;
|
||||
this.relay = relay;
|
||||
}
|
||||
|
||||
public TextSecureAddress(String e164number) {
|
||||
this(e164number, Optional.<String>absent());
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return e164number;
|
||||
}
|
||||
|
||||
public String getRelay() {
|
||||
public Optional<String> getRelay() {
|
||||
return relay;
|
||||
}
|
||||
|
||||
public long getRecipientId() {
|
||||
return recipientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof TextSecureAddress)) return false;
|
||||
|
||||
TextSecureAddress that = (TextSecureAddress)other;
|
||||
|
||||
return this.recipientId == that.recipientId &&
|
||||
equals(this.e164number, that.e164number) &&
|
||||
return equals(this.e164number, that.e164number) &&
|
||||
equals(this.relay, that.relay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = (int)this.recipientId;
|
||||
int hashCode = 0;
|
||||
|
||||
if (this.e164number != null) hashCode ^= this.e164number.hashCode();
|
||||
if (this.relay != null) hashCode ^= this.relay.hashCode();
|
||||
if (this.relay.isPresent()) hashCode ^= this.relay.get().hashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
@ -77,4 +75,9 @@ public class TextSecureAddress {
|
||||
if (one == null) return two == null;
|
||||
return one.equals(two);
|
||||
}
|
||||
|
||||
private boolean equals(Optional<String> one, Optional<String> two) {
|
||||
if (one.isPresent()) return two.isPresent() && one.get().equals(two.get());
|
||||
else return !two.isPresent();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.whispersystems.libaxolotl.logging.Log;
|
||||
import org.whispersystems.libaxolotl.state.PreKeyBundle;
|
||||
import org.whispersystems.libaxolotl.state.PreKeyRecord;
|
||||
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
import org.whispersystems.textsecure.api.crypto.AttachmentCipherOutputStream;
|
||||
import org.whispersystems.textsecure.api.push.ContactTokenDetails;
|
||||
import org.whispersystems.textsecure.api.push.TextSecureAddress;
|
||||
@ -129,11 +130,11 @@ public class PushServiceSocket {
|
||||
JsonUtil.toJson(new ProvisioningMessage(Base64.encodeBytes(body))));
|
||||
}
|
||||
|
||||
public void sendReceipt(String destination, long messageId, String relay) throws IOException {
|
||||
public void sendReceipt(String destination, long messageId, Optional<String> relay) throws IOException {
|
||||
String path = String.format(RECEIPT_PATH, destination, messageId);
|
||||
|
||||
if (!Util.isEmpty(relay)) {
|
||||
path += "?relay=" + relay;
|
||||
if (relay.isPresent()) {
|
||||
path += "?relay=" + relay.get();
|
||||
}
|
||||
|
||||
makeRequest(path, "PUT", null);
|
||||
@ -204,8 +205,8 @@ public class PushServiceSocket {
|
||||
|
||||
String path = String.format(PREKEY_DEVICE_PATH, destination.getNumber(), deviceId);
|
||||
|
||||
if (!Util.isEmpty(destination.getRelay())) {
|
||||
path = path + "?relay=" + destination.getRelay();
|
||||
if (destination.getRelay().isPresent()) {
|
||||
path = path + "?relay=" + destination.getRelay().get();
|
||||
}
|
||||
|
||||
String responseText = makeRequest(path, "GET", null);
|
||||
@ -248,8 +249,8 @@ public class PushServiceSocket {
|
||||
String path = String.format(PREKEY_DEVICE_PATH, destination.getNumber(),
|
||||
String.valueOf(deviceId));
|
||||
|
||||
if (!Util.isEmpty(destination.getRelay())) {
|
||||
path = path + "?relay=" + destination.getRelay();
|
||||
if (destination.getRelay().isPresent()) {
|
||||
path = path + "?relay=" + destination.getRelay().get();
|
||||
}
|
||||
|
||||
String responseText = makeRequest(path, "GET", null);
|
||||
|
Loading…
x
Reference in New Issue
Block a user