Search in sources :

Example 1 with PreKeySignalMessage

use of org.whispersystems.libsignal.protocol.PreKeySignalMessage in project Signal-Android by WhisperSystems.

the class PushDecryptJob method handleUntrustedIdentityMessage.

private void handleUntrustedIdentityMessage(@NonNull MasterSecretUnion masterSecret, @NonNull SignalServiceEnvelope envelope, @NonNull Optional<Long> smsMessageId) {
    try {
        EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
        Recipients recipients = RecipientFactory.getRecipientsFromString(context, envelope.getSource(), false);
        long recipientId = recipients.getPrimaryRecipient().getRecipientId();
        byte[] serialized = envelope.hasLegacyMessage() ? envelope.getLegacyMessage() : envelope.getContent();
        PreKeySignalMessage whisperMessage = new PreKeySignalMessage(serialized);
        IdentityKey identityKey = whisperMessage.getIdentityKey();
        String encoded = Base64.encodeBytes(serialized);
        IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(), envelope.getTimestamp(), encoded, Optional.<SignalServiceGroup>absent(), 0);
        if (!smsMessageId.isPresent()) {
            IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded, envelope.hasLegacyMessage());
            Optional<InsertResult> insertResult = database.insertMessageInbox(masterSecret, bundleMessage);
            if (insertResult.isPresent()) {
                database.setMismatchedIdentity(insertResult.get().getMessageId(), recipientId, identityKey);
                MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), insertResult.get().getThreadId());
            }
        } else {
            database.updateMessageBody(masterSecret, smsMessageId.get(), encoded);
            database.markAsPreKeyBundle(smsMessageId.get());
            database.setMismatchedIdentity(smsMessageId.get(), recipientId, identityKey);
        }
    } catch (InvalidMessageException | InvalidVersionException e) {
        throw new AssertionError(e);
    }
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult) InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) IdentityKey(org.whispersystems.libsignal.IdentityKey) Recipients(org.thoughtcrime.securesms.recipients.Recipients) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) EncryptingSmsDatabase(org.thoughtcrime.securesms.database.EncryptingSmsDatabase) IncomingPreKeyBundleMessage(org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage)

Example 2 with PreKeySignalMessage

use of org.whispersystems.libsignal.protocol.PreKeySignalMessage in project Pix-Art-Messenger by kriztan.

the class XmppAxolotlSession method processReceiving.

@Nullable
public byte[] processReceiving(AxolotlKey encryptedKey) throws CryptoFailedException {
    byte[] plaintext;
    FingerprintStatus status = getTrust();
    if (!status.isCompromised()) {
        try {
            if (encryptedKey.prekey) {
                PreKeySignalMessage preKeySignalMessage = new PreKeySignalMessage(encryptedKey.key);
                Optional<Integer> optionalPreKeyId = preKeySignalMessage.getPreKeyId();
                IdentityKey identityKey = preKeySignalMessage.getIdentityKey();
                if (!optionalPreKeyId.isPresent()) {
                    throw new CryptoFailedException("PreKeyWhisperMessage did not contain a PreKeyId");
                }
                preKeyId = optionalPreKeyId.get();
                if (this.identityKey != null && !this.identityKey.equals(identityKey)) {
                    throw new CryptoFailedException("Received PreKeyWhisperMessage but preexisting identity key changed.");
                }
                this.identityKey = identityKey;
                plaintext = cipher.decrypt(preKeySignalMessage);
            } else {
                SignalMessage signalMessage = new SignalMessage(encryptedKey.key);
                plaintext = cipher.decrypt(signalMessage);
                // better safe than sorry because we use that to do special after prekey handling
                preKeyId = null;
            }
        } catch (InvalidVersionException | InvalidKeyException | LegacyMessageException | InvalidMessageException | DuplicateMessageException | NoSessionException | InvalidKeyIdException | UntrustedIdentityException e) {
            if (!(e instanceof DuplicateMessageException)) {
                e.printStackTrace();
            }
            throw new CryptoFailedException("Error decrypting WhisperMessage " + e.getClass().getSimpleName() + ": " + e.getMessage());
        }
        if (!status.isActive()) {
            setTrust(status.toActive());
        }
    } else {
        throw new CryptoFailedException("not encrypting omemo message from fingerprint " + getFingerprint() + " because it was marked as compromised");
    }
    return plaintext;
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) IdentityKey(org.whispersystems.libsignal.IdentityKey) UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) SignalMessage(org.whispersystems.libsignal.protocol.SignalMessage) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) NoSessionException(org.whispersystems.libsignal.NoSessionException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) DuplicateMessageException(org.whispersystems.libsignal.DuplicateMessageException) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) LegacyMessageException(org.whispersystems.libsignal.LegacyMessageException) Nullable(android.support.annotation.Nullable)

