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 2016 Vector Creations Ltd
* Copyright 2017 OpenMarket Ltd
* Copyright 2017 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -26,8 +26,6 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
......@@ -62,9 +60,21 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
private transient long mNativeId;
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.
* @return native account ID
......@@ -92,26 +102,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
*/
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
......@@ -146,7 +136,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if (null != identityKeysBuffer) {
try {
identityKeysJsonObj = new JSONObject(new String(identityKeysBuffer, "UTF-8"));
//Log.d(LOG_TAG, "## identityKeys(): Identity Json keys=" + identityKeysJsonObj.toString());
} catch (Exception e) {
Log.e(LOG_TAG, "## identityKeys(): Exception - Msg=" + e.getMessage());
}
......@@ -154,14 +143,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
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>
* Keys are Base64 encoded.
* 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();
......@@ -173,6 +162,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
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();
/**
......@@ -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);
/**
......@@ -221,7 +220,6 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if( null != oneTimeKeysBuffer) {
try {
oneTimeKeysJsonObj = new JSONObject(new String(oneTimeKeysBuffer, "UTF-8"));
//Log.d(LOG_TAG, "## oneTimeKeys(): OneTime Json keys=" + oneTimeKeysJsonObj.toString());
} catch (Exception e) {
Log.e(LOG_TAG, "## oneTimeKeys(): Exception - Msg=" + e.getMessage());
}
......@@ -229,7 +227,7 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
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 {
* The returned data is a JSON-formatted object with the single property
* <tt>curve25519</tt>, which is itself an object mapping key id to
* 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();
......@@ -252,7 +250,8 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
if (null != aSession) {
try {
res = (removeOneTimeKeysJni(aSession.getOlmSessionId()) >= 0);
removeOneTimeKeysJni(aSession.getOlmSessionId());
res = true;
Log.d(LOG_TAG,"## removeOneTimeKeysForSession(): result=" + res);
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS, e.getMessage());
......@@ -264,10 +263,10 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
/**
* 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
* @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.
......@@ -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();
/**
......@@ -312,68 +315,13 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
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>
* @param jsonObject the object to parse
* @return the map
* Sign a message with the ed25519 fingerprint key for this account.<br>
* The signed message is returned by the method.
* @param aMessage message to sign
* @return the signed message
*/
private static Map<String, Map<String, String>> toStringMapMap(JSONObject jsonObject) {
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;
}
private native byte[] signMessageJni(byte[] aMessage);
//==============================================================================================================
// Serialization management
......@@ -428,7 +376,12 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
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>
......@@ -439,15 +392,14 @@ public class OlmAccount extends CommonSerializeUtils implements Serializable {
*/
@Override
protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception {
createNewAccount();
String errorMsg;
String errorMsg = null;
try {
if ((null == aSerializedData) || (null == aKey)) {
Log.e(LOG_TAG, "## deserialize(): invalid input parameters");
errorMsg = "invalid input parameters";
} else {
errorMsg = deserializeJni(aSerializedData, aKey);
mNativeId = deserializeJni(aSerializedData, aKey);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage());
......@@ -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 2016 Vector Creations Ltd
* Copyright 2017 OpenMarket Ltd
* Copyright 2017 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......
/*
* Copyright 2016 OpenMarket Ltd
* Copyright 2016 Vector Creations Ltd
* Copyright 2017 OpenMarket Ltd
* Copyright 2017 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -17,7 +17,6 @@
package org.matrix.olm;
import android.text.TextUtils;
import android.util.Log;
......@@ -55,15 +54,31 @@ 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 #initInboundGroupSession(String)}
* The session key parameter is retrieved from an outbound group session.
* @param aSessionKey session key
* @throws OlmException constructor failure
*/
public OlmInboundGroupSession(String aSessionKey) throws OlmException {
createNewSession();
initInboundGroupSession(aSessionKey);
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 {
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>
......@@ -80,30 +95,10 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* Destroy the corresponding OLM inbound group session native object.<br>
* This method must ALWAYS be called when this JAVA instance
* is destroyed (ie. garbage collected) to prevent memory leak in native side.
* See {@link #createNewSessionJni()}.
* See {@link #createNewSessionJni(byte[])}.
*/
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
......@@ -112,28 +107,6 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
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.
* @return the session ID
......@@ -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();
/**
......@@ -174,6 +152,13 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
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);
//==============================================================================================================
......@@ -232,7 +217,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
/**
* JNI counter part of {@link #serialize(byte[], StringBuffer)}.
* @param aKey encryption key
* @return pickled base64 string if operation succeed, null otherwise
* @return the serialized session
*/
private native byte[] serializeJni(byte[] aKey);
......@@ -244,16 +229,14 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
*/
@Override
protected void deserialize(byte[] aSerializedData, byte[] aKey) throws Exception {
createNewSession();
String errorMsg;
String errorMsg = null;
try {
if ((null == aSerializedData) || (null == aKey)) {
Log.e(LOG_TAG, "## deserialize(): invalid input parameters");
errorMsg = "invalid input parameters";
} else {
errorMsg = deserializeJni(aSerializedData, aKey);
mNativeId = deserializeJni(aSerializedData, aKey);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## deserialize() failed " + e.getMessage());
......@@ -267,10 +250,11 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
}
/**
* JNI counter part of {@link #deserialize(byte[], byte[])}.
* @param aSerializedData pickled session in a base64 sbytes buffer
* @param aKey key used to encrypted in {@link #serialize(byte[], StringBuffer)}
* @return null if operation succeed, an error message if operation failed
*/
private native String deserializeJni(byte[] aSerializedData, byte[] aKey);
* Allocate a new session and initialize it with the serialisation data.<br>
* An exception is thrown if the operation fails.
* @param aSerializedData the session serialisation buffer
* @param aKey the key used to encrypt the serialized account data
* @return the deserialized session
**/
private native long deserializeJni(byte[] aSerializedData, byte[] aKey);
}
/*
* Copyright 2016 OpenMarket Ltd
* Copyright 2016 Vector Creations Ltd
* Copyright 2017 OpenMarket Ltd
* Copyright 2017 Vector Creations Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -46,14 +46,24 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
* Constructor.<br>
* Create and save a new session native instance ID and
* initialise a new outbound group session.<br>
* See {@link #createNewSession()} and {@link #initOutboundGroupSession()}
* @throws OlmException constructor failure
*/
public OlmOutboundGroupSession() throws OlmException {
createNewSession();
initOutboundGroupSession();
try {
mNativeId = createNewSessionJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION, e.getMessage());
}
}
/**
* Create the corresponding OLM outbound group session in native side.<br>
* An exception is thrown if the operation fails.
* Do not forget to call {@link #releaseSession()} when JAVA side is done.
* @return native session instance identifier (see {@link #mNativeId})
*/
private native long createNewSessionJni();
/**
* Release native session and invalid its JAVA reference counter part.<br>
* Public API for {@link #releaseSessionJni()}.
......@@ -73,27 +83,6 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
*/
private native void releaseSessionJni();
/**
* Create and save the session native instance ID.
* Wrapper for {@link #createNewSessionJni()}.<br>
* To be called before any other API call.
* @exception OlmException the exception.
*/
private void createNewSession() throws OlmException {
try {
mNativeId = createNewSessionJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION, e.getMessage());
}
}
/**
* Create the corresponding OLM outbound 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
......@@ -102,20 +91,6 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
return (0 == mNativeId);
}
/**
* Start a new outbound group session.<br>
* @exception OlmException the failre reason
*/
private void initOutboundGroupSession() throws OlmException {
try {
initOutboundGroupSessionJni();
} catch (Exception e) {
throw new OlmException(OlmException.EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION, e.getMessage());
}
}
private native void initOutboundGroupSessionJni();
/**
* Get a base64-encoded identifier for this session.
* @return session identifier
......@@ -130,6 +105,11 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
}
}
/**
* Return the session identifier.
* An exception is thrown if the operation fails.
* @return the session identifier
*/
private native byte[] sessionIdentifierJni();
/**
......@@ -141,6 +121,14 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
public int messageIndex() {
return messageIndexJni();
}
/**
* Get the current message index for this session.<br>
* Each message is sent with an increasing index, this
* method returns the index for the next message.
* An exception is thrown if the operation fails.
* @return current session index
*/
private native int messageIndexJni();
/**
......@@ -159,6 +147,11 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser