diff options
Diffstat (limited to 'android/olm-sdk/src/main/jni/olm_jni_helper.cpp')
-rw-r--r-- | android/olm-sdk/src/main/jni/olm_jni_helper.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/android/olm-sdk/src/main/jni/olm_jni_helper.cpp b/android/olm-sdk/src/main/jni/olm_jni_helper.cpp new file mode 100644 index 0000000..a1f5c59 --- /dev/null +++ b/android/olm-sdk/src/main/jni/olm_jni_helper.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2016 OpenMarket Ltd + * Copyright 2016 Vector Creations Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "olm_jni_helper.h" +#include "olm/olm.h" +#include <sys/time.h> + +using namespace AndroidOlmSdk; + +/** +* Init a buffer with a given number of random values. +* @param aBuffer2Ptr the buffer to be initialized +* @param aRandomSize the number of random values to apply +* @return true if operation succeed, false otherwise +**/ +bool setRandomInBuffer(JNIEnv *env, uint8_t **aBuffer2Ptr, size_t aRandomSize) +{ + bool retCode = false; + int bufferLen = aRandomSize*sizeof(uint8_t); + + if (!aBuffer2Ptr) + { + LOGE("## setRandomInBuffer(): failure - aBuffer=NULL"); + } + else if (!aRandomSize) + { + LOGE("## setRandomInBuffer(): failure - random size=0"); + } + else if (!(*aBuffer2Ptr = (uint8_t*)malloc(bufferLen))) + { + LOGE("## setRandomInBuffer(): failure - alloc mem OOM"); + } + else + { + LOGD("## setRandomInBuffer(): randomSize=%lu",static_cast<long unsigned int>(aRandomSize)); + + // use the secureRandom class + jclass cls = env->FindClass("java/security/SecureRandom"); + + if (cls) + { + jobject newObj = 0; + jmethodID constructor = env->GetMethodID(cls, "<init>", "()V"); + jmethodID nextByteMethod = env->GetMethodID(cls, "nextBytes", "([B)V"); + + if (constructor) + { + newObj = env->NewObject(cls, constructor); + jbyteArray tempByteArray = env->NewByteArray(bufferLen); + + if (newObj && tempByteArray) + { + env->CallVoidMethod(newObj, nextByteMethod, tempByteArray); + + if (!env->ExceptionOccurred()) + { + jbyte* buffer = env->GetByteArrayElements(tempByteArray, NULL); + + if (buffer) + { + memcpy(*aBuffer2Ptr, buffer, bufferLen); + retCode = true; + + // clear tempByteArray to hide sensitive data. + memset(buffer, 0, bufferLen); + env->SetByteArrayRegion(tempByteArray, 0, bufferLen, buffer); + + // ensure that the buffer is released + env->ReleaseByteArrayElements(tempByteArray, buffer, JNI_ABORT); + } + } + } + + if (tempByteArray) + { + env->DeleteLocalRef(tempByteArray); + } + + if (newObj) + { + env->DeleteLocalRef(newObj); + } + } + } + + // debug purpose + /*for(int i = 0; i < aRandomSize; i++) + { + LOGD("## setRandomInBuffer(): randomBuffPtr[%ld]=%d",i, (*aBuffer2Ptr)[i]); + }*/ + } + + return retCode; +} + +/** +* Read the instance ID of the calling object. +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @param aCallingClass java calling class name +* @return the related instance ID +**/ +jlong getInstanceId(JNIEnv* aJniEnv, jobject aJavaObject, const char *aCallingClass) +{ + jlong instanceId = 0; + + if (aJniEnv) + { + jclass requiredClass = aJniEnv->FindClass(aCallingClass); + jclass loaderClass = 0; + + if (requiredClass && (JNI_TRUE != aJniEnv->IsInstanceOf(aJavaObject, requiredClass))) + { + LOGE("## getInstanceId() failure - invalid instance of"); + } + else if ((loaderClass = aJniEnv->GetObjectClass(aJavaObject))) + { + jfieldID instanceIdField = aJniEnv->GetFieldID(loaderClass, "mNativeId", "J"); + + if (instanceIdField) + { + instanceId = aJniEnv->GetLongField(aJavaObject, instanceIdField); + LOGD("## getInstanceId(): read from java instanceId=%lld",instanceId); + } + else + { + LOGE("## getInstanceId() ERROR! GetFieldID=null"); + } + + aJniEnv->DeleteLocalRef(loaderClass); + } + else + { + LOGE("## getInstanceId() ERROR! GetObjectClass=null"); + } + } + else + { + LOGE("## getInstanceId() ERROR! aJniEnv=NULL"); + } + + LOGD("## getInstanceId() success - instanceId=%p (jlong)(intptr_t)instanceId=%lld",(void*)instanceId, (jlong)(intptr_t)instanceId); + + return instanceId; +} + +/** +* Read the account instance ID of the calling object. +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @return the related OlmAccount. +**/ +struct OlmAccount* getAccountInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) +{ + return (struct OlmAccount*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_ACCOUNT); +} + +/** +* Read the session instance ID of the calling object (aJavaObject).<br> +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @return the related OlmSession. +**/ +struct OlmSession* getSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) +{ + return (struct OlmSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_SESSION); +} + +/** +* Read the inbound group session instance ID of the calling object (aJavaObject).<br> +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @return the related OlmInboundGroupSession. +**/ +struct OlmInboundGroupSession* getInboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) +{ + return (struct OlmInboundGroupSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_INBOUND_GROUP_SESSION); +} + +/** +* Read the outbound group session instance ID of the calling object (aJavaObject).<br> +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @return the related OlmOutboundGroupSession +**/ +struct OlmOutboundGroupSession* getOutboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) +{ + return (struct OlmOutboundGroupSession*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_OUTBOUND_GROUP_SESSION); +} + +/** +* Read the utility instance ID of the calling object (aJavaObject).<br> +* @param aJniEnv pointer pointing on the JNI function table +* @param aJavaObject reference to the object on which the method is invoked +* @return the related OlmUtility +**/ +struct OlmUtility* getUtilityInstanceId(JNIEnv* aJniEnv, jobject aJavaObject) +{ + return (struct OlmUtility*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_UTILITY); +} |