aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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/OlmException.java2
-rw-r--r--android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java23
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.cpp124
-rw-r--r--android/olm-sdk/src/main/jni/olm_pk.h2
5 files changed, 195 insertions, 0 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/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/OlmPkDecryption.java b/android/olm-sdk/src/main/java/org/matrix/olm/OlmPkDecryption.java
index 1a33547..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,6 +75,17 @@ 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;
diff --git a/android/olm-sdk/src/main/jni/olm_pk.cpp b/android/olm-sdk/src/main/jni/olm_pk.cpp
index dce62d8..eff57a5 100644
--- a/android/olm-sdk/src/main/jni/olm_pk.cpp
+++ b/android/olm-sdk/src/main/jni/olm_pk.cpp
@@ -364,6 +364,79 @@ 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_private_key_length();
@@ -420,6 +493,57 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
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)))
+ {
+ 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 privateKeyRet;
+}
+
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(
JNIEnv *env, jobject thiz, jobject aEncryptedMsg
) {
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