Search in sources :

Example 6 with InvalidKeyIdException

use of org.whispersystems.libsignal.InvalidKeyIdException 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 7 with InvalidKeyIdException

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

the class PreKeyUtil method generateLastResortKey.

public static PreKeyRecord generateLastResortKey(Context context) {
    PreKeyStore preKeyStore = new TextSecurePreKeyStore(context);
    if (preKeyStore.containsPreKey(Medium.MAX_VALUE)) {
        try {
            return preKeyStore.loadPreKey(Medium.MAX_VALUE);
        } catch (InvalidKeyIdException e) {
            Log.w("PreKeyUtil", e);
            preKeyStore.removePreKey(Medium.MAX_VALUE);
        }
    }
    ECKeyPair keyPair = Curve.generateKeyPair();
    PreKeyRecord record = new PreKeyRecord(Medium.MAX_VALUE, keyPair);
    preKeyStore.storePreKey(Medium.MAX_VALUE, record);
    return record;
}
Also used : TextSecurePreKeyStore(org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore) ECKeyPair(org.whispersystems.libsignal.ecc.ECKeyPair) PreKeyRecord(org.whispersystems.libsignal.state.PreKeyRecord) SignedPreKeyRecord(org.whispersystems.libsignal.state.SignedPreKeyRecord) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) PreKeyStore(org.whispersystems.libsignal.state.PreKeyStore) TextSecurePreKeyStore(org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore) SignedPreKeyStore(org.whispersystems.libsignal.state.SignedPreKeyStore)

Example 8 with InvalidKeyIdException

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

the class TextSecurePreKeyStore method migrateRecords.

public void migrateRecords() {
    synchronized (FILE_LOCK) {
        File preKeyRecords = getPreKeyDirectory();
        for (File preKeyRecord : preKeyRecords.listFiles()) {
            try {
                int preKeyId = Integer.parseInt(preKeyRecord.getName());
                PreKeyRecord record = loadPreKey(preKeyId);
                storePreKey(preKeyId, record);
            } catch (InvalidKeyIdException | NumberFormatException e) {
                Log.w(TAG, e);
            }
        }
        File signedPreKeyRecords = getSignedPreKeyDirectory();
        for (File signedPreKeyRecord : signedPreKeyRecords.listFiles()) {
            try {
                int signedPreKeyId = Integer.parseInt(signedPreKeyRecord.getName());
                SignedPreKeyRecord record = loadSignedPreKey(signedPreKeyId);
                storeSignedPreKey(signedPreKeyId, record);
            } catch (InvalidKeyIdException | NumberFormatException e) {
                Log.w(TAG, e);
            }
        }
    }
}
Also used : PreKeyRecord(org.whispersystems.libsignal.state.PreKeyRecord) SignedPreKeyRecord(org.whispersystems.libsignal.state.SignedPreKeyRecord) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) SignedPreKeyRecord(org.whispersystems.libsignal.state.SignedPreKeyRecord)

Example 9 with InvalidKeyIdException

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

the class CleanPreKeysJob method onRun.

@Override
public void onRun(MasterSecret masterSecret) throws IOException {
    try {
        Log.w(TAG, "Cleaning prekeys...");
        int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context);
        SignedPreKeyStore signedPreKeyStore = signedPreKeyStoreFactory.create();
        if (activeSignedPreKeyId < 0)
            return;
        SignedPreKeyRecord currentRecord = signedPreKeyStore.loadSignedPreKey(activeSignedPreKeyId);
        List<SignedPreKeyRecord> allRecords = signedPreKeyStore.loadSignedPreKeys();
        LinkedList<SignedPreKeyRecord> oldRecords = removeRecordFrom(currentRecord, allRecords);
        Collections.sort(oldRecords, new SignedPreKeySorter());
        Log.w(TAG, "Active signed prekey: " + activeSignedPreKeyId);
        Log.w(TAG, "Old signed prekey record count: " + oldRecords.size());
        boolean foundAgedRecord = false;
        for (SignedPreKeyRecord oldRecord : oldRecords) {
            long archiveDuration = System.currentTimeMillis() - oldRecord.getTimestamp();
            if (archiveDuration >= ARCHIVE_AGE) {
                if (!foundAgedRecord) {
                    foundAgedRecord = true;
                } else {
                    Log.w(TAG, "Removing signed prekey record: " + oldRecord.getId() + " with timestamp: " + oldRecord.getTimestamp());
                    signedPreKeyStore.removeSignedPreKey(oldRecord.getId());
                }
            }
        }
    } catch (InvalidKeyIdException e) {
        Log.w(TAG, e);
    }
}
Also used : SignedPreKeyStore(org.whispersystems.libsignal.state.SignedPreKeyStore) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) SignedPreKeyRecord(org.whispersystems.libsignal.state.SignedPreKeyRecord)

Example 10 with InvalidKeyIdException

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

the class PushDecryptJob method handleMessage.

