aboutsummaryrefslogtreecommitdiff
path: root/java/android/OlmLibSdk/olm-sdk/src/main/jni
diff options
context:
space:
mode:
authorpedroGitt <pedro.contreiras@amdocs.com>2016-10-06 19:55:03 +0200
committerpedroGitt <pedro.contreiras@amdocs.com>2016-10-06 19:55:03 +0200
commit655c841cc3720d1bb9892d60a2d7ca136c90cfbd (patch)
treee598da0ee20e90620873e7c13d36c9b32a3fe8d4 /java/android/OlmLibSdk/olm-sdk/src/main/jni
parent0393ad68438669f60a6679c9e0f8010c7366c5ed (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')
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/Android.mk3
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp56
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h2
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp174
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h2
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.cpp60
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_utility.h16
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