Search in sources :

Example 21 with MXDeviceInfo

use of org.matrix.androidsdk.crypto.data.MXDeviceInfo in project matrix-android-sdk by matrix-org.

the class MXMegolmDecryption method shareKeysWithDevice.

@Override
public void shareKeysWithDevice(final IncomingRoomKeyRequest request) {
    // sanity checks
    if ((null == request) || (null == request.mRequestBody)) {
        return;
    }
    final String userId = request.mUserId;
    mSession.getCrypto().getDeviceList().downloadKeys(Arrays.asList(userId), false, new ApiCallback<MXUsersDevicesMap<MXDeviceInfo>>() {

        @Override
        public void onSuccess(MXUsersDevicesMap<MXDeviceInfo> devicesMap) {
            final String deviceId = request.mDeviceId;
            final MXDeviceInfo deviceInfo = mSession.getCrypto().mCryptoStore.getUserDevice(deviceId, userId);
            if (null != deviceInfo) {
                final RoomKeyRequestBody body = request.mRequestBody;
                HashMap<String, ArrayList<MXDeviceInfo>> devicesByUser = new HashMap<>();
                devicesByUser.put(userId, new ArrayList<>(Arrays.asList(deviceInfo)));
                mSession.getCrypto().ensureOlmSessionsForDevices(devicesByUser, new ApiCallback<MXUsersDevicesMap<MXOlmSessionResult>>() {

                    @Override
                    public void onSuccess(MXUsersDevicesMap<MXOlmSessionResult> map) {
                        MXOlmSessionResult olmSessionResult = map.getObject(deviceId, userId);
                        if ((null == olmSessionResult) || (null == olmSessionResult.mSessionId)) {
                            // so just skip it.
                            return;
                        }
                        Log.d(LOG_TAG, "## shareKeysWithDevice() : sharing keys for session " + body.sender_key + "|" + body.session_id + " with device " + userId + ":" + deviceId);
                        MXOlmInboundGroupSession2 inboundGroupSession = mSession.getCrypto().getOlmDevice().getInboundGroupSession(body.session_id, body.sender_key, body.room_id);
                        Map<String, Object> payloadJson = new HashMap<>();
                        payloadJson.put("type", Event.EVENT_TYPE_FORWARDED_ROOM_KEY);
                        payloadJson.put("content", inboundGroupSession.exportKeys());
                        Map<String, Object> encodedPayload = mSession.getCrypto().encryptMessage(payloadJson, Arrays.asList(deviceInfo));
                        MXUsersDevicesMap<Map<String, Object>> sendToDeviceMap = new MXUsersDevicesMap<>();
                        sendToDeviceMap.setObject(encodedPayload, userId, deviceId);
                        Log.d(LOG_TAG, "## shareKeysWithDevice() : sending to " + userId + ":" + deviceId);
                        mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_MESSAGE_ENCRYPTED, sendToDeviceMap, new ApiCallback<Void>() {

                            @Override
                            public void onSuccess(Void info) {
                                Log.d(LOG_TAG, "## shareKeysWithDevice() : sent to " + userId + ":" + deviceId);
                            }

                            @Override
                            public void onNetworkError(Exception e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }

                            @Override
                            public void onMatrixError(MatrixError e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }

                            @Override
                            public void onUnexpectedError(Exception e) {
                                Log.e(LOG_TAG, "## shareKeysWithDevice() : sendToDevice " + userId + ":" + deviceId + " failed " + e.getMessage());
                            }
                        });
                    }

                    @Override
                    public void onNetworkError(Exception e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }

                    @Override
                    public void onMatrixError(MatrixError e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }

                    @Override
                    public void onUnexpectedError(Exception e) {
                        Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " failed " + e.getMessage());
                    }
                });
            } else {
                Log.e(LOG_TAG, "## shareKeysWithDevice() : ensureOlmSessionsForDevices " + userId + ":" + deviceId + " not found");
            }
        }

        @Override
        public void onNetworkError(Exception e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "## shareKeysWithDevice() : downloadKeys " + userId + " failed " + e.getMessage());
        }
    });
}
Also used : HashMap(java.util.HashMap) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) MXOlmSessionResult(org.matrix.androidsdk.crypto.data.MXOlmSessionResult) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) RoomKeyRequestBody(org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody) MXOlmInboundGroupSession2(org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) HashMap(java.util.HashMap) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) Map(java.util.Map)

