From 6cd9383e53900e03d324b227c0f01b1537881148 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sat, 1 Aug 2015 18:27:52 +0200 Subject: Let UNTRUSTED/UNDECIDED keys become INACTIVE --- .../crypto/axolotl/AxolotlService.java | 30 +++++--- .../crypto/axolotl/SQLiteAxolotlStore.java | 64 ++---------------- .../crypto/axolotl/XmppAxolotlSession.java | 79 +++++++++++++++++++--- 3 files changed, 94 insertions(+), 79 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/crypto') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 7a92a1f7..255939a4 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -191,11 +191,11 @@ public class AxolotlService { return axolotlStore.getIdentityKeyPair().getPublicKey(); } - public Set getKeysWithTrust(SQLiteAxolotlStore.Trust trust) { + public Set getKeysWithTrust(XmppAxolotlSession.Trust trust) { return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toString(), trust); } - public Set getKeysWithTrust(SQLiteAxolotlStore.Trust trust, Contact contact) { + public Set getKeysWithTrust(XmppAxolotlSession.Trust trust, Contact contact) { return axolotlStore.getContactKeysWithTrust(contact.getJid().toBareJid().toString(), trust); } @@ -241,8 +241,8 @@ public class AxolotlService { } private void setTrustOnSessions(final Jid jid, @NonNull final Set deviceIds, - final SQLiteAxolotlStore.Trust from, - final SQLiteAxolotlStore.Trust to) { + final XmppAxolotlSession.Trust from, + final XmppAxolotlSession.Trust to) { for (Integer deviceId : deviceIds) { AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toString(), deviceId); XmppAxolotlSession session = sessions.get(address); @@ -267,11 +267,19 @@ public class AxolotlService { } Set expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toString())); expiredDevices.removeAll(deviceIds); - setTrustOnSessions(jid, expiredDevices, SQLiteAxolotlStore.Trust.TRUSTED, - SQLiteAxolotlStore.Trust.INACTIVE); + setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.TRUSTED, + XmppAxolotlSession.Trust.INACTIVE_TRUSTED); + setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNDECIDED, + XmppAxolotlSession.Trust.INACTIVE_UNDECIDED); + setTrustOnSessions(jid, expiredDevices, XmppAxolotlSession.Trust.UNTRUSTED, + XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED); Set newDevices = new HashSet<>(deviceIds); - setTrustOnSessions(jid, newDevices, SQLiteAxolotlStore.Trust.INACTIVE, - SQLiteAxolotlStore.Trust.TRUSTED); + setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_TRUSTED, + XmppAxolotlSession.Trust.TRUSTED); + setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNDECIDED, + XmppAxolotlSession.Trust.UNDECIDED); + setTrustOnSessions(jid, newDevices, XmppAxolotlSession.Trust.INACTIVE_UNTRUSTED, + XmppAxolotlSession.Trust.UNTRUSTED); this.deviceIds.put(jid, deviceIds); mXmppConnectionService.keyStatusUpdated(); publishOwnDeviceIdIfNeeded(); @@ -291,7 +299,7 @@ public class AxolotlService { } public void purgeKey(IdentityKey identityKey) { - axolotlStore.setFingerprintTrust(identityKey.getFingerprint().replaceAll("\\s", ""), SQLiteAxolotlStore.Trust.COMPROMISED); + axolotlStore.setFingerprintTrust(identityKey.getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); } public void publishOwnDeviceIdIfNeeded() { @@ -419,11 +427,11 @@ public class AxolotlService { (deviceIds.containsKey(jid) && !deviceIds.get(jid).isEmpty()); } - public SQLiteAxolotlStore.Trust getFingerprintTrust(String fingerprint) { + public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { return axolotlStore.getFingerprintTrust(fingerprint); } - public void setFingerprintTrust(String fingerprint, SQLiteAxolotlStore.Trust trust) { + public void setFingerprintTrust(String fingerprint, XmppAxolotlSession.Trust trust) { axolotlStore.setFingerprintTrust(fingerprint, trust); } diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/SQLiteAxolotlStore.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/SQLiteAxolotlStore.java index 0c9c4e65..190eb88a 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/SQLiteAxolotlStore.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/SQLiteAxolotlStore.java @@ -15,9 +15,7 @@ import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.util.KeyHelper; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; import eu.siacs.conversations.Config; @@ -51,64 +49,14 @@ public class SQLiteAxolotlStore implements AxolotlStore { private int localRegistrationId; private int currentPreKeyId = 0; - private final LruCache trustCache = - new LruCache(NUM_TRUSTS_TO_CACHE) { + private final LruCache trustCache = + new LruCache(NUM_TRUSTS_TO_CACHE) { @Override - protected Trust create(String fingerprint) { + protected XmppAxolotlSession.Trust create(String fingerprint) { return mXmppConnectionService.databaseBackend.isIdentityKeyTrusted(account, fingerprint); } }; - public enum Trust { - UNDECIDED(0), - TRUSTED(1), - UNTRUSTED(2), - COMPROMISED(3), - INACTIVE(4); - - private static final Map trustsByValue = new HashMap<>(); - - static { - for (Trust trust : Trust.values()) { - trustsByValue.put(trust.getCode(), trust); - } - } - - private final int code; - - Trust(int code) { - this.code = code; - } - - public int getCode() { - return this.code; - } - - public String toString() { - switch (this) { - case UNDECIDED: - return "Trust undecided " + getCode(); - case TRUSTED: - return "Trusted " + getCode(); - case COMPROMISED: - return "Compromised " + getCode(); - case INACTIVE: - return "Inactive " + getCode(); - case UNTRUSTED: - default: - return "Untrusted " + getCode(); - } - } - - public static Trust fromBoolean(Boolean trusted) { - return trusted ? TRUSTED : UNTRUSTED; - } - - public static Trust fromCode(int code) { - return trustsByValue.get(code); - } - } - private static IdentityKeyPair generateIdentityKeyPair() { Log.i(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + "Generating axolotl IdentityKeyPair..."); ECKeyPair identityKeyPairKeys = Curve.generateKeyPair(); @@ -258,16 +206,16 @@ public class SQLiteAxolotlStore implements AxolotlStore { return true; } - public Trust getFingerprintTrust(String fingerprint) { + public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { return (fingerprint == null)? null : trustCache.get(fingerprint); } - public void setFingerprintTrust(String fingerprint, Trust trust) { + public void setFingerprintTrust(String fingerprint, XmppAxolotlSession.Trust trust) { mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, fingerprint, trust); trustCache.remove(fingerprint); } - public Set getContactKeysWithTrust(String bareJid, Trust trust) { + public Set getContactKeysWithTrust(String bareJid, XmppAxolotlSession.Trust trust) { return mXmppConnectionService.databaseBackend.loadIdentityKeys(account, bareJid, trust); } diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java index 46004a1a..c4053854 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlSession.java @@ -18,6 +18,9 @@ import org.whispersystems.libaxolotl.protocol.CiphertextMessage; import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; import org.whispersystems.libaxolotl.protocol.WhisperMessage; +import java.util.HashMap; +import java.util.Map; + import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -30,6 +33,62 @@ public class XmppAxolotlSession { private Integer preKeyId = null; private boolean fresh = true; + public enum Trust { + UNDECIDED(0), + TRUSTED(1), + UNTRUSTED(2), + COMPROMISED(3), + INACTIVE_TRUSTED(4), + INACTIVE_UNDECIDED(5), + INACTIVE_UNTRUSTED(6); + + private static final Map trustsByValue = new HashMap<>(); + + static { + for (Trust trust : Trust.values()) { + trustsByValue.put(trust.getCode(), trust); + } + } + + private final int code; + + Trust(int code) { + this.code = code; + } + + public int getCode() { + return this.code; + } + + public String toString() { + switch (this) { + case UNDECIDED: + return "Trust undecided " + getCode(); + case TRUSTED: + return "Trusted " + getCode(); + case COMPROMISED: + return "Compromised " + getCode(); + case INACTIVE_TRUSTED: + return "Inactive (Trusted)" + getCode(); + case INACTIVE_UNDECIDED: + return "Inactive (Undecided)" + getCode(); + case INACTIVE_UNTRUSTED: + return "Inactive (Untrusted)" + getCode(); + case UNTRUSTED: + default: + return "Untrusted " + getCode(); + } + } + + public static Trust fromBoolean(Boolean trusted) { + return trusted ? TRUSTED : UNTRUSTED; + } + + public static Trust fromCode(int code) { + return trustsByValue.get(code); + } + } + public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) { this(account, store, remoteAddress); this.fingerprint = fingerprint; @@ -67,21 +126,21 @@ public class XmppAxolotlSession { this.fresh = false; } - protected void setTrust(SQLiteAxolotlStore.Trust trust) { + protected void setTrust(Trust trust) { sqLiteAxolotlStore.setFingerprintTrust(fingerprint, trust); } - protected SQLiteAxolotlStore.Trust getTrust() { - SQLiteAxolotlStore.Trust trust = sqLiteAxolotlStore.getFingerprintTrust(fingerprint); - return (trust == null) ? SQLiteAxolotlStore.Trust.UNDECIDED : trust; + protected Trust getTrust() { + Trust trust = sqLiteAxolotlStore.getFingerprintTrust(fingerprint); + return (trust == null) ? Trust.UNDECIDED : trust; } @Nullable public byte[] processReceiving(byte[] encryptedKey) { byte[] plaintext = null; - SQLiteAxolotlStore.Trust trust = getTrust(); + Trust trust = getTrust(); switch (trust) { - case INACTIVE: + case INACTIVE_TRUSTED: case UNDECIDED: case UNTRUSTED: case TRUSTED: @@ -110,8 +169,8 @@ public class XmppAxolotlSession { Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error decrypting axolotl header, " + e.getClass().getName() + ": " + e.getMessage()); } - if (plaintext != null && trust == SQLiteAxolotlStore.Trust.INACTIVE) { - setTrust(SQLiteAxolotlStore.Trust.TRUSTED); + if (plaintext != null && trust == Trust.INACTIVE_TRUSTED) { + setTrust(Trust.TRUSTED); } break; @@ -126,8 +185,8 @@ public class XmppAxolotlSession { @Nullable public byte[] processSending(@NonNull byte[] outgoingMessage) { - SQLiteAxolotlStore.Trust trust = getTrust(); - if (trust == SQLiteAxolotlStore.Trust.TRUSTED) { + Trust trust = getTrust(); + if (trust == Trust.TRUSTED) { CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); return ciphertextMessage.serialize(); } else { -- cgit v1.2.3