aboutsummaryrefslogtreecommitdiff
path: root/java/android/OlmLibSdk/olm-sdk/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'java/android/OlmLibSdk/olm-sdk/src/main/java')
-rw-r--r--java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java35
-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/java/org/matrix/olm/OlmSession.java174
3 files changed, 162 insertions, 49 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 61b6c52..8d19a0c 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
@@ -31,8 +31,6 @@ 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 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
@@ -63,24 +61,17 @@ public class OlmAccount implements Serializable {
}
}
- private String getRandomKey() {
- String keyRetValue;
- Random rand = new Random();
- StringBuilder strBuilder = new StringBuilder();
-
- for(int i = 0; i< OlmAccount.RANDOM_KEY_SIZE; i++) {
- strBuilder.append(rand.nextInt(RANDOM_RANGE));
- }
- keyRetValue = strBuilder.toString();
-
- return keyRetValue;
- }
-
+ /**
+ * Kick off the serialization mechanism.
+ * @param aOutStream output stream for serializing
+ * @throws IOException
+ * @throws OlmException
+ */
private void writeObject(ObjectOutputStream aOutStream) throws IOException, OlmException {
aOutStream.defaultWriteObject();
// generate serialization key
- String key = getRandomKey();
+ String key = OlmUtility.getRandomKey();
// compute pickle string
StringBuffer errorMsg = new StringBuffer();
@@ -94,6 +85,13 @@ public class OlmAccount implements Serializable {
}
}
+ /**
+ * Kick off the deserialization mechanism.
+ * @param aInStream
+ * @throws IOException
+ * @throws ClassNotFoundException
+ * @throws OlmException
+ */
private void readObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException, OlmException {
aInStream.defaultReadObject();
StringBuffer errorMsg = new StringBuffer();
@@ -379,9 +377,4 @@ public class OlmAccount implements Serializable {
return signMessageJni(aMessage);
}
private native String signMessageJni(String aMessage);
-
- // TODO missing API: initWithSerializedData
- // TODO missing API: serializeDataWithKey
- // TODO missing API: initWithCoder
- // TODO missing API: encodeWithCoder
}
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 b83e77c..280dce1 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
@@ -30,6 +30,7 @@ public class OlmException extends Exception {
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;
+ public static final int EXCEPTION_CODE_INIT_SESSION_CREATION = 9;
// exception human readable messages
public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "failed to create a new outbound group Session";
@@ -40,6 +41,7 @@ public class OlmException extends Exception {
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";
+ public static final String EXCEPTION_MSG_INIT_SESSION_CREATION = "Session 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/java/org/matrix/olm/OlmSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
index 8574f95..ca74352 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
@@ -19,37 +19,146 @@ package org.matrix.olm;
import android.text.TextUtils;
import android.util.Log;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
public class OlmSession implements Serializable {
+ private static final long serialVersionUID = -8975488639186976419L;
private static final String LOG_TAG = "OlmSession";
/** session raw pointer value (OlmSession*) returned by JNI.
* this value uniquely identifies the native session instance.
**/
- private long mNativeOlmSessionId;
+ private transient long mNativeOlmSessionId;
- /** account instance associated with this session. **/
- private OlmAccount mOlmAccount;
- public OlmSession() {
- initNewSession();
+ public OlmSession() throws OlmException {
+ if(!initNewSession()) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_INIT_SESSION_CREATION, OlmException.EXCEPTION_MSG_INIT_SESSION_CREATION);
+ }
}
/**
- * Getter on the session ID.
- * @return native session ID
+ * Kick off the serialization mechanism.
+ * @param aOutStream output stream for serializing
+ * @throws IOException
+ * @throws OlmException
*/
- public long getOlmSessionId(){
- return mNativeOlmSessionId;
+ private void writeObject(ObjectOutputStream aOutStream) throws IOException, OlmException {
+ aOutStream.defaultWriteObject();
+
+ // generate serialization key
+ String key = OlmUtility.getRandomKey();
+
+ // compute pickle string
+ StringBuffer errorMsg = new StringBuffer();
+ String pickledData = serializeDataWithKey(key, errorMsg);
+
+ if(null == pickledData) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_SERIALIZATION, String.valueOf(errorMsg));
+ } else {
+ aOutStream.writeObject(key);
+ aOutStream.writeObject(pickledData);
+ }
}
/**
+ * Kick off the deserialization mechanism.
+ * @param aInStream
+ * @throws IOException
+ * @throws ClassNotFoundException
+ * @throws OlmException
+ */
+ 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_SESSION_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" key");
+
+ } else if(TextUtils.isEmpty(pickledData)) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" pickle");
+
+ } else if(!createNewSession()) {
+ throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DESERIALIZATION, OlmException.EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION);
+
+ } else if(!initWithSerializedData(pickledData, key, errorMsg)) {
+ releaseSession(); // prevent memory leak
+ throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_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 session ID.
* @return native session ID
*/
- public OlmAccount getOlmAccountId(){
- return mOlmAccount;
+ public long getOlmSessionId(){
+ return mNativeOlmSessionId;
}
/**
@@ -93,6 +202,29 @@ public class OlmSession implements Serializable {
/**
+ * 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 #createNewSessionJni()}.
+ * @return true if init succeed, false otherwise.
+ */
+ private boolean createNewSession() {
+ boolean retCode = false;
+ if(0 != (mNativeOlmSessionId = createNewSessionJni())){
+ retCode = true;
+ }
+ return retCode;
+ }
+
+ /**
+ * Create an OLM account in native side.<br>
+ * Do not forget to call {@link #releaseSession()} when JAVA side is done.
+ * @return native account instance identifier (see {@link #mNativeOlmSessionId})
+ */
+ private native long createNewSessionJni();
+
+
+ /**
* Creates a new out-bound session for sending messages to a recipient
* identified by an identity key and a one time key.<br>
* Public API for {@link #initOutboundSessionWithAccount(OlmAccount, String, String)}.
@@ -107,10 +239,7 @@ public class OlmSession implements Serializable {
if((null==aAccount) || TextUtils.isEmpty(aTheirIdentityKey) || TextUtils.isEmpty(aTheirOneTimeKey)){
Log.e(LOG_TAG, "## initOutboundSession(): invalid input parameters");
} else {
- // set the account of this session
- mOlmAccount = aAccount;
-
- if(0 == initOutboundSessionJni(mOlmAccount.getOlmAccountId(), aTheirIdentityKey, aTheirOneTimeKey)) {
+ if(0 == initOutboundSessionJni(aAccount.getOlmAccountId(), aTheirIdentityKey, aTheirOneTimeKey)) {
retObj = this;
}
}
@@ -136,10 +265,7 @@ public class OlmSession implements Serializable {
if((null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){
Log.e(LOG_TAG, "## initInboundSessionWithAccount(): invalid input parameters");
} else {
- // set the account of this session
- mOlmAccount = aAccount;
-
- if( 0 == initInboundSessionJni(mOlmAccount.getOlmAccountId(), aPreKeyMsg)) {
+ if( 0 == initInboundSessionJni(aAccount.getOlmAccountId(), aPreKeyMsg)) {
retObj = this;
}
}
@@ -168,10 +294,7 @@ public class OlmSession implements Serializable {
if((null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){
Log.e(LOG_TAG, "## initInboundSessionWithAccount(): invalid input parameters");
} else {
- // set the account of this session
- mOlmAccount = aAccount;
-
- if(0 == initInboundSessionFromIdKeyJni(mOlmAccount.getOlmAccountId(), aTheirIdentityKey, aPreKeyMsg)){
+ if(0 == initInboundSessionFromIdKeyJni(aAccount.getOlmAccountId(), aTheirIdentityKey, aPreKeyMsg)){
retObj = this;
}
}
@@ -265,10 +388,5 @@ public class OlmSession implements Serializable {
}
private native String decryptMessageJni(OlmMessage aEncryptedMsg);
-
- // TODO missing API: initWithSerializedData
- // TODO missing API: serializeDataWithKey
- // TODO missing API: initWithCoder
- // TODO missing API: encodeWithCoder
}