Example 22 with MXDeviceInfo

use of org.matrix.androidsdk.crypto.data.MXDeviceInfo in project matrix-android-sdk by matrix-org.

the class MXMegolmEncryption method encryptEventContent.

@Override
public void encryptEventContent(final JsonElement eventContent, final String eventType, final List<String> userIds, final ApiCallback<JsonElement> callback) {
    // Queue the encryption request
    // It will be processed when everything is set up
    MXQueuedEncryption queuedEncryption = new MXQueuedEncryption();
    queuedEncryption.mEventContent = eventContent;
    queuedEncryption.mEventType = eventType;
    queuedEncryption.mApiCallback = callback;
    synchronized (mPendingEncryptions) {
        mPendingEncryptions.add(queuedEncryption);
    }
    final long t0 = System.currentTimeMillis();
    Log.d(LOG_TAG, "## encryptEventContent () starts");
    getDevicesInRoom(userIds, new ApiCallback<MXUsersDevicesMap<MXDeviceInfo>>() {

        /**
         * A network error has been received while encrypting
         * @param e the exception
         */
        private void dispatchNetworkError(Exception e) {
            Log.e(LOG_TAG, "## encryptEventContent() : onNetworkError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onNetworkError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        /**
         * A matrix error has been received while encrypting
         * @param e the exception
         */
        private void dispatchMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "## encryptEventContent() : onMatrixError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onMatrixError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        /**
         * An unexpected error has been received while encrypting
         * @param e the exception
         */
        private void dispatchUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "## onUnexpectedError() : onMatrixError " + e.getMessage());
            List<MXQueuedEncryption> queuedEncryptions = getPendingEncryptions();
            for (MXQueuedEncryption queuedEncryption : queuedEncryptions) {
                queuedEncryption.mApiCallback.onUnexpectedError(e);
            }
            synchronized (mPendingEncryptions) {
                mPendingEncryptions.removeAll(queuedEncryptions);
            }
        }

        @Override
        public void onSuccess(MXUsersDevicesMap<MXDeviceInfo> devicesInRoom) {
            ensureOutboundSession(devicesInRoom, new ApiCallback<MXOutboundSessionInfo>() {

                @Override
                public void onSuccess(final MXOutboundSessionInfo session) {
                    mCrypto.getEncryptingThreadHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            Log.d(LOG_TAG, "## encryptEventContent () processPendingEncryptions after " + (System.currentTimeMillis() - t0) + "ms");
                            processPendingEncryptions(session);
                        }
                    });
                }

                @Override
                public void onNetworkError(Exception e) {
                    dispatchNetworkError(e);
                }

                @Override
                public void onMatrixError(MatrixError e) {
                    dispatchMatrixError(e);
                }

                @Override
                public void onUnexpectedError(Exception e) {
                    dispatchUnexpectedError(e);
                }
            });
        }

        @Override
        public void onNetworkError(Exception e) {
            dispatchNetworkError(e);
        }

        @Override
        public void onMatrixError(MatrixError e) {
            dispatchMatrixError(e);
        }

        @Override
        public void onUnexpectedError(Exception e) {
            dispatchUnexpectedError(e);
        }
    });
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) MXQueuedEncryption(org.matrix.androidsdk.crypto.data.MXQueuedEncryption) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) ArrayList(java.util.ArrayList) List(java.util.List) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Example 23 with MXDeviceInfo

use of org.matrix.androidsdk.crypto.data.MXDeviceInfo in project matrix-android-sdk by matrix-org.

the class MXMegolmEncryption method shareUserDevicesKey.

/**
 * Share the device keys of a an user
 *
 * @param session       the session info
 * @param devicesByUser the devices map
 * @param callback      the asynchronous callback
 */
