aboutsummaryrefslogtreecommitdiff
path: root/java/android/OlmLibSdk
diff options
context:
space:
mode:
Diffstat (limited to 'java/android/OlmLibSdk')
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java136
1 files changed, 133 insertions, 3 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 ea8d618..5b2418a 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
@@ -16,15 +16,27 @@
package org.matrix.olm;
+import android.text.TextUtils;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
+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;
// 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
@@ -46,11 +58,129 @@ public class OlmAccount implements Serializable {
/** account raw pointer value (OlmAccount*) returned by JNI.
* this value identifies uniquely the native account instance.
*/
- private long mNativeOlmAccountId;
+ private transient long mNativeOlmAccountId;
+
+ private transient SecureRandom mSecureRandom;
public OlmAccount() {
initNewAccount();
+ mSecureRandom = new SecureRandom();
+ }
+
+ 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));
+ }
+ keyRetValue = "1234567890";//strBuilder.toString();
+
+ return keyRetValue;
+ }
+
+ private void writeObject(ObjectOutputStream aOutStream) throws IOException, OlmException {
+ aOutStream.defaultWriteObject();
+
+ // generate serialization key
+ String key = getRandomKey();
+
+ // compute pickle string
+ StringBuffer errorMsg = new StringBuffer();
+ String pickledData = serializeDataWithKey(key, errorMsg);
+
+ if(null == pickledData) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SERIALIZATION, String.valueOf(errorMsg));
+ } else {
+ aOutStream.writeObject(key);
+ aOutStream.writeObject(pickledData);
+ }
+ }
+
+ private void readObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException, OlmException {
+ aInStream.defaultReadObject();
+ StringBuffer errorMsg = new StringBuffer();
+
+ String key = (String) aInStream.readObject();
+ String pickledData = (String) aInStream.readObject();
+
+ if(TextUtils.isEmpty(key)) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" key");
+
+ } else if(TextUtils.isEmpty(pickledData)) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" pickle");
+
+ } else if(!initNewAccount()) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION);
+
+ } else if(!initWithSerializedData(pickledData, key, errorMsg)) {
+ releaseAccount(); // prevent memory leak
+ throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, String.valueOf(errorMsg));
+
+ } else {
+ Log.d(LOG_TAG,"## readObject(): success");
+ }
+ }
+
+ /**
+ * Return an account as a base64 string.<br>
+ * The account is serialized and encrypted with aKey.
+ * In case of failure, an error human readable
+ * description is provide in aErrorMsg.
+ * @param aKey encryption key
+ * @param aErrorMsg error message description
+ * @return pickled base64 string if operation succeed, null otherwise
+ */
+ private String serializeDataWithKey(String aKey, StringBuffer aErrorMsg) {
+ String pickleRetValue = null;
+
+ // sanity check
+ if(null == aErrorMsg) {
+ Log.e(LOG_TAG,"## serializeDataWithKey(): invalid parameter - aErrorMsg=null");
+ } else if(TextUtils.isEmpty(aKey)) {
+ aErrorMsg.append("Invalid input parameters in serializeDataWithKey()");
+ } else {
+ aErrorMsg.setLength(0);
+ pickleRetValue = serializeDataWithKeyJni(aKey, aErrorMsg);
+ }
+
+ return pickleRetValue;
+ }
+ private native String serializeDataWithKeyJni(String aKey, StringBuffer aErrorMsg);
+
+
+ /**
+ * Loads an account from a pickled base64 string.<br>
+ * See {@link #serializeDataWithKey(String, StringBuffer)}
+ * @param aSerializedData pickled account in a base64 string format
+ * @param aKey key used to encrypted
+ * @param aErrorMsg error message description
+ * @return true if operation succeed, false otherwise
+ */
+ private boolean initWithSerializedData(String aSerializedData, String aKey, StringBuffer aErrorMsg) {
+ boolean retCode = false;
+ String jniError;
+
+ if(null == aErrorMsg) {
+ Log.e(LOG_TAG, "## initWithSerializedData(): invalid input error parameter");
+ } else {
+ aErrorMsg.setLength(0);
+
+ if (TextUtils.isEmpty(aSerializedData) || TextUtils.isEmpty(aKey)) {
+ Log.e(LOG_TAG, "## initWithSerializedData(): invalid input parameters");
+ } else if (null == (jniError = initWithSerializedDataJni(aSerializedData, aKey))) {
+ retCode = true;
+ } else {
+ aErrorMsg.append(jniError);
+ }
+ }
+
+ return retCode;
}
+ private native String initWithSerializedDataJni(String aSerializedData, String aKey);
/**
* Getter on the account ID.
@@ -86,8 +216,8 @@ public class OlmAccount implements Serializable {
private native long initNewAccountJni();
/**
- * Create and save the account native instance ID.
- * Wrapper for {@link #initNewAccountJni()}.<br>
+ * Create and initialize a new native account instance.<br>
+ * Wrapper for {@link #initNewAccountJni()}.
* To be called before any other API call.
* @return true if init succeed, false otherwise.
*/