package org.thoughtcrime.securesms.jobs; import android.content.Context; import android.text.TextUtils; import android.util.Log; import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher; import org.thoughtcrime.securesms.crypto.AsymmetricMasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecretUnion; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.EncryptingSmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.whispersystems.jobqueue.JobParameters; import org.whispersystems.libsignal.InvalidMessageException; import java.io.IOException; public class MasterSecretDecryptJob extends MasterSecretJob { private static final long serialVersionUID = 1L; private static final String TAG = MasterSecretDecryptJob.class.getSimpleName(); public MasterSecretDecryptJob(Context context) { super(context, JobParameters.newBuilder() .withRequirement(new MasterSecretRequirement(context)) .create()); } @Override public void onRun(MasterSecret masterSecret) { EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); SmsDatabase.Reader smsReader = smsDatabase.getDecryptInProgressMessages(masterSecret); SmsMessageRecord smsRecord; while ((smsRecord = smsReader.getNext()) != null) { try { String body = getAsymmetricDecryptedBody(masterSecret, smsRecord.getBody().getBody()); smsDatabase.updateMessageBody(new MasterSecretUnion(masterSecret), smsRecord.getId(), body); } catch (InvalidMessageException e) { Log.w(TAG, e); } } MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context); MmsDatabase.Reader mmsReader = mmsDatabase.getDecryptInProgressMessages(masterSecret); MessageRecord mmsRecord; while ((mmsRecord = mmsReader.getNext()) != null) { try { String body = getAsymmetricDecryptedBody(masterSecret, mmsRecord.getBody().getBody()); mmsDatabase.updateMessageBody(new MasterSecretUnion(masterSecret), mmsRecord.getId(), body); } catch (InvalidMessageException e) { Log.w(TAG, e); } } smsReader.close(); mmsReader.close(); MessageNotifier.updateNotification(context, masterSecret); } @Override public boolean onShouldRetryThrowable(Exception exception) { return false; } @Override public void onAdded() { } @Override public void onCanceled() { } private String getAsymmetricDecryptedBody(MasterSecret masterSecret, String body) throws InvalidMessageException { try { AsymmetricMasterSecret asymmetricMasterSecret = MasterSecretUtil.getAsymmetricMasterSecret(context, masterSecret); AsymmetricMasterCipher asymmetricMasterCipher = new AsymmetricMasterCipher(asymmetricMasterSecret); if (TextUtils.isEmpty(body)) return ""; else return asymmetricMasterCipher.decryptBody(body); } catch (IOException e) { throw new InvalidMessageException(e); } } }