Commit ce9f67d5 authored by ylecollen's avatar ylecollen
Browse files

Simplify the serialization / deserializtion methods (CommonSerializeUtils)

parent 2070de4f
......@@ -112,7 +112,7 @@ public class OlmSessionTest {
assertTrue(0!=aliceSession.getOlmSessionId());
// CREATE ALICE OUTBOUND SESSION and encrypt message to bob
assertNotNull(aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, bobOneTimeKey));
assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey));
String clearMsg = "Heloo bob , this is alice!";
OlmMessage encryptedMsgToBob = aliceSession.encryptMessage(clearMsg);
assertNotNull(encryptedMsgToBob);
......@@ -129,7 +129,7 @@ public class OlmSessionTest {
assertTrue(0!=bobSession.getOlmSessionId());
try {
bobSession.initInboundSessionWithAccount(bobAccount, encryptedMsgToBob.mCipherText);
bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText);
} catch (Exception e) {
assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
}
......@@ -211,7 +211,7 @@ public class OlmSessionTest {
assertTrue(0!=aliceSession.getOlmSessionId());
// CREATE ALICE OUTBOUND SESSION and encrypt message to bob
assertNotNull(aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, bobOneTimeKey));
assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey));
String helloClearMsg = "Hello I'm Alice!";
OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg);
......@@ -229,7 +229,7 @@ public class OlmSessionTest {
assertTrue(0!=bobSession.getOlmSessionId());
try {
bobSession.initInboundSessionWithAccount(bobAccount, encryptedAliceToBobMsg1.mCipherText);
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) {
assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
}
......@@ -381,7 +381,7 @@ public class OlmSessionTest {
String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1);
// create alice inbound session for bob
assertTrue(0==aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, bobOneTimeKey1));
assertTrue(0==aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1));
String aliceClearMsg = "hello helooo to bob!";
OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg);
......@@ -389,7 +389,7 @@ public class OlmSessionTest {
// init bob session with alice PRE KEY
try {
bobSession.initInboundSessionWithAccount(bobAccount, encryptedAliceToBobMsg1.mCipherText);
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) {
assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
}
......@@ -463,7 +463,7 @@ public class OlmSessionTest {
assertTrue(0!=aliceSession.getOlmSessionId());
// CREATE ALICE OUTBOUND SESSION and encrypt message to bob
assertNotNull(aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, bobOneTimeKey));
assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey));
String helloClearMsg = "Hello I'm Alice!";
OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg);
......@@ -481,7 +481,7 @@ public class OlmSessionTest {
// init bob session with alice PRE KEY
try {
bobSession.initInboundSessionWithAccount(bobAccount, encryptedAliceToBobMsg1.mCipherText);
bobSession.initInboundSession(bobAccount, encryptedAliceToBobMsg1.mCipherText);
} catch (Exception e) {
assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false);
}
......@@ -608,13 +608,13 @@ public class OlmSessionTest {
}
// SANITY CHECK TESTS FOR: initOutboundSessionWithAccount()
assertTrue(-1==aliceSession.initOutboundSessionWithAccount(null, bobIdentityKey, bobOneTimeKey));
assertTrue(-1==aliceSession.initOutboundSessionWithAccount(aliceAccount, null, bobOneTimeKey));
assertTrue(-1==aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, null));
assertTrue(-1==aliceSession.initOutboundSessionWithAccount(null, null, null));
assertTrue(-1==aliceSession.initOutboundSession(null, bobIdentityKey, bobOneTimeKey));
assertTrue(-1==aliceSession.initOutboundSession(aliceAccount, null, bobOneTimeKey));
assertTrue(-1==aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, null));
assertTrue(-1==aliceSession.initOutboundSession(null, null, null));
// init properly
assertTrue(0==aliceSession.initOutboundSessionWithAccount(aliceAccount, bobIdentityKey, bobOneTimeKey));
assertTrue(0==aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey));
// SANITY CHECK TESTS FOR: encryptMessage()
assertTrue(null==aliceSession.encryptMessage(null));
......@@ -629,7 +629,7 @@ public class OlmSessionTest {
bobSession = new OlmSession();
String errorMessage = null;
try {
bobSession.initInboundSessionWithAccount(null, encryptedMsgToBob.mCipherText);
bobSession.initInboundSession(null, encryptedMsgToBob.mCipherText);
} catch (Exception e) {
errorMessage = e.getMessage();
}
......@@ -638,7 +638,7 @@ public class OlmSessionTest {
errorMessage = null;
try {
bobSession.initInboundSessionWithAccount(bobAccount, null);
bobSession.initInboundSession(bobAccount, null);
} catch (Exception e) {
errorMessage = e.getMessage();
}
......@@ -647,7 +647,7 @@ public class OlmSessionTest {
errorMessage = null;
try {
bobSession.initInboundSessionWithAccount(bobAccount, INVALID_PRE_KEY);
bobSession.initInboundSession(bobAccount, INVALID_PRE_KEY);
} catch (Exception e) {
errorMessage = e.getMessage();
}
......@@ -657,7 +657,7 @@ public class OlmSessionTest {
// init properly
errorMessage = null;
try {
bobSession.initInboundSessionWithAccount(bobAccount, encryptedMsgToBob.mCipherText);
bobSession.initInboundSession(bobAccount, encryptedMsgToBob.mCipherText);
} catch (Exception e) {
errorMessage = e.getMessage();
}
......
......@@ -35,7 +35,7 @@ abstract class CommonSerializeUtils {
* @param aOutStream output stream for serializing
* @throws IOException exception
*/
protected void serializeObject(ObjectOutputStream aOutStream) throws IOException {
protected void serialize(ObjectOutputStream aOutStream) throws IOException {
aOutStream.defaultWriteObject();
// generate serialization key
......@@ -43,7 +43,7 @@ abstract class CommonSerializeUtils {
// compute pickle string
StringBuffer errorMsg = new StringBuffer();
String pickledData = serializeDataWithKey(key, errorMsg);
String pickledData = serialize(key, errorMsg);
if(null == pickledData) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_SERIALIZATION, String.valueOf(errorMsg));
......@@ -59,33 +59,22 @@ abstract class CommonSerializeUtils {
* @throws IOException exception
* @throws ClassNotFoundException exception
*/
protected void deserializeObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException {
protected void deserialize(ObjectInputStream aInStream) throws IOException, ClassNotFoundException {
aInStream.defaultReadObject();
StringBuffer errorMsg = new StringBuffer();
String key = (String) aInStream.readObject();
String pickledData = (String) aInStream.readObject();
if(TextUtils.isEmpty(key)) {
if (TextUtils.isEmpty(key)) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" key");
} else if(TextUtils.isEmpty(pickledData)) {
} else if (TextUtils.isEmpty(pickledData)) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION+" pickle");
} else if(!createNewObjectFromSerialization()) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, OlmException.EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION);
} else if(!initWithSerializedData(pickledData, key, errorMsg)) {
releaseObjectFromSerialization(); // prevent memory leak
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, String.valueOf(errorMsg));
} else {
Log.d(LOG_TAG,"## readObject(): success");
}
deserialize(pickledData, key);
Log.d(LOG_TAG,"## deserializeObject(): success");
}
protected abstract String serializeDataWithKey(String aKey, StringBuffer aErrorMsg);
protected abstract boolean initWithSerializedData(String aSerializedData, String aKey, StringBuffer aErrorMsg);
protected abstract boolean createNewObjectFromSerialization();
protected abstract void releaseObjectFromSerialization();
protected abstract String serialize(String aKey, StringBuffer aErrorMsg);
protected abstract void deserialize(String aSerializedData, String aKey) throws IOException;
}
......@@ -68,105 +68,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
}
}
/**
* Kick off the serialization mechanism.
* @param aOutStream output stream for serializing
* @throws IOException exception
*/
private void writeObject(ObjectOutputStream aOutStream) throws IOException {
serializeObject(aOutStream);
}
/**
* Kick off the deserialization mechanism.
* @param aInStream input stream
* @throws IOException exception
* @throws ClassNotFoundException exception
*/
private void readObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException {
deserializeObject(aInStream);
}
@Override
protected boolean createNewObjectFromSerialization() {
return createNewAccount();
}
@Override
protected void releaseObjectFromSerialization() {
releaseAccount();
}
/**
* 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
*/
@Override
protected 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);
try {
pickleRetValue = new String(serializeDataWithKeyJni(aKey.getBytes("UTF-8"), aErrorMsg), "UTF-8");
} catch (Exception e) {
Log.e(LOG_TAG, "## serializeDataWithKey() failed " + e.getMessage());
aErrorMsg.append(e.getMessage());
}
}
return pickleRetValue;
}
private native byte[] serializeDataWithKeyJni(byte[] 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
*/
@Override
protected 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);
try {
if (TextUtils.isEmpty(aSerializedData) || TextUtils.isEmpty(aKey)) {
Log.e(LOG_TAG, "## initWithSerializedData(): invalid input parameters");
} else if (null == (jniError = initWithSerializedDataJni(aSerializedData.getBytes("UTF-8"), aKey.getBytes("UTF-8")))) {
retCode = true;
} else {
aErrorMsg.append(jniError);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## initWithSerializedData() failed " + e.getMessage());
aErrorMsg.append(e.getMessage());
}
}
return retCode;
}
private native String initWithSerializedDataJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer);
/**
* Getter on the account ID.
* @return native account ID
......@@ -229,6 +130,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
*/
private native long createNewAccountJni();
/**
* Return true the object resources have been released.<br>
* @return true the object resources have been released
*/
public boolean isReleased() {
return (0 == mNativeId);
}
/**
* Return the identity keys (identity and fingerprint keys) in a dictionary.<br>
* Public API for {@link #identityKeysJni()}.<br>
......@@ -393,14 +302,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
private native byte[] signMessageJni(byte[] aMessage);
/**
* Return true the object resources have been released.<br>
* @return true the object resources have been released
*/
public boolean isReleased() {
return (0 == mNativeId);
}
/**
* Build a string-string dictionary from a jsonObject.<br>
* @param jsonObject the object to parse
......@@ -461,4 +362,95 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
return null;
}
//==============================================================================================================
// Serialization management
//==============================================================================================================
/**
* Kick off the serialization mechanism.
* @param aOutStream output stream for serializing
* @throws IOException exception
*/
private void writeObject(ObjectOutputStream aOutStream) throws IOException {
serialize(aOutStream);
}
/**
* Kick off the deserialization mechanism.
* @param aInStream input stream
* @throws IOException exception
* @throws ClassNotFoundException exception
*/
private void readObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException {
deserialize(aInStream);
}
/**
* 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
*/
@Override
protected String serialize(String aKey, StringBuffer aErrorMsg) {
String pickleRetValue = null;
// sanity check
if(null == aErrorMsg) {
Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null");
} else if(TextUtils.isEmpty(aKey)) {
aErrorMsg.append("Invalid input parameters in serializeDataWithKey()");
} else {
aErrorMsg.setLength(0);
try {
pickleRetValue = new String(serializeJni(aKey.getBytes("UTF-8"), aErrorMsg), "UTF-8");
} catch (Exception e) {
Log.e(LOG_TAG, "## serialize() failed " + e.getMessage());
aErrorMsg.append(e.getMessage());
}
}
return pickleRetValue;
}
private native byte[] serializeJni(byte[] aKey, StringBuffer aErrorMsg);
/**
* Loads an account from a pickled base64 string.<br>
* See {@link #serialize(String, StringBuffer)}
* @param aSerializedData pickled account in a base64 string format
* @param aKey key used to encrypted
*/
@Override
protected void deserialize(String aSerializedData, String aKey) throws IOException {
if (!createNewAccount()) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION,OlmException.EXCEPTION_MSG_INIT_ACCOUNT_CREATION);
}
StringBuffer errorMsg = new StringBuffer();
try {
String jniError;
if (TextUtils.isEmpty(aSerializedData) || TextUtils.isEmpty(aKey)) {
Log.e(LOG_TAG, "## deserialize(): invalid input parameters");
errorMsg.append("invalid input parameters");
} else if (null != (jniError = deserializeJni(aSerializedData.getBytes("UTF-8"), aKey.getBytes("UTF-8")))) {
errorMsg.append(jniError);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage());
errorMsg.append(e.getMessage());
}
if (errorMsg.length() > 0) {
releaseAccount();
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_DESERIALIZATION, String.valueOf(errorMsg));
}
}
private native String deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer);
}
......@@ -65,13 +65,13 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* Constructor.<br>
* Create and save a new native session instance ID and start a new inbound group session.
* The session key parameter is retrieved from an outbound group session
* See {@link #createNewSession()} and {@link #initInboundGroupSessionWithSessionKey(String)}
* See {@link #createNewSession()} and {@link #initInboundGroupSession(String)}
* @param aSessionKey session key
* @throws OlmException constructor failure
*/
public OlmInboundGroupSession(String aSessionKey) throws OlmException {
if(createNewSession()) {
if (0 != initInboundGroupSessionWithSessionKey(aSessionKey)) {
if (0 != initInboundGroupSession(aSessionKey)) {
releaseSession();// prevent memory leak before throwing
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION,OlmException.EXCEPTION_MSG_INIT_INBOUND_GROUP_SESSION);
}
......@@ -114,6 +114,14 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
*/
private native long createNewSessionJni();
/**
* Return true the object resources have been released.<br>
* @return true the object resources have been released
*/
public boolean isReleased() {
return (0 == mNativeId);
}
/**
* Start a new inbound group session.<br>
* The session key parameter is retrieved from an outbound group session
......@@ -121,23 +129,23 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* @param aSessionKey session key
* @return 0 if operation succeed, -1 otherwise
*/
private int initInboundGroupSessionWithSessionKey(String aSessionKey) {
private int initInboundGroupSession(String aSessionKey) {
int retCode = -1;
if(TextUtils.isEmpty(aSessionKey)){
Log.e(LOG_TAG, "## initInboundGroupSessionWithSessionKey(): invalid session key");
Log.e(LOG_TAG, "## initInboundGroupSession(): invalid session key");
} else {
try {
retCode = initInboundGroupSessionWithSessionKeyJni(aSessionKey.getBytes("UTF-8"));
retCode = initInboundGroupSessionJni(aSessionKey.getBytes("UTF-8"));
} catch (Exception e) {
Log.e(LOG_TAG, "## initInboundGroupSessionWithSessionKey() failed " + e.getMessage());
Log.e(LOG_TAG, "## initInboundGroupSession() failed " + e.getMessage());
}
}
return retCode;
}
private native int initInboundGroupSessionWithSessionKeyJni(byte[] aSessionKeyBuffer);
private native int initInboundGroupSessionJni(byte[] aSessionKeyBuffer);
/**
* Retrieve the base64-encoded identifier for this inbound group session.
......@@ -187,13 +195,17 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
private native byte[] decryptMessageJni(byte[] aEncryptedMsg, DecryptMessageResult aDecryptMessageResult, StringBuffer aErrorMsg);
//==============================================================================================================
// Serialization management
//==============================================================================================================
/**
* Kick off the serialization mechanism.
* @param aOutStream output stream for serializing
* @throws IOException exception
*/
private void writeObject(ObjectOutputStream aOutStream) throws IOException {
serializeObject(aOutStream);
serialize(aOutStream);
}
/**
......@@ -203,17 +215,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* @throws ClassNotFoundException exception
*/
private void readObject(ObjectInputStream aInStream) throws IOException, ClassNotFoundException {
deserializeObject(aInStream);
}
@Override
protected boolean createNewObjectFromSerialization() {
return createNewSession();
}
@Override
protected void releaseObjectFromSerialization() {
releaseSession();
deserialize(aInStream);
}
/**
......@@ -226,20 +228,20 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* @return pickled base64 string if operation succeed, null otherwise
*/
@Override
protected String serializeDataWithKey(String aKey, StringBuffer aErrorMsg) {
protected String serialize(String aKey, StringBuffer aErrorMsg) {
String pickleRetValue = null;
// sanity check
if(null == aErrorMsg) {
Log.e(LOG_TAG,"## serializeDataWithKey(): invalid parameter - aErrorMsg=null");
Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null");
} else if(TextUtils.isEmpty(aKey)) {
aErrorMsg.append("Invalid input parameters in serializeDataWithKey()");
aErrorMsg.append("Invalid input parameters in serialize()");
} else {
aErrorMsg.setLength(0);
try {
pickleRetValue = new String(serializeDataWithKeyJni(aKey.getBytes("UTF-8"), aErrorMsg), "UTF-8");
pickleRetValue = new String(serializeJni(aKey.getBytes("UTF-8"), aErrorMsg), "UTF-8");
} catch (Exception e) {
Log.e(LOG_TAG, "## serializeDataWithKey() failed " + e.getMessage());
Log.e(LOG_TAG, "## serialize() failed " + e.getMessage());
aErrorMsg.append(e.getMessage());
}
}
......@@ -247,60 +249,51 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
return pickleRetValue;
}
/**
* JNI counter part of {@link #serializeDataWithKey(String, StringBuffer)}.
* JNI counter part of {@link #serialize(String, StringBuffer)}.
* @param aKey encryption key
* @param aErrorMsg error message description
* @return pickled base64 string if operation succeed, null otherwise
*/
private native byte[] serializeDataWithKeyJni(byte[] aKey, StringBuffer aErrorMsg);
private native byte[] serializeJni(byte[] aKey, StringBuffer aErrorMsg);
/**
* Load an inbound group session from a pickled base64 string.<br>
* See {@link #serializeDataWithKey(String, StringBuffer)}
* @param aSerializedData pickled inbound group session in a base64 string format
* @param aKey encrypting key used in {@link #serializeDataWithKey(String, StringBuffer)}
* @param aErrorMsg error message description
* @return true if operation succeed, false otherwise
* Loads an account from a pickled base64 string.<br>
* See {@link #serialize(String, StringBuffer)}
* @param aSerializedData pickled account in a base64 string format
* @param aKey key used to encrypted
*/
@Override
protected boolean initWithSerializedData(String aSerializedData, String aKey, StringBuffer aErrorMsg) {
boolean retCode = false;
String jniError;
protected void deserialize(String aSerializedData, String aKey) throws IOException {
if (!createNewSession()) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION,OlmException.EXCEPTION_MSG_INIT_ACCOUNT_CREATION);
}
if(null == aErrorMsg) {
Log.e(LOG_TAG, "## initWithSerializedData(): invalid input error parameter");
} else {
aErrorMsg.setLength(0);
try {