Only use MasterSecret for local message encryption.

Not for the axolotl store.

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-07-06 17:36:49 -07:00
parent b1810e2c44
commit 8d9ae731ef
46 changed files with 847 additions and 616 deletions

View File

@@ -19,12 +19,16 @@ package org.thoughtcrime.securesms.database;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher;
import org.thoughtcrime.securesms.crypto.AsymmetricMasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUnion;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.database.model.DisplayRecord;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
@@ -60,57 +64,80 @@ public class EncryptingSmsDatabase extends SmsDatabase {
return ciphertext;
}
public long insertMessageOutbox(MasterSecret masterSecret, long threadId,
public long insertMessageOutbox(MasterSecretUnion masterSecret, long threadId,
OutgoingTextMessage message, boolean forceSms,
long timestamp)
{
long type = Types.BASE_OUTBOX_TYPE;
message = message.withBody(getEncryptedBody(masterSecret, message.getMessageBody()));
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
if (masterSecret.getMasterSecret().isPresent()) {
message = message.withBody(getEncryptedBody(masterSecret.getMasterSecret().get(), message.getMessageBody()));
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
message = message.withBody(getAsymmetricEncryptedBody(masterSecret.getAsymmetricMasterSecret().get(), message.getMessageBody()));
type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
}
return insertMessageOutbox(threadId, message, type, forceSms, timestamp);
}
public Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret,
IncomingTextMessage message)
public Pair<Long, Long> insertMessageInbox(@NonNull MasterSecretUnion masterSecret,
@NonNull IncomingTextMessage message)
{
long type = Types.BASE_INBOX_TYPE;
if (masterSecret == null && message.isSecureMessage()) {
type |= Types.ENCRYPTION_REMOTE_BIT;
if (masterSecret.getMasterSecret().isPresent()) {
return insertMessageInbox(masterSecret.getMasterSecret().get(), message);
} else {
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
message = message.withMessageBody(getEncryptedBody(masterSecret, message.getMessageBody()));
return insertMessageInbox(masterSecret.getAsymmetricMasterSecret().get(), message);
}
}
private Pair<Long, Long> insertMessageInbox(@NonNull MasterSecret masterSecret,
@NonNull IncomingTextMessage message)
{
long type = Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT;
message = message.withMessageBody(getEncryptedBody(masterSecret, message.getMessageBody()));
return insertMessageInbox(message, type);
}
public Pair<Long, Long> insertMessageInbox(AsymmetricMasterSecret masterSecret,
IncomingTextMessage message)
private Pair<Long, Long> insertMessageInbox(@NonNull AsymmetricMasterSecret masterSecret,
@NonNull IncomingTextMessage message)
{
long type = Types.BASE_INBOX_TYPE;
long type = Types.BASE_INBOX_TYPE | Types.ENCRYPTION_ASYMMETRIC_BIT;
if (message.isSecureMessage()) {
type |= Types.ENCRYPTION_REMOTE_BIT;
} else {
message = message.withMessageBody(getAsymmetricEncryptedBody(masterSecret, message.getMessageBody()));
type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
}
message = message.withMessageBody(getAsymmetricEncryptedBody(masterSecret, message.getMessageBody()));
return insertMessageInbox(message, type);
}
public Pair<Long, Long> updateBundleMessageBody(MasterSecret masterSecret, long messageId, String body) {
String encryptedBody = getEncryptedBody(masterSecret, body);
return updateMessageBodyAndType(messageId, encryptedBody, Types.TOTAL_MASK,
Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT | Types.SECURE_MESSAGE_BIT);
public Pair<Long, Long> updateBundleMessageBody(MasterSecretUnion masterSecret, long messageId, String body) {
long type = Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT;
String encryptedBody;
if (masterSecret.getMasterSecret().isPresent()) {
encryptedBody = getEncryptedBody(masterSecret.getMasterSecret().get(), body);
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
encryptedBody = getAsymmetricEncryptedBody(masterSecret.getAsymmetricMasterSecret().get(), body);
type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
}
return updateMessageBodyAndType(messageId, encryptedBody, Types.TOTAL_MASK, type);
}
public void updateMessageBody(MasterSecret masterSecret, long messageId, String body) {
String encryptedBody = getEncryptedBody(masterSecret, body);
updateMessageBodyAndType(messageId, encryptedBody, Types.ENCRYPTION_MASK,
Types.ENCRYPTION_SYMMETRIC_BIT);
public void updateMessageBody(MasterSecretUnion masterSecret, long messageId, String body) {
long type;
if (masterSecret.getMasterSecret().isPresent()) {
body = getEncryptedBody(masterSecret.getMasterSecret().get(), body);
type = Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
body = getAsymmetricEncryptedBody(masterSecret.getAsymmetricMasterSecret().get(), body);
type = Types.ENCRYPTION_ASYMMETRIC_BIT;
}
updateMessageBodyAndType(messageId, body, Types.ENCRYPTION_MASK, type);
}
public Reader getMessages(MasterSecret masterSecret, int skip, int limit) {

View File

@@ -29,8 +29,6 @@ import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.Base64;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.InvalidKeyException;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import java.io.IOException;
@@ -42,13 +40,11 @@ public class IdentityDatabase extends Database {
private static final String ID = "_id";
public static final String RECIPIENT = "recipient";
public static final String IDENTITY_KEY = "key";
public static final String MAC = "mac";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME +
" (" + ID + " INTEGER PRIMARY KEY, " +
RECIPIENT + " INTEGER UNIQUE, " +
IDENTITY_KEY + " TEXT, " +
MAC + " TEXT);";
IDENTITY_KEY + " TEXT);";
public IdentityDatabase(Context context, SQLiteOpenHelper databaseHelper) {
super(context, databaseHelper);
@@ -64,28 +60,19 @@ public class IdentityDatabase extends Database {
return cursor;
}
public boolean isValidIdentity(MasterSecret masterSecret,
long recipientId,
public boolean isValidIdentity(long recipientId,
IdentityKey theirIdentity)
{
SQLiteDatabase database = databaseHelper.getReadableDatabase();
MasterCipher masterCipher = new MasterCipher(masterSecret);
Cursor cursor = null;
SQLiteDatabase database = databaseHelper.getReadableDatabase();
Cursor cursor = null;
try {
cursor = database.query(TABLE_NAME, null, RECIPIENT + " = ?",
new String[] {recipientId+""}, null, null,null);
if (cursor != null && cursor.moveToFirst()) {
String serializedIdentity = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
String mac = cursor.getString(cursor.getColumnIndexOrThrow(MAC));
if (!masterCipher.verifyMacFor(recipientId + serializedIdentity, Base64.decode(mac))) {
Log.w("IdentityDatabase", "MAC failed");
return false;
}
IdentityKey ourIdentity = new IdentityKey(Base64.decode(serializedIdentity), 0);
String serializedIdentity = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
IdentityKey ourIdentity = new IdentityKey(Base64.decode(serializedIdentity), 0);
return ourIdentity.equals(theirIdentity);
} else {
@@ -104,18 +91,14 @@ public class IdentityDatabase extends Database {
}
}
public void saveIdentity(MasterSecret masterSecret, long recipientId, IdentityKey identityKey)
public void saveIdentity(long recipientId, IdentityKey identityKey)
{
SQLiteDatabase database = databaseHelper.getWritableDatabase();
MasterCipher masterCipher = new MasterCipher(masterSecret);
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
String macString = Base64.encodeBytes(masterCipher.getMacFor(recipientId +
identityKeyString));
SQLiteDatabase database = databaseHelper.getWritableDatabase();
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
ContentValues contentValues = new ContentValues();
contentValues.put(RECIPIENT, recipientId);
contentValues.put(IDENTITY_KEY, identityKeyString);
contentValues.put(MAC, macString);
database.replace(TABLE_NAME, null, contentValues);
@@ -129,17 +112,15 @@ public class IdentityDatabase extends Database {
context.getContentResolver().notifyChange(CHANGE_URI, null);
}
public Reader readerFor(MasterSecret masterSecret, Cursor cursor) {
return new Reader(masterSecret, cursor);
public Reader readerFor(Cursor cursor) {
return new Reader(cursor);
}
public class Reader {
private final Cursor cursor;
private final MasterCipher cipher;
public Reader(MasterSecret masterSecret, Cursor cursor) {
public Reader(Cursor cursor) {
this.cursor = cursor;
this.cipher = new MasterCipher(masterSecret);
}
public Identity getCurrent() {
@@ -147,14 +128,9 @@ public class IdentityDatabase extends Database {
Recipients recipients = RecipientFactory.getRecipientsForIds(context, new long[]{recipientId}, true);
try {
String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
String mac = cursor.getString(cursor.getColumnIndexOrThrow(MAC));
String identityKeyString = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
IdentityKey identityKey = new IdentityKey(Base64.decode(identityKeyString), 0);
if (!cipher.verifyMacFor(recipientId + identityKeyString, Base64.decode(mac))) {
return new Identity(recipients, null);
}
IdentityKey identityKey = new IdentityKey(Base64.decode(identityKeyString), 0);
return new Identity(recipients, identityKey);
} catch (IOException e) {
Log.w("IdentityDatabase", e);

View File

@@ -32,8 +32,10 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUnion;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.documents.NetworkFailureList;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
@@ -357,12 +359,11 @@ public class MmsDatabase extends MessagingDatabase {
return cursor;
}
public void updateResponseStatus(long messageId, int status) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(RESPONSE_STATUS, status);
public Reader getDecryptInProgressMessages(MasterSecret masterSecret) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
String where = MESSAGE_BOX + " & " + (Types.ENCRYPTION_ASYMMETRIC_BIT) + " != 0";
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {messageId + ""});
return readerFor(masterSecret, db.query(TABLE_NAME, MMS_PROJECTION, where, null, null, null, null));
}
private void updateMailboxBitmask(long id, long maskOff, long maskOn) {
@@ -417,15 +418,6 @@ public class MmsDatabase extends MessagingDatabase {
notifyConversationListeners(getThreadIdForMessage(messageId));
}
public void markDeliveryStatus(long messageId, int status) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(STATUS, status);
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {messageId + ""});
notifyConversationListeners(getThreadIdForMessage(messageId));
}
public void markAsNoSession(long messageId, long threadId) {
updateMailboxBitmask(messageId, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_NO_SESSION_BIT);
notifyConversationListeners(threadId);
@@ -474,6 +466,36 @@ public class MmsDatabase extends MessagingDatabase {
database.update(TABLE_NAME, contentValues, null, null);
}
public void updateMessageBody(MasterSecretUnion masterSecret, long messageId, String body) {
body = getEncryptedBody(masterSecret, body);
long type;
if (masterSecret.getMasterSecret().isPresent()) {
type = Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
type = Types.ENCRYPTION_ASYMMETRIC_BIT;
}
updateMessageBodyAndType(messageId, body, Types.ENCRYPTION_MASK, type);
}
private Pair<Long, Long> updateMessageBodyAndType(long messageId, String body, long maskOff, long maskOn) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.execSQL("UPDATE " + TABLE_NAME + " SET " + BODY + " = ?, " +
MESSAGE_BOX + " = (" + MESSAGE_BOX + " & " + (Types.TOTAL_MASK - maskOff) + " | " + maskOn + ") " +
"WHERE " + ID + " = ?",
new String[] {body, messageId + ""});
long threadId = getThreadIdForMessage(messageId);
DatabaseFactory.getThreadDatabase(context).update(threadId);
notifyConversationListeners(threadId);
notifyConversationListListeners();
return new Pair<>(messageId, threadId);
}
public Optional<NotificationInd> getNotification(long messageId) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
@@ -544,15 +566,6 @@ public class MmsDatabase extends MessagingDatabase {
}
}
public Reader getNotificationsWithDownloadState(MasterSecret masterSecret, long state) {
SQLiteDatabase database = databaseHelper.getReadableDatabase();
String selection = STATUS + " = ?";
String[] selectionArgs = new String[]{state + ""};
Cursor cursor = database.query(TABLE_NAME, MMS_PROJECTION, selection, selectionArgs, null, null, null);
return new Reader(masterSecret, cursor);
}
public long copyMessageInbox(MasterSecret masterSecret, long messageId) throws MmsException {
try {
SendReq request = getOutgoingMessage(masterSecret, messageId);
@@ -563,15 +576,17 @@ public class MmsDatabase extends MessagingDatabase {
contentValues.put(READ, 1);
contentValues.put(DATE_RECEIVED, contentValues.getAsLong(DATE_SENT));
return insertMediaMessage(masterSecret, request.getPduHeaders(),
return insertMediaMessage(new MasterSecretUnion(masterSecret), request.getPduHeaders(),
request.getBody(), contentValues);
} catch (NoSuchMessageException e) {
throw new MmsException(e);
}
}
private Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret, IncomingMediaMessage retrieved,
String contentLocation, long threadId, long mailbox)
private Pair<Long, Long> insertMessageInbox(MasterSecretUnion masterSecret,
IncomingMediaMessage retrieved,
String contentLocation,
long threadId, long mailbox)
throws MmsException
{
PduHeaders headers = retrieved.getPduHeaders();
@@ -614,35 +629,44 @@ public class MmsDatabase extends MessagingDatabase {
return new Pair<>(messageId, threadId);
}
public Pair<Long, Long> insertMessageInbox(MasterSecret masterSecret,
public Pair<Long, Long> insertMessageInbox(MasterSecretUnion masterSecret,
IncomingMediaMessage retrieved,
String contentLocation, long threadId)
throws MmsException
{
return insertMessageInbox(masterSecret, retrieved, contentLocation, threadId,
Types.BASE_INBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT |
(retrieved.isPushMessage() ? Types.PUSH_MESSAGE_BIT : 0));
long type = Types.BASE_INBOX_TYPE;
if (masterSecret.getMasterSecret().isPresent()) {
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
}
if (retrieved.isPushMessage()) {
type |= Types.PUSH_MESSAGE_BIT;
}
return insertMessageInbox(masterSecret, retrieved, contentLocation, threadId, type);
}
public Pair<Long, Long> insertSecureMessageInbox(MasterSecret masterSecret,
IncomingMediaMessage retrieved,
String contentLocation, long threadId)
throws MmsException
{
return insertMessageInbox(masterSecret, retrieved, contentLocation, threadId,
Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT |
Types.ENCRYPTION_REMOTE_BIT);
}
public Pair<Long, Long> insertSecureDecryptedMessageInbox(MasterSecret masterSecret,
public Pair<Long, Long> insertSecureDecryptedMessageInbox(MasterSecretUnion masterSecret,
IncomingMediaMessage retrieved,
long threadId)
throws MmsException
{
return insertMessageInbox(masterSecret, retrieved, "", threadId,
Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT |
Types.ENCRYPTION_SYMMETRIC_BIT |
(retrieved.isPushMessage() ? Types.PUSH_MESSAGE_BIT : 0));
long type = Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT;
if (masterSecret.getMasterSecret().isPresent()) {
type |= Types.ENCRYPTION_SYMMETRIC_BIT;
} else {
type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
}
if (retrieved.isPushMessage()) {
type |= Types.PUSH_MESSAGE_BIT;
}
return insertMessageInbox(masterSecret, retrieved, "", threadId, type);
}
public Pair<Long, Long> insertMessageInbox(@NonNull NotificationInd notification) {
@@ -680,11 +704,15 @@ public class MmsDatabase extends MessagingDatabase {
jobManager.add(new TrimThreadJob(context, threadId));
}
public long insertMessageOutbox(MasterSecret masterSecret, OutgoingMediaMessage message,
public long insertMessageOutbox(@NonNull MasterSecretUnion masterSecret,
@NonNull OutgoingMediaMessage message,
long threadId, boolean forceSms, long timestamp)
throws MmsException
{
long type = Types.BASE_OUTBOX_TYPE | Types.ENCRYPTION_SYMMETRIC_BIT;
long type = Types.BASE_OUTBOX_TYPE;
if (masterSecret.getMasterSecret().isPresent()) type |= Types.ENCRYPTION_SYMMETRIC_BIT;
else type |= Types.ENCRYPTION_ASYMMETRIC_BIT;
if (message.isSecure()) type |= Types.SECURE_MESSAGE_BIT;
if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT;
@@ -727,14 +755,23 @@ public class MmsDatabase extends MessagingDatabase {
}
}
long messageId = insertMediaMessage(masterSecret, sendRequest.getPduHeaders(),
long messageId = insertMediaMessage(masterSecret,
sendRequest.getPduHeaders(),
sendRequest.getBody(), contentValues);
jobManager.add(new TrimThreadJob(context, threadId));
return messageId;
}
private long insertMediaMessage(MasterSecret masterSecret,
private String getEncryptedBody(MasterSecretUnion masterSecret, String body) {
if (masterSecret.getMasterSecret().isPresent()) {
return new MasterCipher(masterSecret.getMasterSecret().get()).encryptBody(body);
} else {
return new AsymmetricMasterCipher(masterSecret.getAsymmetricMasterSecret().get()).encryptBody(body);
}
}
private long insertMediaMessage(MasterSecretUnion masterSecret,
PduHeaders headers,
PduBody body,
ContentValues contentValues)
@@ -744,12 +781,14 @@ public class MmsDatabase extends MessagingDatabase {
PartDatabase partsDatabase = DatabaseFactory.getPartDatabase(context);
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
if (Types.isSymmetricEncryption(contentValues.getAsLong(MESSAGE_BOX))) {
if (Types.isSymmetricEncryption(contentValues.getAsLong(MESSAGE_BOX)) ||
Types.isAsymmetricEncryption(contentValues.getAsLong(MESSAGE_BOX)))
{
String messageText = PartParser.getMessageText(body);
body = PartParser.getSupportedMediaParts(body);
if (!TextUtils.isEmpty(messageText)) {
contentValues.put(BODY, new MasterCipher(masterSecret).encryptBody(messageText));
contentValues.put(BODY, getEncryptedBody(masterSecret, messageText));
}
}
@@ -1105,6 +1144,8 @@ public class MmsDatabase extends MessagingDatabase {
return new DisplayRecord.Body(masterCipher.decryptBody(body), true);
} else if (!TextUtils.isEmpty(body) && masterCipher == null && Types.isSymmetricEncryption(box)) {
return new DisplayRecord.Body(body, false);
} else if (!TextUtils.isEmpty(body) && Types.isAsymmetricEncryption(box)) {
return new DisplayRecord.Body(body, false);
} else {
return new DisplayRecord.Body(body == null ? "" : body, true);
}

View File

@@ -175,9 +175,7 @@ public interface MmsSmsColumns {
}
public static boolean isDecryptInProgressType(long type) {
return
(type & ENCRYPTION_REMOTE_BIT) != 0 ||
(type & ENCRYPTION_ASYMMETRIC_BIT) != 0;
return (type & ENCRYPTION_ASYMMETRIC_BIT) != 0;
}
public static boolean isNoRemoteSessionType(long type) {
@@ -185,7 +183,8 @@ public interface MmsSmsColumns {
}
public static boolean isLegacyType(long type) {
return (type & ENCRYPTION_REMOTE_LEGACY_BIT) != 0;
return (type & ENCRYPTION_REMOTE_LEGACY_BIT) != 0 ||
(type & ENCRYPTION_REMOTE_BIT) != 0;
}
public static long translateFromSystemBaseType(long theirType) {

View File

@@ -30,6 +30,7 @@ import android.util.Pair;
import org.thoughtcrime.securesms.crypto.DecryptingPartInputStream;
import org.thoughtcrime.securesms.crypto.EncryptingPartOutputStream;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUnion;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.MediaUtil;
@@ -222,7 +223,7 @@ public class PartDatabase extends Database {
}
}
void insertParts(MasterSecret masterSecret, long mmsId, PduBody body) throws MmsException {
void insertParts(MasterSecretUnion masterSecret, long mmsId, PduBody body) throws MmsException {
for (int i=0;i<body.getPartsNum();i++) {
PduPart part = body.getPart(i);
PartId partId = insertPart(masterSecret, part, mmsId, part.getThumbnail());
@@ -432,13 +433,13 @@ public class PartDatabase extends Database {
return part;
}
private PartId insertPart(MasterSecret masterSecret, PduPart part, long mmsId, Bitmap thumbnail) throws MmsException {
private PartId insertPart(MasterSecretUnion masterSecret, PduPart part, long mmsId, Bitmap thumbnail) throws MmsException {
Log.w(TAG, "inserting part to mms " + mmsId);
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Pair<File, Long> partData = null;
if (part.getData() != null || part.getDataUri() != null) {
partData = writePartData(masterSecret, part);
if ((part.getData() != null || part.getDataUri() != null) && masterSecret.getMasterSecret().isPresent()) {
partData = writePartData(masterSecret.getMasterSecret().get(), part);
Log.w(TAG, "Wrote part to file: " + partData.first.getAbsolutePath());
}
@@ -453,12 +454,12 @@ public class PartDatabase extends Database {
long partRowId = database.insert(TABLE_NAME, null, contentValues);
PartId partId = new PartId(partRowId, part.getUniqueId());
if (thumbnail != null) {
if (thumbnail != null && masterSecret.getMasterSecret().isPresent()) {
Log.w(TAG, "inserting pre-generated thumbnail");
ThumbnailData data = new ThumbnailData(thumbnail);
updatePartThumbnail(masterSecret, partId, part, data.toDataStream(), data.getAspectRatio());
updatePartThumbnail(masterSecret.getMasterSecret().get(), partId, part, data.toDataStream(), data.getAspectRatio());
} else if (!part.isInProgress()) {
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret, partId));
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret.getMasterSecret().get(), partId));
}
return partId;

View File

@@ -213,10 +213,6 @@ public class SmsDatabase extends MessagingDatabase {
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_NO_SESSION_BIT);
}
public void markAsDecrypting(long id) {
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_BIT);
}
public void markAsLegacyVersion(long id) {
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_LEGACY_BIT);
}
@@ -461,7 +457,7 @@ public class SmsDatabase extends MessagingDatabase {
}
public Cursor getDecryptInProgressMessages() {
String where = TYPE + " & " + (Types.ENCRYPTION_REMOTE_BIT | Types.ENCRYPTION_ASYMMETRIC_BIT) + " != 0";
String where = TYPE + " & " + (Types.ENCRYPTION_ASYMMETRIC_BIT) + " != 0";
SQLiteDatabase db = databaseHelper.getReadableDatabase();
return db.query(TABLE_NAME, MESSAGE_PROJECTION, where, null, null, null, null);
}