Commit eeb210f7 authored by ylecollen's avatar ylecollen
Browse files

-> Check the function descriptions

-> Update the deserialization methods (the jni methods create an object instance before deserializing them.
parent 29339bc0
/* /*
* Copyright 2016 OpenMarket Ltd * Copyright 2017 OpenMarket Ltd
* Copyright 2016 Vector Creations Ltd * Copyright 2017 Vector Creations Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -26,8 +26,6 @@ import java.io.IOException; ...@@ -26,8 +26,6 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
/** /**
...@@ -62,9 +60,21 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -62,9 +60,21 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
private transient long mNativeId; private transient long mNativeId;
public OlmAccount() throws OlmException { public OlmAccount() throws OlmException {
createNewAccount(); try {
mNativeId = createNewAccountJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION, e.getMessage());
}
} }
/**
* Create a new account and return it to JAVA side.<br>
* Since a C prt is returned as a jlong, special care will be taken
* to make the cast (OlmAccount* to jlong) platform independent.
* @return the initialized OlmAccount* instance or throw an exception if fails
**/
private native long createNewAccountJni();
/** /**
* Getter on the account ID. * Getter on the account ID.
* @return native account ID * @return native account ID
...@@ -92,26 +102,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -92,26 +102,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
*/ */
private native void releaseAccountJni(); private native void releaseAccountJni();
/**
* Create and initialize a native account instance.<br>
* To be called before any other API call.
* @exception OlmException the failure reason
*/
private void createNewAccount() throws OlmException {
try {
mNativeId = createNewAccountJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_ACCOUNT_CREATION, e.getMessage());
}
}
/**
* 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 #mNativeId})
*/
private native long createNewAccountJni();
/** /**
* Return true the object resources have been released.<br> * Return true the object resources have been released.<br>
* @return true the object resources have been released * @return true the object resources have been released
...@@ -146,7 +136,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -146,7 +136,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if (null != identityKeysBuffer) { if (null != identityKeysBuffer) {
try { try {
identityKeysJsonObj = new JSONObject(new String(identityKeysBuffer, "UTF-8")); identityKeysJsonObj = new JSONObject(new String(identityKeysBuffer, "UTF-8"));
//Log.d(LOG_TAG, "## identityKeys(): Identity Json keys=" + identityKeysJsonObj.toString());
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## identityKeys(): Exception - Msg=" + e.getMessage()); Log.e(LOG_TAG, "## identityKeys(): Exception - Msg=" + e.getMessage());
} }
...@@ -154,14 +143,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -154,14 +143,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
Log.e(LOG_TAG, "## identityKeys(): Failure - identityKeysJni()=null"); Log.e(LOG_TAG, "## identityKeys(): Failure - identityKeysJni()=null");
} }
return toStringMap(identityKeysJsonObj); return OlmUtility.toStringMap(identityKeysJsonObj);
} }
/** /**
* Get the public identity keys (Ed25519 fingerprint key and Curve25519 identity key).<br> * Get the public identity keys (Ed25519 fingerprint key and Curve25519 identity key).<br>
* Keys are Base64 encoded. * Keys are Base64 encoded.
* These keys must be published on the server. * These keys must be published on the server.
* @return byte array containing the identity keys if operation succeed, null otherwise * @return the identity keys or throw an exception if it fails
*/ */
private native byte[] identityKeysJni(); private native byte[] identityKeysJni();
...@@ -173,6 +162,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -173,6 +162,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
return maxOneTimeKeysJni(); return maxOneTimeKeysJni();
} }
/**
* Return the largest number of "one time keys" this account can store.
* @return the max number of "one time keys", -1 otherwise
*/
private native long maxOneTimeKeysJni(); private native long maxOneTimeKeysJni();
/** /**
...@@ -190,6 +183,12 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -190,6 +183,12 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
} }
} }
/**
* Generate a number of new one time keys.<br> If total number of keys stored
* by this account exceeds {@link #maxOneTimeKeys()}, the old keys are discarded.
* An exception is thrown if the operation fails.<br>
* @param aNumberOfKeys number of keys to generate
*/
private native void generateOneTimeKeysJni(int aNumberOfKeys); private native void generateOneTimeKeysJni(int aNumberOfKeys);
/** /**
...@@ -221,7 +220,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -221,7 +220,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if( null != oneTimeKeysBuffer) { if( null != oneTimeKeysBuffer) {
try { try {
oneTimeKeysJsonObj = new JSONObject(new String(oneTimeKeysBuffer, "UTF-8")); oneTimeKeysJsonObj = new JSONObject(new String(oneTimeKeysBuffer, "UTF-8"));
//Log.d(LOG_TAG, "## oneTimeKeys(): OneTime Json keys=" + oneTimeKeysJsonObj.toString());
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## oneTimeKeys(): Exception - Msg=" + e.getMessage()); Log.e(LOG_TAG, "## oneTimeKeys(): Exception - Msg=" + e.getMessage());
} }
...@@ -229,7 +227,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -229,7 +227,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
Log.e(LOG_TAG, "## oneTimeKeys(): Failure - identityKeysJni()=null"); Log.e(LOG_TAG, "## oneTimeKeys(): Failure - identityKeysJni()=null");
} }
return toStringMapMap(oneTimeKeysJsonObj); return OlmUtility.toStringMapMap(oneTimeKeysJsonObj);
} }
/** /**
...@@ -237,7 +235,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -237,7 +235,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
* The returned data is a JSON-formatted object with the single property * The returned data is a JSON-formatted object with the single property
* <tt>curve25519</tt>, which is itself an object mapping key id to * <tt>curve25519</tt>, which is itself an object mapping key id to
* base64-encoded Curve25519 key.<br> * base64-encoded Curve25519 key.<br>
* @return byte array containing the one time keys if operation succeed, null otherwise * @return byte array containing the one time keys or throw an exception if it fails
*/ */
private native byte[] oneTimeKeysJni(); private native byte[] oneTimeKeysJni();
...@@ -252,7 +250,8 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -252,7 +250,8 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if (null != aSession) { if (null != aSession) {
try { try {
res = (removeOneTimeKeysJni(aSession.getOlmSessionId()) >= 0); removeOneTimeKeysJni(aSession.getOlmSessionId());
res = true;
Log.d(LOG_TAG,"## removeOneTimeKeysForSession(): result=" + res); Log.d(LOG_TAG,"## removeOneTimeKeysForSession(): result=" + res);
} catch (Exception e) { } catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS, e.getMessage()); throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS, e.getMessage());
...@@ -264,10 +263,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -264,10 +263,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
/** /**
* Remove the "one time keys" that the session used from the account. * Remove the "one time keys" that the session used from the account.
* An exception is thrown if the operation fails.
* @param aNativeOlmSessionId native session instance identifier * @param aNativeOlmSessionId native session instance identifier
* @return 0 if operation succeed, 1 if no matching keys in the sessions to be removed, -1 if operation failed
*/ */
private native int removeOneTimeKeysJni(long aNativeOlmSessionId); private native void removeOneTimeKeysJni(long aNativeOlmSessionId);
/** /**
* Marks the current set of "one time keys" as being published. * Marks the current set of "one time keys" as being published.
...@@ -281,6 +280,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -281,6 +280,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
} }
} }
/**
* Marks the current set of "one time keys" as being published.
* An exception is thrown if the operation fails.
*/
private native void markOneTimeKeysAsPublishedJni(); private native void markOneTimeKeysAsPublishedJni();
/** /**
...@@ -312,68 +315,13 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -312,68 +315,13 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
return result; return result;
} }
private native byte[] signMessageJni(byte[] aMessage);
/**
* Build a string-string dictionary from a jsonObject.<br>
* @param jsonObject the object to parse
* @return the map
*/
private static Map<String, String> toStringMap(JSONObject jsonObject) {
if (null != jsonObject) {
HashMap<String, String> map = new HashMap<>();
Iterator<String> keysItr = jsonObject.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
try {
Object value = jsonObject.get(key);
if (value instanceof String) {
map.put(key, (String) value);
} else {
Log.e(LOG_TAG, "## toStringMap(): unexpected type " + value.getClass());
}
} catch (Exception e) {
Log.e(LOG_TAG, "## toStringMap(): failed " + e.getMessage());
}
}
return map;
}
return null;
}
/** /**
* Build a string-string dictionary of string dictionary from a jsonObject.<br> * Sign a message with the ed25519 fingerprint key for this account.<br>
* @param jsonObject the object to parse * The signed message is returned by the method.
* @return the map * @param aMessage message to sign
* @return the signed message
*/ */
private static Map<String, Map<String, String>> toStringMapMap(JSONObject jsonObject) { private native byte[] signMessageJni(byte[] aMessage);
if (null != jsonObject) {
HashMap<String, Map<String, String>> map = new HashMap<>();
Iterator<String> keysItr = jsonObject.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
try {
Object value = jsonObject.get(key);
if (value instanceof JSONObject) {
map.put(key, toStringMap((JSONObject) value));
} else {
Log.e(LOG_TAG, "## toStringMapMap(): unexpected type " + value.getClass());
}
} catch (Exception e) {
Log.e(LOG_TAG, "## toStringMapMap(): failed " + e.getMessage());
}
}
return map;
}
return null;
}
//============================================================================================================== //==============================================================================================================
// Serialization management // Serialization management
...@@ -428,7 +376,12 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -428,7 +376,12 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
return pickleRetValue; return pickleRetValue;
} }
private native byte[] serializeJni(byte[] aKey); /**
* Serialize and encrypt account instance.<br>
* @param aKeyBuffer key used to encrypt the serialized account data
* @return the serialised account as bytes buffer.
**/
private native byte[] serializeJni(byte[] aKeyBuffer);
/** /**
* Loads an account from a pickled bytes buffer.<br> * Loads an account from a pickled bytes buffer.<br>
...@@ -439,15 +392,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -439,15 +392,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
*/ */
@Override @Override
protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception { protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception {
createNewAccount(); String errorMsg = null;
String errorMsg;
try { try {
if ((null == aSerializedData) || (null == aKey)) { if ((null == aSerializedData) || (null == aKey)) {
Log.e(LOG_TAG, "## deserialize(): invalid input parameters"); Log.e(LOG_TAG, "## deserialize(): invalid input parameters");
errorMsg = "invalid input parameters"; errorMsg = "invalid input parameters";
} else { } else {
errorMsg = deserializeJni(aSerializedData, aKey); mNativeId = deserializeJni(aSerializedData, aKey);
} }
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage()); Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage());
...@@ -460,5 +412,11 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable { ...@@ -460,5 +412,11 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
} }
} }
private native String deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer); /**
* Allocate a new account and initialize it with the serialisation data.<br>
* @param aSerializedDataBuffer the account serialisation buffer
* @param aKeyBuffer the key used to encrypt the serialized account data
* @return the deserialized account
**/
private native long deserializeJni(byte[] aSerializedDataBuffer, byte[] aKeyBuffer);
} }
/* /*
* Copyright 2016 OpenMarket Ltd * Copyright 2017 OpenMarket Ltd
* Copyright 2016 Vector Creations Ltd * Copyright 2017 Vector Creations Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
......
/* /*
* Copyright 2016 OpenMarket Ltd * Copyright 2017 OpenMarket Ltd
* Copyright 2016 Vector Creations Ltd * Copyright 2017 Vector Creations Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
package org.matrix.olm; package org.matrix.olm;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
...@@ -55,16 +54,32 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -55,16 +54,32 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
/** /**
* Constructor.<br> * Constructor.<br>
* Create and save a new native session instance ID and start a new inbound group session. * 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 * The session key parameter is retrieved from an outbound group session.
* See {@link #createNewSession()} and {@link #initInboundGroupSession(String)}
* @param aSessionKey session key * @param aSessionKey session key
* @throws OlmException constructor failure * @throws OlmException constructor failure
*/ */
public OlmInboundGroupSession(String aSessionKey) throws OlmException { public OlmInboundGroupSession(String aSessionKey) throws OlmException {
createNewSession(); if (TextUtils.isEmpty(aSessionKey)) {
initInboundGroupSession(aSessionKey); Log.e(LOG_TAG, "## initInboundGroupSession(): invalid session key");
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, "invalid session key");
} else {
try {
mNativeId = createNewSessionJni(aSessionKey.getBytes("UTF-8"));
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, e.getMessage());
}
}
} }
/**
* Initialize a new inbound group session and return it to JAVA side.<br>
* Since a C prt is returned as a jlong, special care will be taken
* to make the cast (OlmInboundGroupSession* to jlong) platform independent.
* @param aSessionKeyBuffer session key from an outbound session
* @return the initialized OlmInboundGroupSession* instance or throw an exception it fails.
**/
private native long createNewSessionJni(byte[] aSessionKeyBuffer);
/** /**
* Release native session and invalid its JAVA reference counter part.<br> * Release native session and invalid its JAVA reference counter part.<br>
* Public API for {@link #releaseSessionJni()}. * Public API for {@link #releaseSessionJni()}.
...@@ -80,30 +95,10 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -80,30 +95,10 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* Destroy the corresponding OLM inbound group session native object.<br> * Destroy the corresponding OLM inbound group session native object.<br>
* This method must ALWAYS be called when this JAVA instance * This method must ALWAYS be called when this JAVA instance
* is destroyed (ie. garbage collected) to prevent memory leak in native side. * is destroyed (ie. garbage collected) to prevent memory leak in native side.
* See {@link #createNewSessionJni()}. * See {@link #createNewSessionJni(byte[])}.
*/ */
private native void releaseSessionJni(); private native void releaseSessionJni();
/**
* Create and save the session native instance ID.<br>
* To be called before any other API call.
* @exception OlmException the failure reason
*/
private void createNewSession() throws OlmException {
try {
mNativeId = createNewSessionJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION, e.getMessage());
}
}
/**
* Create the corresponding OLM inbound group session in native side.<br>
* Do not forget to call {@link #releaseSession()} when JAVA side is done.
* @return native session instance identifier (see {@link #mNativeId})
*/
private native long createNewSessionJni();
/** /**
* Return true the object resources have been released.<br> * Return true the object resources have been released.<br>
* @return true the object resources have been released * @return true the object resources have been released
...@@ -112,28 +107,6 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -112,28 +107,6 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
return (0 == mNativeId); return (0 == mNativeId);
} }
/**
* Start a new inbound group session.<br>
* The session key parameter is retrieved from an outbound group session
* see {@link OlmOutboundGroupSession#sessionKey()}
* @param aSessionKey session key
* @exception OlmException the failure reason
*/
private void initInboundGroupSession(String aSessionKey) throws OlmException {
if (TextUtils.isEmpty(aSessionKey)) {
Log.e(LOG_TAG, "## initInboundGroupSession(): invalid session key");
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, "invalid session key");
} else {
try {
initInboundGroupSessionJni(aSessionKey.getBytes("UTF-8"));
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION, e.getMessage());
}
}
}
private native void initInboundGroupSessionJni(byte[] aSessionKeyBuffer);
/** /**
* Retrieve the base64-encoded identifier for this inbound group session. * Retrieve the base64-encoded identifier for this inbound group session.
* @return the session ID * @return the session ID
...@@ -148,6 +121,11 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -148,6 +121,11 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
} }
} }
/**
* Get a base64-encoded identifier for this inbound group session.
* An exception is thrown if the operation fails.
* @return the base64-encoded identifier
*/
private native byte[] sessionIdentifierJni(); private native byte[] sessionIdentifierJni();
/** /**
...@@ -174,6 +152,13 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -174,6 +152,13 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
return result; return result;
} }
/**
* Decrypt a message.
* An exception is thrown if the operation fails.
* @param aEncryptedMsg the encrypted message
* @param aDecryptMessageResult the decryptMessage informaton
* @return the decrypted message
*/
private native byte[] decryptMessageJni(byte[] aEncryptedMsg, DecryptMessageResult aDecryptMessageResult); private native byte[] decryptMessageJni(byte[] aEncryptedMsg, DecryptMessageResult aDecryptMessageResult);
//============================================================================================================== //==============================================================================================================
...@@ -232,7 +217,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -232,7 +217,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
/** /**
* JNI counter part of {@link #serialize(byte[], StringBuffer)}. * JNI counter part of {@link #serialize(byte[], StringBuffer)}.
* @param aKey encryption key * @param aKey encryption key
* @return pickled base64 string if operation succeed, null otherwise * @return the serialized session
*/ */
private native byte[] serializeJni(byte[] aKey); private native byte[] serializeJni(byte[] aKey);
...@@ -244,16 +229,14 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -244,16 +229,14 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri