From c9369a4383714c8656fc0ee72965e46476a56691 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 26 Mar 2019 14:30:19 +0100 Subject: E2E: SAS Verification (olm) Fix / missing free() on some errors Added doc regarding string encoding for keys cleaning --- android/olm-sdk/src/main/jni/olm_sas.cpp | 310 +++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 android/olm-sdk/src/main/jni/olm_sas.cpp (limited to 'android/olm-sdk/src/main/jni/olm_sas.cpp') diff --git a/android/olm-sdk/src/main/jni/olm_sas.cpp b/android/olm-sdk/src/main/jni/olm_sas.cpp new file mode 100644 index 0000000..2ad1e0f --- /dev/null +++ b/android/olm-sdk/src/main/jni/olm_sas.cpp @@ -0,0 +1,310 @@ +/* + * Copyright 2019 New Vector 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_sas.h" + +#include "olm/olm.h" + +using namespace AndroidOlmSdk; + +JNIEXPORT jlong OLM_SAS_FUNC_DEF(createNewSASJni)(JNIEnv *env, jobject thiz) +{ + + size_t sasSize = olm_sas_size(); + OlmSAS *sasPtr = (OlmSAS *) malloc(sasSize); + const char* errorMessage = NULL; + + if (!sasPtr) + { + LOGE("## createNewSASJni(): failure - init SAS OOM"); + env->ThrowNew(env->FindClass("java/lang/Exception"), "init sas OOM"); + } + else + { + sasPtr = olm_sas(sasPtr) + LOGD(" ## createNewSASJni(): success - sasPtr=%p (jlong)(intptr_t)accountPtr=%lld",sasPtr,(jlong)(intptr_t)sasPtr); + } + + size_t randomSize = olm_create_sas_random_length(sasPtr); + uint8_t *randomBuffPtr = NULL; + + LOGD("## createNewSASJni(): randomSize=%lu",static_cast(randomSize)); + + if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize)) + { + LOGE("## createNewSASJni(): failure - random buffer init"); + errorMessage = "Failed to init private key"; + } + else + { + size_t result = olm_create_sas(sasPtr, randomBuffPtr, randomSize); + if (result == olm_error()) + { + errorMessage = (const char *)olm_sas_last_error(sasPtr); + LOGE("## createNewSASJni(): failure - error creating SAS Msg=%s", errorMessage); + } + } + + if (randomBuffPtr) + { + memset(randomBuffPtr, 0, randomSize); + free(randomBuffPtr); + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + + return (jlong)(intptr_t)sasPtr; +} + +JNIEXPORT void OLM_SAS_FUNC_DEF(releaseSASJni)(JNIEnv *env, jobject thiz) +{ + LOGD("## releaseSASJni(): IN"); + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + if (!sasPtr) + { + LOGE("## releaseSessionJni(): failure - invalid Session ptr=NULL"); + } + else + { + olm_clear_sas(sasPtr); + // even if free(NULL) does not crash, logs are performed for debug purpose + free(sasPtr); + } +} + + +JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(getPubKeyJni)(JNIEnv *env, jobject thiz) +{ + LOGD("## getPubKeyJni(): IN"); + const char* errorMessage = NULL; + jbyteArray returnValue = 0; + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + if (!sasPtr) + { + LOGE("## getPubKeyJni(): failure - invalid SAS ptr=NULL"); + errorMessage = "invalid SAS ptr=NULL"; + } + else + { + size_t pubKeyLength = olm_sas_pubkey_length(sasPtr); + void *pubkey = malloc(pubKeyLength*sizeof(uint8_t)); + size_t result = olm_sas_get_pubkey(sasPtr, pubkey, pubKeyLength); + if (result == olm_error()) + { + errorMessage = (const char *)olm_sas_last_error(sasPtr); + LOGE("## getPubKeyJni(): failure - error getting pub key Msg=%s", errorMessage); + } + else + { + returnValue = env->NewByteArray(pubKeyLength); + env->SetByteArrayRegion(returnValue, 0 , pubKeyLength, (jbyte*)pubkey); + } + if (pubkey) { + free(pubkey); + } + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + + return returnValue; +} + +JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteArray pubKeyBuffer) { + + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + const char* errorMessage = NULL; + jbyte *pubKeyPtr = NULL; + jboolean pubKeyWasCopied = JNI_FALSE; + + if (!sasPtr) + { + LOGE("## setTheirPubKey(): failure - invalid SAS ptr=NULL"); + errorMessage = "invalid SAS ptr=NULL"; + } else if(!pubKeyBuffer) { + LOGE("## setTheirPubKey(): failure - invalid info"); + errorMessage = "invalid pubKey"; + } + else if (!(pubKeyPtr = env->GetByteArrayElements(pubKeyBuffer, &pubKeyWasCopied))) + { + LOGE(" ## generateShortCodeJni(): failure - info JNI allocation OOM"); + errorMessage = "info JNI allocation OOM"; + } + else + { + size_t pubKeyLength = (size_t)env->GetArrayLength(pubKeyBuffer); + size_t result = olm_sas_set_their_key(sasPtr,pubKeyPtr,pubKeyLength); + if (result == olm_error()) + { + errorMessage = (const char *)olm_sas_last_error(sasPtr); + LOGE("## setTheirPubKey(): failure - error setting their key Msg=%s", errorMessage); + } + } + // free alloc + if (pubKeyPtr) + { + if (pubKeyWasCopied) + { + memset(pubKeyPtr, 0, (size_t)env->GetArrayLength(pubKeyBuffer)); + } + env->ReleaseByteArrayElements(pubKeyBuffer, pubKeyPtr, JNI_ABORT); + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + +} + +JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject thiz, jbyteArray infoStringBytes, jint byteNb) { + LOGD("## generateShortCodeJni(): IN"); + const char* errorMessage = NULL; + jbyteArray returnValue = 0; + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + jbyte *infoPtr = NULL; + jboolean infoWasCopied = JNI_FALSE; + + if (!sasPtr) + { + LOGE("## generateShortCodeJni(): failure - invalid SAS ptr=NULL"); + errorMessage = "invalid SAS ptr=NULL"; + } else if(!infoStringBytes) { + LOGE("## generateShortCodeJni(): failure - invalid info"); + errorMessage = "invalid info"; + } + else if (!(infoPtr = env->GetByteArrayElements(infoStringBytes, &infoWasCopied))) + { + LOGE(" ## generateShortCodeJni(): failure - info JNI allocation OOM"); + errorMessage = "info JNI allocation OOM"; + } + else { + size_t shortBytesCodeLength = (size_t) byteNb; + void *shortBytesCode = malloc(shortBytesCodeLength * sizeof(uint8_t)); + size_t infoLength = (size_t)env->GetArrayLength(infoStringBytes); + olm_sas_generate_bytes(sasPtr, infoPtr, infoLength, shortBytesCode, shortBytesCodeLength); + returnValue = env->NewByteArray(shortBytesCodeLength); + env->SetByteArrayRegion(returnValue, 0 , shortBytesCodeLength, (jbyte*)shortBytesCode); + free(shortBytesCode); + } + + // free alloc + if (infoPtr) + { + if (infoWasCopied) + { + memset(infoPtr, 0, (size_t)env->GetArrayLength(infoStringBytes)); + } + env->ReleaseByteArrayElements(infoStringBytes, infoPtr, JNI_ABORT); + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + + return returnValue; +} + + +JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { + LOGD("## calculateMacJni(): IN"); + const char* errorMessage = NULL; + jbyteArray returnValue = 0; + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + jbyte *messagePtr = NULL; + jboolean messageWasCopied = JNI_FALSE; + + jbyte *infoPtr = NULL; + jboolean infoWasCopied = JNI_FALSE; + + if (!sasPtr) + { + LOGE("## calculateMacJni(): failure - invalid SAS ptr=NULL"); + errorMessage = "invalid SAS ptr=NULL"; + } else if(!messageBuffer) { + LOGE("## calculateMacJni(): failure - invalid message"); + errorMessage = "invalid info"; + } + else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied))) + { + LOGE(" ## calculateMacJni(): failure - message JNI allocation OOM"); + errorMessage = "message JNI allocation OOM"; + } + else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied))) + { + LOGE(" ## calculateMacJni(): failure - info JNI allocation OOM"); + errorMessage = "info JNI allocation OOM"; + } else { + + size_t infoLength = (size_t)env->GetArrayLength(infoBuffer); + size_t messageLength = (size_t)env->GetArrayLength(messageBuffer); + size_t macLength = olm_sas_mac_length(sasPtr); + + void *macPtr = malloc(macLength*sizeof(uint8_t)); + + size_t result = olm_sas_calculate_mac(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength); + if (result == olm_error()) + { + errorMessage = (const char *)olm_sas_last_error(sasPtr); + LOGE("## calculateMacJni(): failure - error calculating SAS mac Msg=%s", errorMessage); + } + else + { + returnValue = env->NewByteArray(macLength); + env->SetByteArrayRegion(returnValue, 0 , macLength, (jbyte*)macPtr); + } + + if (macPtr) { + free(macPtr); + } + } + + // free alloc + if (infoPtr) + { + if (infoWasCopied) + { + memset(infoPtr, 0, (size_t)env->GetArrayLength(infoBuffer)); + } + env->ReleaseByteArrayElements(infoBuffer, infoPtr, JNI_ABORT); + } + if (messagePtr) + { + if (messageWasCopied) + { + memset(messagePtr, 0, (size_t)env->GetArrayLength(messageBuffer)); + } + env->ReleaseByteArrayElements(messageBuffer, messagePtr, JNI_ABORT); + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + + return returnValue; +} \ No newline at end of file -- cgit v1.2.3 From 16a28f297c8d8f782131575c02854904b424eb82 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 4 Apr 2019 09:00:08 +0200 Subject: Added macLongKdf support --- android/olm-sdk/src/main/jni/olm_sas.cpp | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'android/olm-sdk/src/main/jni/olm_sas.cpp') diff --git a/android/olm-sdk/src/main/jni/olm_sas.cpp b/android/olm-sdk/src/main/jni/olm_sas.cpp index 2ad1e0f..40b9183 100644 --- a/android/olm-sdk/src/main/jni/olm_sas.cpp +++ b/android/olm-sdk/src/main/jni/olm_sas.cpp @@ -306,5 +306,85 @@ JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); } + return returnValue; +} + +JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { + LOGD("## calculateMacLongKdfJni(): IN"); + const char* errorMessage = NULL; + jbyteArray returnValue = 0; + OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); + + jbyte *messagePtr = NULL; + jboolean messageWasCopied = JNI_FALSE; + + jbyte *infoPtr = NULL; + jboolean infoWasCopied = JNI_FALSE; + + if (!sasPtr) + { + LOGE("## calculateMacLongKdfJni(): failure - invalid SAS ptr=NULL"); + errorMessage = "invalid SAS ptr=NULL"; + } else if(!messageBuffer) { + LOGE("## calculateMacLongKdfJni(): failure - invalid message"); + errorMessage = "invalid info"; + } + else if (!(messagePtr = env->GetByteArrayElements(messageBuffer, &messageWasCopied))) + { + LOGE(" ## calculateMacLongKdfJni(): failure - message JNI allocation OOM"); + errorMessage = "message JNI allocation OOM"; + } + else if (!(infoPtr = env->GetByteArrayElements(infoBuffer, &infoWasCopied))) + { + LOGE(" ## calculateMacLongKdfJni(): failure - info JNI allocation OOM"); + errorMessage = "info JNI allocation OOM"; + } else { + + size_t infoLength = (size_t)env->GetArrayLength(infoBuffer); + size_t messageLength = (size_t)env->GetArrayLength(messageBuffer); + size_t macLength = olm_sas_mac_length(sasPtr); + + void *macPtr = malloc(macLength*sizeof(uint8_t)); + + size_t result = olm_sas_calculate_mac_long_kdf(sasPtr,messagePtr,messageLength,infoPtr,infoLength,macPtr,macLength); + if (result == olm_error()) + { + errorMessage = (const char *)olm_sas_last_error(sasPtr); + LOGE("## calculateMacLongKdfJni(): failure - error calculating SAS mac Msg=%s", errorMessage); + } + else + { + returnValue = env->NewByteArray(macLength); + env->SetByteArrayRegion(returnValue, 0 , macLength, (jbyte*)macPtr); + } + + if (macPtr) { + free(macPtr); + } + } + + // free alloc + if (infoPtr) + { + if (infoWasCopied) + { + memset(infoPtr, 0, (size_t)env->GetArrayLength(infoBuffer)); + } + env->ReleaseByteArrayElements(infoBuffer, infoPtr, JNI_ABORT); + } + if (messagePtr) + { + if (messageWasCopied) + { + memset(messagePtr, 0, (size_t)env->GetArrayLength(messageBuffer)); + } + env->ReleaseByteArrayElements(messageBuffer, messagePtr, JNI_ABORT); + } + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + return returnValue; } \ No newline at end of file -- cgit v1.2.3 From eb7347bb524b830c1458d64411cd56fc58ad5b91 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 10 Apr 2019 11:26:58 +0200 Subject: Return string instead of byte array for b64 encoded data --- android/olm-sdk/src/main/jni/olm_sas.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'android/olm-sdk/src/main/jni/olm_sas.cpp') diff --git a/android/olm-sdk/src/main/jni/olm_sas.cpp b/android/olm-sdk/src/main/jni/olm_sas.cpp index 40b9183..400934f 100644 --- a/android/olm-sdk/src/main/jni/olm_sas.cpp +++ b/android/olm-sdk/src/main/jni/olm_sas.cpp @@ -148,7 +148,7 @@ JNIEXPORT void OLM_SAS_FUNC_DEF(setTheirPubKey)(JNIEnv *env, jobject thiz,jbyteA } else if (!(pubKeyPtr = env->GetByteArrayElements(pubKeyBuffer, &pubKeyWasCopied))) { - LOGE(" ## generateShortCodeJni(): failure - info JNI allocation OOM"); + LOGE(" ## setTheirPubKey(): failure - info JNI allocation OOM"); errorMessage = "info JNI allocation OOM"; } else @@ -230,7 +230,7 @@ JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(generateShortCodeJni)(JNIEnv *env, jobject JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { - LOGD("## calculateMacJni(): IN"); + LOGD("## calculateMacJni(): IN"); const char* errorMessage = NULL; jbyteArray returnValue = 0; OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); @@ -310,7 +310,7 @@ JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacJni)(JNIEnv *env, jobject thiz } JNIEXPORT jbyteArray OLM_SAS_FUNC_DEF(calculateMacLongKdfJni)(JNIEnv *env, jobject thiz,jbyteArray messageBuffer,jbyteArray infoBuffer) { - LOGD("## calculateMacLongKdfJni(): IN"); + LOGD("## calculateMacLongKdfJni(): IN"); const char* errorMessage = NULL; jbyteArray returnValue = 0; OlmSAS* sasPtr = getOlmSasInstanceId(env, thiz); -- cgit v1.2.3