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,
"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')"
]
}
}

View file

@ -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;

View file

@ -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);
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);
.setIdentity(
account,
address.getJid(),
address.getDeviceId(),
identityKey,
trust);
});
}
@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.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<Trust> trusts);
@Insert(onConflict = OnConflictStrategy.REPLACE)
protected abstract void insert(AxolotlIdentityEntity axolotlIdentityEntity);

View file

@ -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;
}
}

View file

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