use of org.jivesoftware.smackx.omemo.internal.OmemoDevice in project Zom-Android by zom.
the class IOCipherOmemoStore method removeAllRawSessionsOf.
@Override
public void removeAllRawSessionsOf(OmemoManager omemoManager, BareJid contact) {
File contactsDirectory = hierarchy.getContactsDir(omemoManager, contact);
String[] devices = contactsDirectory.list();
for (String deviceId : devices != null ? devices : new String[0]) {
int id;
try {
id = Integer.parseInt(deviceId);
} catch (NumberFormatException e) {
continue;
}
OmemoDevice device = new OmemoDevice(contact, id);
File session = hierarchy.getContactsSessionPath(omemoManager, device);
session.delete();
}
}
use of org.jivesoftware.smackx.omemo.internal.OmemoDevice in project Smack by igniterealtime.
the class OmemoManagerSetupHelper method trustAllIdentities.
public static void trustAllIdentities(OmemoManager alice, OmemoManager bob) throws InterruptedException, SmackException.NotConnectedException, SmackException.NotLoggedInException, SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException, XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException {
Roster roster = Roster.getInstanceFor(alice.getConnection());
if (alice.getOwnJid() != bob.getOwnJid() && (!roster.iAmSubscribedTo(bob.getOwnJid()) || !roster.isSubscribedToMyPresence(bob.getOwnJid()))) {
throw new IllegalStateException("Before trusting identities of a user, we must be subscribed to one another.");
}
alice.requestDeviceListUpdateFor(bob.getOwnJid());
HashMap<OmemoDevice, OmemoFingerprint> fingerprints = alice.getActiveFingerprints(bob.getOwnJid());
for (OmemoDevice device : fingerprints.keySet()) {
OmemoFingerprint fingerprint = fingerprints.get(device);
alice.trustOmemoIdentity(device, fingerprint);
}
}
use of org.jivesoftware.smackx.omemo.internal.OmemoDevice in project Smack by igniterealtime.
the class OmemoService method onOmemoMessageStanzaReceived.
@Override
public void onOmemoMessageStanzaReceived(Stanza stanza, OmemoManager.LoggedInOmemoManager managerGuard) throws IOException {
OmemoManager manager = managerGuard.get();
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
synchronized (manager) {
OmemoDevice userDevice = manager.getOwnDevice();
OmemoElement element = (OmemoElement) stanza.getExtensionElement(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
if (element == null) {
return;
}
OmemoMessage.Received decrypted;
BareJid sender;
try {
MultiUserChat muc = getMuc(manager.getConnection(), stanza.getFrom());
if (muc != null) {
Occupant occupant = muc.getOccupant(stanza.getFrom().asEntityFullJidIfPossible());
if (occupant == null) {
LOGGER.log(Level.WARNING, "Cannot decrypt OMEMO MUC message; MUC Occupant is null.");
return;
}
Jid occupantJid = occupant.getJid();
if (occupantJid == null) {
LOGGER.log(Level.WARNING, "Cannot decrypt OMEMO MUC message; Senders Jid is null. " + stanza.getFrom());
return;
}
sender = occupantJid.asBareJid();
// try is for this
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoMucMessageReceived(muc, stanza, decrypted);
} else {
sender = stanza.getFrom().asBareJid();
// and this
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoMessageReceived(stanza, decrypted);
}
if (decrypted.isPreKeyMessage() && OmemoConfiguration.getCompleteSessionWithEmptyMessage()) {
LOGGER.log(Level.FINE, "Received a preKeyMessage from " + decrypted.getSenderDevice() + ".\n" + "Complete the session by sending an empty response message.");
try {
sendRatchetUpdate(managerGuard, decrypted.getSenderDevice());
} catch (CannotEstablishOmemoSessionException e) {
throw new AssertionError("Since we successfully received a message, we MUST be able to " + "establish a session. " + e);
} catch (NoSuchAlgorithmException | InterruptedException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Cannot send a ratchet update message.", e);
}
}
} catch (NoRawSessionException e) {
OmemoDevice device = e.getDeviceWithoutSession();
LOGGER.log(Level.WARNING, "No raw session found for contact " + device + ". ", e);
if (OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages()) {
repairBrokenSessionWithPreKeyMessage(managerGuard, device);
}
} catch (CorruptedOmemoKeyException | CryptoFailedException e) {
LOGGER.log(Level.WARNING, "Could not decrypt incoming message: ", e);
}
// Upload fresh bundle.
if (getOmemoStoreBackend().loadOmemoPreKeys(userDevice).size() < OmemoConstants.PRE_KEY_COUNT_PER_BUNDLE) {
LOGGER.log(Level.FINE, "We used up a preKey. Upload a fresh bundle.");
try {
getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
}
}
}
}
use of org.jivesoftware.smackx.omemo.internal.OmemoDevice in project Smack by igniterealtime.
the class OmemoService method removeStaleDevicesFromDeviceList.
/**
* Return a copy of the given deviceList of user contact, but with stale devices marked as inactive.
* Never mark our own device as stale. If we haven't yet received a message from a device, store the current date
* as last date of message receipt to allow future decisions.
*
* A stale device is a device, from which we haven't received an OMEMO message from for more than
* "maxAgeMillis" milliseconds.
*
* @param userDevice our OmemoDevice.
* @param contact subjects BareJid.
* @param contactsDeviceList subjects deviceList.
* @return copy of subjects deviceList with stale devices marked as inactive.
*
* @throws IOException if an I/O error occurred.
*/
private OmemoCachedDeviceList removeStaleDevicesFromDeviceList(OmemoDevice userDevice, BareJid contact, OmemoCachedDeviceList contactsDeviceList, int maxAgeHours) throws IOException {
// Don't work on original list.
OmemoCachedDeviceList deviceList = new OmemoCachedDeviceList(contactsDeviceList);
// Iterate through original list, but modify copy instead
for (int deviceId : contactsDeviceList.getActiveDevices()) {
OmemoDevice device = new OmemoDevice(contact, deviceId);
Date lastDeviceIdPublication = getOmemoStoreBackend().getDateOfLastDeviceIdPublication(userDevice, device);
if (lastDeviceIdPublication == null) {
lastDeviceIdPublication = new Date();
getOmemoStoreBackend().setDateOfLastDeviceIdPublication(userDevice, device, lastDeviceIdPublication);
}
Date lastMessageReceived = getOmemoStoreBackend().getDateOfLastReceivedMessage(userDevice, device);
if (lastMessageReceived == null) {
lastMessageReceived = new Date();
getOmemoStoreBackend().setDateOfLastReceivedMessage(userDevice, device, lastMessageReceived);
}
boolean stale = isStale(userDevice, device, lastDeviceIdPublication, maxAgeHours);
stale &= isStale(userDevice, device, lastMessageReceived, maxAgeHours);
if (stale) {
deviceList.addInactiveDevice(deviceId);
}
}
return deviceList;
}
use of org.jivesoftware.smackx.omemo.internal.OmemoDevice in project Smack by igniterealtime.
the class OmemoService method onOmemoCarbonCopyReceived.
@Override
public void onOmemoCarbonCopyReceived(CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage, OmemoManager.LoggedInOmemoManager managerGuard) throws IOException {
OmemoManager manager = managerGuard.get();
// Avoid the ratchet being manipulated and the bundle being published multiple times simultaneously
synchronized (manager) {
OmemoDevice userDevice = manager.getOwnDevice();
OmemoElement element = (OmemoElement) carbonCopy.getExtensionElement(OmemoElement.NAME_ENCRYPTED, OmemoElement_VAxolotl.NAMESPACE);
if (element == null) {
return;
}
OmemoMessage.Received decrypted;
BareJid sender = carbonCopy.getFrom().asBareJid();
try {
decrypted = decryptMessage(managerGuard, sender, element);
manager.notifyOmemoCarbonCopyReceived(direction, carbonCopy, wrappingMessage, decrypted);
if (decrypted.isPreKeyMessage() && OmemoConfiguration.getCompleteSessionWithEmptyMessage()) {
LOGGER.log(Level.FINE, "Received a preKeyMessage in a carbon copy from " + decrypted.getSenderDevice() + ".\n" + "Complete the session by sending an empty response message.");
try {
sendRatchetUpdate(managerGuard, decrypted.getSenderDevice());
} catch (CannotEstablishOmemoSessionException e) {
throw new AssertionError("Since we successfully received a message, we MUST be able to " + "establish a session. " + e);
} catch (NoSuchAlgorithmException | InterruptedException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Cannot send a ratchet update message.", e);
}
}
} catch (NoRawSessionException e) {
OmemoDevice device = e.getDeviceWithoutSession();
LOGGER.log(Level.WARNING, "No raw session found for contact " + device + ". ", e);
if (OmemoConfiguration.getRepairBrokenSessionsWithPreKeyMessages()) {
repairBrokenSessionWithPreKeyMessage(managerGuard, device);
}
} catch (CorruptedOmemoKeyException | CryptoFailedException e) {
LOGGER.log(Level.WARNING, "Could not decrypt incoming carbon copy: ", e);
}
// Upload fresh bundle.
if (getOmemoStoreBackend().loadOmemoPreKeys(userDevice).size() < OmemoConstants.PRE_KEY_COUNT_PER_BUNDLE) {
LOGGER.log(Level.FINE, "We used up a preKey. Upload a fresh bundle.");
try {
getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
}
}
}
}
Aggregations