Example 3 with PreKeySignalMessage

use of org.whispersystems.libsignal.protocol.PreKeySignalMessage in project Signal-Android by WhisperSystems.

the class SignalServiceCipher method decrypt.

private Plaintext decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) throws InvalidMetadataMessageException, InvalidMetadataVersionException, ProtocolDuplicateMessageException, ProtocolUntrustedIdentityException, ProtocolLegacyMessageException, ProtocolInvalidKeyException, ProtocolInvalidVersionException, ProtocolInvalidMessageException, ProtocolInvalidKeyIdException, ProtocolNoSessionException, SelfSendException, InvalidMessageStructureException {
    try {
        byte[] paddedMessage;
        SignalServiceMetadata metadata;
        if (!envelope.hasSourceUuid() && !envelope.isUnidentifiedSender()) {
            throw new InvalidMessageStructureException("Non-UD envelope is missing a UUID!");
        }
        if (envelope.isPreKeySignalMessage()) {
            SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice());
            SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress));
            paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
            signalProtocolStore.clearSenderKeySharedWith(Collections.singleton(sourceAddress));
        } else if (envelope.isSignalMessage()) {
            SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice());
            SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress));
            paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
        } else if (envelope.isPlaintextContent()) {
            paddedMessage = new PlaintextContent(ciphertext).getBody();
            metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent());
        } else if (envelope.isUnidentifiedSender()) {
            SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getServiceId().uuid(), localAddress.getNumber().orNull(), localDeviceId));
            DecryptionResult result = sealedSessionCipher.decrypt(certificateValidator, ciphertext, envelope.getServerReceivedTimestamp());
            SignalServiceAddress resultAddress = new SignalServiceAddress(ACI.parseOrThrow(result.getSenderUuid()), result.getSenderE164());
            Optional<byte[]> groupId = result.getGroupId();
            boolean needsReceipt = true;
            if (envelope.hasSourceUuid()) {
                Log.w(TAG, "[" + envelope.getTimestamp() + "] Received a UD-encrypted message sent over an identified channel. Marking as needsReceipt=false");
                needsReceipt = false;
            }
            if (result.getCiphertextMessageType() == CiphertextMessage.PREKEY_TYPE) {
                signalProtocolStore.clearSenderKeySharedWith(Collections.singleton(new SignalProtocolAddress(result.getSenderUuid(), result.getDeviceId())));
            }
            paddedMessage = result.getPaddedMessage();
            metadata = new SignalServiceMetadata(resultAddress, result.getDeviceId(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), needsReceipt, envelope.getServerGuid(), groupId);
        } else {
            throw new InvalidMetadataMessageException("Unknown type: " + envelope.getType());
        }
        PushTransportDetails transportDetails = new PushTransportDetails();
        byte[] data = transportDetails.getStrippedPaddingMessageBody(paddedMessage);
        return new Plaintext(metadata, data);
    } catch (DuplicateMessageException e) {
        throw new ProtocolDuplicateMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (LegacyMessageException e) {
        throw new ProtocolLegacyMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidMessageException e) {
        throw new ProtocolInvalidMessageException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidKeyIdException e) {
        throw new ProtocolInvalidKeyIdException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidKeyException e) {
        throw new ProtocolInvalidKeyException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (UntrustedIdentityException e) {
        throw new ProtocolUntrustedIdentityException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (InvalidVersionException e) {
        throw new ProtocolInvalidVersionException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    } catch (NoSessionException e) {
        throw new ProtocolNoSessionException(e, envelope.getSourceIdentifier(), envelope.getSourceDevice());
    }
}
Also used : SealedSessionCipher(org.signal.libsignal.metadata.SealedSessionCipher) ProtocolInvalidMessageException(org.signal.libsignal.metadata.ProtocolInvalidMessageException) InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) ProtocolInvalidMessageException(org.signal.libsignal.metadata.ProtocolInvalidMessageException) UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) ProtocolUntrustedIdentityException(org.signal.libsignal.metadata.ProtocolUntrustedIdentityException) ProtocolUntrustedIdentityException(org.signal.libsignal.metadata.ProtocolUntrustedIdentityException) ProtocolInvalidVersionException(org.signal.libsignal.metadata.ProtocolInvalidVersionException) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) InvalidMessageStructureException(org.whispersystems.signalservice.api.InvalidMessageStructureException) ProtocolInvalidVersionException(org.signal.libsignal.metadata.ProtocolInvalidVersionException) PlaintextContent(org.whispersystems.libsignal.protocol.PlaintextContent) ProtocolInvalidKeyIdException(org.signal.libsignal.metadata.ProtocolInvalidKeyIdException) NoSessionException(org.whispersystems.libsignal.NoSessionException) ProtocolNoSessionException(org.signal.libsignal.metadata.ProtocolNoSessionException) ProtocolDuplicateMessageException(org.signal.libsignal.metadata.ProtocolDuplicateMessageException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) PushTransportDetails(org.whispersystems.signalservice.internal.push.PushTransportDetails) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) ProtocolLegacyMessageException(org.signal.libsignal.metadata.ProtocolLegacyMessageException) SessionCipher(org.whispersystems.libsignal.SessionCipher) SealedSessionCipher(org.signal.libsignal.metadata.SealedSessionCipher) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) ProtocolNoSessionException(org.signal.libsignal.metadata.ProtocolNoSessionException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) SignalMessage(org.whispersystems.libsignal.protocol.SignalMessage) Optional(org.whispersystems.libsignal.util.guava.Optional) SignalServiceMetadata(org.whispersystems.signalservice.api.messages.SignalServiceMetadata) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProtocolInvalidKeyException(org.signal.libsignal.metadata.ProtocolInvalidKeyException) InvalidMetadataMessageException(org.signal.libsignal.metadata.InvalidMetadataMessageException) ProtocolInvalidKeyException(org.signal.libsignal.metadata.ProtocolInvalidKeyException) DuplicateMessageException(org.whispersystems.libsignal.DuplicateMessageException) ProtocolDuplicateMessageException(org.signal.libsignal.metadata.ProtocolDuplicateMessageException) DecryptionResult(org.signal.libsignal.metadata.SealedSessionCipher.DecryptionResult) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) ProtocolInvalidKeyIdException(org.signal.libsignal.metadata.ProtocolInvalidKeyIdException) LegacyMessageException(org.whispersystems.libsignal.LegacyMessageException) ProtocolLegacyMessageException(org.signal.libsignal.metadata.ProtocolLegacyMessageException)

