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();
}
});
}
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;
}
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);
}
}
Aggregations