mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 08:39:22 +01:00
Improve handling of badly-serialized data.
h/t @i-infra
This commit is contained in:
@@ -12,6 +12,7 @@ import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.mobilecoin.lib.exceptions.SerializationException;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
@@ -30,6 +31,7 @@ import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.signalservice.api.InvalidMessageStructureException;
|
||||
import org.whispersystems.signalservice.api.payments.Money;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -105,7 +107,7 @@ public final class PaymentDatabase extends Database {
|
||||
@NonNull Money amount,
|
||||
@NonNull Money fee,
|
||||
@NonNull byte[] receipt)
|
||||
throws PublicKeyConflictException
|
||||
throws PublicKeyConflictException, SerializationException
|
||||
{
|
||||
create(uuid, fromRecipient, null, timestamp, 0, note, Direction.RECEIVED, State.SUBMITTED, amount, fee, null, receipt, null, false);
|
||||
}
|
||||
@@ -122,7 +124,9 @@ public final class PaymentDatabase extends Database {
|
||||
create(uuid, toRecipient, publicAddress, timestamp, 0, note, Direction.SENT, State.INITIAL, amount, amount.toZero(), null, null, null, true);
|
||||
} catch (PublicKeyConflictException e) {
|
||||
Log.w(TAG, "Tried to create payment but the public key appears already in the database", e);
|
||||
throw new AssertionError(e);
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (SerializationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +146,7 @@ public final class PaymentDatabase extends Database {
|
||||
@NonNull Money fee,
|
||||
@NonNull byte[] receipt,
|
||||
@NonNull PaymentMetaData metaData)
|
||||
throws SerializationException
|
||||
{
|
||||
try {
|
||||
create(uuid, toRecipient, publicAddress, timestamp, blockIndex, note, Direction.SENT, State.SUCCESSFUL, amount, fee, null, receipt, metaData, true);
|
||||
@@ -165,6 +170,8 @@ public final class PaymentDatabase extends Database {
|
||||
} catch (PublicKeyConflictException e) {
|
||||
Log.w(TAG, "Tried to create payment but the public key appears already in the database", e);
|
||||
throw new AssertionError(e);
|
||||
} catch (SerializationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +190,7 @@ public final class PaymentDatabase extends Database {
|
||||
@Nullable byte[] receipt,
|
||||
@Nullable PaymentMetaData metaData,
|
||||
boolean seen)
|
||||
throws PublicKeyConflictException
|
||||
throws PublicKeyConflictException, SerializationException
|
||||
{
|
||||
if (recipientId == null && publicAddress == null) {
|
||||
throw new AssertionError();
|
||||
@@ -403,8 +410,12 @@ public final class PaymentDatabase extends Database {
|
||||
values.put(STATE, State.SUBMITTED.serialize());
|
||||
values.put(TRANSACTION, transaction);
|
||||
values.put(RECEIPT, receipt);
|
||||
values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
|
||||
values.put(META_DATA, PaymentMetaDataUtil.fromReceiptAndTransaction(receipt, transaction).toByteArray());
|
||||
try {
|
||||
values.put(PUBLIC_KEY, Base64.encodeBytes(PaymentMetaDataUtil.receiptPublic(PaymentMetaDataUtil.fromReceipt(receipt))));
|
||||
values.put(META_DATA, PaymentMetaDataUtil.fromReceiptAndTransaction(receipt, transaction).toByteArray());
|
||||
} catch (SerializationException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
values.put(FEE, CryptoValueUtil.moneyToCryptoValue(fee).toByteArray());
|
||||
|
||||
database.beginTransaction();
|
||||
|
||||
@@ -23,11 +23,11 @@ public final class PaymentMetaDataUtil {
|
||||
try {
|
||||
return PaymentMetaData.parseFrom(requireBlob);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new AssertionError(e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull PaymentMetaData fromReceipt(@Nullable byte[] receipt) {
|
||||
public static @NonNull PaymentMetaData fromReceipt(@Nullable byte[] receipt) throws SerializationException {
|
||||
PaymentMetaData.MobileCoinTxoIdentification.Builder builder = PaymentMetaData.MobileCoinTxoIdentification.newBuilder();
|
||||
|
||||
if (receipt != null) {
|
||||
@@ -46,7 +46,7 @@ public final class PaymentMetaDataUtil {
|
||||
return PaymentMetaData.newBuilder().setMobileCoinTxoIdentification(builder).build();
|
||||
}
|
||||
|
||||
public static @NonNull PaymentMetaData fromReceiptAndTransaction(@Nullable byte[] receipt, @Nullable byte[] transaction) {
|
||||
public static @NonNull PaymentMetaData fromReceiptAndTransaction(@Nullable byte[] receipt, @Nullable byte[] transaction) throws SerializationException {
|
||||
PaymentMetaData.MobileCoinTxoIdentification.Builder builder = PaymentMetaData.MobileCoinTxoIdentification.newBuilder();
|
||||
|
||||
if (transaction != null) {
|
||||
@@ -58,27 +58,19 @@ public final class PaymentMetaDataUtil {
|
||||
return PaymentMetaData.newBuilder().setMobileCoinTxoIdentification(builder).build();
|
||||
}
|
||||
|
||||
private static void addReceiptData(@NonNull byte[] receipt, PaymentMetaData.MobileCoinTxoIdentification.Builder builder) {
|
||||
try {
|
||||
RistrettoPublic publicKey = Receipt.fromBytes(receipt).getPublicKey();
|
||||
addPublicKey(builder, publicKey);
|
||||
} catch (SerializationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
private static void addReceiptData(@NonNull byte[] receipt, PaymentMetaData.MobileCoinTxoIdentification.Builder builder) throws SerializationException {
|
||||
RistrettoPublic publicKey = Receipt.fromBytes(receipt).getPublicKey();
|
||||
addPublicKey(builder, publicKey);
|
||||
}
|
||||
|
||||
private static void addTransactionData(@NonNull byte[] transactionBytes, PaymentMetaData.MobileCoinTxoIdentification.Builder builder) {
|
||||
try {
|
||||
Transaction transaction = Transaction.fromBytes(transactionBytes);
|
||||
Set<KeyImage> keyImages = transaction.getKeyImages();
|
||||
for (KeyImage keyImage : keyImages) {
|
||||
builder.addKeyImages(ByteString.copyFrom(keyImage.getData()));
|
||||
}
|
||||
for (RistrettoPublic publicKey : transaction.getOutputPublicKeys()) {
|
||||
addPublicKey(builder, publicKey);
|
||||
}
|
||||
} catch (SerializationException e) {
|
||||
throw new AssertionError(e);
|
||||
private static void addTransactionData(@NonNull byte[] transactionBytes, PaymentMetaData.MobileCoinTxoIdentification.Builder builder) throws SerializationException {
|
||||
Transaction transaction = Transaction.fromBytes(transactionBytes);
|
||||
Set<KeyImage> keyImages = transaction.getKeyImages();
|
||||
for (KeyImage keyImage : keyImages) {
|
||||
builder.addKeyImages(ByteString.copyFrom(keyImage.getData()));
|
||||
}
|
||||
for (RistrettoPublic publicKey : transaction.getOutputPublicKeys()) {
|
||||
addPublicKey(builder, publicKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user