Search in sources :

Example 1 with RoomKeyRequestBody

use of org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody in project matrix-android-sdk by matrix-org.

the class MXCrypto method processReceivedRoomKeyRequests.

/**
 * Process any m.room_key_request events which were queued up during the
 * current sync.
 */
private void processReceivedRoomKeyRequests() {
    List<IncomingRoomKeyRequest> receivedRoomKeyRequests = null;
    synchronized (mReceivedRoomKeyRequests) {
        if (!mReceivedRoomKeyRequests.isEmpty()) {
            receivedRoomKeyRequests = new ArrayList(mReceivedRoomKeyRequests);
            mReceivedRoomKeyRequests.clear();
        }
    }
    if (null != receivedRoomKeyRequests) {
        for (final IncomingRoomKeyRequest request : receivedRoomKeyRequests) {
            String userId = request.mUserId;
            String deviceId = request.mDeviceId;
            RoomKeyRequestBody body = request.mRequestBody;
            String roomId = body.room_id;
            String alg = body.algorithm;
            Log.d(LOG_TAG, "m.room_key_request from " + userId + ":" + deviceId + " for " + roomId + " / " + body.session_id + " id " + request.mRequestId);
            if (!TextUtils.equals(mSession.getMyUserId(), userId)) {
                // TODO: determine if we sent this device the keys already: in
                Log.e(LOG_TAG, "## processReceivedRoomKeyRequests() : Ignoring room key request from other user for now");
                return;
            }
            // todo: should we queue up requests we don't yet have keys for,
            // in case they turn up later?
            // if we don't have a decryptor for this room/alg, we don't have
            // the keys for the requested events, and can drop the requests.
            final IMXDecrypting decryptor = getRoomDecryptor(roomId, alg);
            if (null == decryptor) {
                Log.e(LOG_TAG, "## processReceivedRoomKeyRequests() : room key request for unknown " + alg + " in room " + roomId);
                continue;
            }
            if (!decryptor.hasKeysForKeyRequest(request)) {
                Log.e(LOG_TAG, "## processReceivedRoomKeyRequests() : room key request for unknown session " + body.session_id);
                mCryptoStore.deleteIncomingRoomKeyRequest(request);
                continue;
            }
            if (TextUtils.equals(deviceId, getMyDevice().deviceId) && TextUtils.equals(mSession.getMyUserId(), userId)) {
                Log.d(LOG_TAG, "## processReceivedRoomKeyRequests() : oneself device - ignored");
                mCryptoStore.deleteIncomingRoomKeyRequest(request);
                continue;
            }
            request.mShare = new Runnable() {

                @Override
                public void run() {
                    getEncryptingThreadHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            decryptor.shareKeysWithDevice(request);
                            mCryptoStore.deleteIncomingRoomKeyRequest(request);
                        }
                    });
                }
            };
            // if the device is is verified already, share the keys
            MXDeviceInfo device = mCryptoStore.getUserDevice(deviceId, userId);
            if (null != device) {
                if (device.isVerified()) {
                    Log.d(LOG_TAG, "## processReceivedRoomKeyRequests() : device is already verified: sharing keys");
                    mCryptoStore.deleteIncomingRoomKeyRequest(request);
                    request.mShare.run();
                    continue;
                }
                if (device.isBlocked()) {
                    Log.d(LOG_TAG, "## processReceivedRoomKeyRequests() : device is blocked -> ignored");
                    mCryptoStore.deleteIncomingRoomKeyRequest(request);
                    continue;
                }
            }
            mCryptoStore.storeIncomingRoomKeyRequest(request);
            onRoomKeyRequest(request);
        }
    }
    List<IncomingRoomKeyRequestCancellation> receivedRoomKeyRequestCancellations = null;
    synchronized (mReceivedRoomKeyRequestCancellations) {
        if (!mReceivedRoomKeyRequestCancellations.isEmpty()) {
            receivedRoomKeyRequestCancellations = new ArrayList(mReceivedRoomKeyRequestCancellations);
            mReceivedRoomKeyRequestCancellations.clear();
        }
    }
    if (null != receivedRoomKeyRequestCancellations) {
        for (IncomingRoomKeyRequestCancellation request : receivedRoomKeyRequestCancellations) {
            Log.d(LOG_TAG, "## ## processReceivedRoomKeyRequests() : m.room_key_request cancellation for " + request.mUserId + ":" + request.mDeviceId + " id " + request.mRequestId);
            // we should probably only notify the app of cancellations we told it
            // about, but we don't currently have a record of that, so we just pass
            // everything through.
            onRoomKeyRequestCancellation(request);
            mCryptoStore.deleteIncomingRoomKeyRequest(request);
        }
    }
}
Also used : RoomKeyRequestBody(org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) IMXDecrypting(org.matrix.androidsdk.crypto.algorithms.IMXDecrypting)

Example 2 with RoomKeyRequestBody

use of org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody 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)

Aggregations

ArrayList (java.util.ArrayList)2 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)2 RoomKeyRequestBody (org.matrix.androidsdk.rest.model.crypto.RoomKeyRequestBody)2 HashMap (java.util.HashMap)1 Map (java.util.Map)1 MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)1 IMXDecrypting (org.matrix.androidsdk.crypto.algorithms.IMXDecrypting)1 MXOlmInboundGroupSession2 (org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2)1 MXOlmSessionResult (org.matrix.androidsdk.crypto.data.MXOlmSessionResult)1 MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)1 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)1 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)1