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>`_
This release includes the following changes since 2.2.2:
......
......@@ -14,12 +14,25 @@ AFL_CC = afl-gcc
AFL_CXX = afl-g++
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
DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.so.$(VERSION)
JS_TARGET := javascript/olm.js
DEBUG_TARGET := $(BUILD_DIR)/libolm_debug.$(SO).$(VERSION)
JS_WASM_TARGET := javascript/olm.js
JS_ASMJS_TARGET := javascript/olm_legacy.js
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
......@@ -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))
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
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_POST := javascript/olm_outbound_group_session.js \
javascript/olm_inbound_group_session.js \
javascript/olm_pk.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/megolm.html \
docs/olm.html \
......@@ -60,11 +84,23 @@ CFLAGS += -Wall -Werror -std=c99 -fPIC
CXXFLAGS += -Wall -Werror -std=c++11 -fPIC
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
# longer needed.
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.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c
EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS)
......@@ -99,7 +135,8 @@ $(FUZZER_DEBUG_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(JS_OBJECTS): CFLAGS += $(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
ifeq ($(shell echo "check_quotes"),"check_quotes")
......@@ -121,21 +158,19 @@ lib: $(RELEASE_TARGET)
$(RELEASE_TARGET): $(RELEASE_OBJECTS)
$(CXX) $(LDFLAGS) --shared -fPIC \
-Wl,-soname,libolm.so.$(MAJOR) \
-Wl,--version-script,version_script.ver \
$(OLM_LDFLAGS) \
$(OUTPUT_OPTION) $(RELEASE_OBJECTS)
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).$(MAJOR)
ln -sf libolm.$(SO).$(VERSION) $(BUILD_DIR)/libolm.$(SO)
debug: $(DEBUG_TARGET)
.PHONY: debug
$(DEBUG_TARGET): $(DEBUG_OBJECTS)
$(CXX) $(LDFLAGS) --shared -fPIC \
-Wl,-soname,libolm_debug.so.$(MAJOR) \
-Wl,--version-script,version_script.ver \
$(OLM_LDFLAGS) \
$(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)
.PHONY: static
......@@ -143,15 +178,35 @@ static: $(STATIC_RELEASE_TARGET)
$(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS)
$(AR) rcs $@ $^
js: $(JS_TARGET)
js: $(JS_WASM_TARGET) $(JS_ASMJS_TARGET)
.PHONY: js
$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS)
$(EMCC_LINK) \
# Note that the output file we give to emcc determines the name of the
# 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_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
build_tests: $(TEST_BINARIES)
......@@ -165,7 +220,7 @@ fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES)
.PHONY: fuzzers
$(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 $@
all: test js lib debug doc
......@@ -178,16 +233,16 @@ install-headers: $(PUBLIC_HEADERS)
install-debug: debug install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
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
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)
.PHONY: install-debug
install: lib install-headers
test -d $(DESTDIR)$(PREFIX)/lib || $(call mkdir,$(DESTDIR)$(PREFIX)/lib)
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
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)
.PHONY: install
clean:;
......
......@@ -31,6 +31,9 @@ To build the javascript bindings, install emscripten from http://kripken.github.
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:
.. code:: bash
......
......@@ -25,6 +25,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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>
* 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
* In case of error, null is returned and an error message description is provided in aErrorMsg.
* @param aEncryptedMsg the message to be decrypted
* @return the decrypted message information
* @exception OlmException teh failure reason
* @exception OlmException the failure reason
*/
public DecryptMessageResult decryptMessage(String aEncryptedMsg) throws OlmException {
DecryptMessageResult result = new DecryptMessageResult();
......@@ -246,6 +248,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
if (null != decryptedMessageBuffer) {
result.mDecryptedMessage = new String(decryptedMessageBuffer, "UTF-8");
Arrays.fill(decryptedMessageBuffer, (byte) 0);
}
} catch (Exception e) {
Log.e(LOG_TAG, "## decryptMessage() failed " + e.getMessage());
......
......@@ -26,6 +26,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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>
* 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
if (!TextUtils.isEmpty(aClearMsg)) {
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) {
retValue = new String(encryptedBuffer , "UTF-8");
......
......@@ -18,6 +18,8 @@ package org.matrix.olm;
import android.util.Log;
import java.util.Arrays;
public class OlmPkDecryption {
private static final String LOG_TAG = "OlmPkDecryption";
......@@ -67,7 +69,10 @@ public class OlmPkDecryption {
}
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) {
Log.e(LOG_TAG, "## pkDecrypt(): failed " + e.getMessage());
throw new OlmException(OlmException.EXCEPTION_CODE_PK_DECRYPTION_DECRYPT, e.getMessage());
......
......@@ -18,6 +18,8 @@ package org.matrix.olm;
import android.util.Log;
import java.util.Arrays;
public class OlmPkEncryption {
private static final String LOG_TAG = "OlmPkEncryption";
......@@ -72,7 +74,9 @@ public class OlmPkEncryption {
OlmPkMessage encryptedMsgRetValue = new OlmPkMessage();
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) {
encryptedMsgRetValue.mCipherText = new String(ciphertextBuffer, "UTF-8");
......
......@@ -25,6 +25,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
/**
* 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>
......@@ -295,7 +297,9 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
OlmMessage encryptedMsgRetValue = new OlmMessage();
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) {
encryptedMsgRetValue.mCipherText = new String(encryptedMessageBuffer, "UTF-8");
......@@ -330,7 +334,10 @@ public class OlmSession extends CommonSerializeUtils implements Serializable {
}
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) {
Log.e(LOG_TAG, "## decryptMessage(): failed " + 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
OlmOutboundGroupSession *sessionPtr = NULL;
jbyte* clearMsgPtr = NULL;
jboolean clearMsgIsCopied = JNI_FALSE;
if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz)))
{
......@@ -308,7 +309,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
LOGE(" ## encryptMessageJni(): failure - 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");
errorMessage = "clear message JNI allocation OOM";
......@@ -359,6 +360,10 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
// free alloc
if (clearMsgPtr)
{
if (clearMsgIsCopied)
{
memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer));
}
env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT);
}
......
......@@ -29,7 +29,10 @@ OlmPkEncryption * initializePkEncryptionMemory()
{
// init encryption object
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
{
......@@ -53,7 +56,10 @@ JNIEXPORT jlong OLM_PK_ENCRYPTION_FUNC_DEF(createNewPkEncryptionJni)(JNIEnv *env
else
{
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)
......@@ -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;
jbyte *keyPtr = NULL;
......@@ -116,10 +123,13 @@ JNIEXPORT void OLM_PK_ENCRYPTION_FUNC_DEF(setRecipientKeyJni)(JNIEnv *env, jobje
}
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);
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
}
}
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;
const char* errorMessage = NULL;
jbyte *plaintextPtr = NULL;
jboolean plaintextIsCopied = JNI_FALSE;
OlmPkEncryption *encryptionPtr = getPkEncryptionInstanceId(env, thiz);
jclass encryptedMsgJClass = 0;
......@@ -154,15 +166,15 @@ JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject
LOGE(" ## pkEncryptJni(): failure - invalid clear message");
errorMessage = "invalid clear message";
}
else if (!(plaintextPtr = env->GetByteArrayElements(aPlaintextBuffer, 0)))
else if (!(plaintextPtr = env->GetByteArrayElements(aPlaintextBuffer, &plaintextIsCopied)))
{
LOGE(" ## pkEncryptJni(): failure - plaintext JNI allocation OOM");
errorMessage = "plaintext JNI allocation OOM";
}
else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg)))
{
LOGE(" ## pkEncryptJni(): failure - unable to get crypted message class");
errorMessage = "unable to get crypted message class";
LOGE(" ## pkEncryptJni(): failure - unable to get encrypted message class");
errorMessage = "unable to get encrypted message class";
}
else if (!(macFieldId = env->GetFieldID(encryptedMsgJClass, "mMac", "Ljava/lang/String;")))
{
......@@ -226,7 +238,9 @@ JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject
else
{
encryptedMsgRet = env->NewByteArray(ciphertextLength);
env->SetByteArrayRegion(encryptedMsgRet, 0, ciphertextLength, (jbyte*)ciphertextPtr);
env->SetByteArrayRegion(
encryptedMsgRet, 0, ciphertextLength, (jbyte*)ciphertextPtr
);
jstring macStr = env->NewStringUTF((char*)macPtr);
env->SetObjectField(aEncryptedMsg, macFieldId, macStr);
......@@ -256,6 +270,10 @@ JNIEXPORT jbyteArray OLM_PK_ENCRYPTION_FUNC_DEF(encryptJni)(JNIEnv *env, jobject
if (plaintextPtr)
{
if (plaintextIsCopied)
{
memset(plaintextPtr, 0, (size_t)env->GetArrayLength(aPlaintextBuffer));
}
env->ReleaseByteArrayElements(aPlaintextBuffer, plaintextPtr, JNI_ABORT);
}
......@@ -276,7 +294,10 @@ OlmPkDecryption * initializePkDecryptionMemory()
{
// init decryption object
decryptionPtr = olm_pk_decryption(decryptionPtr);
LOGD("## initializePkDecryptionMemory(): success - OLM decryption size=%lu",static_cast<long unsigned int>(decryptionSize));
LOGD(
"## initializePkDecryptionMemory(): success - OLM decryption size=%lu",
static_cast<long unsigned int>(decryptionSize)
);
}
else
{
......@@ -300,7 +321,10 @@ JNIEXPORT jlong OLM_PK_DECRYPTION_FUNC_DEF(createNewPkDecryptionJni)(JNIEnv *env
else
{
LOGD("## createNewPkDecryptionJni(): success - OLM decryption created");
LOGD("## createNewPkDecryptionJni(): decryptionPtr=%p (jlong)(intptr_t)decryptionPtr=%lld", decryptionPtr, (jlong)(intptr_t)decryptionPtr);
LOGD(
"## createNewPkDecryptionJni(): decryptionPtr=%p (jlong)(intptr_t)decryptionPtr=%lld",
decryptionPtr, (jlong)(intptr_t)decryptionPtr
);
}
if (errorMessage)
......@@ -402,8 +426,9 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(generateKeyJni)(JNIEnv *env, job
return publicKeyRet;
}
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg)
{
JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(
JNIEnv *env, jobject thiz, jobject aEncryptedMsg
) {
const char* errorMessage = NULL;
OlmPkDecryption *decryptionPtr = getPkDecryptionInstanceId(env, thiz);
......@@ -528,7 +553,10 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject
{
decryptedMsgRet = env->NewByteArray(plaintextLength);
env->SetByteArrayRegion(decryptedMsgRet, 0, plaintextLength, (jbyte*)plaintextPtr);
LOGD("## pkDecryptJni(): success returnedLg=%lu OK", static_cast<long unsigned int>(plaintextLength));
LOGD(
"## pkDecryptJni(): success returnedLg=%lu OK",
static_cast<long unsigned int>(plaintextLength)
);
}
}
......@@ -538,6 +566,7 @@ JNIEXPORT jbyteArray OLM_PK_DECRYPTION_FUNC_DEF(decryptJni)(JNIEnv *env, jobject
}
if (plaintextPtr)
{
memset(plaintextPtr, 0, maxPlaintextLength);
free(plaintextPtr);
}
}
......
......@@ -472,6 +472,7 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobjec
OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
jbyte *clearMsgPtr = NULL;
jboolean clearMsgIsCopied = JNI_FALSE;
jclass encryptedMsgJClass = 0;
jfieldID typeMsgFieldId;
......@@ -490,8 +491,9 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobjec
else if (!aEncryptedMsg)
{
LOGE("## encryptMessageJni(): failure - invalid encrypted message");
errorMessage = "invalid encrypted message";
}
else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, 0)))
else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, &clearMsgIsCopied)))
{
LOGE("## encryptMessageJni(): failure - clear message JNI allocation OOM");
errorMessage = "clear message JNI allocation OOM";
......@@ -580,6 +582,10 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobjec
// free alloc
if (clearMsgPtr)
{
if (clearMsgIsCopied)
{
memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer));
}
env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT);
}
......@@ -702,6 +708,8 @@ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobjec
LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength));
}
memset(plainTextMsgPtr, 0, maxPlainTextLength);
}
}
......
......@@ -72,7 +72,7 @@ info.
Advancing the chain key
~~~~~~~~~~~~~~~~~~~~~~~
Advancing a chain key takes the previous chain key, :math:`C_{i,j-i}`. The next
Advancing a chain key takes the previous chain key, :math:`C_{i,j-1}`. The next
chain key, :math:`C_{i,j}`, is the HMAC-SHA-256_ of ``"\x02"`` using the
previous chain key as the key.
......@@ -338,7 +338,7 @@ The Olm specification (this document) is hereby placed in the public domain.
Feedback
--------
Can be sent to mark at matrix.org.
Can be sent to olm at matrix.org.
Acknowledgements
----------------
......
......@@ -113,6 +113,6 @@ This document is licensed under the `Apache License, Version 2.0
Feedback
--------
Questions and feedback can be sent to richard at matrix.org.
Questions and feedback can be sent to olm at matrix.org.
.. _`Ed25519`: http://ed25519.cr.yp.to/
#!/usr/bin/env python
import sys
import re
import json