Example 4 with PreKeySignalMessage

use of org.whispersystems.libsignal.protocol.PreKeySignalMessage in project Signal-Android by signalapp.

the class PushDecryptJob method handleUntrustedIdentityMessage.

private void handleUntrustedIdentityMessage(@NonNull SignalServiceEnvelope envelope, @NonNull Optional<Long> smsMessageId) {
    try {
        SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
        Address sourceAddress = Address.fromExternal(context, envelope.getSource());
        byte[] serialized = envelope.hasLegacyMessage() ? envelope.getLegacyMessage() : envelope.getContent();
        PreKeySignalMessage whisperMessage = new PreKeySignalMessage(serialized);
        IdentityKey identityKey = whisperMessage.getIdentityKey();
        String encoded = Base64.encodeBytes(serialized);
        IncomingTextMessage textMessage = new IncomingTextMessage(sourceAddress, envelope.getSourceDevice(), envelope.getTimestamp(), encoded, Optional.absent(), 0);
        if (!smsMessageId.isPresent()) {
            IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded, envelope.hasLegacyMessage());
            Optional<InsertResult> insertResult = database.insertMessageInbox(bundleMessage);
            if (insertResult.isPresent()) {
                database.setMismatchedIdentity(insertResult.get().getMessageId(), sourceAddress, identityKey);
                MessageNotifier.updateNotification(context, insertResult.get().getThreadId());
            }
        } else {
            database.updateMessageBody(smsMessageId.get(), encoded);
            database.markAsPreKeyBundle(smsMessageId.get());
            database.setMismatchedIdentity(smsMessageId.get(), sourceAddress, identityKey);
        }
    } catch (InvalidMessageException | InvalidVersionException e) {
        throw new AssertionError(e);
    }
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult) InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) IdentityKey(org.whispersystems.libsignal.IdentityKey) Address(org.thoughtcrime.securesms.database.Address) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) IncomingPreKeyBundleMessage(org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) SmsDatabase(org.thoughtcrime.securesms.database.SmsDatabase)

