Search in sources :

Example 6 with MXCryptoError

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

the class MXCallsManager method checkPendingIncomingCalls.

/**
 * check if there is a pending incoming call
 */
public void checkPendingIncomingCalls() {
    // Log.d(LOG_TAG, "checkPendingIncomingCalls");
    mUIThreadHandler.post(new Runnable() {

        @Override
        public void run() {
            if (mxPendingIncomingCallId.size() > 0) {
                for (String callId : mxPendingIncomingCallId) {
                    final IMXCall call = getCallWithCallId(callId);
                    if (null != call) {
                        final Room room = call.getRoom();
                        // If there are some unknown devices, the answer event would not be encrypted.
                        if ((null != room) && room.isEncrypted() && mSession.getCrypto().warnOnUnknownDevices() && (room.getJoinedMembers().size() == 2)) {
                            // test if the encrypted events are sent only to the verified devices (any room)
                            mSession.getCrypto().getGlobalBlacklistUnverifiedDevices(new SimpleApiCallback<Boolean>() {

                                @Override
                                public void onSuccess(Boolean sendToVerifiedDevicesOnly) {
                                    if (sendToVerifiedDevicesOnly) {
                                        dispatchOnIncomingCall(call, null);
                                    } else {
                                        // test if the encrypted events are sent only to the verified devices (only this room)
                                        mSession.getCrypto().isRoomBlacklistUnverifiedDevices(room.getRoomId(), new SimpleApiCallback<Boolean>() {

                                            @Override
                                            public void onSuccess(Boolean sendToVerifiedDevicesOnly) {
                                                if (sendToVerifiedDevicesOnly) {
                                                    dispatchOnIncomingCall(call, null);
                                                } else {
                                                    List<RoomMember> members = new ArrayList<>(room.getJoinedMembers());
                                                    String userId1 = members.get(0).getUserId();
                                                    String userId2 = members.get(1).getUserId();
                                                    Log.d(LOG_TAG, "## checkPendingIncomingCalls() : check the unknown devices");
                                                    // 
                                                    mSession.getCrypto().checkUnknownDevices(Arrays.asList(userId1, userId2), new ApiCallback<Void>() {

                                                        @Override
                                                        public void onSuccess(Void anything) {
                                                            Log.d(LOG_TAG, "## checkPendingIncomingCalls() : no unknown device");
                                                            dispatchOnIncomingCall(call, null);
                                                        }

                                                        @Override
                                                        public void onNetworkError(Exception e) {
                                                            Log.e(LOG_TAG, "## checkPendingIncomingCalls() : checkUnknownDevices failed " + e.getMessage());
                                                            dispatchOnIncomingCall(call, null);
                                                        }

                                                        @Override
                                                        public void onMatrixError(MatrixError e) {
                                                            MXUsersDevicesMap<MXDeviceInfo> unknownDevices = null;
                                                            if (e instanceof MXCryptoError) {
                                                                MXCryptoError cryptoError = (MXCryptoError) e;
                                                                if (MXCryptoError.UNKNOWN_DEVICES_CODE.equals(cryptoError.errcode)) {
                                                                    unknownDevices = (MXUsersDevicesMap<MXDeviceInfo>) cryptoError.mExceptionData;
                                                                }
                                                            }
                                                            if (null != unknownDevices) {
                                                                Log.d(LOG_TAG, "## checkPendingIncomingCalls() : checkUnknownDevices found some unknown devices");
                                                            } else {
                                                                Log.e(LOG_TAG, "## checkPendingIncomingCalls() : checkUnknownDevices failed " + e.getMessage());
                                                            }
                                                            dispatchOnIncomingCall(call, unknownDevices);
                                                        }

                                                        @Override
                                                        public void onUnexpectedError(Exception e) {
                                                            Log.e(LOG_TAG, "## checkPendingIncomingCalls() : checkUnknownDevices failed " + e.getMessage());
                                                            dispatchOnIncomingCall(call, null);
                                                        }
                                                    });
                                                }
                                            }
                                        });
                                    }
                                }
                            });
                        } else {
                            dispatchOnIncomingCall(call, null);
                        }
                    }
                }
            }
            mxPendingIncomingCallId.clear();
        }
    });
}
Also used : SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) MXDeviceInfo(org.matrix.androidsdk.crypto.data.MXDeviceInfo) ArrayList(java.util.ArrayList) List(java.util.List) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) Room(org.matrix.androidsdk.data.Room) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Example 7 with MXCryptoError

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

