Search in sources :

Example 1 with PaymentsAddressException

use of org.thoughtcrime.securesms.payments.PaymentsAddressException in project Signal-Android by WhisperSystems.

the class ConfirmPaymentRepository method confirmPayment.

@AnyThread
void confirmPayment(@NonNull ConfirmPaymentState state, @NonNull Consumer<ConfirmPaymentResult> consumer) {
    Log.i(TAG, "confirmPayment");
    SignalExecutors.BOUNDED.execute(() -> {
        Balance balance = wallet.getCachedBalance();
        if (state.getTotal().requireMobileCoin().greaterThan(balance.getFullAmount().requireMobileCoin())) {
            Log.w(TAG, "The total was greater than the wallet's balance");
            consumer.accept(new ConfirmPaymentResult.Error());
            return;
        }
        Payee payee = state.getPayee();
        RecipientId recipientId;
        MobileCoinPublicAddress mobileCoinPublicAddress;
        if (payee.hasRecipientId()) {
            recipientId = payee.requireRecipientId();
            try {
                mobileCoinPublicAddress = ProfileUtil.getAddressForRecipient(Recipient.resolved(recipientId));
            } catch (IOException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error());
                return;
            } catch (PaymentsAddressException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error(e.getCode()));
                return;
            }
        } else if (payee.hasPublicAddress()) {
            recipientId = null;
            mobileCoinPublicAddress = payee.requirePublicAddress();
        } else
            throw new AssertionError();
        UUID paymentUuid = PaymentSendJob.enqueuePayment(recipientId, mobileCoinPublicAddress, Util.emptyIfNull(state.getNote()), state.getAmount().requireMobileCoin(), state.getFee().requireMobileCoin());
        Log.i(TAG, "confirmPayment: PaymentSendJob enqueued");
        consumer.accept(new ConfirmPaymentResult.Success(paymentUuid));
    });
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) UUID(java.util.UUID) Balance(org.thoughtcrime.securesms.payments.Balance) Payee(org.thoughtcrime.securesms.payments.Payee) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) AnyThread(androidx.annotation.AnyThread)

Example 2 with PaymentsAddressException

use of org.thoughtcrime.securesms.payments.PaymentsAddressException in project Signal-Android by WhisperSystems.

the class ProfileUtil method getAddressForRecipient.

@WorkerThread
@NonNull
public static MobileCoinPublicAddress getAddressForRecipient(@NonNull Recipient recipient) throws IOException, PaymentsAddressException {
    ProfileKey profileKey;
    try {
        profileKey = getProfileKey(recipient);
    } catch (IOException e) {
        Log.w(TAG, "Profile key not available for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NO_PROFILE_KEY);
    }
    ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE);
    SignalServiceProfile profile = profileAndCredential.getProfile();
    byte[] encryptedPaymentsAddress = profile.getPaymentAddress();
    if (encryptedPaymentsAddress == null) {
        Log.w(TAG, "Payments not enabled for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NOT_ENABLED);
    }
    try {
        IdentityKey identityKey = new IdentityKey(Base64.decode(profileAndCredential.getProfile().getIdentityKey()), 0);
        ProfileCipher profileCipher = new ProfileCipher(profileKey);
        byte[] decrypted = profileCipher.decryptWithLength(encryptedPaymentsAddress);
        SignalServiceProtos.PaymentAddress paymentAddress = SignalServiceProtos.PaymentAddress.parseFrom(decrypted);
        byte[] bytes = MobileCoinPublicAddressProfileUtil.verifyPaymentsAddress(paymentAddress, identityKey);
        MobileCoinPublicAddress mobileCoinPublicAddress = MobileCoinPublicAddress.fromBytes(bytes);
        if (mobileCoinPublicAddress == null) {
            throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS);
        }
        return mobileCoinPublicAddress;
    } catch (InvalidCiphertextException | IOException e) {
        Log.w(TAG, "Could not decrypt payments address, ProfileKey may be outdated for " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.COULD_NOT_DECRYPT);
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Could not verify payments address due to bad identity key " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
    }
}
Also used : IdentityKey(org.whispersystems.libsignal.IdentityKey) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) SignalServiceProtos(org.whispersystems.signalservice.internal.push.SignalServiceProtos) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 3 with PaymentsAddressException

use of org.thoughtcrime.securesms.payments.PaymentsAddressException in project Signal-Android by signalapp.

the class ConfirmPaymentRepository method confirmPayment.