Example 5 with PreKeySignalMessage

use of org.whispersystems.libsignal.protocol.PreKeySignalMessage in project libsignal-service-java by signalapp.

the class SignalServiceCipher method decrypt.

private byte[] decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) throws InvalidVersionException, InvalidMessageException, InvalidKeyException, DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException, LegacyMessageException, NoSessionException {
    SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSource(), envelope.getSourceDevice());
    SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress);
    byte[] paddedMessage;
    if (envelope.isPreKeySignalMessage()) {
        paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
    } else if (envelope.isSignalMessage()) {
        paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
    } else {
        throw new InvalidMessageException("Unknown type: " + envelope.getType());
    }
    PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion());
    return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) SignalMessage(org.whispersystems.libsignal.protocol.SignalMessage) PreKeySignalMessage(org.whispersystems.libsignal.protocol.PreKeySignalMessage) PushTransportDetails(org.whispersystems.signalservice.internal.push.PushTransportDetails) SessionCipher(org.whispersystems.libsignal.SessionCipher) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress)

Aggregations

InvalidMessageException (org.whispersystems.libsignal.InvalidMessageException)7 PreKeySignalMessage (org.whispersystems.libsignal.protocol.PreKeySignalMessage)7 InvalidVersionException (org.whispersystems.libsignal.InvalidVersionException)6 IdentityKey (org.whispersystems.libsignal.IdentityKey)5 SignalMessage (org.whispersystems.libsignal.protocol.SignalMessage)5 DuplicateMessageException (org.whispersystems.libsignal.DuplicateMessageException)4 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)4 InvalidKeyIdException (org.whispersystems.libsignal.InvalidKeyIdException)4 LegacyMessageException (org.whispersystems.libsignal.LegacyMessageException)4 UntrustedIdentityException (org.whispersystems.libsignal.UntrustedIdentityException)4 NoSessionException (org.whispersystems.libsignal.NoSessionException)3 SessionCipher (org.whispersystems.libsignal.SessionCipher)3 InsertResult (org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult)2 IncomingPreKeyBundleMessage (org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage)2 IncomingTextMessage (org.thoughtcrime.securesms.sms.IncomingTextMessage)2 SignalProtocolAddress (org.whispersystems.libsignal.SignalProtocolAddress)2 SignalServiceAddress (org.whispersystems.signalservice.api.push.SignalServiceAddress)2 PushTransportDetails (org.whispersystems.signalservice.internal.push.PushTransportDetails)2 Nullable (android.support.annotation.Nullable)1 Nullable (androidx.annotation.Nullable)1