private void shareUserDevicesKey(final MXOutboundSessionInfo session, final HashMap<String, ArrayList<MXDeviceInfo>> devicesByUser, final ApiCallback<Void> callback) {
    final String sessionKey = mCrypto.getOlmDevice().getSessionKey(session.mSessionId);
    final int chainIndex = mCrypto.getOlmDevice().getMessageIndex(session.mSessionId);
    HashMap<String, Object> submap = new HashMap<>();
    submap.put("algorithm", MXCryptoAlgorithms.MXCRYPTO_ALGORITHM_MEGOLM);
    submap.put("room_id", mRoomId);
    submap.put("session_id", session.mSessionId);
    submap.put("session_key", sessionKey);
    submap.put("chain_index", chainIndex);
    final HashMap<String, Object> payload = new HashMap<>();
    payload.put("type", Event.EVENT_TYPE_ROOM_KEY);
    payload.put("content", submap);
    final long t0 = System.currentTimeMillis();
    Log.d(LOG_TAG, "## shareUserDevicesKey() : starts");
    mCrypto.ensureOlmSessionsForDevices(devicesByUser, new ApiCallback<MXUsersDevicesMap<MXOlmSessionResult>>() {

        @Override
        public void onSuccess(final MXUsersDevicesMap<MXOlmSessionResult> results) {
            mCrypto.getEncryptingThreadHandler().post(new Runnable() {

                @Override
                public void run() {
                    Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after " + (System.currentTimeMillis() - t0) + " ms");
                    MXUsersDevicesMap<Map<String, Object>> contentMap = new MXUsersDevicesMap<>();
                    boolean haveTargets = false;
                    List<String> userIds = results.getUserIds();
                    for (String userId : userIds) {
                        ArrayList<MXDeviceInfo> devicesToShareWith = devicesByUser.get(userId);
                        for (MXDeviceInfo deviceInfo : devicesToShareWith) {
                            String deviceID = deviceInfo.deviceId;
                            MXOlmSessionResult sessionResult = results.getObject(deviceID, userId);
                            if ((null == sessionResult) || (null == sessionResult.mSessionId)) {
                                // so just skip it.
                                continue;
                            }
                            Log.d(LOG_TAG, "## shareUserDevicesKey() : Sharing keys with device " + userId + ":" + deviceID);
                            // noinspection ArraysAsListWithZeroOrOneArgument,ArraysAsListWithZeroOrOneArgument
                            contentMap.setObject(mCrypto.encryptMessage(payload, Arrays.asList(sessionResult.mDevice)), userId, deviceID);
                            haveTargets = true;
                        }
                    }
                    if (haveTargets && !mCrypto.hasBeenReleased()) {
                        final long t0 = System.currentTimeMillis();
                        Log.d(LOG_TAG, "## shareUserDevicesKey() : has target");
                        mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_MESSAGE_ENCRYPTED, contentMap, new ApiCallback<Void>() {

                            @Override
                            public void onSuccess(Void info) {
                                mCrypto.getEncryptingThreadHandler().post(new Runnable() {

                                    @Override
                                    public void run() {
                                        Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice succeeds after " + (System.currentTimeMillis() - t0) + " ms");
                                        // for dead devices on every message.
                                        for (String userId : devicesByUser.keySet()) {
                                            List<MXDeviceInfo> devicesToShareWith = devicesByUser.get(userId);
                                            for (MXDeviceInfo deviceInfo : devicesToShareWith) {
                                                session.mSharedWithDevices.setObject(chainIndex, userId, deviceInfo.deviceId);
                                            }
                                        }
                                        mCrypto.getUIHandler().post(new Runnable() {

                                            @Override
                                            public void run() {
                                                if (null != callback) {
                                                    callback.onSuccess(null);
                                                }
                                            }
                                        });
                                    }
                                });
                            }

                            @Override
                            public void onNetworkError(Exception e) {
                                Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onNetworkError " + e.getMessage());
                                if (null != callback) {
                                    callback.onNetworkError(e);
                                }
                            }

                            @Override
                            public void onMatrixError(MatrixError e) {
                                Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onMatrixError " + e.getMessage());
                                if (null != callback) {
                                    callback.onMatrixError(e);
                                }
                            }

                            @Override
                            public void onUnexpectedError(Exception e) {
                                Log.d(LOG_TAG, "## shareUserDevicesKey() : sendToDevice onUnexpectedError " + e.getMessage());
                                if (null != callback) {
                                    callback.onUnexpectedError(e);
                                }
                            }
                        });
                    } else {
                        Log.d(LOG_TAG, "## shareUserDevicesKey() : no need to sharekey");
                        if (null != callback) {
                            mCrypto.getUIHandler().post(new Runnable() {

                                @Override
                                public void run() {
                                    callback.onSuccess(null);
                                }
                            });
                        }
                    }
                }
            });
        }

        @Override
        public void onNetworkError(Exception e) {
            Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
            if (null != callback) {
                callback.onNetworkError(e);
            }
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
            if (null != callback) {
                callback.onMatrixError(e);
            }
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.d(LOG_TAG, "## shareUserDevicesKey() : ensureOlmSessionsForDevices failed " + e.getMessage());
            if (null != callback) {
                callback.onUnexpectedError(e);
            }
        }
    });
}
Also used : HashMap(java.util.HashMap) MXOlmSessionResult(org.matrix.androidsdk.crypto.data.MXOlmSessionResult) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) HashMap(java.util.HashMap) MXUsersDevicesMap(org.matrix.androidsdk.crypto.data.MXUsersDevicesMap) Map(java.util.Map)