@AnyThread
void confirmPayment(@NonNull ConfirmPaymentState state, @NonNull Consumer<ConfirmPaymentResult> consumer) {
    Log.i(TAG, "confirmPayment");
    SignalExecutors.BOUNDED.execute(() -> {
        Balance balance = wallet.getCachedBalance();
        if (state.getTotal().requireMobileCoin().greaterThan(balance.getFullAmount().requireMobileCoin())) {
            Log.w(TAG, "The total was greater than the wallet's balance");
            consumer.accept(new ConfirmPaymentResult.Error());
            return;
        }
        Payee payee = state.getPayee();
        RecipientId recipientId;
        MobileCoinPublicAddress mobileCoinPublicAddress;
        if (payee.hasRecipientId()) {
            recipientId = payee.requireRecipientId();
            try {
                mobileCoinPublicAddress = ProfileUtil.getAddressForRecipient(Recipient.resolved(recipientId));
            } catch (IOException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error());
                return;
            } catch (PaymentsAddressException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error(e.getCode()));
                return;
            }
        } else if (payee.hasPublicAddress()) {
            recipientId = null;
            mobileCoinPublicAddress = payee.requirePublicAddress();
        } else
            throw new AssertionError();
        UUID paymentUuid = PaymentSendJob.enqueuePayment(recipientId, mobileCoinPublicAddress, Util.emptyIfNull(state.getNote()), state.getAmount().requireMobileCoin(), state.getFee().requireMobileCoin());
        Log.i(TAG, "confirmPayment: PaymentSendJob enqueued");
        consumer.accept(new ConfirmPaymentResult.Success(paymentUuid));
    });
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) UUID(java.util.UUID) Balance(org.thoughtcrime.securesms.payments.Balance) Payee(org.thoughtcrime.securesms.payments.Payee) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) AnyThread(androidx.annotation.AnyThread)

Example 4 with PaymentsAddressException

use of org.thoughtcrime.securesms.payments.PaymentsAddressException in project Signal-Android by signalapp.

the class ProfileUtil method getAddressForRecipient.

@WorkerThread
@NonNull
public static MobileCoinPublicAddress getAddressForRecipient(@NonNull Recipient recipient) throws IOException, PaymentsAddressException {
    ProfileKey profileKey;
    try {
        profileKey = getProfileKey(recipient);
    } catch (IOException e) {
        Log.w(TAG, "Profile key not available for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NO_PROFILE_KEY);
    }
    ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE);
    SignalServiceProfile profile = profileAndCredential.getProfile();
    byte[] encryptedPaymentsAddress = profile.getPaymentAddress();
    if (encryptedPaymentsAddress == null) {
        Log.w(TAG, "Payments not enabled for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NOT_ENABLED);
    }
    try {
        IdentityKey identityKey = new IdentityKey(Base64.decode(profileAndCredential.getProfile().getIdentityKey()), 0);
        ProfileCipher profileCipher = new ProfileCipher(profileKey);
        byte[] decrypted = profileCipher.decryptWithLength(encryptedPaymentsAddress);
        SignalServiceProtos.PaymentAddress paymentAddress = SignalServiceProtos.PaymentAddress.parseFrom(decrypted);
        byte[] bytes = MobileCoinPublicAddressProfileUtil.verifyPaymentsAddress(paymentAddress, identityKey);
        MobileCoinPublicAddress mobileCoinPublicAddress = MobileCoinPublicAddress.fromBytes(bytes);
        if (mobileCoinPublicAddress == null) {
            throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS);
        }
        return mobileCoinPublicAddress;
    } catch (InvalidCiphertextException | IOException e) {
        Log.w(TAG, "Could not decrypt payments address, ProfileKey may be outdated for " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.COULD_NOT_DECRYPT);
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Could not verify payments address due to bad identity key " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
    }
}
Also used : IdentityKey(org.whispersystems.libsignal.IdentityKey) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) SignalServiceProtos(org.whispersystems.signalservice.internal.push.SignalServiceProtos) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Aggregations

IOException (java.io.IOException)4 MobileCoinPublicAddress (org.thoughtcrime.securesms.payments.MobileCoinPublicAddress)4 PaymentsAddressException (org.thoughtcrime.securesms.payments.PaymentsAddressException)4 AnyThread (androidx.annotation.AnyThread)2 NonNull (androidx.annotation.NonNull)2 WorkerThread (androidx.annotation.WorkerThread)2 UUID (java.util.UUID)2 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)2 Balance (org.thoughtcrime.securesms.payments.Balance)2 Payee (org.thoughtcrime.securesms.payments.Payee)2 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)2 IdentityKey (org.whispersystems.libsignal.IdentityKey)2 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)2 InvalidCiphertextException (org.whispersystems.signalservice.api.crypto.InvalidCiphertextException)2 ProfileCipher (org.whispersystems.signalservice.api.crypto.ProfileCipher)2 ProfileAndCredential (org.whispersystems.signalservice.api.profiles.ProfileAndCredential)2 SignalServiceProfile (org.whispersystems.signalservice.api.profiles.SignalServiceProfile)2 SignalServiceProtos (org.whispersystems.signalservice.internal.push.SignalServiceProtos)2