diff options
author | pedroGitt <pedro.contreiras@amdocs.com> | 2016-10-06 19:55:03 +0200 |
---|---|---|
committer | pedroGitt <pedro.contreiras@amdocs.com> | 2016-10-06 19:55:03 +0200 |
commit | 655c841cc3720d1bb9892d60a2d7ca136c90cfbd (patch) | |
tree | e598da0ee20e90620873e7c13d36c9b32a3fe8d4 /java/android/OlmLibSdk/olm-sdk/src/main/jni | |
parent | 0393ad68438669f60a6679c9e0f8010c7366c5ed (diff) |
- Update Unit tests for OlmAccount
- new file olm_utility.cpp to have a stand alone function to initialize/alloc a random buffer
- new class OlmMessage
- complete OlmSession API with encryptMessage()
- comments review
- OlmAccount unit tests are green
- new gradle to compile the shared lib according to debug mode
Diffstat (limited to 'java/android/OlmLibSdk/olm-sdk/src/main/jni')
7 files changed, 265 insertions, 48 deletions
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/Android.mk b/java/android/OlmLibSdk/olm-sdk/src/main/jni/Android.mk index d59f916..26a6a90 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/Android.mk +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/Android.mk @@ -44,7 +44,8 @@ $(SRC_ROOT_DIR)/lib/crypto-algorithms/sha256.c \ $(SRC_ROOT_DIR)/lib/crypto-algorithms/aes.c \ $(SRC_ROOT_DIR)/lib/curve25519-donna/curve25519-donna.c \ olm_account.cpp \ -olm_session.cpp +olm_session.cpp \ +olm_utility.cpp LOCAL_LDLIBS := -llog 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 d8ee409..51c0ca8 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 @@ -15,7 +15,7 @@ */ #include "olm_account.h" - +#include "olm_utility.h" /** * Init memory allocation for account creation. @@ -70,10 +70,10 @@ JNIEXPORT void JNICALL Java_org_matrix_olm_OlmAccount_releaseAccountJni(JNIEnv * **/ JNIEXPORT jlong JNICALL Java_org_matrix_olm_OlmAccount_initNewAccountJni(JNIEnv *env, jobject thiz) { - OlmAccount* accountPtr = NULL; + OlmAccount *accountPtr = NULL; + uint8_t *randomBuffPtr = NULL; size_t accountRetCode; - uint8_t* randomBuffPtr = NULL; - int randomSize; + size_t randomSize; // init account memory allocation if(NULL == (accountPtr = initializeAccountMemory())) @@ -84,36 +84,34 @@ JNIEXPORT jlong JNICALL Java_org_matrix_olm_OlmAccount_initNewAccountJni(JNIEnv { // allocate random buffer randomSize = olm_create_account_random_length(accountPtr); - if(NULL == (randomBuffPtr = (std::uint8_t*)malloc(randomSize*sizeof(std::uint8_t)))) + if(false == setRandomInBuffer(&randomBuffPtr, randomSize)) { - LOGE("## initNewAccount(): failure - random buffer OOM"); + LOGE("## initNewAccount(): failure - random buffer init"); } else - { // create random buffer - LOGD("## initNewAccount(): randomSize=%d",randomSize); - - srand(time(NULL)); // init seed - for(int i=0;i<randomSize;i++) - { - randomBuffPtr[i] = (std::uint8_t)(rand()%ACCOUNT_CREATION_RANDOM_MODULO);; - } - + { // create account - accountRetCode = olm_create_account(accountPtr, randomBuffPtr, randomSize); + accountRetCode = olm_create_account(accountPtr, (void*)randomBuffPtr, randomSize); if(accountRetCode == olm_error()) { const char *errorMsgPtr = olm_account_last_error(accountPtr); LOGE("## initNewAccount(): failure - account creation failed Msg=%s", errorMsgPtr); } - free(randomBuffPtr); LOGD("## initNewAccount(): success - OLM account created"); LOGD("## initNewAccount(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr); } } + if(NULL != randomBuffPtr) + { + free(randomBuffPtr); + } + return (jlong)(intptr_t)accountPtr; } + + // ********************************************************************* // ************************* IDENTITY KEYS API ************************* // ********************************************************************* @@ -202,10 +200,10 @@ JNIEXPORT jlong JNICALL Java_org_matrix_olm_OlmAccount_maxOneTimeKeys(JNIEnv *en **/ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmAccount_generateOneTimeKeys(JNIEnv *env, jobject thiz, jint aNumberOfKeys) { - OlmAccount* accountPtr = NULL;; + OlmAccount *accountPtr = NULL; + uint8_t *randomBufferPtr = NULL; jint retCode = ERROR_CODE_KO; - size_t length; - void* keysBytesPtr; // TODO check type: or uint8_t? + size_t randomLength; size_t result; LOGD("## generateOneTimeKeys(): accountPtr =%p aNumberOfKeys=%d",accountPtr, aNumberOfKeys); @@ -216,15 +214,16 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmAccount_generateOneTimeKeys(JNIEnv } else { // keys memory allocation - length = olm_account_generate_one_time_keys_random_length(accountPtr, aNumberOfKeys); - LOGD("## generateOneTimeKeys(): randomLength=%ld", length); - if(NULL == (keysBytesPtr=(void*)malloc(length*sizeof(void*)))) + randomLength = olm_account_generate_one_time_keys_random_length(accountPtr, aNumberOfKeys); + LOGD("## generateOneTimeKeys(): randomLength=%ld", randomLength); + + if(false == setRandomInBuffer(&randomBufferPtr, randomLength)) { - LOGE("## generateOneTimeKeys(): failure - random allocation OOM"); + LOGE("## generateOneTimeKeys(): failure - random buffer init"); } else { // retrieve key pairs in keysBytesPtr - result = olm_account_generate_one_time_keys(accountPtr, aNumberOfKeys, keysBytesPtr, length); + result = olm_account_generate_one_time_keys(accountPtr, aNumberOfKeys, (void*)randomBufferPtr, randomLength); if(result == olm_error()) { const char *errorMsgPtr = olm_account_last_error(accountPtr); LOGE("## generateOneTimeKeys(): failure - error generating one time keys Msg=%s",errorMsgPtr); @@ -234,11 +233,14 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmAccount_generateOneTimeKeys(JNIEnv retCode = ERROR_CODE_OK; LOGD("## generateOneTimeKeys(): success - result=%ld", result); } - - free(keysBytesPtr); } } + if(NULL != randomBufferPtr) + { + free(randomBufferPtr); + } + return retCode; } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h index a504333..1e85cc1 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h @@ -34,7 +34,7 @@ static const int ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS = ERROR_CODE_OK+1; static const int ERROR_CODE_KO = -1; // constants -static const int ACCOUNT_CREATION_RANDOM_MODULO = 500; +static const int ACCOUNT_CREATION_RANDOM_MODULO = 256; typedef struct _AccountContext diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp index 22544d4..93b0658 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp @@ -15,6 +15,7 @@ */ #include "olm_session.h" +#include "olm_utility.h" /** @@ -95,7 +96,9 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initOutboundSessionJni(JNI jint retCode = ERROR_CODE_KO; OlmSession* sessionPtr = NULL; OlmAccount* accountPtr = NULL; - void *randomBuffPtr; + const char* theirIdentityKeyPtr = NULL; + const char* theirOneTimeKeyPtr = NULL; + uint8_t *randomBuffPtr = NULL; size_t sessionResult; if(NULL == (sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) @@ -113,15 +116,12 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initOutboundSessionJni(JNI else { // allocate random buffer size_t randomSize = olm_create_outbound_session_random_length(sessionPtr); - if(NULL == (randomBuffPtr = (void*)malloc(randomSize*sizeof(void*)))) + if(false == setRandomInBuffer(&randomBuffPtr, randomSize)) { - LOGE("## initOutboundSessionJni(): failure - random buffer OOM"); + LOGE("## initOutboundSessionJni(): failure - random buffer init"); } else { // convert identity & one time keys to C strings - const char* theirIdentityKeyPtr = NULL; - const char* theirOneTimeKeyPtr = NULL; - if(NULL == (theirIdentityKeyPtr = env->GetStringUTFChars(aTheirIdentityKey, 0))) { LOGE("## initOutboundSessionJni(): failure - identityKey JNI allocation OOM"); @@ -136,7 +136,14 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initOutboundSessionJni(JNI int theirOneTimeKeyLength = env->GetStringUTFLength(aTheirOneTimeKey); LOGD("## initOutboundSessionJni(): identityKey=%s oneTimeKey=%s",theirIdentityKeyPtr,theirOneTimeKeyPtr); - sessionResult = olm_create_outbound_session(sessionPtr, accountPtr, theirIdentityKeyPtr, theirIdentityKeyLength, theirOneTimeKeyPtr, theirOneTimeKeyLength, randomBuffPtr, randomSize); + sessionResult = olm_create_outbound_session(sessionPtr, + accountPtr, + theirIdentityKeyPtr, + theirIdentityKeyLength, + theirOneTimeKeyPtr, + theirOneTimeKeyLength, + (void*)randomBuffPtr, + randomSize); if(sessionResult == olm_error()) { const char *errorMsgPtr = olm_session_last_error(sessionPtr); LOGE("## initOutboundSessionJni(): failure - session creation Msg=%s",errorMsgPtr); @@ -147,20 +154,25 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initOutboundSessionJni(JNI LOGD("## initOutboundSessionJni(): success - result=%ld", sessionResult); } } - - // free local alloc - free(randomBuffPtr); - if(NULL!= theirIdentityKeyPtr) - { - env->ReleaseStringUTFChars(aTheirIdentityKey, theirIdentityKeyPtr); - } - if(NULL!= theirOneTimeKeyPtr) - { - env->ReleaseStringUTFChars(aTheirOneTimeKey, theirOneTimeKeyPtr); - } } } + // **** free mem alloc *** + if(NULL!= randomBuffPtr) + { + free(randomBuffPtr); + } + + if(NULL!= theirIdentityKeyPtr) + { + env->ReleaseStringUTFChars(aTheirIdentityKey, theirIdentityKeyPtr); + } + + if(NULL!= theirOneTimeKeyPtr) + { + env->ReleaseStringUTFChars(aTheirOneTimeKey, theirOneTimeKeyPtr); + } + return retCode; } @@ -172,7 +184,7 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initOutboundSessionJni(JNI * Create a new in-bound session for sending/receiving messages from an * incoming PRE_KEY message.<br> * @param aOlmAccountId account instance - * @param aOneTimeKeyMsg PRE_KEY message TODO TBC + * @param aOneTimeKeyMsg PRE_KEY message * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise */ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initInboundSessionJni(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jstring aOneTimeKeyMsg) @@ -337,6 +349,12 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_matchesInboundSessionJni(J } } + // free local alloc + if(NULL!= messagePtr) + { + env->ReleaseStringUTFChars(aOneTimeKeyMsg, messagePtr); + } + return retCode; } @@ -392,11 +410,129 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_matchesInboundSessionFromI } } + // free local alloc + if(NULL!= theirIdentityKeyPtr) + { + env->ReleaseStringUTFChars(aTheirIdentityKey, theirIdentityKeyPtr); + } + + if(NULL!= messagePtr) + { + env->ReleaseStringUTFChars(aOneTimeKeyMsg, messagePtr); + } + return retCode; } /** + * Encrypt a message using the session. to a base64 ciphertext.<br> + * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). + * @param aTheirIdentityKey the identity key of the sender + * @param aOneTimeKeyMsg PRE KEY message + * @return ERROR_CODE_OK if match, ERROR_CODE_KO otherwise + */ +JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_encryptMessageJni(JNIEnv *env, jobject thiz, jstring aClearMsg, jobject aEncryptedMsg) +{ + jint retCode = ERROR_CODE_KO; + OlmSession *sessionPtr = NULL; + const char *clearMsgPtr = NULL; + uint8_t *randomBuffPtr = NULL; + void *encryptedMsgPtr = NULL; + jclass encryptedMsgJClass; + jfieldID encryptedMsgFieldId; + jfieldID typeMsgFieldId; + + + if(NULL == (sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) + { + LOGE("## encryptMessageJni(): failure - invalid Session ptr=NULL"); + } + else if(0 == aClearMsg) + { + LOGE("## encryptMessageJni(): failure - invalid clear message"); + } + else if(0 == aEncryptedMsg) + { + LOGE("## encryptMessageJni(): failure - invalid clear message"); + } + else if(NULL == (clearMsgPtr = env->GetStringUTFChars(aClearMsg, 0))) + { + LOGE("## encryptMessageJni(): failure - clear message JNI allocation OOM"); + } + else if(0 == (encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) + { + LOGE("## encryptMessageJni(): failure - unable to get crypted message class"); + } + else if(0 == (encryptedMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;"))) + { + LOGE("## encryptMessageJni(): failure - unable to get message field"); + } + else if(0 == (typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","I"))) + { + LOGE("## encryptMessageJni(): failure - unable to get message type field"); + } + else + { + // compute random buffer + size_t randomLength = olm_encrypt_random_length(sessionPtr); + if(false == setRandomInBuffer(&randomBuffPtr, randomLength)) + { + LOGE("## encryptMessageJni(): failure - random buffer init"); + } + else + { + // alloc buffer for encrypted message + size_t clearMsgLength = env->GetStringUTFLength(aClearMsg); + size_t encryptedMsgLength = olm_encrypt_message_length(sessionPtr, clearMsgLength); + if(NULL == (encryptedMsgPtr = (void*)malloc(encryptedMsgLength*sizeof(void*)))) + { + LOGE("## encryptMessageJni(): failure - random buffer OOM"); + } + + size_t result = olm_encrypt(sessionPtr, + (void const *)clearMsgPtr, + clearMsgLength, + randomBuffPtr, + randomLength, + encryptedMsgPtr, + encryptedMsgLength); + if(result == olm_error()) + { + const char *errorMsgPtr = olm_session_last_error(sessionPtr); + LOGE("## encryptMessageJni(): failure - Msg=%s",errorMsgPtr); + } + else + { + // update type: PRE KEY message or normal message + size_t messageType = olm_encrypt_message_type(sessionPtr); + env->SetLongField(aEncryptedMsg, typeMsgFieldId, (jlong)messageType); + + // update message + jstring encryptedStr = env->NewStringUTF((const char*)encryptedMsgPtr); + env->SetObjectField(aEncryptedMsg, encryptedMsgFieldId, (jobject)encryptedStr); + + retCode = ERROR_CODE_OK; + LOGD("## encryptMessageJni(): success - result=%lu Type=%lu encryptedMsg=%s", result, messageType, (const char*)encryptedMsgPtr); + } + } + } + + // free alloc + if(NULL != clearMsgPtr) + { + env->ReleaseStringUTFChars(aClearMsg, clearMsgPtr); + } + + if(NULL != randomBuffPtr) + { + free(randomBuffPtr); + } + + return retCode; +} + +/** * Get the session identifier for this session. * @return the session identifier if operation succeed, null otherwise */ diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h index edd1012..8e162b0 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h @@ -24,6 +24,8 @@ JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_initInboundSessionFromIdKe JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_matchesInboundSessionJni(JNIEnv *env, jobject thiz, jstring aOneTimeKeyMsg); JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_matchesInboundSessionFromIdKeyJni(JNIEnv *env, jobject thiz, jstring aTheirIdentityKey, jstring aOneTimeKeyMsg); +JNIEXPORT jint JNICALL Java_org_matrix_olm_OlmSession_encryptMessageJni(JNIEnv *env, jobject thiz, jstring aClearMsg, jobject aEncryptedMsg); + JNIEXPORT jstring JNICALL Java_org_matrix_olm_OlmSession_getSessionIdentifierJni(JNIEnv *env, jobject thiz); diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.cpp new file mode 100644 index 0000000..9abd228 --- /dev/null +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.cpp @@ -0,0 +1,60 @@ +/** + * Created by pedrocon on 06/10/2016. + */ +/* + * Copyright 2016 OpenMarket 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.h" +#include "olm_utility.h" + +/** +* 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(uint8_t **aBuffer2Ptr, size_t aRandomSize) +{ + bool retCode = false; + if(NULL == aBuffer2Ptr) + { + LOGD("## setRandomInBuffer(): failure - aBuffer=NULL"); + } + else if(0 == aRandomSize) + { + LOGD("## setRandomInBuffer(): failure - random size=0"); + } + else if(NULL == (*aBuffer2Ptr = (uint8_t*)malloc(aRandomSize*sizeof(uint8_t)))) + { + LOGD("## setRandomInBuffer(): failure - alloc mem OOM"); + } + else + { + LOGD("## setRandomInBuffer(): randomSize=%ld",aRandomSize); + + srand(time(NULL)); // init seed + for(size_t i=0;i<aRandomSize;i++) + { + (*aBuffer2Ptr)[i] = (uint8_t)(rand()%ACCOUNT_CREATION_RANDOM_MODULO); + + // TODO debug purpose - remove asap + LOGD("## setRandomInBuffer(): randomBuffPtr[%ld]=%d",i, (*aBuffer2Ptr)[i]); + } + + retCode = true; + } + return retCode; +}
\ No newline at end of file diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.h new file mode 100644 index 0000000..bf29eed --- /dev/null +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.h @@ -0,0 +1,16 @@ +#ifndef _OMLUTILITY_H +#define _OMLUTILITY_H + + +#ifdef __cplusplus +extern "C" { +#endif + +bool setRandomInBuffer(uint8_t **aBuffer2Ptr, size_t aRandomSize); + +#ifdef __cplusplus +} +#endif + + +#endif |