From 643165067f4140d7cb3cba88f21b3fc8dd2d244f Mon Sep 17 00:00:00 2001
From: ylecollen <ylecollen@amdocs.com>
Date: Wed, 21 Dec 2016 15:10:54 +0100
Subject: [PATCH] setRandomInBuffer uses java.lang.SecureRandom.

---
 .../olm-sdk/src/main/jni/olm_account.cpp      |  4 +-
 .../OlmLibSdk/olm-sdk/src/main/jni/olm_jni.h  |  2 +-
 .../olm-sdk/src/main/jni/olm_jni_helper.cpp   | 70 ++++++++++++++++---
 .../main/jni/olm_outbound_group_session.cpp   |  2 +-
 .../olm-sdk/src/main/jni/olm_session.cpp      |  4 +-
 5 files changed, 68 insertions(+), 14 deletions(-)

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 00c8a8e..68dcc0b 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
@@ -104,7 +104,7 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thi
         LOGD("## initNewAccount(): randomSize=%lu", static_cast<long unsigned int>(randomSize));
 
         // allocate random buffer
-        if((0!=randomSize) && !setRandomInBuffer(&randomBuffPtr, randomSize))
+        if((0!=randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
         {
             LOGE("## initNewAccount(): failure - random buffer init");
         }
@@ -234,7 +234,7 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject
         randomLength = olm_account_generate_one_time_keys_random_length(accountPtr, (size_t)aNumberOfKeys);
         LOGD("## generateOneTimeKeysJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength));
 
-        if((0!=randomLength) && !setRandomInBuffer(&randomBufferPtr, randomLength))
+        if((0!=randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength))
         {
             LOGE("## generateOneTimeKeysJni(): failure - random buffer init");
         }
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 d70dc58..2c8430c 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
@@ -67,7 +67,7 @@ extern "C" {
 #endif
 
 // internal helper functions
-bool setRandomInBuffer(uint8_t **aBuffer2Ptr, size_t aRandomSize);
+bool setRandomInBuffer(JNIEnv *env, uint8_t **aBuffer2Ptr, size_t aRandomSize);
 jlong getSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
 jlong getAccountInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
 jlong getInboundGroupSessionInstanceId(JNIEnv* aJniEnv, jobject aJavaObject);
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp
index a0525dc..b52ac30 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_jni_helper.cpp
@@ -29,10 +29,11 @@ using namespace AndroidOlmSdk;
 * @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 setRandomInBuffer(JNIEnv *env, uint8_t **aBuffer2Ptr, size_t aRandomSize)
 {
     bool retCode = false;
     struct timeval timeValue;
+    int bufferLen = aRandomSize*sizeof(uint8_t);
 
     if(NULL == aBuffer2Ptr)
     {
@@ -42,7 +43,7 @@ bool setRandomInBuffer(uint8_t **aBuffer2Ptr, size_t aRandomSize)
     {
         LOGE("## setRandomInBuffer(): failure - random size=0");
     }
-    else if(NULL == (*aBuffer2Ptr = (uint8_t*)malloc(aRandomSize*sizeof(uint8_t))))
+    else if(NULL == (*aBuffer2Ptr = (uint8_t*)malloc(bufferLen)))
     {
         LOGE("## setRandomInBuffer(): failure - alloc mem OOM");
     }
@@ -50,16 +51,69 @@ bool setRandomInBuffer(uint8_t **aBuffer2Ptr, size_t aRandomSize)
     {
         LOGD("## setRandomInBuffer(): randomSize=%lu",static_cast<long unsigned int>(aRandomSize));
 
-        gettimeofday(&timeValue, NULL);
-        srand(timeValue.tv_usec); // init seed
+        bool secureRandomSucceeds = false;
 
-        for(size_t i=0;i<aRandomSize;i++)
+        // clear the buffer
+        memset(*aBuffer2Ptr, 0, bufferLen);
+
+        // use the secureRandom class
+        jclass cls = env->FindClass("java/security/SecureRandom");
+
+        if (cls)
         {
-            (*aBuffer2Ptr)[i] = (uint8_t)(rand()%ACCOUNT_CREATION_RANDOM_MODULO);
-            // debug purpose
-            //LOGD("## setRandomInBuffer(): randomBuffPtr[%ld]=%d",i, (*aBuffer2Ptr)[i]);
+            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);
+
+                    jbyte* buffer = env->GetByteArrayElements(tempByteArray,0);
+
+                    if (buffer)
+                    {
+                        memcpy(*aBuffer2Ptr, buffer, bufferLen);
+                        secureRandomSucceeds = true;
+                    }
+                }
+
+                if (tempByteArray)
+                {
+                    env->DeleteLocalRef(tempByteArray);
+                }
+
+                if (newObj)
+                {
+                    env->DeleteLocalRef(newObj);
+                }
+            }
         }
 
+        if (!secureRandomSucceeds)
+        {
+            LOGE("## setRandomInBuffer(): SecureRandom failed, use a fallback");
+
+            gettimeofday(&timeValue, NULL);
+            srand(timeValue.tv_usec); // init seed
+
+            for(size_t i=0;i<aRandomSize;i++)
+            {
+                (*aBuffer2Ptr)[i] = (uint8_t)(rand()%ACCOUNT_CREATION_RANDOM_MODULO);
+            }
+        }
+
+        // debug purpose
+        /*for(int i = 0; i < aRandomSize; i++)
+        {
+            LOGD("## setRandomInBuffer(): randomBuffPtr[%ld]=%d",i, (*aBuffer2Ptr)[i]);
+        }*/
+
         retCode = true;
     }
     return retCode;
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
index 59327b4..ca8f9ea 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
@@ -102,7 +102,7 @@ JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(
         // compute random buffer
         size_t randomLength = olm_init_outbound_group_session_random_length(sessionPtr);
         LOGW(" ## initOutboundGroupSessionJni(): randomLength=%lu",static_cast<long unsigned int>(randomLength));
-        if((0!=randomLength) && !setRandomInBuffer(&randomBuffPtr, randomLength))
+        if((0!=randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength))
         {
             LOGE(" ## initOutboundGroupSessionJni(): failure - random buffer init");
         }
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 011ad44..98897cb 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
@@ -132,7 +132,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject
     {   // allocate random buffer
         size_t randomSize = olm_create_outbound_session_random_length(sessionPtr);
         LOGD("## initOutboundSessionJni(): randomSize=%lu",static_cast<long unsigned int>(randomSize));
-        if((0!=randomSize) && !setRandomInBuffer(&randomBuffPtr, randomSize))
+        if((0!=randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
         {
             LOGE("## initOutboundSessionJni(): failure - random buffer init");
         }
@@ -497,7 +497,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz
         // it just does not need new random data to encrypt a new message
         size_t randomLength = olm_encrypt_random_length(sessionPtr);
         LOGD("## encryptMessageJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength));
-        if((0!=randomLength) && !setRandomInBuffer(&randomBuffPtr, randomLength))
+        if((0!=randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength))
         {
             LOGE("## encryptMessageJni(): failure - random buffer init");
         }
-- 
GitLab