aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard van der Hoff <richard@matrix.org>2016-05-25 14:42:49 +0100
committerRichard van der Hoff <richard@matrix.org>2016-05-25 17:48:01 +0100
commit013f27f3dc8de747e82b74055c4dde55ca04b4c9 (patch)
treef285ef438ad18545be5d10526e42e38695cf0da3
parentee8172d882e853e737ac7e8b00fb760f21e80bfe (diff)
Javascript bindings for group sessions
-rw-r--r--Makefile11
-rw-r--r--javascript/README.md17
-rw-r--r--javascript/olm_inbound_group_session.js78
-rw-r--r--javascript/olm_outbound_group_session.js104
4 files changed, 206 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 49bec6a..08238c9 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ JS_TARGET := javascript/olm.js
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
-PUBLIC_HEADERS := include/olm/olm.h
+PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) \
lib/crypto-algorithms/sha256.c \
@@ -34,7 +34,9 @@ FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuz
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
JS_PRE := $(wildcard javascript/*pre.js)
-JS_POST := $(wildcard javascript/*post.js)
+JS_POST := javascript/olm_outbound_group_session.js \
+ javascript/olm_inbound_group_session.js \
+ javascript/olm_post.js
CPPFLAGS += -Iinclude -Ilib
# we rely on <stdint.h>, which was introduced in C99
@@ -106,7 +108,8 @@ js: $(JS_TARGET)
$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS)
$(EMCC_LINK) \
- --pre-js $(JS_PRE) --post-js $(JS_POST) \
+ $(foreach f,$(JS_PRE),--pre-js $(f)) \
+ $(foreach f,$(JS_POST),--post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
$(JS_OBJECTS) -o $@
@@ -122,7 +125,7 @@ fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES)
.PHONY: fuzzers
$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS)
- perl -MJSON -ne '/(olm_[^( ]*)\(/ && push @f, "_$$1"; END { print encode_json \@f }' $^ > $@.tmp
+ perl -MJSON -ne '$$f{"_$$1"}=1 if /(olm_[^( ]*)\(/; END { @f=sort keys %f; print encode_json \@f }' $^ > $@.tmp
mv $@.tmp $@
all: test js lib debug
diff --git a/javascript/README.md b/javascript/README.md
index 5c2c96b..6ed9bbb 100644
--- a/javascript/README.md
+++ b/javascript/README.md
@@ -23,3 +23,20 @@ Example:
bob_session.create_inbound(bob, bob_message);
var plaintext = bob_session.decrypt(message_1.type, bob_message);
bob.remove_one_time_keys(bob_session);
+
+
+Group chat:
+
+ var outbound_session = new Olm.OutboundGroupSession();
+ outbound_session.create();
+
+ // exchange these over a secure channel
+ var session_id = group_session.session_id();
+ var session_key = group_session.session_key();
+ var message_index = group_session.message_index();
+
+ var inbound_session = new Olm.InboundGroupSession();
+ inbound_session.create(message_index, session_key);
+
+ var ciphertext = outbound_session.encrypt("Hello");
+ var plaintext = inbound_session.decrypt(ciphertext);
diff --git a/javascript/olm_inbound_group_session.js b/javascript/olm_inbound_group_session.js
new file mode 100644
index 0000000..cfb557f
--- /dev/null
+++ b/javascript/olm_inbound_group_session.js
@@ -0,0 +1,78 @@
+function InboundGroupSession() {
+ var size = Module['_olm_inbound_group_session_size']();
+ this.buf = malloc(size);
+ this.ptr = Module['_olm_inbound_group_session'](this.buf);
+}
+
+function inbound_group_session_method(wrapped) {
+ return function() {
+ var result = wrapped.apply(this, arguments);
+ if (result === OLM_ERROR) {
+ var message = Pointer_stringify(
+ Module['_olm_inbound_group_session_last_error'](arguments[0])
+ );
+ throw new Error("OLM." + message);
+ }
+ return result;
+ }
+}
+
+InboundGroupSession.prototype['free'] = function() {
+ Module['_olm_clear_inbound_group_session'](this.ptr);
+ free(this.ptr);
+}
+
+InboundGroupSession.prototype['pickle'] = restore_stack(function(key) {
+ var key_array = array_from_string(key);
+ var pickle_length = inbound_group_session_method(
+ Module['_olm_pickle_inbound_group_session_length']
+ )(this.ptr);
+ var key_buffer = stack(key_array);
+ var pickle_buffer = stack(pickle_length);
+ inbound_group_session_method(Module['_olm_pickle_inbound_group_session'])(
+ this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
+ );
+ return Pointer_stringify(pickle_buffer, pickle_length);
+});
+
+InboundGroupSession.prototype['unpickle'] = restore_stack(function(key, pickle) {
+ var key_array = array_from_string(key);
+ var key_buffer = stack(key_array);
+ var pickle_array = array_from_string(pickle);
+ var pickle_buffer = stack(pickle_array);
+ inbound_group_session_method(Module['_olm_unpickle_inbound_group_session'])(
+ this.ptr, key_buffer, key_array.length, pickle_buffer,
+ pickle_array.length
+ );
+});
+
+InboundGroupSession.prototype['create'] = restore_stack(function(message_index, session_key) {
+ var key_array = array_from_string(session_key);
+ var key_buffer = stack(key_array);
+
+ inbound_group_session_method(Module['_olm_init_inbound_group_session'])(
+ this.ptr, message_index, key_buffer, key_array.length
+ );
+});
+
+InboundGroupSession.prototype['decrypt'] = restore_stack(function(
+ message
+) {
+ var message_array = array_from_string(message);
+ var message_buffer = stack(message_array);
+ var max_plaintext_length = session_method(
+ Module['_olm_group_decrypt_max_plaintext_length']
+ )(this.ptr, message_buffer, message_array.length);
+ // caculating the length destroys the input buffer.
+ // So we copy the array to a new buffer
+ var message_buffer = stack(message_array);
+ var plaintext_buffer = stack(max_plaintext_length);
+ var plaintext_length = session_method(Module["_olm_group_decrypt"])(
+ this.ptr,
+ message_buffer, message.length,
+ plaintext_buffer, max_plaintext_length
+ );
+ return Pointer_stringify(plaintext_buffer, plaintext_length);
+});
+
+olm_exports['InboundGroupSession'] = InboundGroupSession;
diff --git a/javascript/olm_outbound_group_session.js b/javascript/olm_outbound_group_session.js
new file mode 100644
index 0000000..277a882
--- /dev/null
+++ b/javascript/olm_outbound_group_session.js
@@ -0,0 +1,104 @@
+
+function OutboundGroupSession() {
+ var size = Module['_olm_outbound_group_session_size']();
+ this.buf = malloc(size);
+ this.ptr = Module['_olm_outbound_group_session'](this.buf);
+}
+
+function outbound_group_session_method(wrapped) {
+ return function() {
+ var result = wrapped.apply(this, arguments);
+ if (result === OLM_ERROR) {
+ var message = Pointer_stringify(
+ Module['_olm_outbound_group_session_last_error'](arguments[0])
+ );
+ throw new Error("OLM." + message);
+ }
+ return result;
+ }
+}
+
+OutboundGroupSession.prototype['free'] = function() {
+ Module['_olm_clear_outbound_group_session'](this.ptr);
+ free(this.ptr);
+}
+
+OutboundGroupSession.prototype['pickle'] = restore_stack(function(key) {
+ var key_array = array_from_string(key);
+ var pickle_length = outbound_group_session_method(
+ Module['_olm_pickle_outbound_group_session_length']
+ )(this.ptr);
+ var key_buffer = stack(key_array);
+ var pickle_buffer = stack(pickle_length);
+ outbound_group_session_method(Module['_olm_pickle_outbound_group_session'])(
+ this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
+ );
+ return Pointer_stringify(pickle_buffer, pickle_length);
+});
+
+OutboundGroupSession.prototype['unpickle'] = restore_stack(function(key, pickle) {
+ var key_array = array_from_string(key);
+ var key_buffer = stack(key_array);
+ var pickle_array = array_from_string(pickle);
+ var pickle_buffer = stack(pickle_array);
+ outbound_group_session_method(Module['_olm_unpickle_outbound_group_session'])(
+ this.ptr, key_buffer, key_array.length, pickle_buffer,
+ pickle_array.length
+ );
+});
+
+OutboundGroupSession.prototype['create'] = restore_stack(function(key) {
+ var random_length = session_method(
+ Module['_olm_init_outbound_group_session_random_length']
+ )(this.ptr);
+ var random = random_stack(random_length);
+ outbound_group_session_method(Module['_olm_init_outbound_group_session'])(
+ this.ptr, random, random_length
+ );
+});
+
+OutboundGroupSession.prototype['encrypt'] = restore_stack(function(plaintext) {
+ var plaintext_array = array_from_string(plaintext);
+ var message_length = outbound_group_session_method(
+ Module['_olm_group_encrypt_message_length']
+ )(this.ptr, plaintext_array.length);
+ var plaintext_buffer = stack(plaintext_array);
+ var message_buffer = stack(message_length);
+ outbound_group_session_method(Module['_olm_group_encrypt'])(
+ this.ptr,
+ plaintext_buffer, plaintext_array.length,
+ message_buffer, message_length
+ );
+ return Pointer_stringify(message_buffer, message_length);
+});
+
+OutboundGroupSession.prototype['session_id'] = restore_stack(function(key) {
+ var length = outbound_group_session_method(
+ Module['_olm_outbound_group_session_id_length']
+ )(this.ptr);
+ var session_id = stack(length);
+ outbound_group_session_method(Module['_olm_outbound_group_session_id'])(
+ this.ptr, session_id, length
+ );
+ return Pointer_stringify(session_id, length);
+});
+
+OutboundGroupSession.prototype['session_key'] = restore_stack(function(key) {
+ var key_length = outbound_group_session_method(
+ Module['_olm_outbound_group_session_key_length']
+ )(this.ptr);
+ var key = stack(key_length);
+ outbound_group_session_method(Module['_olm_outbound_group_session_key'])(
+ this.ptr, key, key_length
+ );
+ return Pointer_stringify(key, key_length);
+});
+
+OutboundGroupSession.prototype['message_index'] = function() {
+ var idx = outbound_group_session_method(
+ Module['_olm_outbound_group_session_message_index']
+ )(this.ptr);
+ return idx;
+};
+
+olm_exports['OutboundGroupSession'] = OutboundGroupSession;