diff options
3 files changed, 171 insertions, 133 deletions
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 d8287aff..e490ac64 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -9,6 +9,7 @@ import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.security.cert.X509Certificate; +import java.util.List; import java.util.Set; import eu.siacs.conversations.entities.Account; @@ -30,6 +31,8 @@ public interface AxolotlService extends OnAdvancedStreamFeaturesLoaded { String PEP_BUNDLES = PEP_PREFIX + ".bundles"; String PEP_VERIFICATION = PEP_PREFIX + ".verification"; + int NUM_KEYS_TO_PUBLISH = 100; + enum FetchStatus { PENDING, SUCCESS, @@ -38,15 +41,10 @@ public interface AxolotlService extends OnAdvancedStreamFeaturesLoaded { ERROR } - boolean fetchMapHasErrors(Contact contact); - String getOwnFingerprint(); Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust); - Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Contact contact); - - long getNumTrustedKeys(Contact contact); Set<String> getFingerprintsForOwnSessions(); @@ -77,8 +75,6 @@ public interface AxolotlService extends OnAdvancedStreamFeaturesLoaded { void publishBundlesIfNeeded(boolean announce, boolean wipe); - boolean isContactAxolotlCapable(Contact contact); - XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint); X509Certificate getFingerprintCertificate(String fingerprint); @@ -87,24 +83,36 @@ public interface AxolotlService extends OnAdvancedStreamFeaturesLoaded { Set<AxolotlAddress> findDevicesWithoutSession(Conversation conversation); - Set<AxolotlAddress> findDevicesWithoutSession(Jid contactJid); - boolean createSessionsIfNeeded(Conversation conversation); boolean trustedSessionVerified(Conversation conversation); - boolean hasPendingKeyFetches(Account account, Contact contact); - @Nullable XmppAxolotlMessage encrypt(Message message); void preparePayloadMessage(Message message, boolean delay); - void prepareKeyTransportMessage(Contact contact, OnMessageCreatedCallback onMessageCreatedCallback); - XmppAxolotlMessage fetchAxolotlMessageFromCache(Message message); XmppAxolotlMessage.XmppAxolotlPlaintextMessage processReceivingPayloadMessage(XmppAxolotlMessage message); XmppAxolotlMessage.XmppAxolotlKeyTransportMessage processReceivingKeyTransportMessage(XmppAxolotlMessage message); + + boolean fetchMapHasErrors(List<Jid> jids); + + Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Jid jid); + + Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, List<Jid> jids); + + long getNumTrustedKeys(Jid jid); + + boolean anyTargetHasNoTrustedKeys(List<Jid> jids); + + boolean isConversationAxolotlCapable(Conversation conversation); + + List<Jid> getCryptoTargets(Conversation conversation); + + boolean hasPendingKeyFetches(Account account, List<Jid> jids); + + void prepareKeyTransportMessage(Conversation conversation, OnMessageCreatedCallback onMessageCreatedCallback); } diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceImpl.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceImpl.java index 27d50dbb..73974652 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceImpl.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceImpl.java @@ -51,7 +51,6 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket; public class AxolotlServiceImpl implements AxolotlService { - public static final int NUM_KEYS_TO_PUBLISH = 100; public static final int publishTriesThreshold = 3; private final Account account; @@ -75,13 +74,14 @@ public class AxolotlServiceImpl implements AxolotlService { } @Override - public boolean fetchMapHasErrors(Contact contact) { - Jid jid = contact.getJid().toBareJid(); - if (deviceIds.get(jid) != null) { - for (Integer foreignId : this.deviceIds.get(jid)) { - AxolotlAddress address = new AxolotlAddress(jid.toString(), foreignId); - if (fetchStatusMap.getAll(address).containsValue(FetchStatus.ERROR)) { - return true; + public boolean fetchMapHasErrors(List<Jid> jids) { + for(Jid jid : jids) { + if (deviceIds.get(jid) != null) { + for (Integer foreignId : this.deviceIds.get(jid)) { + AxolotlAddress address = new AxolotlAddress(jid.toString(), foreignId); + if (fetchStatusMap.getAll(address).containsValue(FetchStatus.ERROR)) { + return true; + } } } } @@ -220,24 +220,41 @@ public class AxolotlServiceImpl implements AxolotlService { this.executor = new SerialSingleThreadExecutor(); } - @Override public String getOwnFingerprint() { return axolotlStore.getIdentityKeyPair().getPublicKey().getFingerprint().replaceAll("\\s", ""); } - @Override public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust) { return axolotlStore.getContactKeysWithTrust(account.getJid().toBareJid().toString(), trust); } @Override - public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Contact contact) { - return axolotlStore.getContactKeysWithTrust(contact.getJid().toBareJid().toString(), trust); + public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Jid jid) { + return axolotlStore.getContactKeysWithTrust(jid.toBareJid().toString(), trust); + } + + @Override + public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, List<Jid> jids) { + Set<IdentityKey> keys = new HashSet<>(); + for(Jid jid : jids) { + keys.addAll(axolotlStore.getContactKeysWithTrust(jid.toString(), trust)); + } + return keys; + } + + @Override + public long getNumTrustedKeys(Jid jid) { + return axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toString()); } @Override - public long getNumTrustedKeys(Contact contact) { - return axolotlStore.getContactNumTrustedKeys(contact.getJid().toBareJid().toString()); + public boolean anyTargetHasNoTrustedKeys(List<Jid> jids) { + for(Jid jid : jids) { + if (axolotlStore.getContactNumTrustedKeys(jid.toBareJid().toString()) == 0) { + return true; + } + } + return false; } private AxolotlAddress getAddressForJid(Jid jid) { @@ -249,12 +266,19 @@ public class AxolotlServiceImpl implements AxolotlService { return new HashSet<>(this.sessions.getAll(ownAddress).values()); } - private Set<XmppAxolotlSession> findSessionsforContact(Contact contact) { + private Set<XmppAxolotlSession> findSessionsForContact(Contact contact) { AxolotlAddress contactAddress = getAddressForJid(contact.getJid()); return new HashSet<>(this.sessions.getAll(contactAddress).values()); } - @Override + private Set<XmppAxolotlSession> findSessionsForConversation(Conversation conversation) { + HashSet<XmppAxolotlSession> sessions = new HashSet<>(); + for(Jid jid : conversation.getAcceptedCryptoTargets()) { + sessions.addAll(this.sessions.getAll(getAddressForJid(jid)).values()); + } + return sessions; + } + public Set<String> getFingerprintsForOwnSessions() { Set<String> fingerprints = new HashSet<>(); for (XmppAxolotlSession session : findOwnSessions()) { @@ -263,26 +287,22 @@ public class AxolotlServiceImpl implements AxolotlService { return fingerprints; } - @Override public Set<String> getFingerprintsForContact(final Contact contact) { Set<String> fingerprints = new HashSet<>(); - for (XmppAxolotlSession session : findSessionsforContact(contact)) { + for (XmppAxolotlSession session : findSessionsForContact(contact)) { fingerprints.add(session.getFingerprint()); } return fingerprints; } - private boolean hasAny(Contact contact) { - AxolotlAddress contactAddress = getAddressForJid(contact.getJid()); - return sessions.hasAny(contactAddress); + private boolean hasAny(Jid jid) { + return sessions.hasAny(getAddressForJid(jid)); } - @Override public boolean isPepBroken() { return this.pepBroken; } - @Override public void regenerateKeys(boolean wipeOther) { axolotlStore.regenerate(); sessions.clear(); @@ -290,19 +310,17 @@ public class AxolotlServiceImpl implements AxolotlService { publishBundlesIfNeeded(true, wipeOther); } - @Override public int getOwnDeviceId() { return axolotlStore.getLocalRegistrationId(); } - @Override public Set<Integer> getOwnDeviceIds() { return this.deviceIds.get(account.getJid().toBareJid()); } private void setTrustOnSessions(final Jid jid, @NonNull final Set<Integer> deviceIds, - final XmppAxolotlSession.Trust from, - final XmppAxolotlSession.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); @@ -313,7 +331,6 @@ public class AxolotlServiceImpl implements AxolotlService { } } - @Override public void registerDevices(final Jid jid, @NonNull final Set<Integer> deviceIds) { if (jid.toBareJid().equals(account.getJid().toBareJid())) { if (!deviceIds.isEmpty()) { @@ -356,7 +373,6 @@ public class AxolotlServiceImpl implements AxolotlService { mXmppConnectionService.keyStatusUpdated(null); } - @Override public void wipeOtherPepDevices() { if (pepBroken) { Log.d(Config.LOGTAG, getLogprefix(account) + "wipeOtherPepDevices called, but PEP is broken. Ignoring... "); @@ -374,12 +390,10 @@ public class AxolotlServiceImpl implements AxolotlService { }); } - @Override public void purgeKey(final String fingerprint) { axolotlStore.setFingerprintTrust(fingerprint.replaceAll("\\s", ""), XmppAxolotlSession.Trust.COMPROMISED); } - @Override public void publishOwnDeviceIdIfNeeded() { if (pepBroken) { Log.d(Config.LOGTAG, getLogprefix(account) + "publishOwnDeviceIdIfNeeded called, but PEP is broken. Ignoring... "); @@ -402,7 +416,6 @@ public class AxolotlServiceImpl implements AxolotlService { }); } - @Override public void publishOwnDeviceId(Set<Integer> deviceIds) { Set<Integer> deviceIdsCopy = new HashSet<>(deviceIds); if (!deviceIdsCopy.contains(getOwnDeviceId())) { @@ -432,7 +445,6 @@ public class AxolotlServiceImpl implements AxolotlService { } } - @Override public void publishDeviceVerificationAndBundle(final SignedPreKeyRecord signedPreKeyRecord, final Set<PreKeyRecord> preKeyRecords, final boolean announceAfter, @@ -458,7 +470,6 @@ public class AxolotlServiceImpl implements AxolotlService { } } - @Override public void publishBundlesIfNeeded(final boolean announce, final boolean wipe) { if (pepBroken) { Log.d(Config.LOGTAG, getLogprefix(account) + "publishBundlesIfNeeded called, but PEP is broken. Ignoring... "); @@ -598,23 +609,36 @@ public class AxolotlServiceImpl implements AxolotlService { } @Override - public boolean isContactAxolotlCapable(Contact contact) { - Jid jid = contact.getJid().toBareJid(); - return hasAny(contact) || - (deviceIds.containsKey(jid) && !deviceIds.get(jid).isEmpty()); + public boolean isConversationAxolotlCapable(Conversation conversation) { + final List<Jid> jids = getCryptoTargets(conversation); + for(Jid jid : jids) { + if (!hasAny(jid) && (!deviceIds.containsKey(jid) || deviceIds.get(jid).isEmpty())) { + return false; + } + } + return jids.size() > 0; } @Override + public List<Jid> getCryptoTargets(Conversation conversation) { + final List<Jid> jids; + if (conversation.getMode() == Conversation.MODE_SINGLE) { + jids = Arrays.asList(conversation.getJid().toBareJid()); + } else { + jids = conversation.getMucOptions().getMembers(); + jids.remove(account.getJid().toBareJid()); + } + return jids; + } + public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { return axolotlStore.getFingerprintTrust(fingerprint); } - @Override public X509Certificate getFingerprintCertificate(String fingerprint) { return axolotlStore.getFingerprintCertificate(fingerprint); } - @Override public void setFingerprintTrust(String fingerprint, XmppAxolotlSession.Trust trust) { axolotlStore.setFingerprintTrust(fingerprint, trust); } @@ -759,36 +783,32 @@ public class AxolotlServiceImpl implements AxolotlService { } } - @Override public Set<AxolotlAddress> findDevicesWithoutSession(final Conversation conversation) { - return findDevicesWithoutSession(conversation.getContact().getJid().toBareJid()); - } - - @Override - public Set<AxolotlAddress> findDevicesWithoutSession(final Jid contactJid) { - Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Finding devices without session for " + contactJid); Set<AxolotlAddress> addresses = new HashSet<>(); - if (deviceIds.get(contactJid) != null) { - for (Integer foreignId : this.deviceIds.get(contactJid)) { - AxolotlAddress address = new AxolotlAddress(contactJid.toString(), foreignId); - if (sessions.get(address) == null) { - IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey(); - if (identityKey != null) { - Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Already have session for " + address.toString() + ", adding to cache..."); - XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, identityKey); - sessions.put(address, session); - } else { - Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Found device " + contactJid + ":" + foreignId); - if (fetchStatusMap.get(address) != FetchStatus.ERROR) { - addresses.add(address); + for(Jid jid : getCryptoTargets(conversation)) { + Log.d(Config.LOGTAG, AxolotlServiceImpl.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.toString(), foreignId); + if (sessions.get(address) == null) { + IdentityKey identityKey = axolotlStore.loadSession(address).getSessionState().getRemoteIdentityKey(); + if (identityKey != null) { + Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Already have session for " + address.toString() + ", adding to cache..."); + XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, identityKey); + sessions.put(address, session); } else { - Log.d(Config.LOGTAG,getLogprefix(account)+"skipping over "+address+" because it's broken"); + Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Found device " + jid + ":" + foreignId); + if (fetchStatusMap.get(address) != FetchStatus.ERROR) { + addresses.add(address); + } else { + Log.d(Config.LOGTAG, getLogprefix(account) + "skipping over " + address + " because it's broken"); + } } } } + } else { + Log.w(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Have no target devices in PEP!"); } - } else { - Log.w(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Have no target devices in PEP!"); } if (deviceIds.get(account.getJid().toBareJid()) != null) { for (Integer ownId : this.deviceIds.get(account.getJid().toBareJid())) { @@ -814,7 +834,6 @@ public class AxolotlServiceImpl implements AxolotlService { return addresses; } - @Override public boolean createSessionsIfNeeded(final Conversation conversation) { Log.i(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Creating axolotl sessions if needed..."); boolean newSessions = false; @@ -836,9 +855,8 @@ public class AxolotlServiceImpl implements AxolotlService { return newSessions; } - @Override public boolean trustedSessionVerified(final Conversation conversation) { - Set<XmppAxolotlSession> sessions = findSessionsforContact(conversation.getContact()); + Set<XmppAxolotlSession> sessions = findSessionsForConversation(conversation); sessions.addAll(findOwnSessions()); boolean verified = false; for(XmppAxolotlSession session : sessions) { @@ -854,26 +872,32 @@ public class AxolotlServiceImpl implements AxolotlService { } @Override - public boolean hasPendingKeyFetches(Account account, Contact contact) { + public boolean hasPendingKeyFetches(Account account, List<Jid> jids) { AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), 0); - AxolotlAddress foreignAddress = new AxolotlAddress(contact.getJid().toBareJid().toString(), 0); - return fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING) - || fetchStatusMap.getAll(foreignAddress).containsValue(FetchStatus.PENDING); - + if (fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING)) { + return true; + } + for(Jid jid : jids) { + AxolotlAddress foreignAddress = new AxolotlAddress(jid.toBareJid().toString(), 0); + if (fetchStatusMap.getAll(foreignAddress).containsValue(FetchStatus.PENDING)) { + return true; + } + } + return false; } @Nullable - private XmppAxolotlMessage buildHeader(Contact contact) { + private XmppAxolotlMessage buildHeader(Conversation conversation) { final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage( - contact.getJid().toBareJid(), getOwnDeviceId()); + account.getJid().toBareJid(), getOwnDeviceId()); - Set<XmppAxolotlSession> contactSessions = findSessionsforContact(contact); + Set<XmppAxolotlSession> remoteSessions = findSessionsForConversation(conversation); Set<XmppAxolotlSession> ownSessions = findOwnSessions(); - if (contactSessions.isEmpty()) { + if (remoteSessions.isEmpty()) { return null; } Log.d(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + "Building axolotl foreign keyElements..."); - for (XmppAxolotlSession session : contactSessions) { + for (XmppAxolotlSession session : remoteSessions) { Log.v(Config.LOGTAG, AxolotlServiceImpl.getLogprefix(account) + session.getRemoteAddress().toString()); axolotlMessage.addDevice(session); } @@ -886,10 +910,9 @@ public class AxolotlServiceImpl implements AxolotlService { return axolotlMessage; } - @Override @Nullable public XmppAxolotlMessage encrypt(Message message) { - XmppAxolotlMessage axolotlMessage = buildHeader(message.getContact()); + XmppAxolotlMessage axolotlMessage = buildHeader(message.getConversation()); if (axolotlMessage != null) { final String content; @@ -909,7 +932,6 @@ public class AxolotlServiceImpl implements AxolotlService { return axolotlMessage; } - @Override public void preparePayloadMessage(final Message message, final boolean delay) { executor.execute(new Runnable() { @Override @@ -928,17 +950,16 @@ public class AxolotlServiceImpl implements AxolotlService { } @Override - public void prepareKeyTransportMessage(final Contact contact, final OnMessageCreatedCallback onMessageCreatedCallback) { + public void prepareKeyTransportMessage(final Conversation conversation, final OnMessageCreatedCallback onMessageCreatedCallback) { executor.execute(new Runnable() { @Override public void run() { - XmppAxolotlMessage axolotlMessage = buildHeader(contact); + XmppAxolotlMessage axolotlMessage = buildHeader(conversation); onMessageCreatedCallback.run(axolotlMessage); } }); } - @Override public XmppAxolotlMessage fetchAxolotlMessageFromCache(Message message) { XmppAxolotlMessage axolotlMessage = messageCache.get(message.getUuid()); if (axolotlMessage != null) { @@ -971,7 +992,6 @@ public class AxolotlServiceImpl implements AxolotlService { return session; } - @Override public XmppAxolotlMessage.XmppAxolotlPlaintextMessage processReceivingPayloadMessage(XmppAxolotlMessage message) { XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = null; @@ -994,7 +1014,6 @@ public class AxolotlServiceImpl implements AxolotlService { return plaintextMessage; } - @Override public XmppAxolotlMessage.XmppAxolotlKeyTransportMessage processReceivingKeyTransportMessage(XmppAxolotlMessage message) { XmppAxolotlMessage.XmppAxolotlKeyTransportMessage keyTransportMessage; @@ -1019,4 +1038,4 @@ public class AxolotlServiceImpl implements AxolotlService { } } } -} +}
\ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceStub.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceStub.java index 42777b75..b0228d34 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceStub.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlServiceStub.java @@ -10,6 +10,7 @@ import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.security.cert.X509Certificate; import java.util.Collections; +import java.util.List; import java.util.Set; import eu.siacs.conversations.entities.Account; @@ -24,11 +25,6 @@ import eu.siacs.conversations.xmpp.jid.Jid; public class AxolotlServiceStub implements AxolotlService { @Override - public boolean fetchMapHasErrors(Contact contact) { - return false; - } - - @Override public String getOwnFingerprint() { return null; } @@ -39,16 +35,6 @@ public class AxolotlServiceStub implements AxolotlService { } @Override - public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Contact contact) { - return Collections.emptySet(); - } - - @Override - public long getNumTrustedKeys(Contact contact) { - return 0; - } - - @Override public Set<String> getFingerprintsForOwnSessions() { return Collections.emptySet(); } @@ -114,11 +100,6 @@ public class AxolotlServiceStub implements AxolotlService { } @Override - public boolean isContactAxolotlCapable(Contact contact) { - return false; - } - - @Override public XmppAxolotlSession.Trust getFingerprintTrust(String fingerprint) { return XmppAxolotlSession.Trust.TRUSTED; } @@ -139,11 +120,6 @@ public class AxolotlServiceStub implements AxolotlService { } @Override - public Set<AxolotlAddress> findDevicesWithoutSession(Jid contactJid) { - return Collections.emptySet(); - } - - @Override public boolean createSessionsIfNeeded(Conversation conversation) { return false; } @@ -153,11 +129,6 @@ public class AxolotlServiceStub implements AxolotlService { return false; } - @Override - public boolean hasPendingKeyFetches(Account account, Contact contact) { - return false; - } - @Nullable @Override public XmppAxolotlMessage encrypt(Message message) { @@ -170,11 +141,6 @@ public class AxolotlServiceStub implements AxolotlService { } @Override - public void prepareKeyTransportMessage(Contact contact, OnMessageCreatedCallback onMessageCreatedCallback) { - - } - - @Override public XmppAxolotlMessage fetchAxolotlMessageFromCache(Message message) { return null; } @@ -190,6 +156,51 @@ public class AxolotlServiceStub implements AxolotlService { } @Override + public boolean fetchMapHasErrors(List<Jid> jids) { + return false; + } + + @Override + public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, Jid jid) { + return Collections.emptySet(); + } + + @Override + public Set<IdentityKey> getKeysWithTrust(XmppAxolotlSession.Trust trust, List<Jid> jids) { + return Collections.emptySet(); + } + + @Override + public long getNumTrustedKeys(Jid jid) { + return 0; + } + + @Override + public boolean anyTargetHasNoTrustedKeys(List<Jid> jids) { + return false; + } + + @Override + public boolean isConversationAxolotlCapable(Conversation conversation) { + return false; + } + + @Override + public List<Jid> getCryptoTargets(Conversation conversation) { + return Collections.emptyList(); + } + + @Override + public boolean hasPendingKeyFetches(Account account, List<Jid> jids) { + return false; + } + + @Override + public void prepareKeyTransportMessage(Conversation conversation, OnMessageCreatedCallback onMessageCreatedCallback) { + + } + + @Override public void onAdvancedStreamFeaturesAvailable(Account account) { } |