2949811917
Signed-off-by: Lukas Lihotzki <lukas@lihotzki.de>
234 lines
7.9 KiB
C++
234 lines
7.9 KiB
C++
/*
|
|
* Copyright 2016 OpenMarket Ltd
|
|
* Copyright 2016,2018,2019 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);
|
|
}
|
|
|
|
struct OlmPkDecryption* getPkDecryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
|
|
{
|
|
return (struct OlmPkDecryption*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_DECRYPTION);
|
|
}
|
|
|
|
struct OlmPkEncryption* getPkEncryptionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
|
|
{
|
|
return (struct OlmPkEncryption*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_ENCRYPTION);
|
|
}
|
|
|
|
struct OlmPkSigning* getPkSigningInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
|
|
{
|
|
return (struct OlmPkSigning*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_PK_SIGNING);
|
|
}
|
|
|
|
struct OlmSAS* getOlmSasInstanceId(JNIEnv* aJniEnv, jobject aJavaObject)
|
|
{
|
|
return (struct OlmSAS*)getInstanceId(aJniEnv, aJavaObject, CLASS_OLM_SAS);
|
|
}
|