diff options
6 files changed, 402 insertions, 187 deletions
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java index e8b2288..ec2582f 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java +++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java @@ -131,9 +131,18 @@ public class OlmSessionTest { assertTrue(0!=aliceSession.getOlmSessionId()); // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey)); + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } String clearMsg = "Heloo bob , this is alice!"; - OlmMessage encryptedMsgToBob = aliceSession.encryptMessage(clearMsg); + OlmMessage encryptedMsgToBob = null; + try { + encryptedMsgToBob = aliceSession.encryptMessage(clearMsg); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsgToBob); assertNotNull(encryptedMsgToBob.mCipherText); Log.d(LOG_TAG,"## test01AliceToBob(): encryptedMsg="+encryptedMsgToBob.mCipherText); @@ -153,7 +162,12 @@ public class OlmSessionTest { assertTrue("initInboundSessionWithAccount failed " + e.getMessage(), false); } - String decryptedMsg = bobSession.decryptMessage(encryptedMsgToBob); + String decryptedMsg = null; + try { + decryptedMsg = bobSession.decryptMessage(encryptedMsgToBob); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(decryptedMsg); // MESSAGE COMPARISON: decrypted vs encrypted @@ -255,10 +269,22 @@ public class OlmSessionTest { assertTrue(0!=aliceSession.getOlmSessionId()); // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey)); + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + String helloClearMsg = "Hello I'm Alice!"; - OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); + OlmMessage encryptedAliceToBobMsg1 = null; + + try { + encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(encryptedAliceToBobMsg1); assertNotNull(encryptedAliceToBobMsg1.mCipherText); @@ -279,7 +305,12 @@ public class OlmSessionTest { } // DECRYPT MESSAGE FROM ALICE - String decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); + String decryptedMsg01 = null; + try { + decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(decryptedMsg01); // MESSAGE COMPARISON: decrypted vs encrypted @@ -291,19 +322,54 @@ public class OlmSessionTest { String clearMsg3 = "Let's go to the opera."; // bob encrypts messages - OlmMessage encryptedMsg1 = bobSession.encryptMessage(clearMsg1); + OlmMessage encryptedMsg1 = null; + try { + encryptedMsg1 = bobSession.encryptMessage(clearMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg1); - OlmMessage encryptedMsg2 = bobSession.encryptMessage(clearMsg2); + + OlmMessage encryptedMsg2 = null; + try { + encryptedMsg2 = bobSession.encryptMessage(clearMsg2); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg2); - OlmMessage encryptedMsg3 = bobSession.encryptMessage(clearMsg3); + + + OlmMessage encryptedMsg3 = null; + try { + encryptedMsg3 = bobSession.encryptMessage(clearMsg3); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg3); // alice decrypts bob's messages - String decryptedMsg1 = aliceSession.decryptMessage(encryptedMsg1); + String decryptedMsg1 = null; + try { + decryptedMsg1 = aliceSession.decryptMessage(encryptedMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(decryptedMsg1); - String decryptedMsg2 = aliceSession.decryptMessage(encryptedMsg2); + String decryptedMsg2 = null; + try { + decryptedMsg2 = aliceSession.decryptMessage(encryptedMsg2); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(decryptedMsg2); - String decryptedMsg3 = aliceSession.decryptMessage(encryptedMsg3); + String decryptedMsg3 = null; + try { + decryptedMsg3 = aliceSession.decryptMessage(encryptedMsg3); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(decryptedMsg3); // comparison tests @@ -313,9 +379,22 @@ public class OlmSessionTest { // and one more from alice to bob clearMsg1 = "another message from Alice to Bob!!"; - encryptedMsg1 = aliceSession.encryptMessage(clearMsg1); + encryptedMsg1 = null; + + try { + encryptedMsg1 = aliceSession.encryptMessage(clearMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg1); - decryptedMsg1 = bobSession.decryptMessage(encryptedMsg1); + + decryptedMsg1 = null; + try { + decryptedMsg1 = bobSession.decryptMessage(encryptedMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(decryptedMsg1); assertTrue(clearMsg1.equals(decryptedMsg1)); @@ -378,10 +457,21 @@ public class OlmSessionTest { } assertTrue(0!=bobSession.getOlmSessionId()); - String aliceSessionId = aliceSession.sessionIdentifier(); + String aliceSessionId = null; + try { + aliceSessionId = aliceSession.sessionIdentifier(); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(aliceSessionId); - String bobSessionId = bobSession.sessionIdentifier(); + String bobSessionId = null; + try { + bobSessionId = bobSession.sessionIdentifier(); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(bobSessionId); // must be the same for both ends of the conversation @@ -463,10 +553,21 @@ public class OlmSessionTest { String bobOneTimeKey1 = TestHelper.getOneTimeKey(bobOneTimeKeys, 1); // create alice inbound session for bob - assertTrue(0==aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1)); + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } String aliceClearMsg = "hello helooo to bob!"; - OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg); + OlmMessage encryptedAliceToBobMsg1 = null; + + try { + encryptedAliceToBobMsg1 = aliceSession.encryptMessage(aliceClearMsg); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertFalse(bobSession.matchesInboundSession(encryptedAliceToBobMsg1.mCipherText)); // init bob session with alice PRE KEY @@ -571,10 +672,20 @@ public class OlmSessionTest { assertTrue(0!=aliceSession.getOlmSessionId()); // CREATE ALICE OUTBOUND SESSION and encrypt message to bob - assertNotNull(aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey)); + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + String helloClearMsg = "Hello I'm Alice!"; - OlmMessage encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); + OlmMessage encryptedAliceToBobMsg1 = null; + try { + encryptedAliceToBobMsg1 = aliceSession.encryptMessage(helloClearMsg); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedAliceToBobMsg1); assertNotNull(encryptedAliceToBobMsg1.mCipherText); @@ -595,7 +706,14 @@ public class OlmSessionTest { } // DECRYPT MESSAGE FROM ALICE - String decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); + String decryptedMsg01 = null; + + try { + decryptedMsg01 = bobSession.decryptMessage(encryptedAliceToBobMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertNotNull(decryptedMsg01); // MESSAGE COMPARISON: decrypted vs encrypted @@ -607,11 +725,28 @@ public class OlmSessionTest { String clearMsg3 = "Let's go to the opera."; // bob encrypts messages - OlmMessage encryptedMsg1 = bobSession.encryptMessage(clearMsg1); + OlmMessage encryptedMsg1 = null; + try { + encryptedMsg1 = bobSession.encryptMessage(clearMsg1); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg1); - OlmMessage encryptedMsg2 = bobSession.encryptMessage(clearMsg2); + + OlmMessage encryptedMsg2 = null; + try { + encryptedMsg2 = bobSession.encryptMessage(clearMsg2); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg2); - OlmMessage encryptedMsg3 = bobSession.encryptMessage(clearMsg3); + + OlmMessage encryptedMsg3 = null; + try { + encryptedMsg3 = bobSession.encryptMessage(clearMsg3); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsg3); // serialize alice session @@ -742,26 +877,70 @@ public class OlmSessionTest { } // SANITY CHECK TESTS FOR: initOutboundSessionWithAccount() - 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)); + String errorMessage = null; + try { + aliceSession.initOutboundSession(null, bobIdentityKey, bobOneTimeKey); + } catch (Exception e) { + errorMessage = e.getMessage(); + } + assertTrue(null != errorMessage); + + errorMessage = null; + try { + aliceSession.initOutboundSession(aliceAccount, null, bobOneTimeKey); + } catch (Exception e) { + errorMessage = e.getMessage(); + } + assertTrue(null != errorMessage); + + errorMessage = null; + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, null); + } catch (Exception e) { + errorMessage = e.getMessage(); + } + assertTrue(null != errorMessage); + + errorMessage = null; + try { + aliceSession.initOutboundSession(null, null, null); + } catch (Exception e) { + errorMessage = e.getMessage(); + } + assertTrue(null != errorMessage); // init properly - assertTrue(0==aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey)); + errorMessage = null; + try { + aliceSession.initOutboundSession(aliceAccount, bobIdentityKey, bobOneTimeKey); + } catch (Exception e) { + errorMessage = e.getMessage(); + } + assertTrue(null == errorMessage); // SANITY CHECK TESTS FOR: encryptMessage() - assertTrue(null==aliceSession.encryptMessage(null)); + OlmMessage message = null; + try { + message = aliceSession.encryptMessage(null); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertTrue(null==message); // encrypt properly - OlmMessage encryptedMsgToBob = aliceSession.encryptMessage("A message for bob"); + OlmMessage encryptedMsgToBob = null; + try { + encryptedMsgToBob = aliceSession.encryptMessage("A message for bob"); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } assertNotNull(encryptedMsgToBob); // SANITY CHECK TESTS FOR: initInboundSessionWithAccount() OlmSession bobSession = null; try { bobSession = new OlmSession(); - String errorMessage = null; + errorMessage = null; try { bobSession.initInboundSession(null, encryptedMsgToBob.mCipherText); } catch (Exception e) { @@ -802,7 +981,13 @@ public class OlmSessionTest { } // SANITY CHECK TESTS FOR: decryptMessage() - String decryptedMsg = aliceSession.decryptMessage(null); + String decryptedMsg = null; + try { + decryptedMsg = aliceSession.decryptMessage(null); + } catch (Exception e) { + assertTrue(e.getMessage(), false); + } + assertTrue(null==decryptedMsg); // SANITY CHECK TESTS FOR: matchesInboundSession() 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 1a1b8ab..a6f1805 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 @@ -24,41 +24,40 @@ import java.io.IOException; */ public class OlmException extends IOException { // exception codes - public static final int EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION = 0; - public static final int EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION = 1; - public static final int EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION = 2; - public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 3; - public static final int EXCEPTION_CODE_ACCOUNT_SERIALIZATION = 4; - public static final int EXCEPTION_CODE_ACCOUNT_DESERIALIZATION = 5; - 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; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_SERIALIZATION = 10; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_DESERIALIZATION = 11; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_SERIALIZATION = 12; - public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_DESERIALIZATION = 13; - public static final int EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS = 20; - public static final int EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS = 21; - public static final int EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS = 22; - public static final int EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS = 23; - public static final int EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED = 24; - public static final int EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE = 25; + public static final int EXCEPTION_CODE_INIT_ACCOUNT_CREATION = 10; - public static final int EXCEPTION_CODE_SESSION_IDENTIFIER = 30; - public static final int EXCEPTION_CODE_SESSION_DECRYPT_SESSION = 31; + public static final int EXCEPTION_CODE_ACCOUNT_SERIALIZATION = 20; + public static final int EXCEPTION_CODE_ACCOUNT_DESERIALIZATION = 21; + public static final int EXCEPTION_CODE_ACCOUNT_IDENTITY_KEYS = 22; + public static final int EXCEPTION_CODE_ACCOUNT_GENERATE_ONE_TIME_KEYS = 23; + public static final int EXCEPTION_CODE_ACCOUNT_ONE_TIME_KEYS = 24; + public static final int EXCEPTION_CODE_ACCOUNT_REMOVE_ONE_TIME_KEYS = 25; + public static final int EXCEPTION_CODE_ACCOUNT_MARK_ONE_KEYS_AS_PUBLISHED = 26; + public static final int EXCEPTION_CODE_ACCOUNT_SIGN_MESSAGE = 27; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER = 40; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY = 41; - public static final int EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE = 42; + public static final int EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION = 30; + public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 31; + public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_IDENTIFIER = 32; + public static final int EXCEPTION_CODE_INBOUND_GROUP_SESSION_DECRYPT_SESSION = 33; + + public static final int EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION = 40; + public static final int EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION = 41; + public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER = 42; + public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY = 43; + public static final int EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE = 44; + + public static final int EXCEPTION_CODE_INIT_SESSION_CREATION = 50; + public static final int EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION = 51; + public static final int EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION = 52; + public static final int EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM = 53; + public static final int EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE = 54; + public static final int EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE = 55; + public static final int EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER = 56; // exception human readable messages public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "createNewSession() failed"; public static final String EXCEPTION_MSG_NEW_INBOUND_GROUP_SESSION = "createNewSession() failed"; - public static final String EXCEPTION_MSG_INIT_OUTBOUND_GROUP_SESSION = "initOutboundGroupSession() failed"; - public static final String EXCEPTION_MSG_INIT_INBOUND_GROUP_SESSION = " initInboundGroupSessionWithSessionKey() failed"; - public static final String EXCEPTION_MSG_INIT_NEW_ACCOUNT_DESERIALIZATION = "initNewAccount() failure"; public static final String EXCEPTION_MSG_INVALID_PARAMS_DESERIALIZATION = "invalid de-serialized parameters"; public static final String EXCEPTION_MSG_INIT_ACCOUNT_CREATION = "initNewAccount() failed"; public static final String EXCEPTION_MSG_INIT_SESSION_CREATION = "initNewSession() failed"; diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java index 7ac38b2..41eeba1 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java @@ -141,7 +141,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri return new String(sessionIdentifierJni(), "UTF-8"); } catch (Exception e) { Log.e(LOG_TAG, "## sessionIdentifier() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_IDENTIFIER, e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_IDENTIFIER, e.getMessage()); } } @@ -165,7 +165,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri } } catch (Exception e) { Log.e(LOG_TAG, "## decryptMessage() failed " + e.getMessage()); - throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DECRYPT_SESSION, e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_INBOUND_GROUP_SESSION_DECRYPT_SESSION, e.getMessage()); } return result; 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 36a95a1..9138309 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 @@ -124,25 +124,23 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * @param aAccount the account to associate with this session * @param aTheirIdentityKey the identity key of the recipient * @param aTheirOneTimeKey the one time key of the recipient - * @return 0 if operation succeed, -1 otherwise + * @exception OlmException the failure reason */ - public int initOutboundSession(OlmAccount aAccount, String aTheirIdentityKey, String aTheirOneTimeKey) { - int retCode=-1; - + public void initOutboundSession(OlmAccount aAccount, String aTheirIdentityKey, String aTheirOneTimeKey) throws OlmException { if ((null == aAccount) || TextUtils.isEmpty(aTheirIdentityKey) || TextUtils.isEmpty(aTheirOneTimeKey)) { Log.e(LOG_TAG, "## initOutboundSession(): invalid input parameters"); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION, "invalid input parameters"); } else { try { - retCode = initOutboundSessionJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aTheirOneTimeKey.getBytes("UTF-8")); + initOutboundSessionJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aTheirOneTimeKey.getBytes("UTF-8")); } catch (Exception e) { Log.e(LOG_TAG, "## initOutboundSession(): " + e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_OUTBOUND_SESSION, e.getMessage()); } } - - return retCode; } - private native int initOutboundSessionJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aTheirOneTimeKey); + private native void initOutboundSessionJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aTheirOneTimeKey); /** * Create a new in-bound session for sending/receiving messages from an @@ -150,29 +148,23 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY). * @param aAccount the account to associate with this session * @param aPreKeyMsg PRE KEY message - * @exception Exception the failure reason + * @exception OlmException the failure reason */ - public void initInboundSession(OlmAccount aAccount, String aPreKeyMsg) throws Exception { + public void initInboundSession(OlmAccount aAccount, String aPreKeyMsg) throws OlmException { if ((null == aAccount) || TextUtils.isEmpty(aPreKeyMsg)){ Log.e(LOG_TAG, "## initInboundSession(): invalid input parameters"); - throw new Exception("invalid input parameters"); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION, "invalid input parameters"); } else { - StringBuffer errorMsg = new StringBuffer(); - try { - initInboundSessionJni(aAccount.getOlmAccountId(), aPreKeyMsg.getBytes("UTF-8"), errorMsg); + initInboundSessionJni(aAccount.getOlmAccountId(), aPreKeyMsg.getBytes("UTF-8")); } catch (Exception e) { Log.e(LOG_TAG, "## initInboundSession(): " + e.getMessage()); - errorMsg.append(errorMsg); - } - - if (errorMsg.length() != 0) { - throw new Exception(errorMsg.toString()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION, e.getMessage()); } } } - private native int initInboundSessionJni(long aOlmAccountId, byte[] aOneTimeKeyMsg, StringBuffer aErrorMsg); + private native void initInboundSessionJni(long aOlmAccountId, byte[] aOneTimeKeyMsg); /** * Create a new in-bound session for sending/receiving messages from an @@ -183,38 +175,42 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * @param aAccount the account to associate with this session * @param aTheirIdentityKey the sender identity key * @param aPreKeyMsg PRE KEY message - * @return 0 if operation succeed, -1 otherwise + * @exception OlmException the failure reason */ - public int initInboundSessionFrom(OlmAccount aAccount, String aTheirIdentityKey, String aPreKeyMsg) { - int retCode=-1; - - if((null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){ + public void initInboundSessionFrom(OlmAccount aAccount, String aTheirIdentityKey, String aPreKeyMsg) throws OlmException { + if ( (null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){ Log.e(LOG_TAG, "## initInboundSessionFrom(): invalid input parameters"); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM, "invalid input parameters"); } else { try { - retCode = initInboundSessionFromIdKeyJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aPreKeyMsg.getBytes("UTF-8")); + initInboundSessionFromIdKeyJni(aAccount.getOlmAccountId(), aTheirIdentityKey.getBytes("UTF-8"), aPreKeyMsg.getBytes("UTF-8")); } catch (Exception e) { Log.e(LOG_TAG, "## initInboundSessionFrom(): " + e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_INIT_INBOUND_SESSION_FROM, e.getMessage()); } } - - return retCode; } - private native int initInboundSessionFromIdKeyJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aOneTimeKeyMsg); + private native void initInboundSessionFromIdKeyJni(long aOlmAccountId, byte[] aTheirIdentityKey, byte[] aOneTimeKeyMsg); /** * Get the session identifier.<br> Will be the same for both ends of the * conversation. The session identifier is returned as a String object. * Session Id sample: "session_id":"M4fOVwD6AABrkTKl" * Public API for {@link #getSessionIdentifierJni()}. - * @return the session ID as a String if operation succeed, null otherwise + * @return the session ID + * @exception OlmException the failure reason */ - public String sessionIdentifier() { + public String sessionIdentifier() throws OlmException { try { - return new String(getSessionIdentifierJni(), "UTF-8"); + byte[] buffer = getSessionIdentifierJni(); + + if (null != buffer) { + return new String(buffer, "UTF-8"); + } } catch (Exception e) { Log.e(LOG_TAG, "## sessionIdentifier(): " + e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_SESSION_IDENTIFIER, e.getMessage()); } return null; @@ -272,39 +268,46 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * The encrypted message is returned in a OlmMessage object. * Public API for {@link #encryptMessageJni(byte[], OlmMessage)}. * @param aClearMsg message to encrypted - * @return the encrypted message if operation succeed, null otherwise + * @return the encrypted message + * @exception OlmException the failure reason */ - public OlmMessage encryptMessage(String aClearMsg) { + public OlmMessage encryptMessage(String aClearMsg) throws OlmException { + if (null == aClearMsg) { + return null; + } + OlmMessage encryptedMsgRetValue = new OlmMessage(); try { - if (0 != encryptMessageJni(aClearMsg.getBytes("UTF-8"), encryptedMsgRetValue)) { - encryptedMsgRetValue = null; - } + encryptMessageJni(aClearMsg.getBytes("UTF-8"), encryptedMsgRetValue); } catch (Exception e) { Log.e(LOG_TAG, "## encryptMessage(): failed " + e.getMessage()); - encryptedMsgRetValue = null; + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_ENCRYPT_MESSAGE, e.getMessage()); } return encryptedMsgRetValue; } - private native int encryptMessageJni(byte[] aClearMsg, OlmMessage aEncryptedMsg); + private native void encryptMessageJni(byte[] aClearMsg, OlmMessage aEncryptedMsg); /** * Decrypt a message using the session.<br> * The encrypted message is given as a OlmMessage object. * @param aEncryptedMsg message to decrypt - * @return the decrypted message if operation succeed, null otherwise + * @return the decrypted message + * @exception OlmException the failure reason */ - public String decryptMessage(OlmMessage aEncryptedMsg) { + public String decryptMessage(OlmMessage aEncryptedMsg) throws OlmException { + if (null == aEncryptedMsg) { + return null; + } + try { return new String(decryptMessageJni(aEncryptedMsg), "UTF-8"); } catch (Exception e) { Log.e(LOG_TAG, "## decryptMessage(): failed " + e.getMessage()); + throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE, e.getMessage()); } - - return null; } private native byte[] decryptMessageJni(OlmMessage aEncryptedMsg); @@ -353,7 +356,7 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { } else { aErrorMsg.setLength(0); try { - pickleRetValue = serializeJni(aKey.getBytes("UTF-8"), aErrorMsg); + pickleRetValue = serializeJni(aKey.getBytes("UTF-8")); } catch (Exception e) { Log.e(LOG_TAG,"## serializeDataWithKey(): failed " + e.getMessage()); aErrorMsg.append(e.getMessage()); @@ -362,7 +365,7 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { return pickleRetValue; } - private native String serializeJni(byte[] aKey, StringBuffer aErrorMsg); + private native String serializeJni(byte[] aKey); /** * Loads an account from a pickled base64 string.<br> diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp index 4a1717a..f09ace6 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp @@ -105,25 +105,27 @@ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(initNewSessionJni)(JNIEnv *env, jobject thi * @param aOlmAccountId account instance * @param aTheirIdentityKey the identity key of the recipient * @param aTheirOneTimeKey the one time key of the recipient -* @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise **/ -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aTheirOneTimeKeyBuffer) +JNIEXPORT void OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aTheirOneTimeKeyBuffer) { - jint retCode = ERROR_CODE_KO; + const char* errorMessage = NULL; OlmSession* sessionPtr = NULL; OlmAccount* accountPtr = NULL; if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE("## initOutboundSessionJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) { LOGE("## initOutboundSessionJni(): failure - invalid Account ptr=NULL"); + errorMessage = "invalid Account ptr=NULL"; } else if (!aTheirIdentityKeyBuffer || !aTheirOneTimeKeyBuffer) { LOGE("## initOutboundSessionJni(): failure - invalid keys"); + errorMessage = "invalid keys"; } else { @@ -135,6 +137,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize)) { LOGE("## initOutboundSessionJni(): failure - random buffer init"); + errorMessage = "random buffer init"; } else { @@ -145,10 +148,12 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject if (!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0))) { LOGE("## initOutboundSessionJni(): failure - identityKey JNI allocation OOM"); + errorMessage = "identityKey JNI allocation OOM"; } else if (!(theirOneTimeKeyPtr = env->GetByteArrayElements(aTheirOneTimeKeyBuffer, 0))) { LOGE("## initOutboundSessionJni(): failure - one time Key JNI allocation OOM"); + errorMessage = "one time Key JNI allocation OOM"; } else { @@ -165,11 +170,11 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject (void*)randomBuffPtr, randomSize); if (sessionResult == olm_error()) { - LOGE("## initOutboundSessionJni(): failure - session creation Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## initOutboundSessionJni(): failure - session creation Msg=%s", errorMessage); } else { - retCode = ERROR_CODE_OK; LOGD("## initOutboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); } } @@ -191,7 +196,10 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject } } - return retCode; + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } } @@ -203,40 +211,28 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject * incoming PRE_KEY message.<br> * @param aOlmAccountId account instance * @param aOneTimeKeyMsg PRE_KEY message - * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise */ -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsgBuffer, jobject aErrorMsg) +JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsgBuffer) { - jint retCode = ERROR_CODE_KO; + const char* errorMessage = NULL; OlmSession *sessionPtr = NULL; OlmAccount *accountPtr = NULL; size_t sessionResult; - jclass errorMsgJClass = 0; - jmethodID errorMsgMethodId = 0; if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE("## initInboundSessionJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) { LOGE("## initInboundSessionJni(): failure - invalid Account ptr=NULL"); + errorMessage = "invalid Account ptr=NULL"; } else if (!aOneTimeKeyMsgBuffer) { LOGE("## initInboundSessionJni(): failure - invalid message"); - } - else if (!aErrorMsg) - { - LOGE(" ## initInboundSessionJni(): failure - invalid error output"); - } - else if (!(errorMsgJClass = env->GetObjectClass(aErrorMsg))) - { - LOGE(" ## initInboundSessionJni(): failure - unable to get error class"); - } - else if (!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"))) - { - LOGE(" ## initInboundSessionJni(): failure - unable to get error method ID"); + errorMessage = "invalid message"; } else { @@ -245,6 +241,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject if (!messagePtr) { LOGE("## initInboundSessionJni(): failure - message JNI allocation OOM"); + errorMessage = "message JNI allocation OOM"; } else { @@ -255,19 +252,11 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject if (sessionResult == olm_error()) { - const char *errorMsgPtr = olm_session_last_error(sessionPtr); - LOGE("## initInboundSessionJni(): failure - init inbound session creation Msg=%s", errorMsgPtr); - - jstring errorJstring = env->NewStringUTF(errorMsgPtr); - - if (errorJstring) - { - env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring); - } + errorMessage = olm_session_last_error(sessionPtr); + LOGE("## initInboundSessionJni(): failure - init inbound session creation Msg=%s", errorMessage); } else { - retCode = ERROR_CODE_OK; LOGD("## initInboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); } @@ -275,7 +264,11 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT); } } - return retCode; + + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } } /** @@ -284,11 +277,11 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject * @param aOlmAccountId account instance * @param aTheirIdentityKey the identity key of the recipient * @param aOneTimeKeyMsg encrypted message - * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise */ -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer) +JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer) { - jint retCode = ERROR_CODE_KO; + const char* errorMessage = NULL; + OlmSession *sessionPtr = NULL; OlmAccount *accountPtr = NULL; jbyte *messagePtr = NULL; @@ -298,26 +291,32 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else if (!(accountPtr = (OlmAccount*)aOlmAccountId)) { LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Account ptr=NULL"); + errorMessage = "invalid Account ptr=NULL"; } else if (!aTheirIdentityKeyBuffer) { LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid theirIdentityKey"); + errorMessage = "invalid theirIdentityKey"; } else if (!aOneTimeKeyMsgBuffer) { LOGE("## initInboundSessionJni(): failure - invalid one time key message"); + errorMessage = "invalid invalid one time key message"; } else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0))) { LOGE("## initInboundSessionFromIdKeyJni(): failure - message JNI allocation OOM"); + errorMessage = "message JNI allocation OOM"; } else if(!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0))) { LOGE("## initInboundSessionFromIdKeyJni(): failure - theirIdentityKey JNI allocation OOM"); + errorMessage = "theirIdentityKey JNI allocation OOM"; } else { @@ -329,11 +328,11 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, sessionResult = olm_create_inbound_session_from(sessionPtr, accountPtr, theirIdentityKeyPtr, theirIdentityKeyLength, (void*)messagePtr , messageLength); if (sessionResult == olm_error()) { - LOGE("## initInboundSessionFromIdKeyJni(): failure - init inbound session creation Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## initInboundSessionFromIdKeyJni(): failure - init inbound session creation Msg=%s", errorMessage); } else { - retCode = ERROR_CODE_OK; LOGD("## initInboundSessionFromIdKeyJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult)); } } @@ -349,7 +348,10 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT); } - return retCode; + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } } /** @@ -475,11 +477,11 @@ JNIEXPORT jint JNICALL OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(J * Encrypt a message using the session.<br> * @param aClearMsg clear text message * @param [out] aEncryptedMsg ciphered message - * @return ERROR_CODE_OK if encrypt operation succeed, ERROR_CODE_KO otherwise */ -JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aEncryptedMsg) +JNIEXPORT void OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aEncryptedMsg) { - jint retCode = ERROR_CODE_KO; + const char* errorMessage = NULL; + OlmSession *sessionPtr = NULL; jbyte *clearMsgPtr = NULL; jclass encryptedMsgJClass = 0; @@ -491,10 +493,12 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE("## encryptMessageJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else if (!aClearMsgBuffer) { LOGE("## encryptMessageJni(): failure - invalid clear message"); + errorMessage = "invalid clear message"; } else if (!aEncryptedMsg) { @@ -503,18 +507,22 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, 0))) { LOGE("## encryptMessageJni(): failure - clear message JNI allocation OOM"); + errorMessage = "clear message JNI allocation OOM"; } else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) { LOGE("## encryptMessageJni(): failure - unable to get crypted message class"); + errorMessage = "unable to get crypted message class"; } else if (!(encryptedMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;"))) { LOGE("## encryptMessageJni(): failure - unable to get message field"); + errorMessage = "unable to get message field"; } else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J"))) { LOGE("## encryptMessageJni(): failure - unable to get message type field"); + errorMessage = "unable to get message type field"; } else { @@ -532,6 +540,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz if ((0 != randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength)) { LOGE("## encryptMessageJni(): failure - random buffer init"); + errorMessage = "random buffer init"; } else { @@ -544,6 +553,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz if (!encryptedMsgPtr) { LOGE("## encryptMessageJni(): failure - encryptedMsgPtr buffer OOM"); + errorMessage = "encryptedMsgPtr buffer OOM"; } else { @@ -563,7 +573,8 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz encryptedMsgLength); if (result == olm_error()) { - LOGE("## encryptMessageJni(): failure - Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## encryptMessageJni(): failure - Msg=%s", errorMessage); } else { @@ -577,7 +588,6 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz jstring encryptedJstring = env->NewStringUTF((const char*)encryptedMsgPtr); env->SetObjectField(aEncryptedMsg, encryptedMsgFieldId, (jobject)encryptedJstring); - retCode = ERROR_CODE_OK; LOGD("## encryptMessageJni(): success - result=%lu Type=%lu utfLength=%lu encryptedMsg=%s", static_cast<long unsigned int>(result), static_cast<long unsigned int>(messageType), static_cast<long unsigned int>((size_t)env->GetStringUTFLength(encryptedJstring)), (const char*)encryptedMsgPtr); } @@ -594,16 +604,21 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT); } - return retCode; + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } } /** * Decrypt a message using the session.<br> * @param aEncryptedMsg message to decrypt - * @return decrypted message if operation succeed, null otherwise + * @return decrypted message if operation succeed */ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg) { + const char* errorMessage = NULL; + jbyteArray decryptedMsgRet = 0; jclass encryptedMsgJClass = 0; @@ -622,30 +637,37 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE("## decryptMessageJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else if (!aEncryptedMsg) { LOGE("## decryptMessageJni(): failure - invalid encrypted message"); + errorMessage = "invalid encrypted message"; } else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg))) { LOGE("## decryptMessageJni(): failure - unable to get encrypted message class"); + errorMessage = "unable to get encrypted message class"; } else if (!(encryptedMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;"))) { LOGE("## decryptMessageJni(): failure - unable to get message field"); + errorMessage = "unable to get message field"; } else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J"))) { LOGE("## decryptMessageJni(): failure - unable to get message type field"); + errorMessage = "unable to get message type field"; } else if (!(encryptedMsgJstring = (jstring)env->GetObjectField(aEncryptedMsg, encryptedMsgFieldId))) { LOGE("## decryptMessageJni(): failure - JNI encrypted object "); + errorMessage = "JNI encrypted object"; } else if (!(encryptedMsgPtr = env->GetStringUTFChars(encryptedMsgJstring, 0))) { LOGE("## decryptMessageJni(): failure - encrypted message JNI allocation OOM"); + errorMessage = "encrypted message JNI allocation OOM"; } else { @@ -668,7 +690,8 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec if (maxPlainTextLength == olm_error()) { - LOGE("## decryptMessageJni(): failure - olm_decrypt_max_plaintext_length Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## decryptMessageJni(): failure - olm_decrypt_max_plaintext_length Msg=%s", errorMessage); } else { @@ -687,7 +710,8 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec maxPlainTextLength); if (plaintextLength == olm_error()) { - LOGE("## decryptMessageJni(): failure - olm_decrypt Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## decryptMessageJni(): failure - olm_decrypt Msg=%s", errorMessage); } else { @@ -715,6 +739,11 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec free(plainTextMsgPtr); } + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + return decryptedMsgRet; } @@ -725,6 +754,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec */ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz) { + const char* errorMessage = NULL; jbyteArray returnValue = 0; LOGD("## getSessionIdentifierJni(): IN "); @@ -734,6 +764,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, if (!sessionPtr) { LOGE("## getSessionIdentifierJni(): failure - invalid Session ptr=NULL"); + errorMessage = "invalid Session ptr=NULL"; } else { @@ -746,6 +777,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, if (!sessionIdPtr) { LOGE("## getSessionIdentifierJni(): failure - identifier allocation OOM"); + errorMessage = "identifier allocation OOM"; } else { @@ -753,7 +785,8 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, if (result == olm_error()) { - LOGE("## getSessionIdentifierJni(): failure - get session identifier failure Msg=%s",(const char *)olm_session_last_error(sessionPtr)); + errorMessage = (const char *)olm_session_last_error(sessionPtr); + LOGE("## getSessionIdentifierJni(): failure - get session identifier failure Msg=%s", errorMessage); } else { @@ -770,6 +803,11 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, } } + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + return returnValue; } @@ -777,15 +815,13 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, /** * Serialize and encrypt session instance into a base64 string.<br> * @param aKey key used to encrypt the serialized session data -* @param[out] aErrorMsg error message set if operation failed * @return a base64 string if operation succeed, null otherwise **/ -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer, jobject aErrorMsg) +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) { + const char* errorMessage = NULL; + jstring pickledDataRetValue = 0; - jclass errorMsgJClass = 0; - jmethodID errorMsgMethodId = 0; - jstring errorJstring = 0; jbyte* keyPtr = NULL; OlmSession* sessionPtr = NULL; @@ -794,26 +830,17 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, if (!(sessionPtr = (OlmSession*)getSessionInstanceId(env,thiz))) { LOGE(" ## serializeJni(): failure - invalid session ptr"); + errorMessage = "invalid session ptr"; } else if (!aKeyBuffer) { LOGE(" ## serializeJni(): failure - invalid key"); - } - else if (!aErrorMsg) - { - LOGE(" ## serializeJni(): failure - invalid error object"); - } - else if (!(errorMsgJClass = env->GetObjectClass(aErrorMsg))) - { - LOGE(" ## serializeJni(): failure - unable to get error class"); - } - else if (!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"))) - { - LOGE(" ## serializeJni(): failure - unable to get error method ID"); + errorMessage = "invalid key"; } else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0))) { LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM"); + errorMessage = "ikeyPtr JNI allocation OOM"; } else { @@ -827,6 +854,7 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, if (!pickledPtr) { LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM"); + errorMessage = "pickledPtr buffer OOM"; } else { @@ -837,13 +865,8 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, pickledLength); if (result == olm_error()) { - const char *errorMsgPtr = olm_session_last_error(sessionPtr); - LOGE(" ## serializeJni(): failure - olm_pickle_session() Msg=%s",errorMsgPtr); - - if ((errorJstring = env->NewStringUTF(errorMsgPtr))) - { - env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring); - } + errorMessage = olm_session_last_error(sessionPtr); + LOGE(" ## serializeJni(): failure - olm_pickle_session() Msg=%s", errorMessage); } else { @@ -863,6 +886,11 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT); } + if (errorMessage) + { + env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage); + } + return pickledDataRetValue; } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h index 95b421b..004031e 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h @@ -33,24 +33,24 @@ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(initNewSessionJni)(JNIEnv *env, jobject thi JNIEXPORT jlong OLM_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz); // outbound session -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aTheirOneTimeKey); +JNIEXPORT void OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aTheirOneTimeKey); // inbound sessions: establishment based on PRE KEY message -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsg, jobject aErrorMsg); -JNIEXPORT jint OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aOneTimeKeyMsg); +JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsg); +JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKey, jbyteArray aOneTimeKeyMsg); // match inbound sessions: based on PRE KEY message JNIEXPORT jint OLM_SESSION_FUNC_DEF(matchesInboundSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aOneTimeKeyMsg); JNIEXPORT jint OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aTheirIdentityKey, jbyteArray aOneTimeKeyMsg); // encrypt/decrypt -JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsg, jobject aEncryptedMsg); +JNIEXPORT void OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsg, jobject aEncryptedMsg); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz); // serialization -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey, jobject aErrorMsg); +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey); JNIEXPORT jstring OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedData, jbyteArray aKey); #ifdef __cplusplus |