use of org.matrix.olm.OlmSession in project matrix-android-sdk by matrix-org.
the class MXFileCryptoStore method close.
@Override
public void close() {
// release JNI objects
ArrayList<OlmSession> olmSessions = new ArrayList<>();
Collection<HashMap<String, OlmSession>> sessionValues = mOlmSessions.values();
for (HashMap<String, OlmSession> value : sessionValues) {
olmSessions.addAll(value.values());
}
for (OlmSession olmSession : olmSessions) {
olmSession.releaseSession();
}
mOlmSessions.clear();
ArrayList<MXOlmInboundGroupSession2> groupSessions = new ArrayList<>();
Collection<HashMap<String, MXOlmInboundGroupSession2>> groupSessionsValues = mInboundGroupSessions.values();
for (HashMap<String, MXOlmInboundGroupSession2> map : groupSessionsValues) {
groupSessions.addAll(map.values());
}
for (MXOlmInboundGroupSession2 groupSession : groupSessions) {
if (null != groupSession.mSession) {
groupSession.mSession.releaseSession();
}
}
mInboundGroupSessions.clear();
}
use of org.matrix.olm.OlmSession in project matrix-android-sdk by matrix-org.
the class MXFileCryptoStore method storeSession.
@Override
public void storeSession(final OlmSession olmSession, final String deviceKey) {
if (!mIsReady) {
Log.e(LOG_TAG, "## storeSession() : the store is not ready");
return;
}
String sessionIdentifier = null;
if (null != olmSession) {
try {
sessionIdentifier = olmSession.sessionIdentifier();
} catch (Exception e) {
Log.e(LOG_TAG, "## storeSession : session.sessionIdentifier() failed " + e.getMessage());
}
}
if ((null != deviceKey) && (null != sessionIdentifier)) {
synchronized (mOlmSessionsLock) {
if (!mOlmSessions.containsKey(deviceKey)) {
mOlmSessions.put(deviceKey, new HashMap<String, OlmSession>());
}
OlmSession prevOlmSession = mOlmSessions.get(deviceKey).get(sessionIdentifier);
// test if the session is a new one
if (olmSession != prevOlmSession) {
if (null != prevOlmSession) {
prevOlmSession.releaseSession();
}
mOlmSessions.get(deviceKey).put(sessionIdentifier, olmSession);
}
}
final File keyFolder = new File(mOlmSessionsFolder, encodeFilename(deviceKey));
if (!keyFolder.exists()) {
keyFolder.mkdir();
}
storeObject(olmSession, keyFolder, encodeFilename(sessionIdentifier), "Store olm session " + deviceKey + " " + sessionIdentifier);
}
}
use of org.matrix.olm.OlmSession in project matrix-android-sdk by matrix-org.
the class MXFileCryptoStore method preloadCryptoData.
/**
* Preload the crypto data
*/
private void preloadCryptoData() {
Log.d(LOG_TAG, "## preloadCryptoData() starts");
long t0 = System.currentTimeMillis();
Object olmAccountAsVoid;
if (mAccountFileTmp.exists()) {
olmAccountAsVoid = loadObject(mAccountFileTmp, "preloadCryptoData - mAccountFile - tmp");
} else {
olmAccountAsVoid = loadObject(mAccountFile, "preloadCryptoData - mAccountFile");
}
if (null != olmAccountAsVoid) {
try {
mOlmAccount = (OlmAccount) olmAccountAsVoid;
} catch (Exception e) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mAccountFile " + e.getMessage());
}
}
Log.d(LOG_TAG, "## preloadCryptoData() : load mOlmAccount in " + (System.currentTimeMillis() - t0) + " ms");
// previous store format
if (!mDevicesFolder.exists()) {
Object usersDevicesInfoMapAsVoid;
// if the tmp exists, it means that the latest file backup has been killed / stopped
if (mDevicesFileTmp.exists()) {
usersDevicesInfoMapAsVoid = loadObject(mDevicesFileTmp, "preloadCryptoData - mUsersDevicesInfoMap - tmp");
} else {
usersDevicesInfoMapAsVoid = loadObject(mDevicesFile, "preloadCryptoData - mUsersDevicesInfoMap");
}
if (null != usersDevicesInfoMapAsVoid) {
try {
MXUsersDevicesMap objectAsMap = (MXUsersDevicesMap) usersDevicesInfoMapAsVoid;
mUsersDevicesInfoMap = new MXUsersDevicesMap<>(objectAsMap.getMap());
} catch (Exception e) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mUsersDevicesInfoMap " + e.getMessage());
}
} else {
mIsCorrupted = false;
}
mDevicesFolder.mkdirs();
if (null != mUsersDevicesInfoMap) {
HashMap<String, HashMap<String, MXDeviceInfo>> map = mUsersDevicesInfoMap.getMap();
Set<String> userIds = map.keySet();
for (String userId : userIds) {
storeObject(map.get(userId), mDevicesFolder, userId, "convert devices map of " + userId);
}
mDevicesFileTmp.delete();
mDevicesFile.delete();
}
} else {
// the user devices are loaded on demand
mUsersDevicesInfoMap = new MXUsersDevicesMap<>();
}
long t2 = System.currentTimeMillis();
int algoSize = 0;
Object algorithmsAsVoid;
if (mAlgorithmsFileTmp.exists()) {
algorithmsAsVoid = loadObject(mAlgorithmsFileTmp, "preloadCryptoData - mRoomsAlgorithms - tmp");
} else {
algorithmsAsVoid = loadObject(mAlgorithmsFile, "preloadCryptoData - mRoomsAlgorithms");
}
if (null != algorithmsAsVoid) {
try {
Map<String, String> algorithmsMap = (Map<String, String>) algorithmsAsVoid;
mRoomsAlgorithms = new HashMap<>(algorithmsMap);
algoSize = mRoomsAlgorithms.size();
} catch (Exception e) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mAlgorithmsFile " + e.getMessage());
}
}
Log.d(LOG_TAG, "## preloadCryptoData() : load mRoomsAlgorithms (" + algoSize + " algos) in " + (System.currentTimeMillis() - t2) + " ms");
Object trackingStatusesAsVoid;
if (mTrackingStatusesFileTmp.exists()) {
trackingStatusesAsVoid = loadObject(mTrackingStatusesFileTmp, "preloadCryptoData - mTrackingStatuses - tmp");
} else {
trackingStatusesAsVoid = loadObject(mTrackingStatusesFile, "preloadCryptoData - mTrackingStatuses");
}
if (null != trackingStatusesAsVoid) {
try {
mTrackingStatuses = new HashMap<>((Map<String, Integer>) trackingStatusesAsVoid);
} catch (Exception e) {
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mTrackingStatuses " + e.getMessage());
}
}
File outgoingRequestFile;
if (mOutgoingRoomKeyRequestsFileTmp.exists()) {
outgoingRequestFile = mOutgoingRoomKeyRequestsFileTmp;
} else {
outgoingRequestFile = mOutgoingRoomKeyRequestsFile;
}
if (outgoingRequestFile.exists()) {
Object requestsAsVoid = loadObject(outgoingRequestFile, "get outgoing key request");
try {
if (null != requestsAsVoid) {
mOutgoingRoomKeyRequests.putAll((Map<Map<String, String>, OutgoingRoomKeyRequest>) requestsAsVoid);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## preloadCryptoData() : mOutgoingRoomKeyRequests init failed " + e.getMessage());
}
}
if (mOlmSessionsFolder.exists()) {
long t3 = System.currentTimeMillis();
mOlmSessions = new HashMap<>();
String[] olmSessionFiles = mOlmSessionsFolder.list();
if (null != olmSessionFiles) {
// build mOlmSessions for the file system
for (int i = 0; i < olmSessionFiles.length; i++) {
String deviceKey = olmSessionFiles[i];
HashMap<String, OlmSession> olmSessionSubMap = new HashMap<>();
File sessionsDeviceFolder = new File(mOlmSessionsFolder, deviceKey);
String[] sessionIds = sessionsDeviceFolder.list();
if (null != sessionIds) {
for (int j = 0; j < sessionIds.length; j++) {
String sessionId = sessionIds[j];
OlmSession olmSession = (OlmSession) loadObject(new File(sessionsDeviceFolder, sessionId), "load the olmSession " + deviceKey + " " + sessionId);
if (null != olmSession) {
olmSessionSubMap.put(decodeFilename(sessionId), olmSession);
}
}
}
mOlmSessions.put(decodeFilename(deviceKey), olmSessionSubMap);
}
Log.d(LOG_TAG, "## preloadCryptoData() : load " + olmSessionFiles.length + " olmsessions in " + (System.currentTimeMillis() - t3) + " ms");
}
} else {
Object olmSessionsAsVoid;
if (mOlmSessionsFileTmp.exists()) {
olmSessionsAsVoid = loadObject(mOlmSessionsFileTmp, "preloadCryptoData - mOlmSessions - tmp");
} else {
olmSessionsAsVoid = loadObject(mOlmSessionsFile, "preloadCryptoData - mOlmSessions");
}
if (null != olmSessionsAsVoid) {
try {
Map<String, Map<String, OlmSession>> olmSessionMap = (Map<String, Map<String, OlmSession>>) olmSessionsAsVoid;
mOlmSessions = new HashMap<>();
for (String key : olmSessionMap.keySet()) {
mOlmSessions.put(key, new HashMap<>(olmSessionMap.get(key)));
}
// convert to the new format
if (!mOlmSessionsFolder.mkdir()) {
Log.e(LOG_TAG, "Cannot create the folder " + mOlmSessionsFolder);
}
for (String key : olmSessionMap.keySet()) {
Map<String, OlmSession> submap = olmSessionMap.get(key);
File submapFolder = new File(mOlmSessionsFolder, encodeFilename(key));
if (!submapFolder.mkdir()) {
Log.e(LOG_TAG, "Cannot create the folder " + submapFolder);
}
for (String sessionId : submap.keySet()) {
storeObject(submap.get(sessionId), submapFolder, encodeFilename(sessionId), "Convert olmSession " + key + " " + sessionId);
}
}
} catch (Exception e) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mSessionsFile " + e.getMessage());
}
mOlmSessionsFileTmp.delete();
mOlmSessionsFile.delete();
}
}
if (mInboundGroupSessionsFolder.exists()) {
long t4 = System.currentTimeMillis();
mInboundGroupSessions = new HashMap<>();
int count = 0;
String[] keysFolder = mInboundGroupSessionsFolder.list();
if (null != keysFolder) {
for (int i = 0; i < keysFolder.length; i++) {
File keyFolder = new File(mInboundGroupSessionsFolder, keysFolder[i]);
HashMap<String, MXOlmInboundGroupSession2> submap = new HashMap<>();
String[] sessionIds = keyFolder.list();
if (null != sessionIds) {
for (int j = 0; j < sessionIds.length; j++) {
File inboundSessionFile = new File(keyFolder, sessionIds[j]);
try {
Object inboundSessionAsVoid = loadObject(inboundSessionFile, "load inboundsession " + sessionIds[j] + " ");
MXOlmInboundGroupSession2 inboundSession;
if ((null != inboundSessionAsVoid) && (inboundSessionAsVoid instanceof MXOlmInboundGroupSession)) {
inboundSession = new MXOlmInboundGroupSession2((MXOlmInboundGroupSession) inboundSessionAsVoid);
} else {
inboundSession = (MXOlmInboundGroupSession2) inboundSessionAsVoid;
}
if (null != inboundSession) {
submap.put(decodeFilename(sessionIds[j]), inboundSession);
} else {
Log.e(LOG_TAG, "## preloadCryptoData() : delete " + inboundSessionFile);
inboundSessionFile.delete();
mIsCorrupted = false;
}
count++;
} catch (Exception e) {
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mInboundGroupSessions " + e.getMessage());
}
}
}
mInboundGroupSessions.put(decodeFilename(keysFolder[i]), submap);
}
}
Log.d(LOG_TAG, "## preloadCryptoData() : load " + count + " inboundGroupSessions in " + (System.currentTimeMillis() - t4) + " ms");
} else {
Object inboundGroupSessionsAsVoid;
if (mInboundGroupSessionsFileTmp.exists()) {
inboundGroupSessionsAsVoid = loadObject(mInboundGroupSessionsFileTmp, "preloadCryptoData - mInboundGroupSessions - tmp");
} else {
inboundGroupSessionsAsVoid = loadObject(mInboundGroupSessionsFile, "preloadCryptoData - mInboundGroupSessions");
}
if (null != inboundGroupSessionsAsVoid) {
try {
Map<String, Map<String, MXOlmInboundGroupSession2>> inboundGroupSessionsMap = (Map<String, Map<String, MXOlmInboundGroupSession2>>) inboundGroupSessionsAsVoid;
mInboundGroupSessions = new HashMap<>();
for (String key : inboundGroupSessionsMap.keySet()) {
mInboundGroupSessions.put(key, new HashMap<>(inboundGroupSessionsMap.get(key)));
}
} catch (Exception e) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - invalid mInboundGroupSessions " + e.getMessage());
}
if (!mInboundGroupSessionsFolder.mkdirs()) {
Log.e(LOG_TAG, "Cannot create the folder " + mInboundGroupSessionsFolder);
}
// convert to the new format
for (String key : mInboundGroupSessions.keySet()) {
File keyFolder = new File(mInboundGroupSessionsFolder, encodeFilename(key));
if (!keyFolder.mkdirs()) {
Log.e(LOG_TAG, "Cannot create the folder " + keyFolder);
}
Map<String, MXOlmInboundGroupSession2> inboundMaps = mInboundGroupSessions.get(key);
for (String sessionId : inboundMaps.keySet()) {
storeObject(inboundMaps.get(sessionId), keyFolder, encodeFilename(sessionId), "Convert inboundsession");
}
}
}
mInboundGroupSessionsFileTmp.delete();
mInboundGroupSessionsFile.delete();
}
if ((null == mOlmAccount) && (mUsersDevicesInfoMap.getMap().size() > 0)) {
mIsCorrupted = true;
Log.e(LOG_TAG, "## preloadCryptoData() - there is no account but some devices are defined");
}
}
use of org.matrix.olm.OlmSession in project matrix-android-sdk by matrix-org.
the class MXOlmDevice method encryptMessage.
/**
* Encrypt an outgoing message using an existing session.
*
* @param theirDeviceIdentityKey the Curve25519 identity key for the remote device.
* @param sessionId the id of the active session
* @param payloadString the payload to be encrypted and sent
* @return the cipher text
*/
public Map<String, Object> encryptMessage(String theirDeviceIdentityKey, String sessionId, String payloadString) {
HashMap<String, Object> res = null;
OlmMessage olmMessage;
OlmSession olmSession = getSessionForDevice(theirDeviceIdentityKey, sessionId);
if (null != olmSession) {
try {
Log.d(LOG_TAG, "## encryptMessage() : olmSession.sessionIdentifier: " + olmSession.sessionIdentifier());
// Log.d(LOG_TAG, "## encryptMessage() : payloadString: " + payloadString);
olmMessage = olmSession.encryptMessage(payloadString);
mStore.storeSession(olmSession, theirDeviceIdentityKey);
res = new HashMap<>();
res.put("body", olmMessage.mCipherText);
res.put("type", olmMessage.mType);
} catch (Exception e) {
Log.e(LOG_TAG, "## encryptMessage() : failed " + e.getMessage());
}
}
return res;
}
use of org.matrix.olm.OlmSession in project matrix-android-sdk by matrix-org.
the class MXOlmDevice method createInboundSession.
/**
* Generate a new inbound session, given an incoming message.
*
* @param theirDeviceIdentityKey the remote user's Curve25519 identity key.
* @param messageType the message_type field from the received message (must be 0).
* @param ciphertext base64-encoded body from the received message.
* @return {{payload: string, session_id: string}} decrypted payload, andsession id of new session.
*/
public Map<String, String> createInboundSession(String theirDeviceIdentityKey, int messageType, String ciphertext) {
Log.d(LOG_TAG, "## createInboundSession() : theirIdentityKey: " + theirDeviceIdentityKey);
OlmSession olmSession = null;
try {
try {
olmSession = new OlmSession();
olmSession.initInboundSessionFrom(mOlmAccount, theirDeviceIdentityKey, ciphertext);
} catch (Exception e) {
Log.d(LOG_TAG, "## createInboundSession() : the session creation failed " + e.getMessage());
return null;
}
Log.d(LOG_TAG, "## createInboundSession() : sessionId: " + olmSession.sessionIdentifier());
try {
mOlmAccount.removeOneTimeKeys(olmSession);
mStore.storeAccount(mOlmAccount);
} catch (Exception e) {
Log.e(LOG_TAG, "## createInboundSession() : removeOneTimeKeys failed " + e.getMessage());
}
Log.d(LOG_TAG, "## createInboundSession() : ciphertext: " + ciphertext);
try {
Log.d(LOG_TAG, "## createInboundSession() :ciphertext: SHA256:" + mOlmUtility.sha256(URLEncoder.encode(ciphertext, "utf-8")));
} catch (Exception e) {
Log.e(LOG_TAG, "## createInboundSession() :ciphertext: cannot encode ciphertext");
}
OlmMessage olmMessage = new OlmMessage();
olmMessage.mCipherText = ciphertext;
olmMessage.mType = messageType;
String payloadString = null;
try {
payloadString = olmSession.decryptMessage(olmMessage);
mStore.storeSession(olmSession, theirDeviceIdentityKey);
} catch (Exception e) {
Log.d(LOG_TAG, "## createInboundSession() : decryptMessage failed " + e.getMessage());
}
HashMap<String, String> res = new HashMap<>();
if (!TextUtils.isEmpty(payloadString)) {
res.put("payload", payloadString);
}
String sessionIdentifier = olmSession.sessionIdentifier();
if (!TextUtils.isEmpty(sessionIdentifier)) {
res.put("session_id", sessionIdentifier);
}
return res;
} catch (Exception e) {
Log.e(LOG_TAG, "## createInboundSession() : OlmSession creation failed " + e.getMessage());
if (null != olmSession) {
olmSession.releaseSession();
}
}
return null;
}
Aggregations