Search in sources :

Example 1 with MXDecryptionException

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

the class MXMegolmDecryption method onNewSession.

/**
 * Check if the some messages can be decrypted with a new session
 *
 * @param senderKey the session sender key
 * @param sessionId the session id
 */
public void onNewSession(String senderKey, String sessionId) {
    String k = senderKey + "|" + sessionId;
    HashMap<String, ArrayList<Event>> pending = mPendingEvents.get(k);
    if (null != pending) {
        // Have another go at decrypting events sent with this session.
        mPendingEvents.remove(k);
        Set<String> timelineIds = pending.keySet();
        for (String timelineId : timelineIds) {
            ArrayList<Event> events = pending.get(timelineId);
            for (Event event : events) {
                MXEventDecryptionResult result = null;
                try {
                    result = decryptEvent(event, TextUtils.isEmpty(timelineId) ? null : timelineId);
                } catch (MXDecryptionException e) {
                    Log.e(LOG_TAG, "## onNewSession() : Still can't decrypt " + event.eventId + ". Error " + e.getMessage());
                    event.setCryptoError(e.getCryptoError());
                }
                if (null != result) {
                    final Event fEvent = event;
                    final MXEventDecryptionResult fResut = result;
                    mSession.getCrypto().getUIHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            fEvent.setClearData(fResut);
                            mSession.getDataHandler().onEventDecrypted(fEvent);
                        }
                    });
                    Log.d(LOG_TAG, "## onNewSession() : successful re-decryption of " + event.eventId);
                }
            }
        }
    }
}
Also used : MXEventDecryptionResult(org.matrix.androidsdk.crypto.MXEventDecryptionResult) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) ArrayList(java.util.ArrayList) Event(org.matrix.androidsdk.rest.model.Event)

Example 2 with MXDecryptionException

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

the class MXMegolmDecryption method decryptEvent.

public MXEventDecryptionResult decryptEvent(Event event, String timeline, boolean requestKeysOnFail) throws MXDecryptionException {
    // sanity check
    if (null == event) {
        Log.e(LOG_TAG, "## decryptEvent() : null event");
        return null;
    }
    EncryptedEventContent encryptedEventContent = JsonUtils.toEncryptedEventContent(event.getWireContent().getAsJsonObject());
    String senderKey = encryptedEventContent.sender_key;
    String ciphertext = encryptedEventContent.ciphertext;
    String sessionId = encryptedEventContent.session_id;
    if (TextUtils.isEmpty(senderKey) || TextUtils.isEmpty(sessionId) || TextUtils.isEmpty(ciphertext)) {
        throw new MXDecryptionException(new MXCryptoError(MXCryptoError.MISSING_FIELDS_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_FIELDS_REASON));
    }
    MXEventDecryptionResult eventDecryptionResult = null;
    MXCryptoError cryptoError = null;
    MXDecryptionResult decryptGroupMessageResult = null;
    try {
        decryptGroupMessageResult = mOlmDevice.decryptGroupMessage(ciphertext, event.roomId, timeline, sessionId, senderKey);
    } catch (MXDecryptionException e) {
        cryptoError = e.getCryptoError();
    }
    // the decryption succeeds
    if ((null != decryptGroupMessageResult) && (null != decryptGroupMessageResult.mPayload) && (null == cryptoError)) {
        eventDecryptionResult = new MXEventDecryptionResult();
        eventDecryptionResult.mClearEvent = decryptGroupMessageResult.mPayload;
        eventDecryptionResult.mSenderCurve25519Key = decryptGroupMessageResult.mSenderKey;
        if (null != decryptGroupMessageResult.mKeysClaimed) {
            eventDecryptionResult.mClaimedEd25519Key = decryptGroupMessageResult.mKeysClaimed.get("ed25519");
        }
        eventDecryptionResult.mForwardingCurve25519KeyChain = decryptGroupMessageResult.mForwardingCurve25519KeyChain;
    } else if (null != cryptoError) {
        if (cryptoError.isOlmError()) {
            if (TextUtils.equals("UNKNOWN_MESSAGE_INDEX", cryptoError.error)) {
                addEventToPendingList(event, timeline);
                if (requestKeysOnFail) {
                    requestKeysForEvent(event);
                }
            }
            String reason = String.format(MXCryptoError.OLM_REASON, cryptoError.error);
            String detailedReason = String.format(MXCryptoError.DETAILLED_OLM_REASON, ciphertext, cryptoError.error);
            throw new MXDecryptionException(new MXCryptoError(MXCryptoError.OLM_ERROR_CODE, reason, detailedReason));
        } else if (TextUtils.equals(cryptoError.errcode, MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE)) {
            addEventToPendingList(event, timeline);
            if (requestKeysOnFail) {
                requestKeysForEvent(event);
            }
        }
        throw new MXDecryptionException(cryptoError);
    }
    return eventDecryptionResult;
}
Also used : MXDecryptionResult(org.matrix.androidsdk.crypto.algorithms.MXDecryptionResult) MXEventDecryptionResult(org.matrix.androidsdk.crypto.MXEventDecryptionResult) MXDecryptionException(org.matrix.androidsdk.crypto.MXDecryptionException) EncryptedEventContent(org.matrix.androidsdk.rest.model.crypto.EncryptedEventContent) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Example 3 with MXDecryptionException

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

Aggregations

MXDecryptionException (org.matrix.androidsdk.crypto.MXDecryptionException)3 MXEventDecryptionResult (org.matrix.androidsdk.crypto.MXEventDecryptionResult)3 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)2 JsonElement (com.google.gson.JsonElement)1 JsonParser (com.google.gson.JsonParser)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 MXDecryptionResult (org.matrix.androidsdk.crypto.algorithms.MXDecryptionResult)1 Event (org.matrix.androidsdk.rest.model.Event)1 EncryptedEventContent (org.matrix.androidsdk.rest.model.crypto.EncryptedEventContent)1 OlmEventContent (org.matrix.androidsdk.rest.model.crypto.OlmEventContent)1 OlmPayloadContent (org.matrix.androidsdk.rest.model.crypto.OlmPayloadContent)1