Overhauled Message tagging
Messages are now tagged with the IdentityKey fingerprint of the originating session. IdentityKeys have one of three trust states: undecided (default), trusted, and untrusted/not yet trusted.
This commit is contained in:
parent
7f918542c8
commit
d173913eba
|
@ -85,6 +85,7 @@ public class AxolotlService {
|
|||
public static final String DEVICE_ID = "device_id";
|
||||
public static final String ID = "id";
|
||||
public static final String KEY = "key";
|
||||
public static final String FINGERPRINT = "fingerprint";
|
||||
public static final String NAME = "name";
|
||||
public static final String TRUSTED = "trusted";
|
||||
public static final String OWN = "ownkey";
|
||||
|
@ -99,6 +100,23 @@ public class AxolotlService {
|
|||
private final int localRegistrationId;
|
||||
private int currentPreKeyId = 0;
|
||||
|
||||
public enum Trust {
|
||||
UNDECIDED, // 0
|
||||
TRUSTED,
|
||||
UNTRUSTED;
|
||||
|
||||
public String toString() {
|
||||
switch(this){
|
||||
case UNDECIDED:
|
||||
return "Trust undecided";
|
||||
case TRUSTED:
|
||||
return "Trusted";
|
||||
case UNTRUSTED:
|
||||
default:
|
||||
return "Untrusted";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static IdentityKeyPair generateIdentityKeyPair() {
|
||||
Log.i(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Generating axolotl IdentityKeyPair...");
|
||||
|
@ -242,11 +260,17 @@ public class AxolotlService {
|
|||
*/
|
||||
@Override
|
||||
public boolean isTrustedIdentity(String name, IdentityKey identityKey) {
|
||||
//Set<IdentityKey> trustedKeys = mXmppConnectionService.databaseBackend.loadIdentityKeys(account, name);
|
||||
//return trustedKeys.isEmpty() || trustedKeys.contains(identityKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Trust getFingerprintTrust(String name, String fingerprint) {
|
||||
return mXmppConnectionService.databaseBackend.isIdentityKeyTrusted(account, name, fingerprint);
|
||||
}
|
||||
|
||||
public void setFingerprintTrust(String name, String fingerprint, Trust trust) {
|
||||
mXmppConnectionService.databaseBackend.setIdentityKeyTrust(account, name, fingerprint, trust);
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// SessionStore
|
||||
// --------------------------------------
|
||||
|
@ -325,14 +349,6 @@ public class AxolotlService {
|
|||
new AxolotlAddress(name, 0));
|
||||
}
|
||||
|
||||
public boolean isTrustedSession(AxolotlAddress address) {
|
||||
return mXmppConnectionService.databaseBackend.isTrustedSession(this.account, address);
|
||||
}
|
||||
|
||||
public void setTrustedSession(AxolotlAddress address, boolean trusted) {
|
||||
mXmppConnectionService.databaseBackend.setTrustedSession(this.account, address, trusted);
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// PreKeyStore
|
||||
// --------------------------------------
|
||||
|
@ -453,27 +469,22 @@ public class AxolotlService {
|
|||
|
||||
public static class XmppAxolotlSession {
|
||||
private final SessionCipher cipher;
|
||||
private boolean isTrusted = false;
|
||||
private Integer preKeyId = null;
|
||||
private final SQLiteAxolotlStore sqLiteAxolotlStore;
|
||||
private final AxolotlAddress remoteAddress;
|
||||
private final Account account;
|
||||
private String fingerprint = null;
|
||||
|
||||
public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress, String fingerprint) {
|
||||
this(account, store, remoteAddress);
|
||||
this.fingerprint = fingerprint;
|
||||
}
|
||||
|
||||
public XmppAxolotlSession(Account account, SQLiteAxolotlStore store, AxolotlAddress remoteAddress) {
|
||||
this.cipher = new SessionCipher(store, remoteAddress);
|
||||
this.remoteAddress = remoteAddress;
|
||||
this.sqLiteAxolotlStore = store;
|
||||
this.account = account;
|
||||
this.isTrusted = sqLiteAxolotlStore.isTrustedSession(remoteAddress);
|
||||
}
|
||||
|
||||
public void trust() {
|
||||
sqLiteAxolotlStore.setTrustedSession(remoteAddress, true);
|
||||
this.isTrusted = true;
|
||||
}
|
||||
|
||||
public boolean isTrusted() {
|
||||
return this.isTrusted;
|
||||
}
|
||||
|
||||
public Integer getPreKeyId() {
|
||||
|
@ -481,19 +492,30 @@ public class AxolotlService {
|
|||
}
|
||||
|
||||
public void resetPreKeyId() {
|
||||
|
||||
preKeyId = null;
|
||||
}
|
||||
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
} catch (InvalidMessageException | InvalidVersionException e) {
|
||||
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"WhisperMessage received");
|
||||
WhisperMessage message = new WhisperMessage(incomingHeader.getContents());
|
||||
|
@ -582,7 +604,9 @@ public class AxolotlService {
|
|||
List<Integer> deviceIDs = store.getSubDeviceSessions(address);
|
||||
for (Integer deviceId : deviceIDs) {
|
||||
AxolotlAddress axolotlAddress = new AxolotlAddress(address, deviceId);
|
||||
this.put(axolotlAddress, new XmppAxolotlSession(account, store, axolotlAddress));
|
||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Building session for remote address: "+axolotlAddress.toString());
|
||||
String fingerprint = store.loadSession(axolotlAddress).getSessionState().getRemoteIdentityKey().getFingerprint().replaceAll("\\s", "");
|
||||
this.put(axolotlAddress, new XmppAxolotlSession(account, store, axolotlAddress, fingerprint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -619,18 +643,6 @@ public class AxolotlService {
|
|||
return axolotlStore.getIdentityKeyPair().getPublicKey();
|
||||
}
|
||||
|
||||
public void trustSession(AxolotlAddress counterpart) {
|
||||
XmppAxolotlSession session = sessions.get(counterpart);
|
||||
if (session != null) {
|
||||
session.trust();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTrustedSession(AxolotlAddress counterpart) {
|
||||
XmppAxolotlSession session = sessions.get(counterpart);
|
||||
return session != null && session.isTrusted();
|
||||
}
|
||||
|
||||
private AxolotlAddress getAddressForJid(Jid jid) {
|
||||
return new AxolotlAddress(jid.toString(), 0);
|
||||
}
|
||||
|
@ -808,11 +820,19 @@ public class AxolotlService {
|
|||
}
|
||||
|
||||
public boolean isContactAxolotlCapable(Contact contact) {
|
||||
|
||||
Jid jid = contact.getJid().toBareJid();
|
||||
AxolotlAddress address = new AxolotlAddress(jid.toString(), 0);
|
||||
return sessions.hasAny(address) ||
|
||||
( deviceIds.containsKey(jid) && !deviceIds.get(jid).isEmpty());
|
||||
}
|
||||
public SQLiteAxolotlStore.Trust getFingerprintTrust(String name, String fingerprint) {
|
||||
return axolotlStore.getFingerprintTrust(name, fingerprint);
|
||||
}
|
||||
|
||||
public void setFingerprintTrust(String name, String fingerprint, SQLiteAxolotlStore.Trust trust) {
|
||||
axolotlStore.setFingerprintTrust(name, fingerprint, trust);
|
||||
}
|
||||
|
||||
private void buildSessionFromPEP(final Conversation conversation, final AxolotlAddress address) {
|
||||
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Building new sesstion for " + address.getDeviceId());
|
||||
|
@ -851,7 +871,7 @@ public class AxolotlService {
|
|||
try {
|
||||
SessionBuilder builder = new SessionBuilder(axolotlStore, address);
|
||||
builder.process(preKeyBundle);
|
||||
XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address);
|
||||
XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey().getFingerprint().replaceAll("\\s", ""));
|
||||
sessions.put(address, session);
|
||||
fetchStatusMap.put(address, FetchStatus.SUCCESS);
|
||||
} catch (UntrustedIdentityException|InvalidKeyException e) {
|
||||
|
@ -1003,7 +1023,7 @@ public class AxolotlService {
|
|||
byte[] payloadKey = session.processReceiving(header);
|
||||
if (payloadKey != null) {
|
||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Got payload key from axolotl header. Decrypting message...");
|
||||
plaintextMessage = message.decrypt(session, payloadKey);
|
||||
plaintextMessage = message.decrypt(session, payloadKey, session.getFingerprint());
|
||||
}
|
||||
Integer preKeyId = session.getPreKeyId();
|
||||
if (preKeyId != null) {
|
||||
|
|
|
@ -67,10 +67,12 @@ public class XmppAxolotlMessage {
|
|||
public static class XmppAxolotlPlaintextMessage {
|
||||
private final AxolotlService.XmppAxolotlSession session;
|
||||
private final String plaintext;
|
||||
private final String fingerprint;
|
||||
|
||||
public XmppAxolotlPlaintextMessage(AxolotlService.XmppAxolotlSession session, String plaintext) {
|
||||
public XmppAxolotlPlaintextMessage(AxolotlService.XmppAxolotlSession session, String plaintext, String fingerprint) {
|
||||
this.session = session;
|
||||
this.plaintext = plaintext;
|
||||
this.fingerprint = fingerprint;
|
||||
}
|
||||
|
||||
public String getPlaintext() {
|
||||
|
@ -81,6 +83,9 @@ public class XmppAxolotlMessage {
|
|||
return session;
|
||||
}
|
||||
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
}
|
||||
|
||||
public XmppAxolotlMessage(Jid from, Element axolotlMessage) {
|
||||
|
@ -167,7 +172,7 @@ public class XmppAxolotlMessage {
|
|||
}
|
||||
|
||||
|
||||
public XmppAxolotlPlaintextMessage decrypt(AxolotlService.XmppAxolotlSession session, byte[] key) {
|
||||
public XmppAxolotlPlaintextMessage decrypt(AxolotlService.XmppAxolotlSession session, byte[] key, String fingerprint) {
|
||||
XmppAxolotlPlaintextMessage plaintextMessage = null;
|
||||
try {
|
||||
|
||||
|
@ -178,7 +183,7 @@ public class XmppAxolotlMessage {
|
|||
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
|
||||
|
||||
String plaintext = new String(cipher.doFinal(ciphertext));
|
||||
plaintextMessage = new XmppAxolotlPlaintextMessage(session, plaintext);
|
||||
plaintextMessage = new XmppAxolotlPlaintextMessage(session, plaintext, fingerprint);
|
||||
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
|
||||
| InvalidAlgorithmParameterException | IllegalBlockSizeException
|
||||
|
|
|
@ -54,6 +54,7 @@ public class Message extends AbstractEntity {
|
|||
public static final String REMOTE_MSG_ID = "remoteMsgId";
|
||||
public static final String SERVER_MSG_ID = "serverMsgId";
|
||||
public static final String RELATIVE_FILE_PATH = "relativeFilePath";
|
||||
public static final String FINGERPRINT = "axolotl_fingerprint";
|
||||
public static final String ME_COMMAND = "/me ";
|
||||
|
||||
|
||||
|
@ -67,7 +68,6 @@ public class Message extends AbstractEntity {
|
|||
protected int encryption;
|
||||
protected int status;
|
||||
protected int type;
|
||||
private AxolotlService.XmppAxolotlSession axolotlSession = null;
|
||||
protected String relativeFilePath;
|
||||
protected boolean read = true;
|
||||
protected String remoteMsgId = null;
|
||||
|
@ -76,6 +76,7 @@ public class Message extends AbstractEntity {
|
|||
protected Transferable transferable = null;
|
||||
private Message mNextMessage = null;
|
||||
private Message mPreviousMessage = null;
|
||||
private String axolotlFingerprint = null;
|
||||
|
||||
private Message() {
|
||||
|
||||
|
@ -97,6 +98,7 @@ public class Message extends AbstractEntity {
|
|||
TYPE_TEXT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
this.conversation = conversation;
|
||||
}
|
||||
|
@ -104,7 +106,7 @@ public class Message extends AbstractEntity {
|
|||
private Message(final String uuid, final String conversationUUid, final Jid counterpart,
|
||||
final Jid trueCounterpart, final String body, final long timeSent,
|
||||
final int encryption, final int status, final int type, final String remoteMsgId,
|
||||
final String relativeFilePath, final String serverMsgId) {
|
||||
final String relativeFilePath, final String serverMsgId, final String fingerprint) {
|
||||
this.uuid = uuid;
|
||||
this.conversationUuid = conversationUUid;
|
||||
this.counterpart = counterpart;
|
||||
|
@ -117,6 +119,7 @@ public class Message extends AbstractEntity {
|
|||
this.remoteMsgId = remoteMsgId;
|
||||
this.relativeFilePath = relativeFilePath;
|
||||
this.serverMsgId = serverMsgId;
|
||||
this.axolotlFingerprint = fingerprint;
|
||||
}
|
||||
|
||||
public static Message fromCursor(Cursor cursor) {
|
||||
|
@ -153,7 +156,8 @@ public class Message extends AbstractEntity {
|
|||
cursor.getInt(cursor.getColumnIndex(TYPE)),
|
||||
cursor.getString(cursor.getColumnIndex(REMOTE_MSG_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(RELATIVE_FILE_PATH)),
|
||||
cursor.getString(cursor.getColumnIndex(SERVER_MSG_ID)));
|
||||
cursor.getString(cursor.getColumnIndex(SERVER_MSG_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(FINGERPRINT)));
|
||||
}
|
||||
|
||||
public static Message createStatusMessage(Conversation conversation, String body) {
|
||||
|
@ -187,6 +191,7 @@ public class Message extends AbstractEntity {
|
|||
values.put(REMOTE_MSG_ID, remoteMsgId);
|
||||
values.put(RELATIVE_FILE_PATH, relativeFilePath);
|
||||
values.put(SERVER_MSG_ID, serverMsgId);
|
||||
values.put(FINGERPRINT, axolotlFingerprint);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -667,11 +672,7 @@ public class Message extends AbstractEntity {
|
|||
public int height = 0;
|
||||
}
|
||||
|
||||
public boolean isTrusted() {
|
||||
return this.axolotlSession != null && this.axolotlSession.isTrusted();
|
||||
}
|
||||
|
||||
public void setAxolotlSession(AxolotlService.XmppAxolotlSession session) {
|
||||
this.axolotlSession = session;
|
||||
public void setAxolotlFingerprint(String fingerprint) {
|
||||
this.axolotlFingerprint = fingerprint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,8 @@ public class MessageParser extends AbstractParser implements
|
|||
XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage);
|
||||
if(plaintextMessage != null) {
|
||||
finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status);
|
||||
finishedMessage.setAxolotlSession(plaintextMessage.getSession());
|
||||
finishedMessage.setAxolotlFingerprint(plaintextMessage.getFingerprint());
|
||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(finishedMessage.getConversation().getAccount())+" Received Message with session fingerprint: "+plaintextMessage.getFingerprint());
|
||||
}
|
||||
|
||||
return finishedMessage;
|
||||
|
|
|
@ -82,7 +82,6 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
+ AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
||||
+ AxolotlService.SQLiteAxolotlStore.ACCOUNT
|
||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
||||
|
@ -97,6 +96,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
+ AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.OWN + " INTEGER, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " TEXT PRIMARY KEY ON CONFLICT IGNORE, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, "
|
||||
+ AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
||||
+ AxolotlService.SQLiteAxolotlStore.ACCOUNT
|
||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE "
|
||||
|
@ -132,6 +133,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
+ Message.STATUS + " NUMBER," + Message.TYPE + " NUMBER, "
|
||||
+ Message.RELATIVE_FILE_PATH + " TEXT, "
|
||||
+ Message.SERVER_MSG_ID + " TEXT, "
|
||||
+ Message.FINGERPRINT + " TEXT, "
|
||||
+ Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY("
|
||||
+ Message.CONVERSATION + ") REFERENCES "
|
||||
+ Conversation.TABLENAME + "(" + Conversation.UUID
|
||||
|
@ -284,6 +286,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
}
|
||||
if (oldVersion < 15 && newVersion >= 15) {
|
||||
recreateAxolotlDb();
|
||||
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
|
||||
+ Message.FINGERPRINT + " TEXT");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -645,28 +649,6 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
args);
|
||||
}
|
||||
|
||||
public boolean isTrustedSession(Account account, AxolotlAddress contact) {
|
||||
boolean trusted = false;
|
||||
Cursor cursor = getCursorForSession(account, contact);
|
||||
if(cursor.getCount() != 0) {
|
||||
cursor.moveToFirst();
|
||||
trusted = cursor.getInt(cursor.getColumnIndex(
|
||||
AxolotlService.SQLiteAxolotlStore.TRUSTED)) > 0;
|
||||
}
|
||||
cursor.close();
|
||||
return trusted;
|
||||
}
|
||||
|
||||
public void setTrustedSession(Account account, AxolotlAddress contact, boolean trusted) {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName());
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId());
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted?1:0);
|
||||
db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values);
|
||||
}
|
||||
|
||||
private Cursor getCursorForPreKey(Account account, int preKeyId) {
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY};
|
||||
|
@ -796,17 +778,28 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
}
|
||||
|
||||
private Cursor getIdentityKeyCursor(Account account, String name, boolean own) {
|
||||
return getIdentityKeyCursor(account, name, own, null);
|
||||
}
|
||||
|
||||
private Cursor getIdentityKeyCursor(Account account, String name, boolean own, String fingerprint) {
|
||||
final SQLiteDatabase db = this.getReadableDatabase();
|
||||
String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY};
|
||||
String[] selectionArgs = {account.getUuid(),
|
||||
name,
|
||||
own?"1":"0"};
|
||||
String[] columns = {AxolotlService.SQLiteAxolotlStore.TRUSTED,
|
||||
AxolotlService.SQLiteAxolotlStore.KEY};
|
||||
ArrayList<String> selectionArgs = new ArrayList<>(4);
|
||||
selectionArgs.add(account.getUuid());
|
||||
selectionArgs.add(name);
|
||||
selectionArgs.add(own?"1":"0");
|
||||
String selectionString = AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND "
|
||||
+ AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND "
|
||||
+ AxolotlService.SQLiteAxolotlStore.OWN + " = ? ";
|
||||
if (fingerprint != null){
|
||||
selectionArgs.add(fingerprint);
|
||||
selectionString += "AND " +AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ";
|
||||
}
|
||||
Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME,
|
||||
columns,
|
||||
AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND "
|
||||
+ AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND "
|
||||
+ AxolotlService.SQLiteAxolotlStore.OWN + " = ? ",
|
||||
selectionArgs,
|
||||
selectionString,
|
||||
selectionArgs.toArray(new String[selectionArgs.size()]),
|
||||
null, null, null);
|
||||
|
||||
return cursor;
|
||||
|
@ -844,22 +837,52 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
return identityKeys;
|
||||
}
|
||||
|
||||
private void storeIdentityKey(Account account, String name, boolean own, String base64Serialized) {
|
||||
private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.NAME, name);
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0);
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint);
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized);
|
||||
db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values);
|
||||
}
|
||||
|
||||
public AxolotlService.SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String name, String fingerprint) {
|
||||
Cursor cursor = getIdentityKeyCursor(account, name, false, fingerprint);
|
||||
AxolotlService.SQLiteAxolotlStore.Trust trust = null;
|
||||
if (cursor.getCount() > 0) {
|
||||
cursor.moveToFirst();
|
||||
int trustValue = cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED));
|
||||
trust = AxolotlService.SQLiteAxolotlStore.Trust.values()[trustValue];
|
||||
}
|
||||
cursor.close();
|
||||
return trust;
|
||||
}
|
||||
|
||||
public boolean setIdentityKeyTrust(Account account, String name, String fingerprint, AxolotlService.SQLiteAxolotlStore.Trust trust) {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
String[] selectionArgs = {
|
||||
account.getUuid(),
|
||||
name,
|
||||
fingerprint
|
||||
};
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal());
|
||||
int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values,
|
||||
AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? "
|
||||
+ AxolotlService.SQLiteAxolotlStore.NAME + " = ? "
|
||||
+ AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ",
|
||||
selectionArgs);
|
||||
return rows == 1;
|
||||
}
|
||||
|
||||
public void storeIdentityKey(Account account, String name, IdentityKey identityKey) {
|
||||
storeIdentityKey(account, name, false, Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT));
|
||||
storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT));
|
||||
}
|
||||
|
||||
public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) {
|
||||
storeIdentityKey(account, name, true, Base64.encodeToString(identityKeyPair.serialize(),Base64.DEFAULT));
|
||||
storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT));
|
||||
}
|
||||
|
||||
public void recreateAxolotlDb() {
|
||||
|
|
Loading…
Reference in a new issue