From ab2d114bbc21a5c2d684f8760cb8e4cea54be5de Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 22:18:24 +0200 Subject: Add purge axolotl key option Can now long-press a key to permanently purge it. --- .../crypto/axolotl/AxolotlService.java | 84 ++++++++++++++-------- .../crypto/axolotl/XmppAxolotlMessage.java | 7 +- 2 files changed, 61 insertions(+), 30 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/crypto/axolotl') 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 1fe455ff..6e28f111 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -100,7 +100,8 @@ public class AxolotlService { public enum Trust { UNDECIDED, // 0 TRUSTED, - UNTRUSTED; + UNTRUSTED, + COMPROMISED; public String toString() { switch(this){ @@ -514,41 +515,64 @@ public class AxolotlService { return fingerprint; } + private SQLiteAxolotlStore.Trust getTrust() { + return sqLiteAxolotlStore.getFingerprintTrust(fingerprint); + } + + @Nullable public byte[] processReceiving(XmppAxolotlMessage.XmppAxolotlMessageHeader incomingHeader) { byte[] plaintext = null; - try { - try { - PreKeyWhisperMessage message = new PreKeyWhisperMessage(incomingHeader.getContents()); - Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"PreKeyWhisperMessage received, new session ID:" + message.getSignedPreKeyId() + "/" + message.getPreKeyId()); - String fingerprint = message.getIdentityKey().getFingerprint().replaceAll("\\s", ""); - if (this.fingerprint != null && !this.fingerprint.equals(fingerprint)) { - Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Had session with fingerprint "+ this.fingerprint+", received message with fingerprint "+fingerprint); - } else { - this.fingerprint = fingerprint; - plaintext = cipher.decrypt(message); - if (message.getPreKeyId().isPresent()) { - preKeyId = message.getPreKeyId().get(); + switch (getTrust()) { + case UNDECIDED: + case TRUSTED: + try { + try { + PreKeyWhisperMessage message = new PreKeyWhisperMessage(incomingHeader.getContents()); + Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"PreKeyWhisperMessage received, new session ID:" + message.getSignedPreKeyId() + "/" + message.getPreKeyId()); + String fingerprint = message.getIdentityKey().getFingerprint().replaceAll("\\s", ""); + if (this.fingerprint != null && !this.fingerprint.equals(fingerprint)) { + Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Had session with fingerprint "+ this.fingerprint+", received message with fingerprint "+fingerprint); + } else { + this.fingerprint = fingerprint; + plaintext = cipher.decrypt(message); + if (message.getPreKeyId().isPresent()) { + preKeyId = message.getPreKeyId().get(); + } + } + } catch (InvalidMessageException | InvalidVersionException e) { + Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"WhisperMessage received"); + WhisperMessage message = new WhisperMessage(incomingHeader.getContents()); + plaintext = cipher.decrypt(message); + } catch (InvalidKeyException | InvalidKeyIdException | UntrustedIdentityException e) { + Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage()); } + } catch (LegacyMessageException | InvalidMessageException | DuplicateMessageException | NoSessionException e) { + Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage()); } - } catch (InvalidMessageException | InvalidVersionException e) { - Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"WhisperMessage received"); - WhisperMessage message = new WhisperMessage(incomingHeader.getContents()); - plaintext = cipher.decrypt(message); - } catch (InvalidKeyException | InvalidKeyIdException | UntrustedIdentityException e) { - Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage()); - } - } catch (LegacyMessageException | InvalidMessageException | DuplicateMessageException | NoSessionException e) { - Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage()); + + break; + + case COMPROMISED: + case UNTRUSTED: + default: + // ignore + break; } return plaintext; } - public XmppAxolotlMessage.XmppAxolotlMessageHeader processSending(byte[] outgoingMessage) { - CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); - XmppAxolotlMessage.XmppAxolotlMessageHeader header = - new XmppAxolotlMessage.XmppAxolotlMessageHeader(remoteAddress.getDeviceId(), - ciphertextMessage.serialize()); - return header; + @Nullable + public XmppAxolotlMessage.XmppAxolotlMessageHeader processSending(@NonNull byte[] outgoingMessage) { + SQLiteAxolotlStore.Trust trust = getTrust(); + if (trust == SQLiteAxolotlStore.Trust.TRUSTED) { + CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); + XmppAxolotlMessage.XmppAxolotlMessageHeader header = + new XmppAxolotlMessage.XmppAxolotlMessageHeader(remoteAddress.getDeviceId(), + ciphertextMessage.serialize()); + return header; + } else { + return null; + } } } @@ -742,6 +766,10 @@ public class AxolotlService { }); } + public void purgeKey(IdentityKey identityKey) { + axolotlStore.setFingerprintTrust(identityKey.getFingerprint().replaceAll("\\s",""), SQLiteAxolotlStore.Trust.COMPROMISED); + } + public void publishOwnDeviceIdIfNeeded() { IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveDeviceIds(account.getJid().toBareJid()); mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() { diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java index 1378c94a..ec068ec7 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.crypto.axolotl; +import android.support.annotation.Nullable; import android.util.Base64; import java.security.InvalidAlgorithmParameterException; @@ -145,8 +146,10 @@ public class XmppAxolotlMessage { return headers; } - public void addHeader(XmppAxolotlMessageHeader header) { - headers.add(header); + public void addHeader(@Nullable XmppAxolotlMessageHeader header) { + if (header != null) { + headers.add(header); + } } public byte[] getInnerKey(){ -- cgit v1.2.3