2016-10-06 19:55:03 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2016 OpenMarket Ltd
|
2016-12-22 11:12:41 +01:00
|
|
|
* Copyright 2016 Vector Creations Ltd
|
2016-10-06 19:55:03 +02:00
|
|
|
*
|
|
|
|
* 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_utility.h"
|
|
|
|
|
2016-10-18 15:59:36 +02:00
|
|
|
using namespace AndroidOlmSdk;
|
|
|
|
|
|
|
|
OlmUtility* initializeUtilityMemory()
|
|
|
|
{
|
|
|
|
size_t utilitySize = olm_utility_size();
|
2017-01-03 09:32:59 +01:00
|
|
|
OlmUtility* utilityPtr = (OlmUtility*)malloc(utilitySize);
|
2016-10-18 15:59:36 +02:00
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
if (utilityPtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2017-01-03 09:32:59 +01:00
|
|
|
utilityPtr = olm_utility(utilityPtr);
|
|
|
|
LOGD("## initializeUtilityMemory(): success - OLM utility size=%lu",static_cast<long unsigned int>(utilitySize));
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-03 09:32:59 +01:00
|
|
|
LOGE("## initializeUtilityMemory(): failure - OOM");
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return utilityPtr;
|
|
|
|
}
|
|
|
|
|
2017-01-09 13:55:58 +01:00
|
|
|
JNIEXPORT jlong OLM_UTILITY_FUNC_DEF(createUtilityJni)(JNIEnv *env, jobject thiz)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2017-01-03 09:32:59 +01:00
|
|
|
OlmUtility* utilityPtr = initializeUtilityMemory();
|
2016-10-18 15:59:36 +02:00
|
|
|
|
2017-01-09 13:55:58 +01:00
|
|
|
LOGD("## createUtilityJni(): IN");
|
2016-10-18 15:59:36 +02:00
|
|
|
|
|
|
|
// init account memory allocation
|
2017-01-03 09:32:59 +01:00
|
|
|
if (!utilityPtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2017-01-09 13:55:58 +01:00
|
|
|
LOGE(" ## createUtilityJni(): failure - init OOM");
|
|
|
|
env->ThrowNew(env->FindClass("java/lang/Exception"), "init OOM");
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-09 13:55:58 +01:00
|
|
|
LOGD(" ## createUtilityJni(): success");
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (jlong)(intptr_t)utilityPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
JNIEXPORT void OLM_UTILITY_FUNC_DEF(releaseUtilityJni)(JNIEnv *env, jobject thiz)
|
|
|
|
{
|
2017-01-09 10:01:01 +01:00
|
|
|
OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz);
|
2017-01-03 09:32:59 +01:00
|
|
|
|
|
|
|
LOGD("## releaseUtilityJni(): IN");
|
|
|
|
|
|
|
|
if (!utilityPtr)
|
|
|
|
{
|
|
|
|
LOGE("## releaseUtilityJni(): failure - utility ptr=NULL");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
olm_clear_utility(utilityPtr);
|
|
|
|
free(utilityPtr);
|
|
|
|
}
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-06 19:55:03 +02:00
|
|
|
/**
|
2016-10-14 18:43:57 +02:00
|
|
|
* Verify an ed25519 signature.
|
2016-10-18 15:59:36 +02:00
|
|
|
* @param aSignature the base64-encoded message signature to be checked.
|
|
|
|
* @param aKey the ed25519 key (fingerprint key)
|
|
|
|
* @param aMessage the message which was signed
|
2016-10-18 19:00:23 +02:00
|
|
|
* @return 0 if validation succeed, an error message string if operation failed
|
2016-10-14 18:43:57 +02:00
|
|
|
*/
|
2017-01-03 14:14:56 +01:00
|
|
|
JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, jobject thiz, jbyteArray aSignatureBuffer, jbyteArray aKeyBuffer, jbyteArray aMessageBuffer)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
jstring errorMessageRetValue = 0;
|
2017-01-09 10:01:01 +01:00
|
|
|
OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz);
|
2017-01-03 14:14:56 +01:00
|
|
|
jbyte* signaturePtr = NULL;
|
|
|
|
jbyte* keyPtr = NULL;
|
|
|
|
jbyte* messagePtr = NULL;
|
2018-10-17 21:50:36 +02:00
|
|
|
jboolean messageWasCopied = JNI_FALSE;
|
2016-10-18 15:59:36 +02:00
|
|
|
|
|
|
|
LOGD("## verifyEd25519SignatureJni(): IN");
|
|
|
|
|
2017-01-09 10:01:01 +01:00
|
|
|
if (!utilityPtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## verifyEd25519SignatureJni(): failure - invalid utility ptr=NULL");
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
else if (!aSignatureBuffer || !aKeyBuffer || !aMessageBuffer)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## verifyEd25519SignatureJni(): failure - invalid input parameters ");
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
else if (!(signaturePtr = env->GetByteArrayElements(aSignatureBuffer, 0)))
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## verifyEd25519SignatureJni(): failure - signature JNI allocation OOM");
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## verifyEd25519SignatureJni(): failure - key JNI allocation OOM");
|
|
|
|
}
|
2018-10-17 21:50:36 +02:00
|
|
|
else if (!(messagePtr = env->GetByteArrayElements(aMessageBuffer, &messageWasCopied)))
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## verifyEd25519SignatureJni(): failure - message JNI allocation OOM");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-03 14:14:56 +01:00
|
|
|
size_t signatureLength = (size_t)env->GetArrayLength(aSignatureBuffer);
|
|
|
|
size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer);
|
|
|
|
size_t messageLength = (size_t)env->GetArrayLength(aMessageBuffer);
|
2016-10-24 17:21:28 +02:00
|
|
|
LOGD(" ## verifyEd25519SignatureJni(): signatureLength=%lu keyLength=%lu messageLength=%lu",static_cast<long unsigned int>(signatureLength),static_cast<long unsigned int>(keyLength),static_cast<long unsigned int>(messageLength));
|
2017-01-10 14:45:20 +01:00
|
|
|
LOGD(" ## verifyEd25519SignatureJni(): key=%.*s", static_cast<int>(keyLength), keyPtr);
|
2016-10-18 15:59:36 +02:00
|
|
|
|
|
|
|
size_t result = olm_ed25519_verify(utilityPtr,
|
|
|
|
(void const *)keyPtr,
|
|
|
|
keyLength,
|
|
|
|
(void const *)messagePtr,
|
|
|
|
messageLength,
|
|
|
|
(void*)signaturePtr,
|
|
|
|
signatureLength);
|
2017-01-03 09:32:59 +01:00
|
|
|
if (result == olm_error()) {
|
2016-10-18 15:59:36 +02:00
|
|
|
const char *errorMsgPtr = olm_utility_last_error(utilityPtr);
|
|
|
|
errorMessageRetValue = env->NewStringUTF(errorMsgPtr);
|
2016-10-26 15:08:39 +02:00
|
|
|
LOGE("## verifyEd25519SignatureJni(): failure - olm_ed25519_verify Msg=%s",errorMsgPtr);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-10-24 17:21:28 +02:00
|
|
|
LOGD("## verifyEd25519SignatureJni(): success - result=%lu", static_cast<long unsigned int>(result));
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// free alloc
|
2017-01-03 09:32:59 +01:00
|
|
|
if (signaturePtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2017-01-03 14:14:56 +01:00
|
|
|
env->ReleaseByteArrayElements(aSignatureBuffer, signaturePtr, JNI_ABORT);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
if (keyPtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2017-01-03 14:14:56 +01:00
|
|
|
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
if (messagePtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2018-10-17 21:50:36 +02:00
|
|
|
if (messageWasCopied) {
|
|
|
|
memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageBuffer));
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
env->ReleaseByteArrayElements(aMessageBuffer, messagePtr, JNI_ABORT);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return errorMessageRetValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-10 11:40:57 +01:00
|
|
|
* Compute the digest (SHA 256) for the message passed in parameter.<br>
|
|
|
|
* The digest value is the function return value.
|
|
|
|
* An exception is thrown if the operation fails.
|
|
|
|
* @param aMessage the message
|
|
|
|
* @return digest of the message.
|
|
|
|
**/
|
2017-01-03 16:12:20 +01:00
|
|
|
JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz, jbyteArray aMessageToHashBuffer)
|
2016-10-06 19:55:03 +02:00
|
|
|
{
|
2017-01-03 16:12:20 +01:00
|
|
|
jbyteArray sha256Ret = 0;
|
|
|
|
|
2017-01-09 10:01:01 +01:00
|
|
|
OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz);
|
2017-01-03 14:14:56 +01:00
|
|
|
jbyte* messagePtr = NULL;
|
2018-10-17 21:50:36 +02:00
|
|
|
jboolean messageWasCopied = JNI_FALSE;
|
2016-10-18 15:59:36 +02:00
|
|
|
|
|
|
|
LOGD("## sha256Jni(): IN");
|
|
|
|
|
2017-01-09 10:01:01 +01:00
|
|
|
if (!utilityPtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## sha256Jni(): failure - invalid utility ptr=NULL");
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
else if(!aMessageToHashBuffer)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## sha256Jni(): failure - invalid message parameters ");
|
|
|
|
}
|
2018-10-17 21:50:36 +02:00
|
|
|
else if(!(messagePtr = env->GetByteArrayElements(aMessageToHashBuffer, &messageWasCopied)))
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE(" ## sha256Jni(): failure - message JNI allocation OOM");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// get lengths
|
2017-01-03 14:14:56 +01:00
|
|
|
size_t messageLength = (size_t)env->GetArrayLength(aMessageToHashBuffer);
|
2016-10-18 15:59:36 +02:00
|
|
|
size_t hashLength = olm_sha256_length(utilityPtr);
|
2017-01-10 14:45:20 +01:00
|
|
|
void* hashValuePtr = malloc((hashLength)*sizeof(uint8_t));
|
2016-10-18 15:59:36 +02:00
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
if (!hashValuePtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
|
|
|
LOGE("## sha256Jni(): failure - hash value allocation OOM");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_t result = olm_sha256(utilityPtr,
|
|
|
|
(void const *)messagePtr,
|
|
|
|
messageLength,
|
|
|
|
(void *)hashValuePtr,
|
|
|
|
hashLength);
|
2017-01-03 09:32:59 +01:00
|
|
|
if (result == olm_error())
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2016-10-23 23:55:45 +02:00
|
|
|
LOGE("## sha256Jni(): failure - hash creation Msg=%s",(const char *)olm_utility_last_error(utilityPtr));
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-10 14:45:20 +01:00
|
|
|
LOGD("## sha256Jni(): success - result=%lu hashValue=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), (char*)hashValuePtr);
|
|
|
|
sha256Ret = env->NewByteArray(result);
|
|
|
|
env->SetByteArrayRegion(sha256Ret, 0 , result, (jbyte*)hashValuePtr);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
free(hashValuePtr);
|
|
|
|
}
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
2016-10-06 19:55:03 +02:00
|
|
|
|
2017-01-03 09:32:59 +01:00
|
|
|
if (messagePtr)
|
2016-10-18 15:59:36 +02:00
|
|
|
{
|
2018-10-17 21:50:36 +02:00
|
|
|
if (messageWasCopied) {
|
|
|
|
memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageToHashBuffer));
|
|
|
|
}
|
2017-01-03 14:14:56 +01:00
|
|
|
env->ReleaseByteArrayElements(aMessageToHashBuffer, messagePtr, JNI_ABORT);
|
2016-10-18 15:59:36 +02:00
|
|
|
}
|
2016-10-06 19:55:03 +02:00
|
|
|
|
2017-01-03 16:12:20 +01:00
|
|
|
return sha256Ret;
|
2018-10-17 21:50:36 +02:00
|
|
|
}
|