From 5bc4094ff4a9fe25d458ade55ae1019cb87eeab8 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sat, 24 Jun 2017 09:31:13 +0200 Subject: upgrade to signal-protocol-java --- .../messenger/crypto/axolotl/AxolotlService.java | 106 ++++++++++----------- .../crypto/axolotl/SQLiteAxolotlStore.java | 52 +++++----- .../crypto/axolotl/XmppAxolotlSession.java | 63 ++++++------ .../de/pixart/messenger/generator/IqGenerator.java | 8 +- .../java/de/pixart/messenger/parser/IqParser.java | 8 +- .../messenger/persistance/DatabaseBackend.java | 34 +++---- .../de/pixart/messenger/ui/TrustKeysActivity.java | 2 +- .../de/pixart/messenger/utils/CryptoHelper.java | 3 +- 8 files changed, 141 insertions(+), 135 deletions(-) (limited to 'src/main/java/de/pixart/messenger') diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java index b76630873..c53ec40fe 100644 --- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java +++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java @@ -8,18 +8,18 @@ import android.util.Log; import android.util.Pair; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.whispersystems.libaxolotl.AxolotlAddress; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.IdentityKeyPair; -import org.whispersystems.libaxolotl.InvalidKeyException; -import org.whispersystems.libaxolotl.InvalidKeyIdException; -import org.whispersystems.libaxolotl.SessionBuilder; -import org.whispersystems.libaxolotl.UntrustedIdentityException; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.state.PreKeyBundle; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; -import org.whispersystems.libaxolotl.util.KeyHelper; +import org.whispersystems.libsignal.SignalProtocolAddress; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.IdentityKeyPair; +import org.whispersystems.libsignal.InvalidKeyException; +import org.whispersystems.libsignal.InvalidKeyIdException; +import org.whispersystems.libsignal.SessionBuilder; +import org.whispersystems.libsignal.UntrustedIdentityException; +import org.whispersystems.libsignal.ecc.ECPublicKey; +import org.whispersystems.libsignal.state.PreKeyBundle; +import org.whispersystems.libsignal.state.PreKeyRecord; +import org.whispersystems.libsignal.state.SignedPreKeyRecord; +import org.whispersystems.libsignal.util.KeyHelper; import java.security.PrivateKey; import java.security.Security; @@ -93,8 +93,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { for (Jid jid : jids) { if (deviceIds.get(jid) != null) { for (Integer foreignId : this.deviceIds.get(jid)) { - AxolotlAddress address = new AxolotlAddress(jid.toPreppedString(), foreignId); - if (fetchStatusMap.getAll(address).containsValue(FetchStatus.ERROR)) { + SignalProtocolAddress address = new SignalProtocolAddress(jid.toPreppedString(), foreignId); + if (fetchStatusMap.getAll(address.getName()).containsValue(FetchStatus.ERROR)) { return true; } } @@ -112,7 +112,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } public boolean hasVerifiedKeys(String name) { - for(XmppAxolotlSession session : this.sessions.getAll(new AxolotlAddress(name,0)).values()) { + for(XmppAxolotlSession session : this.sessions.getAll(name).values()) { if (session.getTrust().isVerified()) { return true; } @@ -128,7 +128,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { this.map = new HashMap<>(); } - public void put(AxolotlAddress address, T value) { + public void put(SignalProtocolAddress address, T value) { synchronized (MAP_LOCK) { Map devices = map.get(address.getName()); if (devices == null) { @@ -139,7 +139,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } - public T get(AxolotlAddress address) { + public T get(SignalProtocolAddress address) { synchronized (MAP_LOCK) { Map devices = map.get(address.getName()); if (devices == null) { @@ -149,9 +149,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } - public Map getAll(AxolotlAddress address) { + public Map getAll(String name) { synchronized (MAP_LOCK) { - Map devices = map.get(address.getName()); + Map devices = map.get(name); if (devices == null) { return new HashMap<>(); } @@ -159,7 +159,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } - public boolean hasAny(AxolotlAddress address) { + public boolean hasAny(SignalProtocolAddress address) { synchronized (MAP_LOCK) { Map devices = map.get(address.getName()); return devices != null && !devices.isEmpty(); @@ -185,7 +185,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private void putDevicesForJid(String bareJid, List deviceIds, SQLiteAxolotlStore store) { for (Integer deviceId : deviceIds) { - AxolotlAddress axolotlAddress = new AxolotlAddress(bareJid, deviceId); + SignalProtocolAddress axolotlAddress = new SignalProtocolAddress(bareJid, deviceId); IdentityKey identityKey = store.loadSession(axolotlAddress).getSessionState().getRemoteIdentityKey(); if (Config.X509_VERIFICATION) { X509Certificate certificate = store.getFingerprintCertificate(identityKey.getFingerprint().replaceAll("\\s", "")); @@ -218,7 +218,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } @Override - public void put(AxolotlAddress address, XmppAxolotlSession value) { + public void put(SignalProtocolAddress address, XmppAxolotlSession value) { super.put(address, value); value.setNotFresh(); xmppConnectionService.syncRosterToDisk(account); //TODO why? @@ -275,7 +275,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } public String getOwnFingerprint() { - return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", ""); + return CryptoHelper.bytesToHex(axolotlStore.getIdentityKeyPair().getPublicKey().serialize()); } public Set getKeysWithTrust(FingerprintStatus status) { @@ -307,20 +307,20 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { return false; } - private AxolotlAddress getAddressForJid(Jid jid) { - return new AxolotlAddress(jid.toPreppedString(), 0); + private SignalProtocolAddress getAddressForJid(Jid jid) { + return new SignalProtocolAddress(jid.toPreppedString(), 0); } public Collection findOwnSessions() { - AxolotlAddress ownAddress = getAddressForJid(account.getJid().toBareJid()); - ArrayList s = new ArrayList<>(this.sessions.getAll(ownAddress).values()); + SignalProtocolAddress ownAddress = getAddressForJid(account.getJid().toBareJid()); + ArrayList s = new ArrayList<>(this.sessions.getAll(ownAddress.getName()).values()); Collections.sort(s); return s; } public Collection findSessionsForContact(Contact contact) { - AxolotlAddress contactAddress = getAddressForJid(contact.getJid()); - ArrayList s = new ArrayList<>(this.sessions.getAll(contactAddress).values()); + SignalProtocolAddress contactAddress = getAddressForJid(contact.getJid()); + ArrayList s = new ArrayList<>(this.sessions.getAll(contactAddress.getName()).values()); Collections.sort(s); return s; } @@ -328,7 +328,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private Set findSessionsForConversation(Conversation conversation) { HashSet sessions = new HashSet<>(); for (Jid jid : conversation.getAcceptedCryptoTargets()) { - sessions.addAll(this.sessions.getAll(getAddressForJid(jid)).values()); + sessions.addAll(this.sessions.getAll(getAddressForJid(jid).getName()).values()); } return sessions; } @@ -361,8 +361,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { return axolotlStore.getLocalRegistrationId(); } - public AxolotlAddress getOwnAxolotlAddress() { - return new AxolotlAddress(account.getJid().toBareJid().toPreppedString(),getOwnDeviceId()); + public SignalProtocolAddress getOwnAxolotlAddress() { + return new SignalProtocolAddress(account.getJid().toBareJid().toPreppedString(),getOwnDeviceId()); } public Set getOwnDeviceIds() { @@ -382,7 +382,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { Set expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toPreppedString())); expiredDevices.removeAll(deviceIds); for (Integer deviceId : expiredDevices) { - AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); + SignalProtocolAddress address = new SignalProtocolAddress(jid.toBareJid().toPreppedString(), deviceId); XmppAxolotlSession session = sessions.get(address); if (session != null && session.getFingerprint() != null) { if (session.getTrust().isActive()) { @@ -392,7 +392,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } Set newDevices = new HashSet<>(deviceIds); for (Integer deviceId : newDevices) { - AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); + SignalProtocolAddress address = new SignalProtocolAddress(jid.toBareJid().toPreppedString(), deviceId); XmppAxolotlSession session = sessions.get(address); if (session != null && session.getFingerprint() != null) { if (!session.getTrust().isActive()) { @@ -406,7 +406,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { needsPublishing |= deviceIds.removeAll(getExpiredDevices()); } for (Integer deviceId : deviceIds) { - AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), deviceId); + SignalProtocolAddress ownDeviceAddress = new SignalProtocolAddress(jid.toBareJid().toPreppedString(), deviceId); if (sessions.get(ownDeviceAddress) == null) { FetchStatus status = fetchStatusMap.get(ownDeviceAddress); if (status == null || status == FetchStatus.TIMEOUT) { @@ -751,7 +751,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private void verifySessionWithPEP(final XmppAxolotlSession session) { Log.d(Config.LOGTAG, "trying to verify fresh session (" + session.getRemoteAddress().getName() + ") with pep"); - final AxolotlAddress address = session.getRemoteAddress(); + final SignalProtocolAddress address = session.getRemoteAddress(); final IdentityKey identityKey = session.getIdentityKey(); try { IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveVerificationForDevice(Jid.fromString(address.getName()), address.getDeviceId()); @@ -805,10 +805,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private final Set PREVIOUSLY_REMOVED_FROM_ANNOUNCEMENT = new HashSet<>(); - private void finishBuildingSessionsFromPEP(final AxolotlAddress address) { - AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0); - Map own = fetchStatusMap.getAll(ownAddress); - Map remote = fetchStatusMap.getAll(address); + private void finishBuildingSessionsFromPEP(final SignalProtocolAddress address) { + SignalProtocolAddress ownAddress = new SignalProtocolAddress(account.getJid().toBareJid().toPreppedString(), 0); + Map own = fetchStatusMap.getAll(ownAddress.getName()); + Map remote = fetchStatusMap.getAll(address.getName()); if (!own.containsValue(FetchStatus.PENDING) && !remote.containsValue(FetchStatus.PENDING)) { FetchStatus report = null; if (own.containsValue(FetchStatus.SUCCESS) || remote.containsValue(FetchStatus.SUCCESS)) { @@ -838,7 +838,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } - private void buildSessionFromPEP(final AxolotlAddress address) { + private void buildSessionFromPEP(final SignalProtocolAddress address) { Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Building new session for " + address.toString()); if (address.equals(getOwnAxolotlAddress())) { throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!"); @@ -917,13 +917,13 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } - public Set findDevicesWithoutSession(final Conversation conversation) { - Set addresses = new HashSet<>(); + public Set findDevicesWithoutSession(final Conversation conversation) { + Set addresses = new HashSet<>(); for (Jid jid : getCryptoTargets(conversation)) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Finding devices without session for " + jid); if (deviceIds.get(jid) != null) { for (Integer foreignId : this.deviceIds.get(jid)) { - AxolotlAddress address = new AxolotlAddress(jid.toPreppedString(), foreignId); + SignalProtocolAddress address = new SignalProtocolAddress(jid.toPreppedString(), foreignId); if (sessions.get(address) == null) { IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey(); if (identityKey != null) { @@ -946,7 +946,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } if (deviceIds.get(account.getJid().toBareJid()) != null) { for (Integer ownId : this.deviceIds.get(account.getJid().toBareJid())) { - AxolotlAddress address = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), ownId); + SignalProtocolAddress address = new SignalProtocolAddress(account.getJid().toBareJid().toPreppedString(), ownId); if (sessions.get(address) == null) { IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey(); if (identityKey != null) { @@ -971,8 +971,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { public boolean createSessionsIfNeeded(final Conversation conversation) { Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Creating axolotl sessions if needed..."); boolean newSessions = false; - Set addresses = findDevicesWithoutSession(conversation); - for (AxolotlAddress address : addresses) { + Set addresses = findDevicesWithoutSession(conversation); + for (SignalProtocolAddress address : addresses) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Processing device: " + address.toString()); FetchStatus status = fetchStatusMap.get(address); if (status == null || status == FetchStatus.TIMEOUT) { @@ -1006,13 +1006,13 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } public boolean hasPendingKeyFetches(Account account, List jids) { - AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), 0); - if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING)) { + SignalProtocolAddress ownAddress = new SignalProtocolAddress(account.getJid().toBareJid().toPreppedString(), 0); + if (fetchStatusMap.getAll(ownAddress.getName()).containsValue(FetchStatus.PENDING)) { return true; } for (Jid jid : jids) { - AxolotlAddress foreignAddress = new AxolotlAddress(jid.toBareJid().toPreppedString(), 0); - if (fetchStatusMap.getAll(foreignAddress).containsValue(FetchStatus.PENDING)) { + SignalProtocolAddress foreignAddress = new SignalProtocolAddress(jid.toBareJid().toPreppedString(), 0); + if (fetchStatusMap.getAll(foreignAddress.getName()).containsValue(FetchStatus.PENDING)) { return true; } } @@ -1101,7 +1101,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { return axolotlMessage; } - private XmppAxolotlSession recreateUncachedSession(AxolotlAddress address) { + private XmppAxolotlSession recreateUncachedSession(SignalProtocolAddress address) { IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey(); return (identityKey != null) ? new XmppAxolotlSession(account, axolotlStore, address, identityKey) @@ -1109,7 +1109,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } private XmppAxolotlSession getReceivingSession(XmppAxolotlMessage message) { - AxolotlAddress senderAddress = new AxolotlAddress(message.getFrom().toPreppedString(), + SignalProtocolAddress senderAddress = new SignalProtocolAddress(message.getFrom().toPreppedString(), message.getSenderDeviceId()); XmppAxolotlSession session = sessions.get(senderAddress); if (session == null) { diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/SQLiteAxolotlStore.java b/src/main/java/de/pixart/messenger/crypto/axolotl/SQLiteAxolotlStore.java index 23024a610..3c5ddd3db 100644 --- a/src/main/java/de/pixart/messenger/crypto/axolotl/SQLiteAxolotlStore.java +++ b/src/main/java/de/pixart/messenger/crypto/axolotl/SQLiteAxolotlStore.java @@ -3,17 +3,17 @@ package de.pixart.messenger.crypto.axolotl; import android.util.Log; import android.util.LruCache; -import org.whispersystems.libaxolotl.AxolotlAddress; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.IdentityKeyPair; -import org.whispersystems.libaxolotl.InvalidKeyIdException; -import org.whispersystems.libaxolotl.ecc.Curve; -import org.whispersystems.libaxolotl.ecc.ECKeyPair; -import org.whispersystems.libaxolotl.state.AxolotlStore; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SessionRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; -import org.whispersystems.libaxolotl.util.KeyHelper; +import org.whispersystems.libsignal.SignalProtocolAddress; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.IdentityKeyPair; +import org.whispersystems.libsignal.InvalidKeyIdException; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECKeyPair; +import org.whispersystems.libsignal.state.SignalProtocolStore; +import org.whispersystems.libsignal.state.PreKeyRecord; +import org.whispersystems.libsignal.state.SessionRecord; +import org.whispersystems.libsignal.state.SignedPreKeyRecord; +import org.whispersystems.libsignal.util.KeyHelper; import java.security.cert.X509Certificate; import java.util.List; @@ -23,7 +23,7 @@ import de.pixart.messenger.Config; import de.pixart.messenger.entities.Account; import de.pixart.messenger.services.XmppConnectionService; -public class SQLiteAxolotlStore implements AxolotlStore { +public class SQLiteAxolotlStore implements SignalProtocolStore { public static final String PREKEY_TABLENAME = "prekeys"; public static final String SIGNED_PREKEY_TABLENAME = "signed_prekeys"; @@ -179,17 +179,18 @@ public class SQLiteAxolotlStore implements AxolotlStore { *

* Store a remote client's identity key as trusted. * - * @param name The name of the remote client. + * @param address The address of the remote client. * @param identityKey The remote client's identity key. + * @return true on success */ @Override - public void saveIdentity(String name, IdentityKey identityKey) { - if (!mXmppConnectionService.databaseBackend.loadIdentityKeys(account, name).contains(identityKey)) { + public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) { + if (!mXmppConnectionService.databaseBackend.loadIdentityKeys(account, address.getName()).contains(identityKey)) { String fingerprint = identityKey.getFingerprint().replaceAll("\\s", ""); FingerprintStatus status = getFingerprintStatus(fingerprint); if (status == null) { - if (mXmppConnectionService.blindTrustBeforeVerification() && !account.getAxolotlService().hasVerifiedKeys(name)) { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": blindly trusted "+fingerprint+" of "+name); + if (mXmppConnectionService.blindTrustBeforeVerification() && !account.getAxolotlService().hasVerifiedKeys(address.getName())) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": blindly trusted " + fingerprint + " of " + address.getName()); status = FingerprintStatus.createActiveTrusted(); } else { status = FingerprintStatus.createActiveUndecided(); @@ -197,9 +198,10 @@ public class SQLiteAxolotlStore implements AxolotlStore { } else { status = status.toActive(); } - mXmppConnectionService.databaseBackend.storeIdentityKey(account, name, identityKey, status); + mXmppConnectionService.databaseBackend.storeIdentityKey(account, address.getName(), identityKey, status); trustCache.remove(fingerprint); } + return true; } /** @@ -217,7 +219,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { * @return true if trusted, false if untrusted. */ @Override - public boolean isTrustedIdentity(String name, IdentityKey identityKey) { + public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) { return true; } @@ -264,7 +266,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { * a new SessionRecord if one does not currently exist. */ @Override - public SessionRecord loadSession(AxolotlAddress address) { + public SessionRecord loadSession(SignalProtocolAddress address) { SessionRecord session = mXmppConnectionService.databaseBackend.loadSession(this.account, address); return (session != null) ? session : new SessionRecord(); } @@ -278,7 +280,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { @Override public List getSubDeviceSessions(String name) { return mXmppConnectionService.databaseBackend.getSubDeviceSessions(account, - new AxolotlAddress(name, 0)); + new SignalProtocolAddress(name, 0)); } /** @@ -288,7 +290,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { * @param record the current SessionRecord for the remote client. */ @Override - public void storeSession(AxolotlAddress address, SessionRecord record) { + public void storeSession(SignalProtocolAddress address, SessionRecord record) { mXmppConnectionService.databaseBackend.storeSession(account, address, record); } @@ -299,7 +301,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { * @return true if a {@link SessionRecord} exists, false otherwise. */ @Override - public boolean containsSession(AxolotlAddress address) { + public boolean containsSession(SignalProtocolAddress address) { return mXmppConnectionService.databaseBackend.containsSession(account, address); } @@ -309,7 +311,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { * @param address the address of the remote client. */ @Override - public void deleteSession(AxolotlAddress address) { + public void deleteSession(SignalProtocolAddress address) { mXmppConnectionService.databaseBackend.deleteSession(account, address); } @@ -320,7 +322,7 @@ public class SQLiteAxolotlStore implements AxolotlStore { */ @Override public void deleteAllSessions(String name) { - AxolotlAddress address = new AxolotlAddress(name, 0); + SignalProtocolAddress address = new SignalProtocolAddress(name, 0); mXmppConnectionService.databaseBackend.deleteAllSessions(account, address); } diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlSession.java b/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlSession.java index 5b45e28b2..4327c6116 100644 --- a/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlSession.java +++ b/src/main/java/de/pixart/messenger/crypto/axolotl/XmppAxolotlSession.java @@ -3,39 +3,40 @@ package de.pixart.messenger.crypto.axolotl; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import org.whispersystems.libaxolotl.AxolotlAddress; -import org.whispersystems.libaxolotl.DuplicateMessageException; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.InvalidKeyException; -import org.whispersystems.libaxolotl.InvalidKeyIdException; -import org.whispersystems.libaxolotl.InvalidMessageException; -import org.whispersystems.libaxolotl.InvalidVersionException; -import org.whispersystems.libaxolotl.LegacyMessageException; -import org.whispersystems.libaxolotl.NoSessionException; -import org.whispersystems.libaxolotl.SessionCipher; -import org.whispersystems.libaxolotl.UntrustedIdentityException; -import org.whispersystems.libaxolotl.protocol.CiphertextMessage; -import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; -import org.whispersystems.libaxolotl.protocol.WhisperMessage; -import org.whispersystems.libaxolotl.util.guava.Optional; +import org.whispersystems.libsignal.SignalProtocolAddress; +import org.whispersystems.libsignal.DuplicateMessageException; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.InvalidKeyException; +import org.whispersystems.libsignal.InvalidKeyIdException; +import org.whispersystems.libsignal.InvalidMessageException; +import org.whispersystems.libsignal.InvalidVersionException; +import org.whispersystems.libsignal.LegacyMessageException; +import org.whispersystems.libsignal.NoSessionException; +import org.whispersystems.libsignal.SessionCipher; +import org.whispersystems.libsignal.UntrustedIdentityException; +import org.whispersystems.libsignal.protocol.CiphertextMessage; +import org.whispersystems.libsignal.protocol.PreKeySignalMessage; +import org.whispersystems.libsignal.protocol.SignalMessage; +import org.whispersystems.libsignal.util.guava.Optional; import de.pixart.messenger.entities.Account; +import de.pixart.messenger.utils.CryptoHelper; public class XmppAxolotlSession implements Comparable { private final SessionCipher cipher; private final SQLiteAxolotlStore sqLiteAxolotlStore; - private final AxolotlAddress remoteAddress; + private final SignalProtocolAddress remoteAddress; private final Account account; private IdentityKey identityKey; private Integer preKeyId = null; private boolean fresh = true; - public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, IdentityKey identityKey) { + public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, SignalProtocolAddress remoteAddress, IdentityKey identityKey) { this(account, store, remoteAddress); this.identityKey = identityKey; } - public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress) { + public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, SignalProtocolAddress remoteAddress) { this.cipher = new SessionCipher(store, remoteAddress); this.remoteAddress = remoteAddress; this.sqLiteAxolotlStore = store; @@ -52,14 +53,14 @@ public class XmppAxolotlSession implements Comparable { } public String getFingerprint() { - return identityKey == null ? null : identityKey.getFingerprint().replaceAll("\\s", ""); + return identityKey == null ? null : CryptoHelper.bytesToHex(identityKey.getPublicKey().serialize()); } public IdentityKey getIdentityKey() { return identityKey; } - public AxolotlAddress getRemoteAddress() { + public SignalProtocolAddress getRemoteAddress() { return remoteAddress; } @@ -88,9 +89,9 @@ public class XmppAxolotlSession implements Comparable { try { CiphertextMessage ciphertextMessage; try { - ciphertextMessage = new PreKeyWhisperMessage(encryptedKey.key); - Optional optionalPreKeyId = ((PreKeyWhisperMessage) ciphertextMessage).getPreKeyId(); - IdentityKey identityKey = ((PreKeyWhisperMessage) ciphertextMessage).getIdentityKey(); + ciphertextMessage = new PreKeySignalMessage(encryptedKey.key); + Optional optionalPreKeyId = ((PreKeySignalMessage) ciphertextMessage).getPreKeyId(); + IdentityKey identityKey = ((PreKeySignalMessage) ciphertextMessage).getIdentityKey(); if (!optionalPreKeyId.isPresent()) { throw new CryptoFailedException("PreKeyWhisperMessage did not contain a PreKeyId"); } @@ -100,12 +101,12 @@ public class XmppAxolotlSession implements Comparable { } this.identityKey = identityKey; } catch (InvalidVersionException | InvalidMessageException e) { - ciphertextMessage = new WhisperMessage(encryptedKey.key); + ciphertextMessage = new SignalMessage(encryptedKey.key); } - if (ciphertextMessage instanceof PreKeyWhisperMessage) { - plaintext = cipher.decrypt((PreKeyWhisperMessage) ciphertextMessage); + if (ciphertextMessage instanceof PreKeySignalMessage) { + plaintext = cipher.decrypt((PreKeySignalMessage) ciphertextMessage); } else { - plaintext = cipher.decrypt((WhisperMessage) ciphertextMessage); + plaintext = cipher.decrypt((SignalMessage) ciphertextMessage); } } catch (InvalidKeyException | LegacyMessageException | InvalidMessageException | DuplicateMessageException | NoSessionException | InvalidKeyIdException | UntrustedIdentityException e) { if (!(e instanceof DuplicateMessageException)) { @@ -126,8 +127,12 @@ public class XmppAxolotlSession implements Comparable { public AxolotlKey processSending(@NonNull byte[] outgoingMessage) { FingerprintStatus status = getTrust(); if (status.isTrustedAndActive()) { - CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); - return new AxolotlKey(ciphertextMessage.serialize(),ciphertextMessage.getType() == CiphertextMessage.PREKEY_TYPE); + try { + CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); + return new AxolotlKey(ciphertextMessage.serialize(), ciphertextMessage.getType() == CiphertextMessage.PREKEY_TYPE); + } catch (UntrustedIdentityException e) { + return null; + } } else { return null; } diff --git a/src/main/java/de/pixart/messenger/generator/IqGenerator.java b/src/main/java/de/pixart/messenger/generator/IqGenerator.java index 927d5d07c..2e6d53402 100644 --- a/src/main/java/de/pixart/messenger/generator/IqGenerator.java +++ b/src/main/java/de/pixart/messenger/generator/IqGenerator.java @@ -5,10 +5,10 @@ import android.os.Bundle; import android.util.Base64; import android.util.Log; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.ecc.ECPublicKey; +import org.whispersystems.libsignal.state.PreKeyRecord; +import org.whispersystems.libsignal.state.SignedPreKeyRecord; import java.nio.ByteBuffer; import java.security.cert.CertificateEncodingException; diff --git a/src/main/java/de/pixart/messenger/parser/IqParser.java b/src/main/java/de/pixart/messenger/parser/IqParser.java index 1783fed07..5399dbad4 100644 --- a/src/main/java/de/pixart/messenger/parser/IqParser.java +++ b/src/main/java/de/pixart/messenger/parser/IqParser.java @@ -5,10 +5,10 @@ import android.util.Base64; import android.util.Log; import android.util.Pair; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.ecc.Curve; -import org.whispersystems.libaxolotl.ecc.ECPublicKey; -import org.whispersystems.libaxolotl.state.PreKeyBundle; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECPublicKey; +import org.whispersystems.libsignal.state.PreKeyBundle; import java.io.ByteArrayInputStream; import java.security.cert.CertificateException; diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java index 7b49eb376..ff8caeeb7 100644 --- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java +++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java @@ -13,13 +13,13 @@ import android.util.Log; import org.json.JSONException; import org.json.JSONObject; -import org.whispersystems.libaxolotl.AxolotlAddress; -import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.IdentityKeyPair; -import org.whispersystems.libaxolotl.InvalidKeyException; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SessionRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; +import org.whispersystems.libsignal.SignalProtocolAddress; +import org.whispersystems.libsignal.IdentityKey; +import org.whispersystems.libsignal.IdentityKeyPair; +import org.whispersystems.libsignal.InvalidKeyException; +import org.whispersystems.libsignal.state.PreKeyRecord; +import org.whispersystems.libsignal.state.SessionRecord; +import org.whispersystems.libsignal.state.SignedPreKeyRecord; import java.io.ByteArrayInputStream; import java.io.File; @@ -302,7 +302,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { continue; } int ownDeviceId = Integer.valueOf(ownDeviceIdString); - AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toPreppedString(), ownDeviceId); + SignalProtocolAddress ownAddress = new SignalProtocolAddress(account.getJid().toBareJid().toPreppedString(), ownDeviceId); deleteSession(db, account, ownAddress); IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account); if (identityKeyPair != null) { @@ -897,7 +897,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { return maxClearDate; } - private Cursor getCursorForSession(Account account, AxolotlAddress contact) { + private Cursor getCursorForSession(Account account, SignalProtocolAddress contact) { final SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = {account.getUuid(), contact.getName(), @@ -911,7 +911,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { null, null, null); } - public SessionRecord loadSession(Account account, AxolotlAddress contact) { + public SessionRecord loadSession(Account account, SignalProtocolAddress contact) { SessionRecord session = null; Cursor cursor = getCursorForSession(account, contact); if (cursor.getCount() != 0) { @@ -927,12 +927,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { return session; } - public List getSubDeviceSessions(Account account, AxolotlAddress contact) { + public List getSubDeviceSessions(Account account, SignalProtocolAddress contact) { final SQLiteDatabase db = this.getReadableDatabase(); return getSubDeviceSessions(db, account, contact); } - private List getSubDeviceSessions(SQLiteDatabase db, Account account, AxolotlAddress contact) { + private List getSubDeviceSessions(SQLiteDatabase db, Account account, SignalProtocolAddress contact) { List devices = new ArrayList<>(); String[] columns = {SQLiteAxolotlStore.DEVICE_ID}; String[] selectionArgs = {account.getUuid(), @@ -953,14 +953,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { return devices; } - public boolean containsSession(Account account, AxolotlAddress contact) { + public boolean containsSession(Account account, SignalProtocolAddress contact) { Cursor cursor = getCursorForSession(account, contact); int count = cursor.getCount(); cursor.close(); return count != 0; } - public void storeSession(Account account, AxolotlAddress contact, SessionRecord session) { + public void storeSession(Account account, SignalProtocolAddress contact, SessionRecord session) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(SQLiteAxolotlStore.NAME, contact.getName()); @@ -970,12 +970,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.insert(SQLiteAxolotlStore.SESSION_TABLENAME, null, values); } - public void deleteSession(Account account, AxolotlAddress contact) { + public void deleteSession(Account account, SignalProtocolAddress contact) { SQLiteDatabase db = this.getWritableDatabase(); deleteSession(db, account, contact); } - private void deleteSession(SQLiteDatabase db, Account account, AxolotlAddress contact) { + private void deleteSession(SQLiteDatabase db, Account account, SignalProtocolAddress contact) { String[] args = {account.getUuid(), contact.getName(), Integer.toString(contact.getDeviceId())}; @@ -986,7 +986,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { args); } - public void deleteAllSessions(Account account, AxolotlAddress contact) { + public void deleteAllSessions(Account account, SignalProtocolAddress contact) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = {account.getUuid(), contact.getName()}; db.delete(SQLiteAxolotlStore.SESSION_TABLENAME, diff --git a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java index a49162afb..300210ac9 100644 --- a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java +++ b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java @@ -17,7 +17,7 @@ import android.widget.Toast; import com.google.zxing.integration.android.IntentIntegrator; -import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libsignal.IdentityKey; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java index d15f4bef5..44e89d8fc 100644 --- a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java +++ b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java @@ -22,7 +22,6 @@ import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; import java.util.regex.Pattern; import de.pixart.messenger.Config; @@ -103,7 +102,7 @@ public final class CryptoHelper { } else if (fingerprint.length() < 40) { return fingerprint; } - StringBuilder builder = new StringBuilder(fingerprint.toLowerCase(Locale.US).replaceAll("\\s", "")); + StringBuilder builder = new StringBuilder(fingerprint); for (int i = 8; i < builder.length(); i += 9) { builder.insert(i, ' '); } -- cgit v1.2.3