Javascript bindings for group sessions
This commit is contained in:
parent
ee8172d882
commit
013f27f3dc
4 changed files with 206 additions and 4 deletions
11
Makefile
11
Makefile
|
@ -15,7 +15,7 @@ JS_TARGET := javascript/olm.js
|
||||||
|
|
||||||
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
|
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) \
|
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) \
|
||||||
lib/crypto-algorithms/sha256.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)))
|
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
|
||||||
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
|
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
|
||||||
JS_PRE := $(wildcard javascript/*pre.js)
|
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
|
CPPFLAGS += -Iinclude -Ilib
|
||||||
# we rely on <stdint.h>, which was introduced in C99
|
# 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)
|
$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS)
|
||||||
$(EMCC_LINK) \
|
$(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)" \
|
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
|
||||||
$(JS_OBJECTS) -o $@
|
$(JS_OBJECTS) -o $@
|
||||||
|
|
||||||
|
@ -122,7 +125,7 @@ fuzzers: $(FUZZER_BINARIES) $(FUZZER_DEBUG_BINARIES)
|
||||||
.PHONY: fuzzers
|
.PHONY: fuzzers
|
||||||
|
|
||||||
$(JS_EXPORTED_FUNCTIONS): $(PUBLIC_HEADERS)
|
$(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 $@
|
mv $@.tmp $@
|
||||||
|
|
||||||
all: test js lib debug
|
all: test js lib debug
|
||||||
|
|
|
@ -23,3 +23,20 @@ Example:
|
||||||
bob_session.create_inbound(bob, bob_message);
|
bob_session.create_inbound(bob, bob_message);
|
||||||
var plaintext = bob_session.decrypt(message_1.type, bob_message);
|
var plaintext = bob_session.decrypt(message_1.type, bob_message);
|
||||||
bob.remove_one_time_keys(bob_session);
|
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);
|
||||||
|
|
78
javascript/olm_inbound_group_session.js
Normal file
78
javascript/olm_inbound_group_session.js
Normal file
|
@ -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;
|
104
javascript/olm_outbound_group_session.js
Normal file
104
javascript/olm_outbound_group_session.js
Normal file
|
@ -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;
|
Loading…
Reference in a new issue