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());
}
}
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;
}
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);
}
}
}
}
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);
}
}
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);
}
}
Aggregations