the class MXOlmDecryption method decryptEvent.

@Override
public MXEventDecryptionResult decryptEvent(Event event, String timeline) throws MXDecryptionException {
    // sanity check
    if (null == event) {
        Log.e(LOG_TAG, "## decryptEvent() : null event");
        return null;
    }
    OlmEventContent olmEventContent = JsonUtils.toOlmEventContent(event.getWireContent().getAsJsonObject());
    String deviceKey = olmEventContent.sender_key;
    Map<String, Object> ciphertext = olmEventContent.ciphertext;
    if (null == ciphertext) {
        Log.e(LOG_TAG, "## decryptEvent() : missing cipher text");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.MISSING_CIPHER_TEXT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON));
    }
    if (!ciphertext.containsKey(mOlmDevice.getDeviceCurve25519Key())) {
        Log.e(LOG_TAG, "## decryptEvent() : our device " + mOlmDevice.getDeviceCurve25519Key() + " is not included in recipients. Event " + event.getContentAsJsonObject());
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.NOT_INCLUDE_IN_RECIPIENTS_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.NOT_INCLUDED_IN_RECIPIENT_REASON));
    }
    // The message for myUser
    Map<String, Object> message = (Map<String, Object>) ciphertext.get(mOlmDevice.getDeviceCurve25519Key());
    String payloadString = decryptMessage(message, deviceKey);
    if (null == payloadString) {
        Log.e(LOG_TAG, "## decryptEvent() Failed to decrypt Olm event (id= " + event.eventId + " ) from " + deviceKey);
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON));
    }
    JsonElement payload = new JsonParser().parse(JsonUtils.convertFromUTF8(payloadString));
    if (null == payload) {
        Log.e(LOG_TAG, "## decryptEvent failed : null payload");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON));
    }
    OlmPayloadContent olmPayloadContent = JsonUtils.toOlmPayloadContent(payload);
    if (TextUtils.isEmpty(olmPayloadContent.recipient)) {
        String reason = String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient");
        Log.e(LOG_TAG, "## decryptEvent() : " + reason);
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, reason));
    }
    if (!TextUtils.equals(olmPayloadContent.recipient, mSession.getMyUserId())) {
        Log.e(LOG_TAG, "## decryptEvent() : Event " + event.eventId + ": Intended recipient " + olmPayloadContent.recipient + " does not match our id " + mSession.getMyUserId());
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.BAD_RECIPIENT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)));
    }
    if (null == olmPayloadContent.recipient_keys) {
        Log.e(LOG_TAG, "## decryptEvent() : Olm event (id=" + event.eventId + ") contains no " + "'recipient_keys' property; cannot prevent unknown-key attack");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")));
    }
    String ed25519 = olmPayloadContent.recipient_keys.get("ed25519");
    if (!TextUtils.equals(ed25519, mOlmDevice.getDeviceEd25519Key())) {
        Log.e(LOG_TAG, "## decryptEvent() : Event " + event.eventId + ": Intended recipient ed25519 key " + ed25519 + " did not match ours");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.BAD_RECIPIENT_KEY_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_RECIPIENT_KEY_REASON));
    }
    if (TextUtils.isEmpty(olmPayloadContent.sender)) {
        Log.e(LOG_TAG, "## decryptEvent() : Olm event (id=" + event.eventId + ") contains no " + "'sender' property; cannot prevent unknown-key attack");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.MISSING_PROPERTY_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")));
    }
    if (!TextUtils.equals(olmPayloadContent.sender, event.getSender())) {
        Log.e(LOG_TAG, "Event " + event.eventId + ": original sender " + olmPayloadContent.sender + " does not match reported sender " + event.getSender());
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.FORWARDED_MESSAGE_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)));
    }
    if (!TextUtils.equals(olmPayloadContent.room_id, event.roomId)) {
        Log.e(LOG_TAG, "## decryptEvent() : Event " + event.eventId + ": original room " + olmPayloadContent.room_id + " does not match reported room " + event.roomId);
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.BAD_ROOM_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.room_id)));
    }
    if (null == olmPayloadContent.keys) {
        Log.e(LOG_TAG, "## decryptEvent failed : null keys");
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON));
    }
    MXEventDecryptionResult result = new MXEventDecryptionResult();
    result.mClearEvent = payload;
    result.mSenderCurve25519Key = deviceKey;
    result.mClaimedEd25519Key = olmPayloadContent.keys.get("ed25519");
    return result;
}
Also used : MXEventDecryptionResult(org.matrix.androidsdk.crypto.MXEventDecryptionResult) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) JsonElement(com.google.gson.JsonElement) OlmPayloadContent(org.matrix.androidsdk.rest.model.crypto.OlmPayloadContent) OlmEventContent(org.matrix.androidsdk.rest.model.crypto.OlmEventContent) Map(java.util.Map) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError) JsonParser(com.google.gson.JsonParser)

