Commit 5cf074d3 authored by Hubert Chathi's avatar Hubert Chathi
Browse files

Merge branch 'master' into poljar

parents ac071d9c af86a9a8
version: 2
jobs:
build:
docker:
- image: trzeci/emscripten
working_directory: ~/repo
steps:
- checkout
- run:
name: Native Compile
command: make
- run:
name: Native Tests
command: make test
- run:
name: JS Compile
command: make js
- run:
name: Install JS Deps
working_directory: ~/repo/javascript
command: npm install
- run:
name: JS Tests
working_directory: ~/repo/javascript
command: npm run test
Changes in latest release
BREAKING CHANGE: Olm now uses WebAssembly which means it needs
to load the wasm file asynchronously, and therefore needs to be
started up asynchronously. The imported module now has an init()
method which returns a promise. The library cannot be used until
this promise resolves. It will reject if the library fails to start.
olm_pk_generate_key() and olm_pk_generate_key_random_length() have
been removed: to generate a random key, use olm_pk_key_from_private()
with random bytes as the private key.
Changes in `2.3.0 <http://matrix.org/git/olm/commit/?h=2.3.0>`_ Changes in `2.3.0 <http://matrix.org/git/olm/commit/?h=2.3.0>`_
This release includes the following changes since 2.2.2: This release includes the following changes since 2.2.2:
......
...@@ -14,12 +14,25 @@ AFL_CC = afl-gcc ...@@ -14,12 +14,25 @@ AFL_CC = afl-gcc
AFL_CXX = afl-g++ AFL_CXX = afl-g++
AR = ar AR = ar
RELEASE_TARGET := $(BUILD_DIR)/libolm.so.$(VERSION) UNAME := $(shell uname)
ifeq ($(UNAME),Darwin)
SO := dylib
OLM_LDFLAGS :=
else
SO := so
OLM_LDFLAGS := -Wl,-soname,libolm.so.$(MAJOR) \
-Wl,--version-script,version_script.ver
endif
RELEASE_TARGET := $(BUILD_DIR)/libolm.$(SO).$(VERSION)
STATIC_RELEASE_TARGET := $(BUILD_DIR)/libolm.a STATIC_RELEASE_TARGET := $(BUILD_DIR)/libolm.a
DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.so.$(VERSION) DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.$(SO).$(VERSION)
JS_TARGET := javascript/olm.js JS_WASM_TARGET := javascript/olm.js
JS_ASMJS_TARGET := javascript/olm_legacy.js
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
JS_EXTRA_EXPORTED_RUNTIME_METHODS := ALLOC_STACK
JS_EXTERNS := javascript/externs.js
PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h include/olm/pk.h PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h include/olm/pk.h
...@@ -39,11 +52,22 @@ FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/,$(basename $(FUZZER_SOURCES))) ...@@ -39,11 +52,22 @@ FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/,$(basename $(FUZZER_SOURCES)))
FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES)) FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES))
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES))) TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS)) JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
# pre & post are the js-pre/js-post options to emcc.
# They are injected inside the modularised code and
# processed by the optimiser.
JS_PRE := $(wildcard javascript/*pre.js) JS_PRE := $(wildcard javascript/*pre.js)
JS_POST := javascript/olm_outbound_group_session.js \ JS_POST := javascript/olm_outbound_group_session.js \
javascript/olm_inbound_group_session.js \ javascript/olm_inbound_group_session.js \
javascript/olm_pk.js \ javascript/olm_pk.js \
javascript/olm_post.js javascript/olm_post.js
# The prefix & suffix are just added onto the start & end
# of what comes out emcc, so are outside of the modularised
# code and not seen by the opimiser.
JS_PREFIX := javascript/olm_prefix.js
JS_SUFFIX := javascript/olm_suffix.js
DOCS := tracing/README.html \ DOCS := tracing/README.html \
docs/megolm.html \ docs/megolm.html \
docs/olm.html \ docs/olm.html \
...@@ -60,11 +84,23 @@ CFLAGS += -Wall -Werror -std=c99 -fPIC ...@@ -60,11 +84,23 @@ CFLAGS += -Wall -Werror -std=c99 -fPIC
CXXFLAGS += -Wall -Werror -std=c++11 -fPIC CXXFLAGS += -Wall -Werror -std=c++11 -fPIC
LDFLAGS += -Wall -Werror LDFLAGS += -Wall -Werror
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 -s MODULARIZE=1
# NO_BROWSER is kept for compatibility with emscripten 1.35.24, but is no # NO_BROWSER is kept for compatibility with emscripten 1.35.24, but is no
# longer needed. # longer needed.
EMCCFLAGS += -s NO_BROWSER=1 EMCCFLAGS += -s NO_BROWSER=1
# Olm generally doesn't need a lot of memory to encrypt / decrypt its usual
# payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt
# a 64K event (enough to store the ciphertext and the plaintext, bearing in
# mind that the plaintext can only be 48K because base64). We also have about
# 36K of statics. So let's have 256K of memory.
# (This can't be changed by the app with wasm since it's baked into the wasm).
# (emscripten also mandates at least 16MB of memory for asm.js now, so
# we don't use this for the legacy build.)
EMCCFLAGS_WASM += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144
EMCCFLAGS_ASMJS += -s WASM=0
EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c
EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c
EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS) EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS)
...@@ -99,7 +135,8 @@ $(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) ...@@ -99,7 +135,8 @@ $(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS) $(JS_OBJECTS): CFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS) $(JS_OBJECTS): CXXFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS) $(JS_WASM_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS)
$(JS_ASMJS_TARGET): LDFLAGS += $(JS_OPTIMIZE_FLAGS)
### Fix to make mkdir work on windows and linux ### Fix to make mkdir work on windows and linux
ifeq ($(shell echo "check_quotes"),"check_quotes") ifeq ($(shell echo "check_quotes"),"check_quotes")
...@@ -121,21 +158,19 @@ lib: $(RELEASE_TARGET) ...@@ -121,21 +158,19 @@ lib: $(RELEASE_TARGET)
$(RELEASE_TARGET): $(RELEASE_OBJECTS) $(RELEASE_TARGET): $(RELEASE_OBJECTS)
$(CXX) $(LDFLAGS) --shared -fPIC \ $(CXX) $(LDFLAGS) --shared -fPIC \
-Wl,-soname,libolm.so.$(MAJOR) \ $(OLM_LDFLAGS) \
-Wl,--version-script,version_script.ver \
$(OUTPUT_OPTION) $(RELEASE_OBJECTS) $(OUTPUT_OPTION) $(RELEASE_OBJECTS)
ln -sf libolm.so.$(VERSION) $(BUILD_DIR)/libolm.so.$(MAJOR) ln -sf libolm.$(SO).$(VERSION) $(BUILD_DIR)/libolm.$(SO).$(MAJOR)
ln -sf libolm.so.$(VERSION) $(BUILD_DIR)/libolm.so ln -sf libolm.$(SO).$(VERSION) $(BUILD_DIR)/libolm.$(SO)
debug: $(DEBUG_TARGET) debug: $(DEBUG_TARGET)
.PHONY: debug .PHONY: debug
$(DEBUG_TARGET): $(DEBUG_OBJECTS) $(DEBUG_TARGET): $(DEBUG_OBJECTS)
$(CXX) $(LDFLAGS) --shared -fPIC \ $(CXX) $(LDFLAGS) --shared -fPIC \
-Wl,-soname,libolm_debug.so.$(MAJOR) \ $(OLM_LDFLAGS) \
-Wl,--version-script,version_script.ver \
$(OUTPUT_OPTION) $(DEBUG_OBJECTS) $(OUTPUT_OPTION) $(DEBUG_OBJECTS)
ln -sf libolm_debug.so.$(VERSION) $(BUILD_DIR)/libolm_debug.so.$(MAJOR) ln -sf libolm_debug.$(SO).$(VERSION) $(BUILD_DIR)/libolm_debug.$(SO).$(MAJOR)
static: $(STATIC_RELEASE_TARGET) static: $(STATIC_RELEASE_TARGET)
.PHONY: static .PHONY: static
...@@ -143,15 +178,35 @@ static: $(STATIC_RELEASE_TARGET) ...@@ -143,15 +178,35 @@ static: $(STATIC_RELEASE_TARGET)
$(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS) $(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS)
$(AR) rcs $@ $^ $(AR) rcs $@ $^
js: $(JS_TARGET) js: $(JS_WASM_TARGET) $(JS_ASMJS_TARGET)
.PHONY: js .PHONY: js
$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) # Note that the output file we give to emcc determines the name of the
$(EMCC_LINK) \ # wasm file baked into the js, hence messing around outputting to olm.js
# and then renaming it.
$(JS_WASM_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX)
EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \
$(EMCCFLAGS_WASM) \
$(foreach f,$(JS_PRE),--pre-js $(f)) \
$(foreach f,$(JS_POST),--post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
-s "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \
$(JS_OBJECTS) -o $@
mv $@ javascript/olmtmp.js
cat $(JS_PREFIX) javascript/olmtmp.js $(JS_SUFFIX) > $@
rm javascript/olmtmp.js
$(JS_ASMJS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX)
EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \
$(EMCCFLAGS_ASMJS) \
$(foreach f,$(JS_PRE),--pre-js $(f)) \ $(foreach f,$(JS_PRE),--pre-js $(f)) \
$(foreach f,$(JS_POST),--post-js $(f)) \ $(foreach f,$(JS_POST),--post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \ -s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
-s "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \
$(JS_OBJECTS) -o $@ $(JS_OBJECTS) -o $@
mv $@ javascript/olmtmp.js
cat $(JS_PREFIX) javascript/olmtmp.js $(JS_SUFFIX) > $@
rm javascript/olmtmp.js
build_tests: $(TEST_BINARIES) build_tests: $(TEST_BINARIES)
...@@ -165,7 +220,7 @@ fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES) ...@@ -165,7 +220,7 @@ fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES)
.PHONY: fuzzers .PHONY: fuzzers
$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS) $(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS)
perl -MJSON -ne '$$f{"_$$1"}=1 if /(olm_[^( ]*)\(/; END { @f=sort keys %f; print encode_json \@f }' $^ > $@.tmp ./exports.py $^ > $@.tmp
mv $@.tmp $@ mv $@.tmp $@
all: test js lib debug doc all: test js lib debug doc
...@@ -178,16 +233,16 @@ install-headers: $(PUBLIC_HEADERS) ...@@ -178,16 +233,16 @@ install-headers: $(PUBLIC_HEADERS)
install-debug: debug install-headers install-debug: debug install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
install -Dm755 $(DEBUG_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm_debug.so.$(VERSION) install -Dm755 $(DEBUG_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(VERSION)
ln -s libolm_debug.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.so.$(MAJOR) ln -s libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO).$(MAJOR)
ln -s libolm_debug.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.so ln -s libolm_debug.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm_debug.$(SO)
.PHONY: install-debug .PHONY: install-debug
install: lib install-headers install: lib install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib) test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
install -Dm755 $(RELEASE_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm.so.$(VERSION) install -Dm755 $(RELEASE_TARGET) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(VERSION)
ln -s libolm.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.so.$(MAJOR) ln -s libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO).$(MAJOR)
ln -s libolm.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.so ln -s libolm.$(SO).$(VERSION) $(DESTDIR)$(PREFIX)/lib/libolm.$(SO)
.PHONY: install .PHONY: install
clean:; clean:;
......
...@@ -31,6 +31,9 @@ To build the javascript bindings, install emscripten from http://kripken.github. ...@@ -31,6 +31,9 @@ To build the javascript bindings, install emscripten from http://kripken.github.
make js make js
Note that if you run emscripten in a docker container, you need to pass through
the EMCC_CLOSURE_ARGS environment variable.
To build the android project for Android bindings, run: To build the android project for Android bindings, run:
.. code:: bash .. code:: bash
......
...@@ -25,6 +25,8 @@ import java.io.ObjectInputStream; ...@@ -25,6 +25,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
/** /**
* Class used to create an inbound <a href="http://matrix.org/docs/guides/e2e_implementation.html#handling-an-m-room-key-event">Megolm session</a>.<br> * Class used to create an inbound <a href="http://matrix.org/docs/guides/e2e_implementation.html#handling-an-m-room-key-event">Megolm session</a>.<br>
* Counter part of the outbound group session {@link OlmOutboundGroupSession}, this class decrypts the messages sent by the outbound side. * Counter part of the outbound group session {@link OlmOutboundGroupSession}, this class decrypts the messages sent by the outbound side.
...@@ -236,7 +238,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -236,7 +238,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
* In case of error, null is returned and an error message description is provided in aErrorMsg. * In case of error, null is returned and an error message description is provided in aErrorMsg.
* @param aEncryptedMsg the message to be decrypted * @param aEncryptedMsg the message to be decrypted
* @return the decrypted message information * @return the decrypted message information
* @exception OlmException teh failure reason * @exception OlmException the failure reason
*/ */
public DecryptMessageResult decryptMessage(String aEncryptedMsg) throws OlmException { public DecryptMessageResult decryptMessage(String aEncryptedMsg) throws OlmException {
DecryptMessageResult result = new DecryptMessageResult(); DecryptMessageResult result = new DecryptMessageResult();
...@@ -246,6 +248,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri ...@@ -246,6 +248,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
if (null != decryptedMessageBuffer) { if (null != decryptedMessageBuffer) {
result.mDecryptedMessage = new String(decryptedMessageBuffer, "UTF-8"); result.mDecryptedMessage = new String(decryptedMessageBuffer, "UTF-8");
Arrays.fill(decryptedMessageBuffer, (byte) 0);
} }
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## decryptMessage() failed " + e.getMessage()); Log.e(LOG_TAG, "## decryptMessage() failed " + e.getMessage());
......
...@@ -26,6 +26,8 @@ import java.io.ObjectInputStream; ...@@ -26,6 +26,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
/** /**
* Class used to create an outbound a <a href="http://matrix.org/docs/guides/e2e_implementation.html#starting-a-megolm-session">Megolm session</a>.<br> * Class used to create an outbound a <a href="http://matrix.org/docs/guides/e2e_implementation.html#starting-a-megolm-session">Megolm session</a>.<br>
* To send a first message in an encrypted room, the client should start a new outbound Megolm session. * To send a first message in an encrypted room, the client should start a new outbound Megolm session.
...@@ -166,7 +168,9 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser ...@@ -166,7 +168,9 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
if (!TextUtils.isEmpty(aClearMsg)) { if (!TextUtils.isEmpty(aClearMsg)) {
try { try {
byte[] encryptedBuffer = encryptMessageJni(aClearMsg.getBytes("UTF-8")); byte[] clearMsgBuffer = aClearMsg.getBytes("UTF-8");
byte[] encryptedBuffer = encryptMessageJni(clearMsgBuffer);
Arrays.fill(clearMsgBuffer, (byte) 0);
if (null != encryptedBuffer) { if (null != encryptedBuffer) {
retValue = new String(encryptedBuffer , "UTF-8"); retValue = new String(encryptedBuffer , "UTF-8");
......
...@@ -18,6 +18,8 @@ package org.matrix.olm; ...@@ -18,6 +18,8 @@ package org.matrix.olm;
import android.util.Log; import android.util.Log;
import java.util.Arrays;
public class OlmPkDecryption { public class OlmPkDecryption {
private static final String LOG_TAG = "OlmPkDecryption"; private static final String LOG_TAG = "OlmPkDecryption";
...@@ -67,7 +69,10 @@ public class OlmPkDecryption { ...@@ -67,7 +69,10 @@ public class OlmPkDecryption {
} }
try { try {
return new String(decryptJni(aMessage), "UTF-8"); byte[] plaintextBuffer = decryptJni(aMessage);
String plaintext = new String(plaintextBuffer, "UTF-8");
Arrays.fill(plaintextBuffer, (byte) 0);
return plaintext;
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## pkDecrypt(): failed " + e.getMessage()); Log.e(LOG_TAG, "## pkDecrypt(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_DECRYPT, e.getMessage()); throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_DECRYPT, e.getMessage());
......
...@@ -18,6 +18,8 @@ package org.matrix.olm; ...@@ -18,6 +18,8 @@ package org.matrix.olm;
import android.util.Log; import android.util.Log;
import java.util.Arrays;
public class OlmPkEncryption { public class OlmPkEncryption {
private static final String LOG_TAG = "OlmPkEncryption"; private static final String LOG_TAG = "OlmPkEncryption";
...@@ -72,7 +74,9 @@ public class OlmPkEncryption { ...@@ -72,7 +74,9 @@ public class OlmPkEncryption {
OlmPkMessage encryptedMsgRetValue = new OlmPkMessage(); OlmPkMessage encryptedMsgRetValue = new OlmPkMessage();
try { try {
byte[] ciphertextBuffer = encryptJni(aPlaintext.getBytes("UTF-8"), encryptedMsgRetValue); byte[] plaintextBuffer = aPlaintext.getBytes("UTF-8");
byte[] ciphertextBuffer = encryptJni(plaintextBuffer, encryptedMsgRetValue);
Arrays.fill(plaintextBuffer, (byte) 0);
if (null != ciphertextBuffer) { if (null != ciphertextBuffer) {
encryptedMsgRetValue.mCipherText = new String(ciphertextBuffer, "UTF-8"); encryptedMsgRetValue.mCipherText = new String(ciphertextBuffer, "UTF-8");
......
...@@ -25,6 +25,8 @@ import java.io.ObjectInputStream; ...@@ -25,6 +25,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
/** /**
* Session class used to create Olm sessions in conjunction with {@link OlmAccount} class.<br> * Session class used to create Olm sessions in conjunction with {@link OlmAccount} class.<br>
* Olm session is used to encrypt data between devices, especially to create Olm group sessions (see {@link OlmOutboundGroupSession} and {@link OlmInboundGroupSession}).<br> * Olm session is used to encrypt data between devices, especially to create Olm group sessions (see {@link OlmOutboundGroupSession} and {@link OlmInboundGroupSession}).<br>
...@@ -295,7 +297,9 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { ...@@ -295,7 +297,9 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
OlmMessage encryptedMsgRetValue = new OlmMessage(); OlmMessage encryptedMsgRetValue = new OlmMessage();
try { try {
byte[] encryptedMessageBuffer = encryptMessageJni(aClearMsg.getBytes("UTF-8"), encryptedMsgRetValue); byte[] clearMsgBuffer = aClearMsg.getBytes("UTF-8");
byte[] encryptedMessageBuffer = encryptMessageJni(clearMsgBuffer, encryptedMsgRetValue);
Arrays.fill(clearMsgBuffer, (byte) 0);
if (null != encryptedMessageBuffer) { if (null != encryptedMessageBuffer) {
encryptedMsgRetValue.mCipherText = new String(encryptedMessageBuffer, "UTF-8"); encryptedMsgRetValue.mCipherText = new String(encryptedMessageBuffer, "UTF-8");
...@@ -330,7 +334,10 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { ...@@ -330,7 +334,10 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
} }
try { try {
return new String(decryptMessageJni(aEncryptedMsg), "UTF-8"); byte[] plaintextBuffer = decryptMessageJni(aEncryptedMsg);
String plaintext = new String(plaintextBuffer, "UTF-8");
Arrays.fill(plaintextBuffer, (byte) 0);
return plaintext;
} catch (Exception e) { } catch (Exception e) {
Log.e(LOG_TAG, "## decryptMessage(): failed " + e.getMessage()); Log.e(LOG_TAG, "## decryptMessage(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE, e.getMessage()); throw new OlmException(OlmException.EXCEPTION_CODE_SESSION_DECRYPT_MESSAGE, e.getMessage());
......
...@@ -297,6 +297,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE ...@@ -297,6 +297,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
OlmOutboundGroupSession *sessionPtr = NULL; OlmOutboundGroupSession *sessionPtr = NULL;
jbyte* clearMsgPtr = NULL; jbyte* clearMsgPtr = NULL;
jboolean clearMsgIsCopied = JNI_FALSE;
if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz))) if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz)))
{ {
...@@ -308,7 +309,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE ...@@ -308,7 +309,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
LOGE(" ## encryptMessageJni(): failure - invalid clear message"); LOGE(" ## encryptMessageJni(): failure - invalid clear message");
errorMessage = "invalid clear message"; errorMessage = "invalid clear message";
} }
else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, NULL))) else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, &clearMsgIsCopied)))
{ {
LOGE(" ## encryptMessageJni(): failure - clear message JNI allocation OOM"); LOGE(" ## encryptMessageJni(): failure - clear message JNI allocation OOM");
errorMessage = "clear message JNI allocation OOM"; errorMessage = "clear message JNI allocation OOM";
...@@ -359,6 +360,10 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE ...@@ -359,6 +360,10 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
// free alloc // free alloc
if (clearMsgPtr) if (clearMsgPtr)
{ {
if (clearMsgIsCopied)
{
memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer));
}
env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT); env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT);
} }
......
...@@ -29,7 +29,10 @@ OlmPkEncryption * initializePkEncryptionMemory() ...@@ -29,7 +29,10 @@ OlmPkEncryption * initializePkEncryptionMemory()
{ {
// init encryption object // init encryption object
encryptionPtr = olm_pk_encryption(encryptionPtr); encryptionPtr = olm_pk_encryption(encryptionPtr);
LOGD("## initializePkEncryptionMemory(): success - OLM encryption size=%lu",static_cast<long unsigned int>(encryptionSize)); LOGD(
"## initializePkEncryptionMemory(): success - OLM encryption size=%lu",
static_cast<long unsigned int>(encryptionSize)
);
} }
else else
{ {
...@@ -53,7 +56,10 @@ JNIEXPORT jlong OLM_PK_ENCRYPTION_FUNC_DEF(createNewPkEncryptionJni)(JNIEnv *env ...@@ -53,7 +56,10 @@ JNIEXPORT jlong OLM_PK_ENCRYPTION_FUNC_DEF(createNewPkEncryptionJni)(JNIEnv *env
else else
{ {
LOGD("## createNewPkEncryptionJni(): success - OLM encryption created"); LOGD("## createNewPkEncryptionJni(): success - OLM encryption created");
LOGD("## createNewPkEncryptionJni(): encryptionPtr=%p (jlong)(intptr_t)encryptionPtr=%lld", encryptionPtr, (jlong)(intptr_t)encryptionPtr); LOGD(
"## createNewPkEncryptionJni(): encryptionPtr=%p (jlong)(intptr_t)encryptionPtr=%lld",
encryptionPtr, (jlong)(intptr_t)encryptionPtr
);
} }
if (errorMessage) if (errorMessage)
...@@ -93,8 +99,9 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(releasePkEncryptionJni)(JNIEnv *env, j ...@@ -93,8 +99,9 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(releasePkEncryptionJni)(JNIEnv *env, j
} }
} }
JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer) JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(
{ JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer
) {
const char *errorMessage = NULL; const char *errorMessage = NULL;
jbyte *keyPtr = NULL; jbyte *keyPtr = NULL;
...@@ -116,10 +123,13 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobje ...@@ -116,10 +123,13 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobje
} }
else else
{ {
if(olm_pk_encryption_set_recipient_key(encryptionPtr, keyPtr, (size_t)env->GetArrayLength(aKeyBuffer)) == olm_error()) if (olm_pk_encryption_set_recipient_key(encryptionPtr, keyPtr, (size_t)env->GetArrayLength(aKeyBuffer)) == olm_error())
{ {
errorMessage = olm_pk_encryption_last_error(encryptionPtr); errorMessage = olm_pk_encryption_last_error(encryptionPtr);
LOGE(" ## pkSetRecipientKeyJni(): failure - olm_pk_encryption_set_recipient_key Msg=%s", errorMessage); LOGE(
" ## pkSetRecipientKeyJni(): failure - olm_pk_encryption_set_recipient_key Msg=%s",
errorMessage
);
} }
} }
...@@ -134,11 +144,13 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobje ...@@ -134,11 +144,13 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobje
} }
} }
JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject thiz, jbyteArray aPlaintextBuffer, jobject aEncryptedMsg) JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(
{ JNIEnv *env, jobject thiz, jbyteArray aPlaintextBuffer, jobject aEncryptedMsg
) {
jbyteArray encryptedMsgRet = 0; jbyteArray encryptedMsgRet = 0;
const char* errorMessage = NULL; const char* errorMessage = NULL;
jbyte *plaintextPtr = NULL; jbyte *plaintextPtr = NULL;
jboolean plaintextIsCopied = JNI_FALSE;