From 1511962df194b9b414b3629b37b6fd3a42081295 Mon Sep 17 00:00:00 2001 From: pedroGitt Date: Thu, 20 Oct 2016 17:42:57 +0200 Subject: Add serialization feature to OlmAccount - new JNI API: serializeDataWithKeyJni() and initWithSerializedDataJni() - update account unit test - modify OlmAccount constructor API: an exception may be thrown --- .../OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp | 183 ++++++++++++++++++++- 1 file changed, 179 insertions(+), 4 deletions(-) (limited to 'java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp') diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp index a10b8e0..6f2e6ee 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp @@ -40,6 +40,17 @@ OlmAccount* initializeAccountMemory() return accountPtr; } + +JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz) +{ + LOGD("## createNewAccountJni(): IN"); + OlmAccount* accountPtr = initializeAccountMemory(); + + LOGD(" ## createNewAccountJni(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr); + return (jlong)(intptr_t)accountPtr; +} + + /** * Release the account allocation made by initializeAccountMemory().
* This method MUST be called when java counter part account instance is done. @@ -49,20 +60,21 @@ JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz { OlmAccount* accountPtr = NULL; - LOGD("## releaseAccountJni(): accountPtr=%p",accountPtr); + LOGD("## releaseAccountJni(): IN"); if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz))) { - LOGE("## releaseAccountJni(): failure - invalid Account ptr=NULL"); + LOGE(" ## releaseAccountJni(): failure - invalid Account ptr=NULL"); } else { + LOGD(" ## releaseAccountJni(): accountPtr=%p",accountPtr); olm_clear_account(accountPtr); - LOGD("## releaseAccountJni(): IN"); + LOGD(" ## releaseAccountJni(): IN"); // even if free(NULL) does not crash, logs are performed for debug purpose free(accountPtr); - LOGD("## releaseAccountJni(): OUT"); + LOGD(" ## releaseAccountJni(): OUT"); } } @@ -467,4 +479,167 @@ JNIEXPORT jstring OLM_MANAGER_FUNC_DEF(getOlmLibVersion)(JNIEnv* env, jobject th return returnValueStr; } +/** +* Serialize and encrypt account instance into a base64 string.
+* @param aKey key used to encrypt the serialized account data +* @param[out] aErrorMsg error message set if operation failed +* @return a base64 string if operation succeed, null otherwise +**/ +JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg) +{ + jstring pickledDataRetValue = 0; + jclass errorMsgJClass = 0; + jmethodID errorMsgMethodId = 0; + jstring errorJstring = 0; + const char *keyPtr = NULL; + void *pickledPtr = NULL; + OlmAccount* accountPtr = NULL; + + LOGD("## serializeDataWithKeyJni(): IN"); + + if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz))) + { + LOGE(" ## serializeDataWithKeyJni(): failure - invalid account ptr"); + } + else if(0 == aKey) + { + LOGE(" ## serializeDataWithKeyJni(): failure - invalid key"); + } + else if(0 == aErrorMsg) + { + LOGE(" ## serializeDataWithKeyJni(): failure - invalid error object"); + } + else if(0 == (errorMsgJClass = env->GetObjectClass(aErrorMsg))) + { + LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error class"); + } + else if(0 == (errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"))) + { + LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error method ID"); + } + else if(NULL == (keyPtr = env->GetStringUTFChars(aKey, 0))) + { + LOGE(" ## serializeDataWithKeyJni(): failure - keyPtr JNI allocation OOM"); + } + else + { + size_t pickledLength = olm_pickle_account_length(accountPtr); + size_t keyLength = (size_t)env->GetStringUTFLength(aKey); + LOGD(" ## serializeDataWithKeyJni(): pickledLength=%lu keyLength=%lu",pickledLength, keyLength); + LOGD(" ## serializeDataWithKeyJni(): key=%s",(char const *)keyPtr); + + if(NULL == (pickledPtr = (void*)malloc((pickledLength+1)*sizeof(uint8_t)))) + { + LOGE(" ## serializeDataWithKeyJni(): failure - pickledPtr buffer OOM"); + } + else + { + size_t result = olm_pickle_account(accountPtr, + (void const *)keyPtr, + keyLength, + (void*)pickledPtr, + pickledLength); + if(result == olm_error()) + { + const char *errorMsgPtr = olm_account_last_error(accountPtr); + LOGE(" ## serializeDataWithKeyJni(): failure - olm_pickle_account() Msg=%s",errorMsgPtr); + + if(0 != (errorJstring = env->NewStringUTF(errorMsgPtr))) + { + env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring); + } + } + else + { + // build success output + (static_cast(pickledPtr))[pickledLength] = static_cast('\0'); + pickledDataRetValue = env->NewStringUTF((const char*)pickledPtr); + LOGD(" ## serializeDataWithKeyJni(): success - result=%lu pickled=%s", result, static_cast(pickledPtr)); + } + } + } + + // free alloc + if(NULL != keyPtr) + { + env->ReleaseStringUTFChars(aKey, keyPtr); + } + + if(NULL != pickledPtr) + { + free(pickledPtr); + } + + return pickledDataRetValue; +} + + +JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(initWithSerializedDataJni)(JNIEnv *env, jobject thiz, jstring aSerializedData, jstring aKey) +{ + OlmAccount* accountPtr = NULL; + jstring errorMessageRetValue = 0; + const char *keyPtr = NULL; + const char *pickledPtr = NULL; + + LOGD("## initWithSerializedDataJni(): IN"); + + if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz))) + //if(NULL == (accountPtr = initializeAccountMemory())) + { + LOGE(" ## initWithSerializedDataJni(): failure - account failure OOM"); + } + else if(0 == aKey) + { + LOGE(" ## initWithSerializedDataJni(): failure - invalid key"); + } + else if(0 == aSerializedData) + { + LOGE(" ## initWithSerializedDataJni(): failure - serialized data"); + } + else if(NULL == (keyPtr = env->GetStringUTFChars(aKey, 0))) + { + LOGE(" ## initWithSerializedDataJni(): failure - keyPtr JNI allocation OOM"); + } + else if(NULL == (pickledPtr = env->GetStringUTFChars(aSerializedData, 0))) + { + LOGE(" ## initWithSerializedDataJni(): failure - pickledPtr JNI allocation OOM"); + } + else + { + size_t pickledLength = (size_t)env->GetStringUTFLength(aSerializedData); + size_t keyLength = (size_t)env->GetStringUTFLength(aKey); + LOGD(" ## initWithSerializedDataJni(): pickledLength=%lu keyLength=%lu",pickledLength, keyLength); + LOGD(" ## initWithSerializedDataJni(): key=%s",(char const *)keyPtr); + LOGD(" ## initWithSerializedDataJni(): pickled=%s",(char const *)pickledPtr); + + size_t result = olm_unpickle_account(accountPtr, + (void const *)keyPtr, + keyLength, + (void*)pickledPtr, + pickledLength); + if(result == olm_error()) + { + const char *errorMsgPtr = olm_account_last_error(accountPtr); + LOGE(" ## initWithSerializedDataJni(): failure - olm_unpickle_account() Msg=%s",errorMsgPtr); + errorMessageRetValue = env->NewStringUTF(errorMsgPtr); + } + else + { + LOGD(" ## initWithSerializedDataJni(): success - result=%lu ", result); + } + + } + + // free alloc + if(NULL != keyPtr) + { + env->ReleaseStringUTFChars(aKey, keyPtr); + } + + if(NULL != pickledPtr) + { + env->ReleaseStringUTFChars(aSerializedData, pickledPtr); + } + return errorMessageRetValue; +} \ No newline at end of file -- cgit v1.2.3