use of org.whispersystems.libaxolotl.InvalidKeyIdException in project Conversations by siacs.
the class AxolotlService method publishBundlesIfNeeded.
public void publishBundlesIfNeeded(final boolean announce, final boolean wipe) {
if (pepBroken) {
Log.d(Config.LOGTAG, getLogprefix(account) + "publishBundlesIfNeeded called, but PEP is broken. Ignoring... ");
return;
}
IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(account.getJid().toBareJid(), getOwnDeviceId());
mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
//ignore timeout. do nothing
return;
}
if (packet.getType() == IqPacket.TYPE.ERROR) {
Element error = packet.findChild("error");
if (error == null || !error.hasChild("item-not-found")) {
pepBroken = true;
Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "request for device bundles came back with something other than item-not-found" + packet);
return;
}
}
PreKeyBundle bundle = mXmppConnectionService.getIqParser().bundle(packet);
Map<Integer, ECPublicKey> keys = mXmppConnectionService.getIqParser().preKeyPublics(packet);
boolean flush = false;
if (bundle == null) {
Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received invalid bundle:" + packet);
bundle = new PreKeyBundle(-1, -1, -1, null, -1, null, null, null);
flush = true;
}
if (keys == null) {
Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received invalid prekeys:" + packet);
}
try {
boolean changed = false;
// Validate IdentityKey
IdentityKeyPair identityKeyPair = axolotlStore.getIdentityKeyPair();
if (flush || !identityKeyPair.getPublicKey().equals(bundle.getIdentityKey())) {
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Adding own IdentityKey " + identityKeyPair.getPublicKey() + " to PEP.");
changed = true;
}
// Validate signedPreKeyRecord + ID
SignedPreKeyRecord signedPreKeyRecord;
int numSignedPreKeys = axolotlStore.loadSignedPreKeys().size();
try {
signedPreKeyRecord = axolotlStore.loadSignedPreKey(bundle.getSignedPreKeyId());
if (flush || !bundle.getSignedPreKey().equals(signedPreKeyRecord.getKeyPair().getPublicKey()) || !Arrays.equals(bundle.getSignedPreKeySignature(), signedPreKeyRecord.getSignature())) {
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Adding new signedPreKey with ID " + (numSignedPreKeys + 1) + " to PEP.");
signedPreKeyRecord = KeyHelper.generateSignedPreKey(identityKeyPair, numSignedPreKeys + 1);
axolotlStore.storeSignedPreKey(signedPreKeyRecord.getId(), signedPreKeyRecord);
changed = true;
}
} catch (InvalidKeyIdException e) {
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Adding new signedPreKey with ID " + (numSignedPreKeys + 1) + " to PEP.");
signedPreKeyRecord = KeyHelper.generateSignedPreKey(identityKeyPair, numSignedPreKeys + 1);
axolotlStore.storeSignedPreKey(signedPreKeyRecord.getId(), signedPreKeyRecord);
changed = true;
}
// Validate PreKeys
Set<PreKeyRecord> preKeyRecords = new HashSet<>();
if (keys != null) {
for (Integer id : keys.keySet()) {
try {
PreKeyRecord preKeyRecord = axolotlStore.loadPreKey(id);
if (preKeyRecord.getKeyPair().getPublicKey().equals(keys.get(id))) {
preKeyRecords.add(preKeyRecord);
}
} catch (InvalidKeyIdException ignored) {
}
}
}
int newKeys = NUM_KEYS_TO_PUBLISH - preKeyRecords.size();
if (newKeys > 0) {
List<PreKeyRecord> newRecords = KeyHelper.generatePreKeys(axolotlStore.getCurrentPreKeyId() + 1, newKeys);
preKeyRecords.addAll(newRecords);
for (PreKeyRecord record : newRecords) {
axolotlStore.storePreKey(record.getId(), record);
}
changed = true;
Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Adding " + newKeys + " new preKeys to PEP.");
}
if (changed) {
if (account.getPrivateKeyAlias() != null && Config.X509_VERIFICATION) {
mXmppConnectionService.publishDisplayName(account);
publishDeviceVerificationAndBundle(signedPreKeyRecord, preKeyRecords, announce, wipe);
} else {
publishDeviceBundle(signedPreKeyRecord, preKeyRecords, announce, wipe);
}
} else {
Log.d(Config.LOGTAG, getLogprefix(account) + "Bundle " + getOwnDeviceId() + " in PEP was current");
if (wipe) {
wipeOtherPepDevices();
} else if (announce) {
Log.d(Config.LOGTAG, getLogprefix(account) + "Announcing device " + getOwnDeviceId());
publishOwnDeviceIdIfNeeded();
}
}
} catch (InvalidKeyException e) {
Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Failed to publish bundle " + getOwnDeviceId() + ", reason: " + e.getMessage());
}
}
});
}
use of org.whispersystems.libaxolotl.InvalidKeyIdException in project Conversations by siacs.
the class XmppAxolotlSession method processReceiving.
@Nullable
public byte[] processReceiving(AxolotlKey encryptedKey) throws CryptoFailedException {
byte[] plaintext;
FingerprintStatus status = getTrust();
if (!status.isCompromised()) {
try {
CiphertextMessage ciphertextMessage;
try {
ciphertextMessage = new PreKeyWhisperMessage(encryptedKey.key);
Optional<Integer> optionalPreKeyId = ((PreKeyWhisperMessage) ciphertextMessage).getPreKeyId();
IdentityKey identityKey = ((PreKeyWhisperMessage) ciphertextMessage).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;
} catch (InvalidVersionException | InvalidMessageException e) {
ciphertextMessage = new WhisperMessage(encryptedKey.key);
}
if (ciphertextMessage instanceof PreKeyWhisperMessage) {
plaintext = cipher.decrypt((PreKeyWhisperMessage) ciphertextMessage);
} else {
plaintext = cipher.decrypt((WhisperMessage) ciphertextMessage);
}
} catch (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;
}
Aggregations