add trust to identity table

This commit is contained in:
Daniel Gultsch 2023-02-28 17:39:20 +01:00
parent ac2866a682
commit 9c95554782
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
6 changed files with 63 additions and 9 deletions

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 1, "version": 1,
"identityHash": "983b8fb918cf0019a31e3a59b37dc368", "identityHash": "8f66e4197a1676d0164aa77eea8f2a20",
"entities": [ "entities": [
{ {
"tableName": "account", "tableName": "account",
@ -432,7 +432,7 @@
}, },
{ {
"tableName": "axolotl_identity", "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": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -463,6 +463,12 @@
"columnName": "identityKey", "columnName": "identityKey",
"affinity": "BLOB", "affinity": "BLOB",
"notNull": true "notNull": true
},
{
"fieldPath": "trust",
"columnName": "trust",
"affinity": "TEXT",
"notNull": true
} }
], ],
"primaryKey": { "primaryKey": {
@ -2370,7 +2376,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "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')"
] ]
} }
} }

View file

@ -46,7 +46,7 @@ public class MessageTransformationTest {
@Before @Before
public void setupTransformer() throws ExecutionException, InterruptedException { public void setupTransformer() throws ExecutionException, InterruptedException {
Context context = ApplicationProvider.getApplicationContext(); final Context context = ApplicationProvider.getApplicationContext();
this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build(); this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build();
final var account = new AccountEntity(); final var account = new AccountEntity();
account.address = ACCOUNT; account.address = ACCOUNT;

View file

@ -4,6 +4,7 @@ import im.conversations.android.AbstractAccountService;
import im.conversations.android.axolotl.AxolotlAddress; import im.conversations.android.axolotl.AxolotlAddress;
import im.conversations.android.database.dao.AxolotlDao; import im.conversations.android.database.dao.AxolotlDao;
import im.conversations.android.database.model.Account; import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.Trust;
import java.util.List; import java.util.List;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.IdentityKeyPair;
@ -39,8 +40,24 @@ public class AxolotlDatabaseStore extends AbstractAccountService implements Sign
public boolean saveIdentity( public boolean saveIdentity(
final SignalProtocolAddress signalProtocolAddress, IdentityKey identityKey) { final SignalProtocolAddress signalProtocolAddress, IdentityKey identityKey) {
final var address = AxolotlAddress.cast(signalProtocolAddress); final var address = AxolotlAddress.cast(signalProtocolAddress);
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() return axolotlDao()
.setIdentity(account, address.getJid(), address.getDeviceId(), identityKey); .setIdentity(
account,
address.getJid(),
address.getDeviceId(),
identityKey,
trust);
});
} }
@Override @Override

View file

@ -15,7 +15,9 @@ import im.conversations.android.database.entity.AxolotlPreKeyEntity;
import im.conversations.android.database.entity.AxolotlSessionEntity; import im.conversations.android.database.entity.AxolotlSessionEntity;
import im.conversations.android.database.entity.AxolotlSignedPreKeyEntity; import im.conversations.android.database.entity.AxolotlSignedPreKeyEntity;
import im.conversations.android.database.model.Account; import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.Trust;
import im.conversations.android.xmpp.model.error.Condition; import im.conversations.android.xmpp.model.error.Condition;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -123,16 +125,31 @@ public abstract class AxolotlDao {
@Transaction @Transaction
public boolean setIdentity( 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); final var existing = getIdentityKey(account.id, address, deviceId);
if (existing == null || !existing.equals(identityKey)) { if (existing == null || !existing.equals(identityKey)) {
insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey)); insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey, trust));
return true; return true;
} else { } else {
return false; 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<Trust> trusts);
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
protected abstract void insert(AxolotlIdentityEntity axolotlIdentityEntity); protected abstract void insert(AxolotlIdentityEntity axolotlIdentityEntity);

View file

@ -6,6 +6,7 @@ import androidx.room.ForeignKey;
import androidx.room.Index; import androidx.room.Index;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import im.conversations.android.database.model.Account; import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.Trust;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
@ -35,13 +36,16 @@ public class AxolotlIdentityEntity {
@NonNull public IdentityKey identityKey; @NonNull public IdentityKey identityKey;
@NonNull public Trust trust;
public static AxolotlIdentityEntity of( 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(); final var entity = new AxolotlIdentityEntity();
entity.accountId = account.id; entity.accountId = account.id;
entity.address = address; entity.address = address;
entity.deviceId = deviceId; entity.deviceId = deviceId;
entity.identityKey = identityKey; entity.identityKey = identityKey;
entity.trust = trust;
return entity; return entity;
} }
} }

View file

@ -0,0 +1,10 @@
package im.conversations.android.database.model;
public enum Trust {
COMPROMISED,
UNDECIDED,
UNTRUSTED,
TRUSTED,
VERIFIED,
VERIFIED_X509
}