From 04fd4c5a1301545419fb72533c57e4253085bdc0 Mon Sep 17 00:00:00 2001 From: pedroGitt Date: Mon, 14 Nov 2016 11:56:37 +0100 Subject: Fix the decrypt issue (crash on V5.1.1) when the message to decrypt contains emojis: - add an internal specific JNI function (javaCStringToUtf8()) to perform the UTF-8 conversion - the SDK is configured to enable/disable the use of javaCStringToUtf8() --- .../OlmLibSdk/olm-sdk/src/main/jni/Application.mk | 2 +- .../src/main/jni/olm_inbound_group_session.cpp | 28 +++++++++++--- .../src/main/jni/olm_inbound_group_session.h | 2 +- .../OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h | 1 + .../olm-sdk/src/main/jni/olm_jni_helper.cpp | 45 +++++++++++++++++++++- .../OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp | 32 +++++++++++---- .../OlmLibSdk/olm-sdk/src/main/jni/olm_session.h | 2 +- 7 files changed, 94 insertions(+), 18 deletions(-) (limited to 'java/android/OlmLibSdk/olm-sdk/src/main/jni') 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('\0'); - - LOGD(" ## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast(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(plaintextLength)); + } + } + else + { + // update decrypted buffer size + plainTextMsgPtr[plaintextLength] = static_cast('\0'); + + LOGD(" ## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast(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, "", "([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(maxPlainTextLength)); // allocate output decrypted message - plainTextMsgPtr = static_cast(malloc((maxPlainTextLength+1)*sizeof(uint8_t))); + plainTextMsgPtr = static_cast(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(plainTextMsgPtr))[plaintextLength] = static_cast('\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(plaintextLength)); + } + } + else + { + // update decrypted buffer size + plainTextMsgPtr[plaintextLength] = static_cast('\0'); - LOGD("## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast(plaintextLength), static_cast(plainTextMsgPtr)); - decryptedMsgRetValue = env->NewStringUTF(static_cast(plainTextMsgPtr)); + LOGD("## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast(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); -- cgit v1.2.3