Example 8 with MXCryptoError

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

the class MatrixMessageListFragment method add.

/**
 * Add a media item in the room.
 */
private void add(final RoomMediaMessage roomMediaMessage) {
    MessageRow messageRow = addMessageRow(roomMediaMessage);
    // add sanity check
    if (null == messageRow) {
        return;
    }
    final Event event = messageRow.getEvent();
    if (!event.isUndeliverable()) {
        ApiCallback<Void> callback = new ApiCallback<Void>() {

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

                    @Override
                    public void run() {
                        onMessageSendingSucceeded(event);
                    }
                });
            }

            private void commonFailure(final Event event) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        Activity activity = getActivity();
                        if (null != activity) {
                            // display the error message only if the message cannot be resent
                            if ((null != event.unsentException) && (event.isUndeliverable())) {
                                if ((event.unsentException instanceof RetrofitError) && ((RetrofitError) event.unsentException).isNetworkError()) {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + getActivity().getString(R.string.network_error), Toast.LENGTH_LONG).show();
                                } else {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + event.unsentException.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                                }
                            } else if (null != event.unsentMatrixError) {
                                String localised = (event.unsentMatrixError instanceof MXCryptoError) ? ((MXCryptoError) event.unsentMatrixError).getDetailedErrorDescription() : event.unsentMatrixError.getLocalizedMessage();
                                Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + localised, Toast.LENGTH_LONG).show();
                            }
                            mAdapter.notifyDataSetChanged();
                            onMessageSendingFailed(event);
                        }
                    }
                });
            }

            @Override
            public void onNetworkError(final Exception e) {
                commonFailure(event);
            }

            @Override
            public void onMatrixError(final MatrixError e) {
                // do not display toast if the sending failed because of unknown deviced (e2e issue)
                if (event.mSentState == Event.SentState.FAILED_UNKNOWN_DEVICES) {
                    getUiHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                            onUnknownDevices(event, (MXCryptoError) e);
                        }
                    });
                } else {
                    commonFailure(event);
                }
            }

            @Override
            public void onUnexpectedError(final Exception e) {
                commonFailure(event);
            }
        };
        roomMediaMessage.setEventSendingCallback(callback);
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) Activity(android.app.Activity) MessageRow(org.matrix.androidsdk.adapters.MessageRow) MotionEvent(android.view.MotionEvent) Event(org.matrix.androidsdk.rest.model.Event) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) RetrofitError(retrofit.RetrofitError) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Aggregations

MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)8 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)5 MXDeviceInfo (org.matrix.androidsdk.crypto.data.MXDeviceInfo)4 JsonObject (com.google.gson.JsonObject)3 MXUsersDevicesMap (org.matrix.androidsdk.crypto.data.MXUsersDevicesMap)3 Room (org.matrix.androidsdk.data.Room)3 Event (org.matrix.androidsdk.rest.model.Event)3 Context (android.content.Context)2 JsonElement (com.google.gson.JsonElement)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Test (org.junit.Test)2 MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)2 MXEventDecryptionResult (org.matrix.androidsdk.crypto.MXEventDecryptionResult)2 RoomState (org.matrix.androidsdk.data.RoomState)2 MXEventListener (org.matrix.androidsdk.listeners.MXEventListener)2 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)2 SimpleApiCallback (org.matrix.androidsdk.rest.callback.SimpleApiCallback)2 Activity (android.app.Activity)1