private void handleMessage(SignalServiceEnvelope envelope, Optional<Long> smsMessageId) {
    try {
        GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
        SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
        SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context));
        SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore);
        SignalServiceContent content = cipher.decrypt(envelope);
        if (content.getDataMessage().isPresent()) {
            SignalServiceDataMessage message = content.getDataMessage().get();
            if (message.isEndSession())
                handleEndSessionMessage(envelope, message, smsMessageId);
            else if (message.isGroupUpdate())
                handleGroupMessage(envelope, message, smsMessageId);
            else if (message.isExpirationUpdate())
                handleExpirationUpdate(envelope, message, smsMessageId);
            else if (message.getAttachments().isPresent())
                handleMediaMessage(envelope, message, smsMessageId);
            else if (message.getBody().isPresent())
                handleTextMessage(envelope, message, smsMessageId);
            if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false))) {
                handleUnknownGroupMessage(envelope, message.getGroupInfo().get());
            }
            if (message.getProfileKey().isPresent() && message.getProfileKey().get().length == 32) {
                handleProfileKey(envelope, message);
            }
        } else if (content.getSyncMessage().isPresent()) {
            SignalServiceSyncMessage syncMessage = content.getSyncMessage().get();
            if (syncMessage.getSent().isPresent())
                handleSynchronizeSentMessage(envelope, syncMessage.getSent().get());
            else if (syncMessage.getRequest().isPresent())
                handleSynchronizeRequestMessage(syncMessage.getRequest().get());
            else if (syncMessage.getRead().isPresent())
                handleSynchronizeReadMessage(syncMessage.getRead().get(), envelope.getTimestamp());
            else if (syncMessage.getVerified().isPresent())
                handleSynchronizeVerifiedMessage(syncMessage.getVerified().get());
            else
                Log.w(TAG, "Contains no known sync types...");
        } else if (content.getCallMessage().isPresent()) {
            Log.w(TAG, "Got call message...");
            SignalServiceCallMessage message = content.getCallMessage().get();
            if (message.getOfferMessage().isPresent())
                handleCallOfferMessage(envelope, message.getOfferMessage().get(), smsMessageId);
            else if (message.getAnswerMessage().isPresent())
                handleCallAnswerMessage(envelope, message.getAnswerMessage().get());
            else if (message.getIceUpdateMessages().isPresent())
                handleCallIceUpdateMessage(envelope, message.getIceUpdateMessages().get());
            else if (message.getHangupMessage().isPresent())
                handleCallHangupMessage(envelope, message.getHangupMessage().get(), smsMessageId);
            else if (message.getBusyMessage().isPresent())
                handleCallBusyMessage(envelope, message.getBusyMessage().get());
        } else if (content.getReceiptMessage().isPresent()) {
            SignalServiceReceiptMessage message = content.getReceiptMessage().get();
            if (message.isReadReceipt())
                handleReadReceipt(envelope, message);
            else if (message.isDeliveryReceipt())
                handleDeliveryReceipt(envelope, message);
        } else {
            Log.w(TAG, "Got unrecognized message...");
        }
        if (envelope.isPreKeySignalMessage()) {
            ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob(context));
        }
    } catch (InvalidVersionException e) {
        Log.w(TAG, e);
        handleInvalidVersionMessage(envelope, smsMessageId);
    } catch (InvalidMessageException | InvalidKeyIdException | InvalidKeyException | MmsException e) {
        Log.w(TAG, e);
        handleCorruptMessage(envelope, smsMessageId);
    } catch (NoSessionException e) {
        Log.w(TAG, e);
        handleNoSessionMessage(envelope, smsMessageId);
    } catch (LegacyMessageException e) {
        Log.w(TAG, e);
        handleLegacyMessage(envelope, smsMessageId);
    } catch (DuplicateMessageException e) {
        Log.w(TAG, e);
        handleDuplicateMessage(envelope, smsMessageId);
    } catch (UntrustedIdentityException e) {
        Log.w(TAG, e);
        handleUntrustedIdentityMessage(envelope, smsMessageId);
    }
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) SignalServiceCipher(org.whispersystems.signalservice.api.crypto.SignalServiceCipher) InvalidVersionException(org.whispersystems.libsignal.InvalidVersionException) SignalServiceReceiptMessage(org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalServiceSyncMessage(org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage) SignalServiceContent(org.whispersystems.signalservice.api.messages.SignalServiceContent) NoSessionException(org.whispersystems.libsignal.NoSessionException) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SignalProtocolStore(org.whispersystems.libsignal.state.SignalProtocolStore) MmsException(org.thoughtcrime.securesms.mms.MmsException) DuplicateMessageException(org.whispersystems.libsignal.DuplicateMessageException) SignalProtocolStoreImpl(org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) SignalServiceCallMessage(org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage) InvalidKeyIdException(org.whispersystems.libsignal.InvalidKeyIdException) LegacyMessageException(org.whispersystems.libsignal.LegacyMessageException)

Aggregations

InvalidKeyIdException (org.whispersystems.libsignal.InvalidKeyIdException)15 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)9 SignedPreKeyRecord (org.whispersystems.libsignal.state.SignedPreKeyRecord)9 PreKeyRecord (org.whispersystems.libsignal.state.PreKeyRecord)7 DuplicateMessageException (org.whispersystems.libsignal.DuplicateMessageException)6 InvalidMessageException (org.whispersystems.libsignal.InvalidMessageException)6 InvalidVersionException (org.whispersystems.libsignal.InvalidVersionException)6 LegacyMessageException (org.whispersystems.libsignal.LegacyMessageException)6 UntrustedIdentityException (org.whispersystems.libsignal.UntrustedIdentityException)6 NoSessionException (org.whispersystems.libsignal.NoSessionException)5 PreKeySignalMessage (org.whispersystems.libsignal.protocol.PreKeySignalMessage)4 SignalMessage (org.whispersystems.libsignal.protocol.SignalMessage)4 List (java.util.List)3 ECKeyPair (org.whispersystems.libsignal.ecc.ECKeyPair)3 SignedPreKeyStore (org.whispersystems.libsignal.state.SignedPreKeyStore)3 File (java.io.File)2 RandomAccessFile (java.io.RandomAccessFile)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2