diff options
Diffstat (limited to 'java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java')
-rw-r--r-- | java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java | 174 |
1 files changed, 146 insertions, 28 deletions
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 } |