aboutsummaryrefslogtreecommitdiff
path: root/android/olm-sdk/src
diff options
context:
space:
mode:
Diffstat (limited to 'android/olm-sdk/src')
-rw-r--r--android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java44
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java9
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java2
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java7
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java5
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java28
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java8
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java17
-rw-r--r--android/olm-sdk/src/main/jni/olm_account.cpp14
-rw-r--r--android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp18
-rw-r--r--android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp12
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.cpp132
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.h2
-rw-r--r--android/olm-sdk/src/main/jni/olm_session.cpp12
-rw-r--r--android/olm-sdk/src/main/jni/olm_utility.cpp14
15 files changed, 295 insertions, 29 deletions
diff --git a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
index 04b2217..1577f3b 100644
--- a/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
+++ b/android/olm-sdk/src/androidTest/java/org/matrix/olm/OlmPkTest.java
@@ -19,6 +19,8 @@ package org.matrix.olm;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
+import java.util.Arrays;
+
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
@@ -91,4 +93,46 @@ public class OlmPkTest {
assertTrue(mOlmPkEncryption.isReleased());
assertTrue(mOlmPkDecryption.isReleased());
}
+
+ @Test
+ public void test02PrivateKey() {
+ try {
+ mOlmPkDecryption = new OlmPkDecryption();
+ } catch (OlmException e) {
+ e.printStackTrace();
+ assertTrue("OlmPkEncryption failed " + e.getMessage(), false);
+ }
+
+ assertNotNull(mOlmPkDecryption);
+
+ byte[] privateKey = {
+ (byte)0x77, (byte)0x07, (byte)0x6D, (byte)0x0A,
+ (byte)0x73, (byte)0x18, (byte)0xA5, (byte)0x7D,
+ (byte)0x3C, (byte)0x16, (byte)0xC1, (byte)0x72,
+ (byte)0x51, (byte)0xB2, (byte)0x66, (byte)0x45,
+ (byte)0xDF, (byte)0x4C, (byte)0x2F, (byte)0x87,
+ (byte)0xEB, (byte)0xC0, (byte)0x99, (byte)0x2A,
+ (byte)0xB1, (byte)0x77, (byte)0xFB, (byte)0xA5,
+ (byte)0x1D, (byte)0xB9, (byte)0x2C, (byte)0x2A
+ };
+
+ try {
+ mOlmPkDecryption.setPrivateKey(privateKey);
+ } catch (OlmException e) {
+ assertTrue("Exception in setPrivateKey, Exception code=" + e.getExceptionCode(), false);
+ }
+
+ byte[] privateKeyCopy = null;
+
+ try {
+ privateKeyCopy = mOlmPkDecryption.privateKey();
+ } catch (OlmException e) {
+ assertTrue("Exception in privateKey, Exception code=" + e.getExceptionCode(), false);
+ }
+
+ assertTrue(Arrays.equals(privateKey, privateKeyCopy));
+
+ mOlmPkDecryption.releaseDecryption();
+ assertTrue(mOlmPkDecryption.isReleased());
+ }
}
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
index 26c3e60..98a3c5b 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.Map;
/**
@@ -290,9 +291,9 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
String result = null;
if (null != aMessage) {
+ byte[] utf8String = null;
try {
- byte[] utf8String = aMessage.getBytes("UTF-8");
-
+ utf8String = aMessage.getBytes("UTF-8");
if (null != utf8String) {
byte[] signedMessage = signMessageJni(utf8String);
@@ -302,6 +303,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
}
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE, e.getMessage());
+ } finally {
+ if (null != utf8String) {
+ Arrays.fill(utf8String, (byte) 0);
+ }
}
}
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index 31b5729..5b534d5 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -68,6 +68,8 @@ public class OlmException extends IOException {
public static final int EXCEPTION_CODE_PK_DECRYPTION_CREATION = 700;
public static final int EXCEPTION_CODE_PK_DECRYPTION_GENERATE_KEY = 701;
public static final int EXCEPTION_CODE_PK_DECRYPTION_DECRYPT = 702;
+ public static final int EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY = 703;
+ public static final int EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY = 704;
// exception human readable messages
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters";
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
index b41c67a..2fc81ef 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
@@ -77,10 +77,16 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
Log.e(LOG_TAG, "## initInboundGroupSession(): invalid session key");
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, "invalid session key");
} else {
+ byte[] sessionBuffer = null;
try {
+ sessionBuffer = aSessionKey.getBytes("UTF-8");
mNativeId = createNewSessionJni(aSessionKey.getBytes("UTF-8"), isImported);
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, e.getMessage());
+ } finally {
+ if (null != sessionBuffer) {
+ Arrays.fill(sessionBuffer, (byte) 0);
+ }
}
}
}
@@ -216,6 +222,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
if (null != bytesBuffer) {
result = new String(bytesBuffer, "UTF-8");
+ Arrays.fill(bytesBuffer, (byte) 0);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## export() failed " + e.getMessage());
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
index e4d4a44..55732fe 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
@@ -142,7 +142,10 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
*/
public String sessionKey() throws OlmException {
try {
- return new String(sessionKeyJni(), "UTF-8");
+ byte[] sessionKeyBuffer = sessionKeyJni();
+ String ret = new String(sessionKeyBuffer, "UTF-8");
+ Arrays.fill(sessionKeyBuffer, (byte) 0);
+ return ret;
} catch (Exception e) {
Log.e(LOG_TAG, "## sessionKey() failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY, e.getMessage());
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java
index ea838f1..6522f70 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java
@@ -51,6 +51,18 @@ public class OlmPkDecryption {
return (0 == mNativeId);
}
+ public String setPrivateKey(byte[] privateKey) throws OlmException {
+ try {
+ byte[] key = setPrivateKeyJni(privateKey);
+ return new String(key, "UTF-8");
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "## setPrivateKey(): failed " + e.getMessage());
+ throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_SET_PRIVATE_KEY, e.getMessage());
+ }
+ }
+
+ private native byte[] setPrivateKeyJni(byte[] privateKey);
+
public String generateKey() throws OlmException {
try {
byte[] key = generateKeyJni();
@@ -63,19 +75,31 @@ public class OlmPkDecryption {
private native byte[] generateKeyJni();
+ public byte[] privateKey() throws OlmException {
+ try {
+ return privateKeyJni();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "## privateKey(): failed " + e.getMessage());
+ throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_PRIVATE_KEY, e.getMessage());
+ }
+ }
+
+ private native byte[] privateKeyJni();
+
public String decrypt(OlmPkMessage aMessage) throws OlmException {
if (null == aMessage) {
return null;
}
+ byte[] plaintextBuffer = decryptJni(aMessage);
try {
- byte[] plaintextBuffer = decryptJni(aMessage);
String plaintext = new String(plaintextBuffer, "UTF-8");
- Arrays.fill(plaintextBuffer, (byte) 0);
return plaintext;
} catch (Exception e) {
Log.e(LOG_TAG, "## pkDecrypt(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_DECRYPT, e.getMessage());
+ } finally {
+ Arrays.fill(plaintextBuffer, (byte) 0);
}
}
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java
index a2ccf2e..01666fd 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkEncryption.java
@@ -73,10 +73,10 @@ public class OlmPkEncryption {
OlmPkMessage encryptedMsgRetValue = new OlmPkMessage();
+ byte[] plaintextBuffer = null;
try {
- byte[] plaintextBuffer = aPlaintext.getBytes("UTF-8");
+ plaintextBuffer = aPlaintext.getBytes("UTF-8");
byte[] ciphertextBuffer = encryptJni(plaintextBuffer, encryptedMsgRetValue);
- Arrays.fill(plaintextBuffer, (byte) 0);
if (null != ciphertextBuffer) {
encryptedMsgRetValue.mCipherText = new String(ciphertextBuffer, "UTF-8");
@@ -84,6 +84,10 @@ public class OlmPkEncryption {
} catch (Exception e) {
Log.e(LOG_TAG, "## pkEncrypt(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_ENCRYPTION_ENCRYPT, e.getMessage());
+ } finally {
+ if (null != plaintextBuffer) {
+ Arrays.fill(plaintextBuffer, (byte) 0);
+ }
}
return encryptedMsgRetValue;
diff --git a/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java
index bf9ef90..250cfb1 100644
--- a/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java
+++ b/android/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java
@@ -23,6 +23,7 @@ import android.util.Log;
import org.json.JSONObject;
import java.security.SecureRandom;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -81,17 +82,23 @@ public class OlmUtility {
*/
public void verifyEd25519Signature(String aSignature, String aFingerprintKey, String aMessage) throws OlmException {
String errorMessage;
+ byte[] messageBuffer = null;
try {
if (TextUtils.isEmpty(aSignature) || TextUtils.isEmpty(aFingerprintKey) || TextUtils.isEmpty(aMessage)) {
Log.e(LOG_TAG, "## verifyEd25519Signature(): invalid input parameters");
errorMessage = "JAVA sanity check failure - invalid input parameters";
} else {
- errorMessage = verifyEd25519SignatureJni(aSignature.getBytes("UTF-8"), aFingerprintKey.getBytes("UTF-8"), aMessage.getBytes("UTF-8"));
+ messageBuffer = aMessage.getBytes("UTF-8");
+ errorMessage = verifyEd25519SignatureJni(aSignature.getBytes("UTF-8"), aFingerprintKey.getBytes("UTF-8"), messageBuffer);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## verifyEd25519Signature(): failed " + e.getMessage());
errorMessage = e.getMessage();
+ } finally {
+ if (messageBuffer != null) {
+ Arrays.fill(messageBuffer, (byte) 0);
+ }
}
if (!TextUtils.isEmpty(errorMessage)) {
@@ -119,10 +126,16 @@ public class OlmUtility {
String hashRetValue = null;
if (null != aMessageToHash) {
+ byte[] messageBuffer = null;
try {
- hashRetValue = new String(sha256Jni(aMessageToHash.getBytes("UTF-8")), "UTF-8");
+ messageBuffer = aMessageToHash.getBytes("UTF-8");
+ hashRetValue = new String(sha256Jni(messageBuffer), "UTF-8");
} catch (Exception e) {
Log.e(LOG_TAG, "## sha256(): failed " + e.getMessage());
+ } finally {
+ if (null != messageBuffer) {
+ Arrays.fill(messageBuffer, (byte) 0);
+ }
}
}
diff --git a/android/olm-sdk/src/main/jni/olm_account.cpp b/android/olm-sdk/src/main/jni/olm_account.cpp
index 40081ac..00b1460 100644
--- a/android/olm-sdk/src/main/jni/olm_account.cpp
+++ b/android/olm-sdk/src/main/jni/olm_account.cpp
@@ -528,6 +528,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
const char* errorMessage = NULL;
jbyteArray pickledDataRetValue = 0;
jbyte* keyPtr = NULL;
+ jboolean keyIsCopied = JNI_FALSE;
OlmAccount* accountPtr = NULL;
LOGD("## serializeJni(): IN");
@@ -542,7 +543,7 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
LOGE(" ## serializeJni(): failure - invalid account ptr");
errorMessage = "invalid account ptr";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, NULL)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyIsCopied)))
{
LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -586,6 +587,9 @@ JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
// free alloc
if (keyPtr)
{
+ if (keyIsCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
@@ -610,6 +614,7 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
OlmAccount* accountPtr = NULL;
jbyte* keyPtr = NULL;
+ jboolean keyIsCopied = JNI_FALSE;
jbyte* pickledPtr = NULL;
LOGD("## deserializeJni(): IN");
@@ -629,7 +634,7 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
LOGE(" ## deserializeJni(): failure - account failure OOM");
errorMessage = "account failure OOM";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyIsCopied)))
{
LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -665,6 +670,9 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
// free alloc
if (keyPtr)
{
+ if (keyIsCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
@@ -684,4 +692,4 @@ JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
}
return (jlong)(intptr_t)accountPtr;
-} \ No newline at end of file
+}
diff --git a/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp b/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp
index 114b7cd..ae9ecf1 100644
--- a/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp
+++ b/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp
@@ -62,6 +62,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *
const char* errorMessage = NULL;
OlmInboundGroupSession* sessionPtr = NULL;
jbyte* sessionKeyPtr = NULL;
+ jboolean sessionWasCopied = JNI_FALSE;
size_t sessionSize = olm_inbound_group_session_size();
LOGD("## createNewSessionJni(): inbound group session IN");
@@ -81,7 +82,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *
LOGE(" ## createNewSessionJni(): failure - invalid aSessionKey");
errorMessage = "invalid aSessionKey";
}
- else if (!(sessionKeyPtr = env->GetByteArrayElements(aSessionKeyBuffer, 0)))
+ else if (!(sessionKeyPtr = env->GetByteArrayElements(aSessionKeyBuffer, &sessionWasCopied)))
{
LOGE(" ## createNewSessionJni(): failure - session key JNI allocation OOM");
errorMessage = "Session key JNI allocation OOM";
@@ -119,6 +120,9 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *
if (sessionKeyPtr)
{
+ if (sessionWasCopied) {
+ memset(sessionKeyPtr, 0, (size_t)env->GetArrayLength(aSessionKeyBuffer));
+ }
env->ReleaseByteArrayElements(aSessionKeyBuffer, sessionKeyPtr, JNI_ABORT);
}
@@ -474,6 +478,7 @@ JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *en
jbyteArray pickledDataRet = 0;
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
OlmInboundGroupSession* sessionPtr = getInboundGroupSessionInstanceId(env, thiz);
LOGD("## inbound group session serializeJni(): IN");
@@ -488,7 +493,7 @@ JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *en
LOGE(" ## serializeJni(): failure - invalid key");
errorMessage = "invalid key";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -533,6 +538,9 @@ JNIEXPORT jbyteArray OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *en
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
@@ -558,6 +566,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
OlmInboundGroupSession* sessionPtr = NULL;
size_t sessionSize = olm_inbound_group_session_size();
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
jbyte* pickledPtr = NULL;
LOGD("## deserializeJni(): IN");
@@ -582,7 +591,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
LOGE(" ## deserializeJni(): failure - serialized data");
errorMessage = "serialized data";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -620,6 +629,9 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
diff --git a/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp b/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
index b11c474..a22122a 100644
--- a/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
+++ b/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
@@ -387,6 +387,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *e
jbyteArray returnValue = 0;
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
OlmOutboundGroupSession* sessionPtr = NULL;
LOGD("## outbound group session serializeJni(): IN");
@@ -401,7 +402,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *e
LOGE(" ## serializeJni(): failure - invalid key");
errorMessage = "invalid key";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -446,6 +447,9 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *e
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
@@ -471,6 +475,7 @@ JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
OlmOutboundGroupSession* sessionPtr = NULL;
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
jbyte* pickledPtr = NULL;
LOGD("## deserializeJni(): IN");
@@ -495,7 +500,7 @@ JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
LOGE(" ## deserializeJni(): failure - serialized data");
errorMessage = "invalid serialized data";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -532,6 +537,9 @@ JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env,
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
diff --git a/android/olm-sdk/src/main/jni/olm_pk.cpp b/android/olm-sdk/src/main/jni/olm_pk.cpp
index 12528de..eff57a5 100644
--- a/android/olm-sdk/src/main/jni/olm_pk.cpp
+++ b/android/olm-sdk/src/main/jni/olm_pk.cpp
@@ -364,9 +364,82 @@ JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, j
}
}
+JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key)
+{
+ jbyteArray publicKeyRet = 0;
+ jbyte *keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
+
+ const char* errorMessage = NULL;
+
+ OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz);
+
+ if (!decryptionPtr)
+ {
+ LOGE(" ## pkSetPrivateKeyJni(): failure - invalid Decryption ptr=NULL");
+ }
+ else if (!key)
+ {
+ LOGE(" ## pkSetPrivateKeyJni(): failure - invalid key");
+ errorMessage = "invalid key";
+ }
+ else if (!(keyPtr = env->GetByteArrayElements(key, &keyWasCopied)))
+ {
+ LOGE(" ## pkSetPrivateKeyJni(): failure - key JNI allocation OOM");
+ errorMessage = "key JNI allocation OOM";
+ }
+ else
+ {
+ size_t publicKeyLength = olm_pk_key_length();
+ uint8_t *publicKeyPtr = NULL;
+ size_t keyLength = (size_t)env->GetArrayLength(key);
+ if (!(publicKeyPtr = (uint8_t*)malloc(publicKeyLength)))
+ {
+ LOGE("## pkSetPrivateKeyJni(): failure - public key JNI allocation OOM");
+ errorMessage = "public key JNI allocation OOM";
+ }
+ else
+ {
+ size_t returnValue = olm_pk_key_from_private(
+ decryptionPtr,
+ publicKeyPtr, publicKeyLength,
+ keyPtr, keyLength
+ );
+ if (returnValue == olm_error())
+ {
+ errorMessage = olm_pk_decryption_last_error(decryptionPtr);
+ LOGE(" ## pkSetPrivateKeyJni(): failure - olm_pk_key_from_private Msg=%s", errorMessage);
+ }
+ else
+ {
+ publicKeyRet = env->NewByteArray(publicKeyLength);
+ env->SetByteArrayRegion(
+ publicKeyRet, 0, publicKeyLength, (jbyte*)publicKeyPtr
+ );
+ }
+ }
+ }
+
+ if (keyPtr)
+ {
+ if (keyWasCopied)
+ {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(key));
+ }
+ env->ReleaseByteArrayElements(key, keyPtr, JNI_ABORT);
+ }
+
+ if (errorMessage)
+ {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return publicKeyRet;
+}
+
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz)
{
- size_t randomLength = olm_pk_generate_key_random_length();
+ size_t randomLength = olm_pk_private_key_length();
uint8_t *randomBuffPtr = NULL;
jbyteArray publicKeyRet = 0;
@@ -393,7 +466,7 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
}
else
{
- if (olm_pk_generate_key(decryptionPtr, publicKeyPtr, publicKeyLength, randomBuffPtr, randomLength) == olm_error())
+ if (olm_pk_key_from_private(decryptionPtr, publicKeyPtr, publicKeyLength, randomBuffPtr, randomLength) == olm_error())
{
errorMessage = olm_pk_decryption_last_error(decryptionPtr);
LOGE("## pkGenerateKeyJni(): failure - olm_pk_generate_key Msg=%s", errorMessage);
@@ -414,16 +487,61 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
if (errorMessage)
{
- // release the allocated data
- if (decryptionPtr)
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+ }
+
+ return publicKeyRet;
+}
+
+JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz)
+{
+ jbyteArray privateKeyRet = 0;
+
+ const char* errorMessage = NULL;
+
+ OlmPkDecryption* decryptionPtr = getPkDecryptionInstanceId(env, thiz);
+
+ if (!decryptionPtr)
+ {
+ LOGE(" ## pkPrivateKeyJni(): failure - invalid Decryption ptr=NULL");
+ }
+ else
+ {
+ size_t privateKeyLength = olm_pk_private_key_length();
+ uint8_t *privateKeyPtr = NULL;
+ if (!(privateKeyPtr = (uint8_t*)malloc(privateKeyLength)))
{
- olm_clear_pk_decryption(decryptionPtr);
- free(decryptionPtr);
+ LOGE("## pkPrivateKeyJni(): failure - private key JNI allocation OOM");
+ errorMessage = "private key JNI allocation OOM";
+ }
+ else
+ {
+ size_t returnValue = olm_pk_get_private_key(
+ decryptionPtr,
+ privateKeyPtr, privateKeyLength
+ );
+ if (returnValue == olm_error())
+ {
+ errorMessage = olm_pk_decryption_last_error(decryptionPtr);
+ LOGE(" ## pkPrivateKeyJni(): failure - olm_pk_get_private_key Msg=%s", errorMessage);
+ }
+ else
+ {
+ privateKeyRet = env->NewByteArray(privateKeyLength);
+ env->SetByteArrayRegion(
+ privateKeyRet, 0, privateKeyLength, (jbyte*)privateKeyPtr
+ );
+ memset(privateKeyPtr, 0, privateKeyLength);
+ }
}
+ }
+
+ if (errorMessage)
+ {
env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
}
- return publicKeyRet;
+ return privateKeyRet;
}
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(
diff --git a/android/olm-sdk/src/main/jni/olm_pk.h b/android/olm-sdk/src/main/jni/olm_pk.h
index 984c5f8..5f45462 100644
--- a/android/olm-sdk/src/main/jni/olm_pk.h
+++ b/android/olm-sdk/src/main/jni/olm_pk.h
@@ -35,7 +35,9 @@ JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject
JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env, jobject thiz);
JNIEXPORT void OLM_PK_DECRYPTION_FUNC_DEF(releasePkDecryptionJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(setPrivateKeyJni)(JNIEnv *env, jobject thiz, jbyteArray key);
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(privateKeyJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg);
#ifdef __cplusplus
diff --git a/android/olm-sdk/src/main/jni/olm_session.cpp b/android/olm-sdk/src/main/jni/olm_session.cpp
index b9db286..15ad4fe 100644
--- a/android/olm-sdk/src/main/jni/olm_session.cpp
+++ b/android/olm-sdk/src/main/jni/olm_session.cpp
@@ -810,6 +810,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
jbyteArray returnValue = 0;
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
OlmSession* sessionPtr = getSessionInstanceId(env, thiz);
LOGD("## serializeJni(): IN");
@@ -824,7 +825,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
LOGE(" ## serializeJni(): failure - invalid key");
errorMessage = "invalid key";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "ikeyPtr JNI allocation OOM";
@@ -869,6 +870,9 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thi
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
@@ -892,6 +896,7 @@ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
const char* errorMessage = NULL;
OlmSession* sessionPtr = initializeSessionMemory();
jbyte* keyPtr = NULL;
+ jboolean keyWasCopied = JNI_FALSE;
jbyte* pickledPtr = NULL;
LOGD("## deserializeJni(): IN");
@@ -911,7 +916,7 @@ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
LOGE(" ## deserializeJni(): failure - serialized data");
errorMessage = "serialized data";
}
- else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
{
LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
errorMessage = "keyPtr JNI allocation OOM";
@@ -947,6 +952,9 @@ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz,
// free alloc
if (keyPtr)
{
+ if (keyWasCopied) {
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
+ }
env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
}
diff --git a/android/olm-sdk/src/main/jni/olm_utility.cpp b/android/olm-sdk/src/main/jni/olm_utility.cpp
index f6fe719..da27eda 100644
--- a/android/olm-sdk/src/main/jni/olm_utility.cpp
+++ b/android/olm-sdk/src/main/jni/olm_utility.cpp
@@ -90,6 +90,7 @@ JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, j
jbyte* signaturePtr = NULL;
jbyte* keyPtr = NULL;
jbyte* messagePtr = NULL;
+ jboolean messageWasCopied = JNI_FALSE;
LOGD("## verifyEd25519SignatureJni(): IN");
@@ -109,7 +110,7 @@ JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, j
{
LOGE(" ## verifyEd25519SignatureJni(): failure - key JNI allocation OOM");
}
- else if (!(messagePtr = env->GetByteArrayElements(aMessageBuffer, 0)))
+ else if (!(messagePtr = env->GetByteArrayElements(aMessageBuffer, &messageWasCopied)))
{
LOGE(" ## verifyEd25519SignatureJni(): failure - message JNI allocation OOM");
}
@@ -152,6 +153,9 @@ JNIEXPORT jstring OLM_UTILITY_FUNC_DEF(verifyEd25519SignatureJni)(JNIEnv *env, j
if (messagePtr)
{
+ if (messageWasCopied) {
+ memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageBuffer));
+ }
env->ReleaseByteArrayElements(aMessageBuffer, messagePtr, JNI_ABORT);
}
@@ -171,6 +175,7 @@ JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz,
OlmUtility* utilityPtr = getUtilityInstanceId(env, thiz);
jbyte* messagePtr = NULL;
+ jboolean messageWasCopied = JNI_FALSE;
LOGD("## sha256Jni(): IN");
@@ -182,7 +187,7 @@ JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz,
{
LOGE(" ## sha256Jni(): failure - invalid message parameters ");
}
- else if(!(messagePtr = env->GetByteArrayElements(aMessageToHashBuffer, 0)))
+ else if(!(messagePtr = env->GetByteArrayElements(aMessageToHashBuffer, &messageWasCopied)))
{
LOGE(" ## sha256Jni(): failure - message JNI allocation OOM");
}
@@ -221,8 +226,11 @@ JNIEXPORT jbyteArray OLM_UTILITY_FUNC_DEF(sha256Jni)(JNIEnv *env, jobject thiz,
if (messagePtr)
{
+ if (messageWasCopied) {
+ memset(messagePtr, 0, (size_t)env->GetArrayLength(aMessageToHashBuffer));
+ }
env->ReleaseByteArrayElements(aMessageToHashBuffer, messagePtr, JNI_ABORT);
}
return sha256Ret;
-} \ No newline at end of file
+}