aboutsummaryrefslogtreecommitdiff
path: root/java/android/OlmLibSdk/olm-sdk/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'java/android/OlmLibSdk/olm-sdk/src/main')
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java72
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java2
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.cpp183
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h5
4 files changed, 230 insertions, 32 deletions
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
index 5b2418a..61b6c52 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
@@ -26,17 +26,13 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-import java.math.BigInteger;
-import java.security.SecureRandom;
-import java.util.Arrays;
import java.util.Random;
public class OlmAccount implements Serializable {
private static final long serialVersionUID = 3497486121598434824L;
private static final String LOG_TAG = "OlmAccount";
- private static final int MAX_BITS_LENGTH = 128;
- private static final int RANDOM_TAB_SIZE = 32;
- private static final int RANDOM_MAX = 256;
+ private static final int RANDOM_KEY_SIZE = 32;
+ private static final int RANDOM_RANGE = 256;
// JSON keys used in the JSON objects returned by JNI
/** As well as the identity key, each device creates a number of Curve25519 key pairs which are
@@ -60,24 +56,22 @@ public class OlmAccount implements Serializable {
*/
private transient long mNativeOlmAccountId;
- private transient SecureRandom mSecureRandom;
- public OlmAccount() {
- initNewAccount();
- mSecureRandom = new SecureRandom();
+ public OlmAccount() throws OlmException {
+ if(!initNewAccount()) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION,OlmException.EXCEPTION_MSG_INIT_ACCOUNT_CREATION);
+ }
}
private String getRandomKey() {
- //String keyRetValue = new BigInteger(MAX_BITS_LENGTH, mSecureRandom).toString(RANDOM_TAB_SIZE);
String keyRetValue;
Random rand = new Random();
-
StringBuilder strBuilder = new StringBuilder();
- for(int i=0;i<RANDOM_TAB_SIZE;i++) {
- strBuilder.append(rand.nextInt(RANDOM_MAX));
+ for(int i = 0; i< OlmAccount.RANDOM_KEY_SIZE; i++) {
+ strBuilder.append(rand.nextInt(RANDOM_RANGE));
}
- keyRetValue = "1234567890";//strBuilder.toString();
+ keyRetValue = strBuilder.toString();
return keyRetValue;
}
@@ -113,7 +107,7 @@ public class OlmAccount implements Serializable {
} else if(TextUtils.isEmpty(pickledData)) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" pickle");
- } else if(!initNewAccount()) {
+ } else if(!createNewAccount()) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION);
} else if(!initWithSerializedData(pickledData, key, errorMsg)) {
@@ -191,6 +185,16 @@ public class OlmAccount implements Serializable {
}
/**
+ * Release native account and invalid its JAVA reference counter part.<br>
+ * Public API for {@link #releaseAccountJni()}.
+ */
+ public void releaseAccount(){
+ releaseAccountJni();
+
+ mNativeOlmAccountId = 0;
+ }
+
+ /**
* Destroy the corresponding OLM account native object.<br>
* This method must ALWAYS be called when this JAVA instance
* is destroyed (ie. garbage collected) to prevent memory leak in native side.
@@ -199,37 +203,49 @@ public class OlmAccount implements Serializable {
private native void releaseAccountJni();
/**
- * Release native account and invalid its JAVA reference counter part.<br>
- * Public API for {@link #releaseAccountJni()}.
+ * Create and initialize a native account instance.<br>
+ * Wrapper for {@link #initNewAccountJni()}.
+ * To be called before any other API call.
+ * @return true if init succeed, false otherwise.
*/
- public void releaseAccount(){
- releaseAccountJni();
-
- mNativeOlmAccountId = 0;
+ private boolean initNewAccount() {
+ boolean retCode = false;
+ if(0 != (mNativeOlmAccountId = initNewAccountJni())){
+ retCode = true;
+ }
+ return retCode;
}
/**
- * Create the corresponding OLM account in native side.<br>
+ * Create and initialize an OLM account in native side.<br>
* Do not forget to call {@link #releaseAccount()} when JAVA side is done.
* @return native account instance identifier (see {@link #mNativeOlmAccountId})
*/
private native long initNewAccountJni();
/**
- * Create and initialize a new native account instance.<br>
- * Wrapper for {@link #initNewAccountJni()}.
- * To be called before any other API call.
+ * Create a native account instance without any initialization.<br>
+ * Since the account is left uninitialized, this
+ * method is intended to be used in the serialization mechanism (see {@link #readObject(ObjectInputStream)}).<br>
+ * Public wrapper for {@link #createNewAccountJni()}.
* @return true if init succeed, false otherwise.
*/
- private boolean initNewAccount() {
+ private boolean createNewAccount() {
boolean retCode = false;
- if(0 != (mNativeOlmAccountId = initNewAccountJni())){
+ if(0 != (mNativeOlmAccountId = createNewAccountJni())){
retCode = true;
}
return retCode;
}
/**
+ * Create an OLM account in native side.<br>
+ * Do not forget to call {@link #releaseAccount()} when JAVA side is done.
+ * @return native account instance identifier (see {@link #mNativeOlmAccountId})
+ */
+ private native long createNewAccountJni();
+
+ /**
* Return the identity keys (identity &amp fingerprint keys) in a JSON array.<br>
* Public API for {@link #identityKeysJni()}.<br>
* Ex:<tt>
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index 97589f0..b83e77c 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -29,6 +29,7 @@ public class OlmException extends Exception {
public static final int EXCEPTION_CODE_ACCOUNT_DESERIALIZATION = 5;
public static final int EXCEPTION_CODE_SESSION_SERIALIZATION = 6;
public static final int EXCEPTION_CODE_SESSION_DESERIALIZATION = 7;
+ public static final int EXCEPTION_CODE_INIT_ACCOUNT_CREATION = 8;
// exception human readable messages
public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "failed to create a new outbound group Session";
@@ -38,6 +39,7 @@ public class OlmException extends Exception {
public static final String EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION = "initNewAccount() failure";
public static final String EXCEPTION_MSG_INIT_ACCOUNT_DESERIALIZATION = "initWithSerializedData() failure";
public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid deserialized parameters";
+ public static final String EXCEPTION_MSG_INIT_ACCOUNT_CREATION = "Account constructor failure";
/** exception code to be taken from: {@link #EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION} {@link #EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION}
* {@link #EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION} {@link #EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION}**/
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 a10b8e0..6f2e6ee 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
@@ -40,6 +40,17 @@ OlmAccount* initializeAccountMemory()
return accountPtr;
}
+
+JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz)
+{
+ LOGD("## createNewAccountJni(): IN");
+ OlmAccount* accountPtr = initializeAccountMemory();
+
+ LOGD(" ## createNewAccountJni(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr);
+ return (jlong)(intptr_t)accountPtr;
+}
+
+
/**
* Release the account allocation made by initializeAccountMemory().<br>
* This method MUST be called when java counter part account instance is done.
@@ -49,20 +60,21 @@ JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz
{
OlmAccount* accountPtr = NULL;
- LOGD("## releaseAccountJni(): accountPtr=%p",accountPtr);
+ LOGD("## releaseAccountJni(): IN");
if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
{
- LOGE("## releaseAccountJni(): failure - invalid Account ptr=NULL");
+ LOGE(" ## releaseAccountJni(): failure - invalid Account ptr=NULL");
}
else
{
+ LOGD(" ## releaseAccountJni(): accountPtr=%p",accountPtr);
olm_clear_account(accountPtr);
- LOGD("## releaseAccountJni(): IN");
+ LOGD(" ## releaseAccountJni(): IN");
// even if free(NULL) does not crash, logs are performed for debug purpose
free(accountPtr);
- LOGD("## releaseAccountJni(): OUT");
+ LOGD(" ## releaseAccountJni(): OUT");
}
}
@@ -467,4 +479,167 @@ JNIEXPORT jstring OLM_MANAGER_FUNC_DEF(getOlmLibVersion)(JNIEnv* env, jobject th
return returnValueStr;
}
+/**
+* Serialize and encrypt account instance into a base64 string.<br>
+* @param aKey key used to encrypt the serialized account data
+* @param[out] aErrorMsg error message set if operation failed
+* @return a base64 string if operation succeed, null otherwise
+**/
+JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg)
+{
+ jstring pickledDataRetValue = 0;
+ jclass errorMsgJClass = 0;
+ jmethodID errorMsgMethodId = 0;
+ jstring errorJstring = 0;
+ const char *keyPtr = NULL;
+ void *pickledPtr = NULL;
+ OlmAccount* accountPtr = NULL;
+
+ LOGD("## serializeDataWithKeyJni(): IN");
+
+ if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - invalid account ptr");
+ }
+ else if(0 == aKey)
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - invalid key");
+ }
+ else if(0 == aErrorMsg)
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - invalid error object");
+ }
+ else if(0 == (errorMsgJClass = env->GetObjectClass(aErrorMsg)))
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error class");
+ }
+ else if(0 == (errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")))
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error method ID");
+ }
+ else if(NULL == (keyPtr = env->GetStringUTFChars(aKey, 0)))
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - keyPtr JNI allocation OOM");
+ }
+ else
+ {
+ size_t pickledLength = olm_pickle_account_length(accountPtr);
+ size_t keyLength = (size_t)env->GetStringUTFLength(aKey);
+ LOGD(" ## serializeDataWithKeyJni(): pickledLength=%lu keyLength=%lu",pickledLength, keyLength);
+ LOGD(" ## serializeDataWithKeyJni(): key=%s",(char const *)keyPtr);
+
+ if(NULL == (pickledPtr = (void*)malloc((pickledLength+1)*sizeof(uint8_t))))
+ {
+ LOGE(" ## serializeDataWithKeyJni(): failure - pickledPtr buffer OOM");
+ }
+ else
+ {
+ size_t result = olm_pickle_account(accountPtr,
+ (void const *)keyPtr,
+ keyLength,
+ (void*)pickledPtr,
+ pickledLength);
+ if(result == olm_error())
+ {
+ const char *errorMsgPtr = olm_account_last_error(accountPtr);
+ LOGE(" ## serializeDataWithKeyJni(): failure - olm_pickle_account() Msg=%s",errorMsgPtr);
+
+ if(0 != (errorJstring = env->NewStringUTF(errorMsgPtr)))
+ {
+ env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring);
+ }
+ }
+ else
+ {
+ // build success output
+ (static_cast<char*>(pickledPtr))[pickledLength] = static_cast<char>('\0');
+ pickledDataRetValue = env->NewStringUTF((const char*)pickledPtr);
+ LOGD(" ## serializeDataWithKeyJni(): success - result=%lu pickled=%s", result, static_cast<char*>(pickledPtr));
+ }
+ }
+ }
+
+ // free alloc
+ if(NULL != keyPtr)
+ {
+ env->ReleaseStringUTFChars(aKey, keyPtr);
+ }
+
+ if(NULL != pickledPtr)
+ {
+ free(pickledPtr);
+ }
+
+ return pickledDataRetValue;
+}
+
+
+JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(initWithSerializedDataJni)(JNIEnv *env, jobject thiz, jstring aSerializedData, jstring aKey)
+{
+ OlmAccount* accountPtr = NULL;
+ jstring errorMessageRetValue = 0;
+ const char *keyPtr = NULL;
+ const char *pickledPtr = NULL;
+
+ LOGD("## initWithSerializedDataJni(): IN");
+
+ if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
+ //if(NULL == (accountPtr = initializeAccountMemory()))
+ {
+ LOGE(" ## initWithSerializedDataJni(): failure - account failure OOM");
+ }
+ else if(0 == aKey)
+ {
+ LOGE(" ## initWithSerializedDataJni(): failure - invalid key");
+ }
+ else if(0 == aSerializedData)
+ {
+ LOGE(" ## initWithSerializedDataJni(): failure - serialized data");
+ }
+ else if(NULL == (keyPtr = env->GetStringUTFChars(aKey, 0)))
+ {
+ LOGE(" ## initWithSerializedDataJni(): failure - keyPtr JNI allocation OOM");
+ }
+ else if(NULL == (pickledPtr = env->GetStringUTFChars(aSerializedData, 0)))
+ {
+ LOGE(" ## initWithSerializedDataJni(): failure - pickledPtr JNI allocation OOM");
+ }
+ else
+ {
+ size_t pickledLength = (size_t)env->GetStringUTFLength(aSerializedData);
+ size_t keyLength = (size_t)env->GetStringUTFLength(aKey);
+ LOGD(" ## initWithSerializedDataJni(): pickledLength=%lu keyLength=%lu",pickledLength, keyLength);
+ LOGD(" ## initWithSerializedDataJni(): key=%s",(char const *)keyPtr);
+ LOGD(" ## initWithSerializedDataJni(): pickled=%s",(char const *)pickledPtr);
+
+ size_t result = olm_unpickle_account(accountPtr,
+ (void const *)keyPtr,
+ keyLength,
+ (void*)pickledPtr,
+ pickledLength);
+ if(result == olm_error())
+ {
+ const char *errorMsgPtr = olm_account_last_error(accountPtr);
+ LOGE(" ## initWithSerializedDataJni(): failure - olm_unpickle_account() Msg=%s",errorMsgPtr);
+ errorMessageRetValue = env->NewStringUTF(errorMsgPtr);
+ }
+ else
+ {
+ LOGD(" ## initWithSerializedDataJni(): success - result=%lu ", result);
+ }
+
+ }
+
+ // free alloc
+ if(NULL != keyPtr)
+ {
+ env->ReleaseStringUTFChars(aKey, keyPtr);
+ }
+
+ if(NULL != pickledPtr)
+ {
+ env->ReleaseStringUTFChars(aSerializedData, pickledPtr);
+ }
+ return errorMessageRetValue;
+} \ No newline at end of file
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
index 63ec3ef..1c8fb96 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_account.h
@@ -32,6 +32,7 @@ JNIEXPORT jstring OLM_MANAGER_FUNC_DEF(getOlmLibVersion)(JNIEnv *env, jobject th
// account creation/destruction
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz);
JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz);
// identity keys
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz);
@@ -46,6 +47,10 @@ JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env,
// signing
JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jstring aMessage);
+// serialization
+JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg);
+JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(initWithSerializedDataJni)(JNIEnv *env, jobject thiz, jstring aSerializedData, jstring aKey);
+
#ifdef __cplusplus
}
#endif