diff options
author | pedroGitt <pedro.contreiras@amdocs.com> | 2016-11-14 11:56:37 +0100 |
---|---|---|
committer | pedroGitt <pedro.contreiras@amdocs.com> | 2016-11-14 11:56:37 +0100 |
commit | 04fd4c5a1301545419fb72533c57e4253085bdc0 (patch) | |
tree | 642de7b2fb37daebfdfc7a9ca80744bf58a5e044 /java/android/OlmLibSdk/olm-sdk/src/main | |
parent | d944d5fad70283e4cc095802fd893b87309f341d (diff) |
Fix the decrypt issue (crash on V5.1.1) when the message to decrypt contains emojis:AndroidSdk_v0.2.0
- add an internal specific JNI function (javaCStringToUtf8()) to perform the UTF-8 conversion
- the SDK is configured to enable/disable the use of javaCStringToUtf8()
Diffstat (limited to 'java/android/OlmLibSdk/olm-sdk/src/main')
10 files changed, 120 insertions, 22 deletions
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java index 50e77f7..fa4ca1d 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java @@ -123,16 +123,26 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri private native int initInboundGroupSessionWithSessionKeyJni(String aSessionKey); + /** + * Retrieve the base64-encoded identifier for this inbound group session. + * @return the session ID if operation succeed, null otherwise + */ public String sessionIdentifier() { return sessionIdentifierJni(); } private native String sessionIdentifierJni(); + /** + * Decrypt the message passed in parameter. + * @param aEncryptedMsg the message to be decrypted + * @return the decrypted message if operation succeed, null otherwise. + */ public String decryptMessage(String aEncryptedMsg) { - return decryptMessageJni(aEncryptedMsg); + String decryptedMessage = decryptMessageJni(aEncryptedMsg, OlmManager.ENABLE_STRING_UTF8_SPECIFIC_CONVERSION); + return decryptedMessage; } - private native String decryptMessageJni(String aEncryptedMsg); + private native String decryptMessageJni(String aEncryptedMsg, boolean aIsUtf8ConversionRequired); /** diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java index 92fbe2b..5170ee9 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java @@ -25,6 +25,18 @@ import android.util.Log; public class OlmManager { private static final String LOG_TAG = "OlmManager"; private static final String SDK_OLM_VERSION = "V0.1.0_1"; + /** specific flag to enable UTF-8 specific conversion for pre Marshmallow(23) android versions.<br> + * <a href="https://github.com/eclipsesource/J2V8/issues/142">NDK NewStringUTF() UTF8 issue</a> + **/ + public static boolean ENABLE_STRING_UTF8_SPECIFIC_CONVERSION; + + /** + * Constructor. + * @param aIsUtf8SpecificConversionEnabled true to enable JNI specific UTF-8 conversion, false otherwie + */ + public OlmManager(boolean aIsUtf8SpecificConversionEnabled) { + ENABLE_STRING_UTF8_SPECIFIC_CONVERSION = aIsUtf8SpecificConversionEnabled; + } static { try { diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java index 6d570d1..dddc588 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java @@ -361,10 +361,10 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * @return the decrypted message if operation succeed, null otherwise */ public String decryptMessage(OlmMessage aEncryptedMsg) { - return decryptMessageJni(aEncryptedMsg); + return decryptMessageJni(aEncryptedMsg, OlmManager.ENABLE_STRING_UTF8_SPECIFIC_CONVERSION); } - private native String decryptMessageJni(OlmMessage aEncryptedMsg); + private native String decryptMessageJni(OlmMessage aEncryptedMsg, boolean aIsUtf8ConversionRequired); /** * Return the number of unreleased OlmSession instances.<br> diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/Application.mk b/java/android/OlmLibSdk/olm-sdk/src/main/jni/Application.mk index adff86a..6516f5e 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/Application.mk +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/Application.mk @@ -1,3 +1,3 @@ APP_PLATFORM := android-16 -APP_ABI := arm64-v8a armeabi-v7a x86 x86_64 armeabi +APP_ABI := arm64-v8a armeabi-v7a armeabi x86_64 x86 APP_STL := gnustl_static
\ No newline at end of file diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp index 05df22b..a78c2cf 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp @@ -180,7 +180,7 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEn } -JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg) +JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jboolean aIsUtf8ConversionRequired) { jstring decryptedMsgRetValue = 0; OlmInboundGroupSession *sessionPtr = NULL; @@ -245,11 +245,27 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv * } else { - // update decrypted buffer size - plainTextMsgPtr[plaintextLength] = static_cast<char>('\0'); - - LOGD(" ## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), (char*)plainTextMsgPtr); - decryptedMsgRetValue = env->NewStringUTF((const char*)plainTextMsgPtr); + // UTF-8 conversion workaround for issue on Android versions older than Marshmallow (23) + if(aIsUtf8ConversionRequired) + { + decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); + if(0 == decryptedMsgRetValue) + { + LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); + } + else + { + LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); + } + } + else + { + // update decrypted buffer size + plainTextMsgPtr[plaintextLength] = static_cast<char>('\0'); + + LOGD(" ## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), (char*)plainTextMsgPtr); + decryptedMsgRetValue = env->NewStringUTF((const char*)plainTextMsgPtr); + } } } } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h index 897ef46..ec402fd 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h @@ -33,7 +33,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv * JNIEXPORT jint OLM_INBOUND_GROUP_SESSION_FUNC_DEF(initInboundGroupSessionWithSessionKeyJni)(JNIEnv *env, jobject thiz, jstring aSessionKey); JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg); +JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jboolean aIsUtf8ConversionRequired); // serialization JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg); diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h index 29f0310..a5cae46 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h @@ -86,6 +86,7 @@ jlong getAccountInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); jlong getInboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); jlong getOutboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); jlong getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject); +jstring javaCStringToUtf8(JNIEnv *env, uint8_t *aCStringMsgPtr, size_t aMsgLength); #ifdef __cplusplus } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp index 239fc68..561010d 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp @@ -270,4 +270,47 @@ jstring serializeDataWithKey(JNIEnv *env, jobject thiz, } return pickledDataRetValue; -}
\ No newline at end of file +} + + +/** +* Convert a C string into a UTF-8 format string. +* The conversion is performed in JAVA side to workaround the issue in NewStringUTF(). +* The problem is described here: https://github.com/eclipsesource/J2V8/issues/142 +*/ +jstring javaCStringToUtf8(JNIEnv *env, uint8_t *aCStringMsgPtr, size_t aMsgLength) +{ + jstring convertedRetValue = 0; + jbyteArray tempByteArray = NULL; + + if((NULL == aCStringMsgPtr) || (NULL == env)) + { + LOGE("## javaCStringToUtf8(): failure - invalid parameters (null)"); + } + else if(NULL == (tempByteArray=env->NewByteArray(aMsgLength))) + { + LOGE("## javaCStringToUtf8(): failure - return byte array OOM"); + } + else + { + env->SetByteArrayRegion(tempByteArray, 0, aMsgLength, (const jbyte*)aCStringMsgPtr); + + // UTF-8 conversion from JAVA + jstring strEncode = (env)->NewStringUTF("UTF-8"); + jclass jClass = env->FindClass("java/lang/String"); + jmethodID cstor = env->GetMethodID(jClass, "<init>", "([BLjava/lang/String;)V"); + + if((0!=jClass) && (0!=jClass) && (0!=strEncode)) + { + convertedRetValue = (jstring) env->NewObject(jClass, cstor, tempByteArray, strEncode); + LOGD(" ## javaCStringToUtf8(): succeed"); + env->DeleteLocalRef(tempByteArray); + } + else + { + LOGE(" ## javaCStringToUtf8(): failure - invalid Java references"); + } + } + + return convertedRetValue; +} diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp index a31d48f..011ad44 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp @@ -574,7 +574,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz * @param aEncryptedMsg message to decrypt * @return decrypted message if operation succeed, null otherwise */ -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg) +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg, jboolean aIsUtf8ConversionRequired) { jstring decryptedMsgRetValue = 0; jclass encryptedMsgJClass = 0; @@ -585,10 +585,10 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject t // ptrs OlmSession *sessionPtr = NULL; const char *encryptedMsgPtr = NULL; // <= obtained from encryptedMsgJstring - void *plainTextMsgPtr = NULL; + uint8_t *plainTextMsgPtr = NULL; char *tempEncryptedPtr = NULL; - LOGD("## decryptMessageJni(): IN "); + LOGD("## decryptMessageJni(): IN - OlmSession"); if(NULL == (sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { @@ -646,7 +646,7 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject t LOGD("## decryptMessageJni(): maxPlaintextLength=%lu",static_cast<long unsigned int>(maxPlainTextLength)); // allocate output decrypted message - plainTextMsgPtr = static_cast<void*>(malloc((maxPlainTextLength+1)*sizeof(uint8_t))); + plainTextMsgPtr = static_cast<uint8_t*>(malloc((maxPlainTextLength+1)*sizeof(uint8_t))); // decrypt, but before reload encrypted buffer (previous one was destroyed) memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength); @@ -662,11 +662,27 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject t } else { - // update decrypted buffer size - (static_cast<char*>(plainTextMsgPtr))[plaintextLength] = static_cast<char>('\0'); + // UTF-8 conversion workaround for issue on Android versions older than Marshmallow (23) + if(aIsUtf8ConversionRequired) + { + decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); + if(0 == decryptedMsgRetValue) + { + LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); + } + else + { + LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); + } + } + else + { + // update decrypted buffer size + plainTextMsgPtr[plaintextLength] = static_cast<char>('\0'); - LOGD("## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), static_cast<char*>(plainTextMsgPtr)); - decryptedMsgRetValue = env->NewStringUTF(static_cast<const char*>(plainTextMsgPtr)); + LOGD("## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), (char*)(plainTextMsgPtr)); + decryptedMsgRetValue = env->NewStringUTF((const char*)(plainTextMsgPtr)); + } } } } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h index a08b775..e5bea92 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h @@ -44,7 +44,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *e // encrypt/decrypt JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jstring aClearMsg, jobject aEncryptedMsg); -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg, jboolean aIsUtf8ConversionRequired); JNIEXPORT jstring OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz); |