Example 24 with MXDeviceInfo

use of org.matrix.androidsdk.crypto.data.MXDeviceInfo in project matrix-android-sdk by matrix-org.

the class MXFileCryptoStore method loadUserDevices.

/**
 * Load the user devices from the filesystem
 * if it is not yet done.
 *
 * @param userId the user id.
 */
private void loadUserDevices(String userId) {
    if (!TextUtils.isEmpty(userId)) {
        boolean alreadyDone;
        synchronized (mUsersDevicesInfoMapLock) {
            alreadyDone = mUsersDevicesInfoMap.getMap().containsKey(userId);
        }
        if (!alreadyDone) {
            File devicesFile = new File(mDevicesFolder, userId);
            if (devicesFile.exists()) {
                long t0 = System.currentTimeMillis();
                // clear the corrupted flag
                mIsCorrupted = false;
                Object devicesMapAsVoid = loadObject(devicesFile, "load devices of " + userId);
                if (null != devicesMapAsVoid) {
                    try {
                        synchronized (mUsersDevicesInfoMapLock) {
                            mUsersDevicesInfoMap.setObjects((Map<String, MXDeviceInfo>) devicesMapAsVoid, userId);
                        }
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "## loadUserDevices : mUsersDevicesInfoMap.setObjects failed " + e.getMessage());
                        mIsCorrupted = true;
                    }
                }
                // something was wrong (loadObject set this boolean)
                if (mIsCorrupted) {
                    Log.e(LOG_TAG, "## loadUserDevices : failed to load the device of " + userId);
                    // delete the corrupted file
                    devicesFile.delete();
                    // it is not a blocking thing
                    mIsCorrupted = false;
                } else {
                    Log.d(LOG_TAG, "## loadUserDevices : Load the devices of " + userId + " in " + (System.currentTimeMillis() - t0) + "ms");
                }
            }
        }
    }
}
Also used : MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) File(java.io.File)

Example 25 with MXDeviceInfo

use of org.matrix.androidsdk.crypto.data.MXDeviceInfo in project matrix-android-sdk by matrix-org.

the class MXFileCryptoStore method getUserDevice.

@Override
public MXDeviceInfo getUserDevice(String deviceId, String userId) {
    if (!mIsReady) {
        Log.e(LOG_TAG, "## getUserDevice() : the store is not ready");
        return null;
    }
    MXDeviceInfo deviceInfo;
    loadUserDevices(userId);
    synchronized (mUsersDevicesInfoMapLock) {
        deviceInfo = mUsersDevicesInfoMap.getObject(deviceId, userId);
    }
    return deviceInfo;
}
Also used : MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo)

Aggregations

MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)25 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)17 HashMap (java.util.HashMap)15 MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)13 ArrayList (java.util.ArrayList)12 CountDownLatch (java.util.concurrent.CountDownLatch)10 JsonObject (com.google.gson.JsonObject)8 Test (org.junit.Test)8 Context (android.content.Context)7 Room (org.matrix.androidsdk.data.Room)6 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)6 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)4 MXOlmSessionResult (org.matrix.androidsdk.crypto.data.MXOlmSessionResult)4 Uri (android.net.Uri)3 List (java.util.List)3 RoomState (org.matrix.androidsdk.data.RoomState)3 IMXStore (org.matrix.androidsdk.data.store.IMXStore)3 MXFileStore (org.matrix.androidsdk.data.store.MXFileStore)3 MXStoreListener (org.matrix.androidsdk.data.store.MXStoreListener)3 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)3