mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-22 16:07:30 +00:00
Fix for NPE during a secure session with no sender identity key.
This commit is contained in:
parent
3900808578
commit
5fb7ae7ecf
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2011 Whisper Systems
|
* Copyright (C) 2011 Whisper Systems
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
@ -10,20 +10,12 @@
|
|||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms.database;
|
package org.thoughtcrime.securesms.database;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKey;
|
|
||||||
import org.thoughtcrime.securesms.crypto.InvalidKeyException;
|
|
||||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|
||||||
import org.thoughtcrime.securesms.util.Base64;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -32,56 +24,67 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKey;
|
||||||
|
import org.thoughtcrime.securesms.crypto.InvalidKeyException;
|
||||||
|
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||||
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
|
import org.thoughtcrime.securesms.util.Base64;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class IdentityDatabase extends Database {
|
public class IdentityDatabase extends Database {
|
||||||
|
|
||||||
private static final Uri CHANGE_URI = Uri.parse("content://textsecure/identities");
|
private static final Uri CHANGE_URI = Uri.parse("content://textsecure/identities");
|
||||||
|
|
||||||
private static final String TABLE_NAME = "identities";
|
private static final String TABLE_NAME = "identities";
|
||||||
private static final String ID = "_id";
|
private static final String ID = "_id";
|
||||||
public static final String IDENTITY_KEY = "key";
|
public static final String IDENTITY_KEY = "key";
|
||||||
public static final String IDENTITY_NAME = "name";
|
public static final String IDENTITY_NAME = "name";
|
||||||
public static final String MAC = "mac";
|
public static final String MAC = "mac";
|
||||||
|
|
||||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
|
||||||
IDENTITY_KEY + " TEXT UNIQUE, " + IDENTITY_NAME + " TEXT UNIQUE, " +
|
IDENTITY_KEY + " TEXT UNIQUE, " + IDENTITY_NAME + " TEXT UNIQUE, " +
|
||||||
MAC + " TEXT);";
|
MAC + " TEXT);";
|
||||||
|
|
||||||
public IdentityDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public IdentityDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
super(context, databaseHelper);
|
super(context, databaseHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cursor getIdentities() {
|
public Cursor getIdentities() {
|
||||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = database.query(TABLE_NAME, null, null, null, null, null, null);
|
Cursor cursor = database.query(TABLE_NAME, null, null, null, null, null, null);
|
||||||
|
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.setNotificationUri(context.getContentResolver(), CHANGE_URI);
|
cursor.setNotificationUri(context.getContentResolver(), CHANGE_URI);
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNameForIdentity(MasterSecret masterSecret, IdentityKey identityKey) {
|
public String getNameForIdentity(MasterSecret masterSecret, IdentityKey identityKey) {
|
||||||
|
if (identityKey == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
||||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
|
||||||
Log.w("IdentityDatabase", "Querying for: " + Base64.encodeBytes(identityKey.serialize()));
|
Log.w("IdentityDatabase", "Querying for: " + Base64.encodeBytes(identityKey.serialize()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cursor = database.query(TABLE_NAME, null, IDENTITY_KEY + " = ?", new String[] {Base64.encodeBytes(identityKey.serialize())}, null, null, null);
|
cursor = database.query(TABLE_NAME, null, IDENTITY_KEY + " = ?", new String[] {Base64.encodeBytes(identityKey.serialize())}, null, null, null);
|
||||||
|
|
||||||
if (cursor == null || !cursor.moveToFirst())
|
if (cursor == null || !cursor.moveToFirst())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
String identityName = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_NAME));
|
String identityName = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_NAME));
|
||||||
String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
|
String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
|
||||||
byte[] mac = Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(MAC)));
|
byte[] mac = Base64.decode(cursor.getString(cursor.getColumnIndexOrThrow(MAC)));
|
||||||
|
|
||||||
if (!masterCipher.verifyMacFor(identityName + identityKeyString, mac)) {
|
if (!masterCipher.verifyMacFor(identityName + identityKeyString, mac)) {
|
||||||
Log.w("IdentityDatabase", "Mac check failed!");
|
Log.w("IdentityDatabase", "Mac check failed!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.w("IdentityDatabase", "Returning identity name: " + identityName);
|
Log.w("IdentityDatabase", "Returning identity name: " + identityName);
|
||||||
return identityName;
|
return identityName;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -92,23 +95,23 @@ public class IdentityDatabase extends Database {
|
|||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveIdentity(MasterSecret masterSecret, IdentityKey identityKey, String tagName) throws InvalidKeyException {
|
public void saveIdentity(MasterSecret masterSecret, IdentityKey identityKey, String tagName) throws InvalidKeyException {
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
MasterCipher masterCipher = new MasterCipher(masterSecret);
|
||||||
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
|
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
|
||||||
String macString = Base64.encodeBytes(masterCipher.getMacFor(tagName + identityKeyString));
|
String macString = Base64.encodeBytes(masterCipher.getMacFor(tagName + identityKeyString));
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues();
|
ContentValues contentValues = new ContentValues();
|
||||||
contentValues.put(IDENTITY_KEY, identityKeyString);
|
contentValues.put(IDENTITY_KEY, identityKeyString);
|
||||||
contentValues.put(IDENTITY_NAME, tagName);
|
contentValues.put(IDENTITY_NAME, tagName);
|
||||||
contentValues.put(MAC, macString);
|
contentValues.put(MAC, macString);
|
||||||
|
|
||||||
long id = database.insert(TABLE_NAME, null, contentValues);
|
long id = database.insert(TABLE_NAME, null, contentValues);
|
||||||
|
|
||||||
if (id == -1)
|
if (id == -1)
|
||||||
throw new InvalidKeyException("Error inserting key!");
|
throw new InvalidKeyException("Error inserting key!");
|
||||||
|
|
||||||
context.getContentResolver().notifyChange(CHANGE_URI, null);
|
context.getContentResolver().notifyChange(CHANGE_URI, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +119,9 @@ public class IdentityDatabase extends Database {
|
|||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
String where = IDENTITY_NAME + " = ? AND " + IDENTITY_KEY + " = ?";
|
String where = IDENTITY_NAME + " = ? AND " + IDENTITY_KEY + " = ?";
|
||||||
String[] args = new String[] {name, keyString};
|
String[] args = new String[] {name, keyString};
|
||||||
|
|
||||||
database.delete(TABLE_NAME, where, args);
|
database.delete(TABLE_NAME, where, args);
|
||||||
|
|
||||||
context.getContentResolver().notifyChange(CHANGE_URI, null);
|
context.getContentResolver().notifyChange(CHANGE_URI, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user