From 9c95554782ccc0e952de0abbc3ecec9ee1d183a9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Feb 2023 17:39:20 +0100 Subject: [PATCH] add trust to identity table --- .../1.json | 12 ++++++++--- .../xmpp/MessageTransformationTest.java | 2 +- .../database/AxolotlDatabaseStore.java | 21 +++++++++++++++++-- .../android/database/dao/AxolotlDao.java | 21 +++++++++++++++++-- .../entity/AxolotlIdentityEntity.java | 6 +++++- .../android/database/model/Trust.java | 10 +++++++++ 6 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/im/conversations/android/database/model/Trust.java diff --git a/app/schemas/im.conversations.android.database.ConversationsDatabase/1.json b/app/schemas/im.conversations.android.database.ConversationsDatabase/1.json index bbce9c12b..0c37ff688 100644 --- a/app/schemas/im.conversations.android.database.ConversationsDatabase/1.json +++ b/app/schemas/im.conversations.android.database.ConversationsDatabase/1.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "983b8fb918cf0019a31e3a59b37dc368", + "identityHash": "8f66e4197a1676d0164aa77eea8f2a20", "entities": [ { "tableName": "account", @@ -432,7 +432,7 @@ }, { "tableName": "axolotl_identity", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `deviceId` INTEGER NOT NULL, `identityKey` BLOB NOT NULL, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `accountId` INTEGER NOT NULL, `address` TEXT NOT NULL, `deviceId` INTEGER NOT NULL, `identityKey` BLOB NOT NULL, `trust` TEXT NOT NULL, FOREIGN KEY(`accountId`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "fields": [ { "fieldPath": "id", @@ -463,6 +463,12 @@ "columnName": "identityKey", "affinity": "BLOB", "notNull": true + }, + { + "fieldPath": "trust", + "columnName": "trust", + "affinity": "TEXT", + "notNull": true } ], "primaryKey": { @@ -2370,7 +2376,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '983b8fb918cf0019a31e3a59b37dc368')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8f66e4197a1676d0164aa77eea8f2a20')" ] } } \ No newline at end of file diff --git a/app/src/androidTest/java/im/conversations/android/xmpp/MessageTransformationTest.java b/app/src/androidTest/java/im/conversations/android/xmpp/MessageTransformationTest.java index 9779618e4..e506350a9 100644 --- a/app/src/androidTest/java/im/conversations/android/xmpp/MessageTransformationTest.java +++ b/app/src/androidTest/java/im/conversations/android/xmpp/MessageTransformationTest.java @@ -46,7 +46,7 @@ public class MessageTransformationTest { @Before public void setupTransformer() throws ExecutionException, InterruptedException { - Context context = ApplicationProvider.getApplicationContext(); + final Context context = ApplicationProvider.getApplicationContext(); this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build(); final var account = new AccountEntity(); account.address = ACCOUNT; diff --git a/app/src/main/java/im/conversations/android/database/AxolotlDatabaseStore.java b/app/src/main/java/im/conversations/android/database/AxolotlDatabaseStore.java index fd467d5b8..60a8270ac 100644 --- a/app/src/main/java/im/conversations/android/database/AxolotlDatabaseStore.java +++ b/app/src/main/java/im/conversations/android/database/AxolotlDatabaseStore.java @@ -4,6 +4,7 @@ import im.conversations.android.AbstractAccountService; import im.conversations.android.axolotl.AxolotlAddress; import im.conversations.android.database.dao.AxolotlDao; import im.conversations.android.database.model.Account; +import im.conversations.android.database.model.Trust; import java.util.List; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKeyPair; @@ -39,8 +40,24 @@ public class AxolotlDatabaseStore extends AbstractAccountService implements Sign public boolean saveIdentity( final SignalProtocolAddress signalProtocolAddress, IdentityKey identityKey) { final var address = AxolotlAddress.cast(signalProtocolAddress); - return axolotlDao() - .setIdentity(account, address.getJid(), address.getDeviceId(), identityKey); + final boolean isBTBVEnabled = true; + return database.runInTransaction( + () -> { + final Trust trust; + if (!isBTBVEnabled + || axolotlDao().isAnyIdentityVerified(account, address.getJid())) { + trust = Trust.UNDECIDED; + } else { + trust = Trust.TRUSTED; + } + return axolotlDao() + .setIdentity( + account, + address.getJid(), + address.getDeviceId(), + identityKey, + trust); + }); } @Override diff --git a/app/src/main/java/im/conversations/android/database/dao/AxolotlDao.java b/app/src/main/java/im/conversations/android/database/dao/AxolotlDao.java index 9a59c9f9d..07c4e3909 100644 --- a/app/src/main/java/im/conversations/android/database/dao/AxolotlDao.java +++ b/app/src/main/java/im/conversations/android/database/dao/AxolotlDao.java @@ -15,7 +15,9 @@ import im.conversations.android.database.entity.AxolotlPreKeyEntity; import im.conversations.android.database.entity.AxolotlSessionEntity; import im.conversations.android.database.entity.AxolotlSignedPreKeyEntity; import im.conversations.android.database.model.Account; +import im.conversations.android.database.model.Trust; import im.conversations.android.xmpp.model.error.Condition; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; @@ -123,16 +125,31 @@ public abstract class AxolotlDao { @Transaction public boolean setIdentity( - Account account, BareJid address, int deviceId, IdentityKey identityKey) { + final Account account, + final BareJid address, + final int deviceId, + final IdentityKey identityKey, + final Trust trust) { final var existing = getIdentityKey(account.id, address, deviceId); if (existing == null || !existing.equals(identityKey)) { - insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey)); + insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey, trust)); return true; } else { return false; } } + public boolean isAnyIdentityVerified(final Account account, final BareJid address) { + return isAnyIdentityTrustStatus( + account.id, address, Arrays.asList(Trust.VERIFIED, Trust.VERIFIED_X509)); + } + + @Query( + "SELECT EXISTS (SELECT id FROM axolotl_identity WHERE accountId=:account AND" + + " address=:address AND trust IN(:trusts))") + abstract boolean isAnyIdentityTrustStatus( + long account, BareJid address, Collection trusts); + @Insert(onConflict = OnConflictStrategy.REPLACE) protected abstract void insert(AxolotlIdentityEntity axolotlIdentityEntity); diff --git a/app/src/main/java/im/conversations/android/database/entity/AxolotlIdentityEntity.java b/app/src/main/java/im/conversations/android/database/entity/AxolotlIdentityEntity.java index c47e924c3..5c9a4055a 100644 --- a/app/src/main/java/im/conversations/android/database/entity/AxolotlIdentityEntity.java +++ b/app/src/main/java/im/conversations/android/database/entity/AxolotlIdentityEntity.java @@ -6,6 +6,7 @@ import androidx.room.ForeignKey; import androidx.room.Index; import androidx.room.PrimaryKey; import im.conversations.android.database.model.Account; +import im.conversations.android.database.model.Trust; import org.jxmpp.jid.BareJid; import org.whispersystems.libsignal.IdentityKey; @@ -35,13 +36,16 @@ public class AxolotlIdentityEntity { @NonNull public IdentityKey identityKey; + @NonNull public Trust trust; + public static AxolotlIdentityEntity of( - Account account, BareJid address, int deviceId, IdentityKey identityKey) { + Account account, BareJid address, int deviceId, IdentityKey identityKey, Trust trust) { final var entity = new AxolotlIdentityEntity(); entity.accountId = account.id; entity.address = address; entity.deviceId = deviceId; entity.identityKey = identityKey; + entity.trust = trust; return entity; } } diff --git a/app/src/main/java/im/conversations/android/database/model/Trust.java b/app/src/main/java/im/conversations/android/database/model/Trust.java new file mode 100644 index 000000000..6ded59c19 --- /dev/null +++ b/app/src/main/java/im/conversations/android/database/model/Trust.java @@ -0,0 +1,10 @@ +package im.conversations.android.database.model; + +public enum Trust { + COMPROMISED, + UNDECIDED, + UNTRUSTED, + TRUSTED, + VERIFIED, + VERIFIED_X509 +}