re-add null termination in javascript

because older versions of emscripten don't support the length argument to
UTF8ToString.
This commit is contained in:
Hubert Chathi 2019-04-08 15:54:02 -04:00
parent 071029c201
commit ebc156e7c2
6 changed files with 78 additions and 30 deletions

View file

@ -28,7 +28,7 @@ InboundGroupSession.prototype['pickle'] = restore_stack(function(key) {
Module['_olm_pickle_inbound_group_session_length'] Module['_olm_pickle_inbound_group_session_length']
)(this.ptr); )(this.ptr);
var key_buffer = stack(key_array); var key_buffer = stack(key_array);
var pickle_buffer = stack(pickle_length); var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH);
try { try {
inbound_group_session_method(Module['_olm_pickle_inbound_group_session'])( inbound_group_session_method(Module['_olm_pickle_inbound_group_session'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
@ -112,7 +112,7 @@ InboundGroupSession.prototype['decrypt'] = restore_stack(function(
// caculating the length destroys the input buffer, so we need to re-copy it. // caculating the length destroys the input buffer, so we need to re-copy it.
writeAsciiToMemory(message, message_buffer, true); writeAsciiToMemory(message, message_buffer, true);
plaintext_buffer = malloc(max_plaintext_length); plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH);
var message_index = stack(4); var message_index = stack(4);
plaintext_length = inbound_group_session_method( plaintext_length = inbound_group_session_method(
@ -124,6 +124,13 @@ InboundGroupSession.prototype['decrypt'] = restore_stack(function(
message_index message_index
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
plaintext_buffer+plaintext_length,
0, "i8"
);
return { return {
"plaintext": UTF8ToString(plaintext_buffer, plaintext_length), "plaintext": UTF8ToString(plaintext_buffer, plaintext_length),
"message_index": getValue(message_index, "i32") "message_index": getValue(message_index, "i32")
@ -144,7 +151,7 @@ InboundGroupSession.prototype['session_id'] = restore_stack(function() {
var length = inbound_group_session_method( var length = inbound_group_session_method(
Module['_olm_inbound_group_session_id_length'] Module['_olm_inbound_group_session_id_length']
)(this.ptr); )(this.ptr);
var session_id = stack(length); var session_id = stack(length + NULL_BYTE_PADDING_LENGTH);
inbound_group_session_method(Module['_olm_inbound_group_session_id'])( inbound_group_session_method(Module['_olm_inbound_group_session_id'])(
this.ptr, session_id, length this.ptr, session_id, length
); );
@ -161,7 +168,7 @@ InboundGroupSession.prototype['export_session'] = restore_stack(function(message
var key_length = inbound_group_session_method( var key_length = inbound_group_session_method(
Module['_olm_export_inbound_group_session_length'] Module['_olm_export_inbound_group_session_length']
)(this.ptr); )(this.ptr);
var key = stack(key_length); var key = stack(key_length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_export_inbound_group_session'])( outbound_group_session_method(Module['_olm_export_inbound_group_session'])(
this.ptr, key, key_length, message_index this.ptr, key, key_length, message_index
); );

View file

@ -28,7 +28,7 @@ OutboundGroupSession.prototype['pickle'] = restore_stack(function(key) {
Module['_olm_pickle_outbound_group_session_length'] Module['_olm_pickle_outbound_group_session_length']
)(this.ptr); )(this.ptr);
var key_buffer = stack(key_array); var key_buffer = stack(key_array);
var pickle_buffer = stack(pickle_length); var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH);
try { try {
outbound_group_session_method(Module['_olm_pickle_outbound_group_session'])( outbound_group_session_method(Module['_olm_pickle_outbound_group_session'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
@ -86,13 +86,20 @@ OutboundGroupSession.prototype['encrypt'] = function(plaintext) {
plaintext_buffer = malloc(plaintext_length + 1); plaintext_buffer = malloc(plaintext_length + 1);
stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1); stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1);
message_buffer = malloc(message_length); message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_group_encrypt'])( outbound_group_session_method(Module['_olm_group_encrypt'])(
this.ptr, this.ptr,
plaintext_buffer, plaintext_length, plaintext_buffer, plaintext_length,
message_buffer, message_length message_buffer, message_length
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
message_buffer+message_length,
0, "i8"
);
return UTF8ToString(message_buffer, message_length); return UTF8ToString(message_buffer, message_length);
} finally { } finally {
if (plaintext_buffer !== undefined) { if (plaintext_buffer !== undefined) {
@ -110,7 +117,7 @@ OutboundGroupSession.prototype['session_id'] = restore_stack(function() {
var length = outbound_group_session_method( var length = outbound_group_session_method(
Module['_olm_outbound_group_session_id_length'] Module['_olm_outbound_group_session_id_length']
)(this.ptr); )(this.ptr);
var session_id = stack(length); var session_id = stack(length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_outbound_group_session_id'])( outbound_group_session_method(Module['_olm_outbound_group_session_id'])(
this.ptr, session_id, length this.ptr, session_id, length
); );
@ -121,7 +128,7 @@ OutboundGroupSession.prototype['session_key'] = restore_stack(function() {
var key_length = outbound_group_session_method( var key_length = outbound_group_session_method(
Module['_olm_outbound_group_session_key_length'] Module['_olm_outbound_group_session_key_length']
)(this.ptr); )(this.ptr);
var key = stack(key_length); var key = stack(key_length + NULL_BYTE_PADDING_LENGTH);
outbound_group_session_method(Module['_olm_outbound_group_session_key'])( outbound_group_session_method(Module['_olm_outbound_group_session_key'])(
this.ptr, key, key_length this.ptr, key, key_length
); );

View file

@ -45,11 +45,11 @@ PkEncryption.prototype['encrypt'] = restore_stack(function(
var ciphertext_length = pk_encryption_method( var ciphertext_length = pk_encryption_method(
Module['_olm_pk_ciphertext_length'] Module['_olm_pk_ciphertext_length']
)(this.ptr, plaintext_length); )(this.ptr, plaintext_length);
ciphertext_buffer = malloc(ciphertext_length); ciphertext_buffer = malloc(ciphertext_length + NULL_BYTE_PADDING_LENGTH);
var mac_length = pk_encryption_method( var mac_length = pk_encryption_method(
Module['_olm_pk_mac_length'] Module['_olm_pk_mac_length']
)(this.ptr); )(this.ptr);
var mac_buffer = stack(mac_length); var mac_buffer = stack(mac_length + NULL_BYTE_PADDING_LENGTH);
setValue( setValue(
mac_buffer + mac_length, mac_buffer + mac_length,
0, "i8" 0, "i8"
@ -57,7 +57,7 @@ PkEncryption.prototype['encrypt'] = restore_stack(function(
var ephemeral_length = pk_encryption_method( var ephemeral_length = pk_encryption_method(
Module['_olm_pk_key_length'] Module['_olm_pk_key_length']
)(); )();
var ephemeral_buffer = stack(ephemeral_length); var ephemeral_buffer = stack(ephemeral_length + NULL_BYTE_PADDING_LENGTH);
setValue( setValue(
ephemeral_buffer + ephemeral_length, ephemeral_buffer + ephemeral_length,
0, "i8" 0, "i8"
@ -70,6 +70,12 @@ PkEncryption.prototype['encrypt'] = restore_stack(function(
ephemeral_buffer, ephemeral_length, ephemeral_buffer, ephemeral_length,
random, random_length random, random_length
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
ciphertext_buffer + ciphertext_length,
0, "i8"
);
return { return {
"ciphertext": UTF8ToString(ciphertext_buffer, ciphertext_length), "ciphertext": UTF8ToString(ciphertext_buffer, ciphertext_length),
"mac": UTF8ToString(mac_buffer, mac_length), "mac": UTF8ToString(mac_buffer, mac_length),
@ -123,7 +129,7 @@ PkDecryption.prototype['init_with_private_key'] = restore_stack(function (privat
var pubkey_length = pk_decryption_method( var pubkey_length = pk_decryption_method(
Module['_olm_pk_key_length'] Module['_olm_pk_key_length']
)(); )();
var pubkey_buffer = stack(pubkey_length); var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH);
try { try {
pk_decryption_method(Module['_olm_pk_key_from_private'])( pk_decryption_method(Module['_olm_pk_key_from_private'])(
this.ptr, this.ptr,
@ -145,7 +151,7 @@ PkDecryption.prototype['generate_key'] = restore_stack(function () {
var pubkey_length = pk_decryption_method( var pubkey_length = pk_decryption_method(
Module['_olm_pk_key_length'] Module['_olm_pk_key_length']
)(); )();
var pubkey_buffer = stack(pubkey_length); var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH);
try { try {
pk_decryption_method(Module['_olm_pk_key_from_private'])( pk_decryption_method(Module['_olm_pk_key_from_private'])(
this.ptr, this.ptr,
@ -184,7 +190,7 @@ PkDecryption.prototype['pickle'] = restore_stack(function (key) {
Module['_olm_pickle_pk_decryption_length'] Module['_olm_pickle_pk_decryption_length']
)(this.ptr); )(this.ptr);
var key_buffer = stack(key_array); var key_buffer = stack(key_array);
var pickle_buffer = stack(pickle_length); var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH);
try { try {
pk_decryption_method(Module['_olm_pickle_pk_decryption'])( pk_decryption_method(Module['_olm_pickle_pk_decryption'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
@ -207,7 +213,7 @@ PkDecryption.prototype['unpickle'] = restore_stack(function (key, pickle) {
var ephemeral_length = pk_decryption_method( var ephemeral_length = pk_decryption_method(
Module["_olm_pk_key_length"] Module["_olm_pk_key_length"]
)(); )();
var ephemeral_buffer = stack(ephemeral_length); var ephemeral_buffer = stack(ephemeral_length + NULL_BYTE_PADDING_LENGTH);
try { try {
pk_decryption_method(Module['_olm_unpickle_pk_decryption'])( pk_decryption_method(Module['_olm_unpickle_pk_decryption'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, this.ptr, key_buffer, key_array.length, pickle_buffer,
@ -239,7 +245,7 @@ PkDecryption.prototype['decrypt'] = restore_stack(function (
this.ptr, this.ptr,
ciphertext_length ciphertext_length
); );
plaintext_buffer = malloc(plaintext_max_length); plaintext_buffer = malloc(plaintext_max_length + NULL_BYTE_PADDING_LENGTH);
var plaintext_length = pk_decryption_method(Module['_olm_pk_decrypt'])( var plaintext_length = pk_decryption_method(Module['_olm_pk_decrypt'])(
this.ptr, this.ptr,
ephemeralkey_buffer, ephemeralkey_array.length, ephemeralkey_buffer, ephemeralkey_array.length,
@ -247,6 +253,12 @@ PkDecryption.prototype['decrypt'] = restore_stack(function (
ciphertext_buffer, ciphertext_length, ciphertext_buffer, ciphertext_length,
plaintext_buffer, plaintext_max_length plaintext_buffer, plaintext_max_length
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
plaintext_buffer + plaintext_length,
0, "i8"
);
return UTF8ToString(plaintext_buffer, plaintext_length); return UTF8ToString(plaintext_buffer, plaintext_length);
} finally { } finally {
if (plaintext_buffer !== undefined) { if (plaintext_buffer !== undefined) {
@ -292,7 +304,7 @@ PkSigning.prototype['init_with_seed'] = restore_stack(function (seed) {
var pubkey_length = pk_signing_method( var pubkey_length = pk_signing_method(
Module['_olm_pk_signing_public_key_length'] Module['_olm_pk_signing_public_key_length']
)(); )();
var pubkey_buffer = stack(pubkey_length); var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH);
try { try {
pk_signing_method(Module['_olm_pk_signing_key_from_seed'])( pk_signing_method(Module['_olm_pk_signing_key_from_seed'])(
this.ptr, this.ptr,
@ -333,7 +345,7 @@ PkSigning.prototype['sign'] = restore_stack(function (message) {
var sig_length = pk_signing_method( var sig_length = pk_signing_method(
Module['_olm_pk_signature_length'] Module['_olm_pk_signature_length']
)(); )();
var sig_buffer = stack(sig_length); var sig_buffer = stack(sig_length + NULL_BYTE_PADDING_LENGTH);
pk_signing_method(Module['_olm_pk_sign'])( pk_signing_method(Module['_olm_pk_sign'])(
this.ptr, this.ptr,
message_buffer, message_length, message_buffer, message_length,

View file

@ -77,7 +77,7 @@ Account.prototype['identity_keys'] = restore_stack(function() {
var keys_length = account_method( var keys_length = account_method(
Module['_olm_account_identity_keys_length'] Module['_olm_account_identity_keys_length']
)(this.ptr); )(this.ptr);
var keys = stack(keys_length); var keys = stack(keys_length + NULL_BYTE_PADDING_LENGTH);
account_method(Module['_olm_account_identity_keys'])( account_method(Module['_olm_account_identity_keys'])(
this.ptr, keys, keys_length this.ptr, keys, keys_length
); );
@ -90,7 +90,7 @@ Account.prototype['sign'] = restore_stack(function(message) {
)(this.ptr); )(this.ptr);
var message_array = array_from_string(message); var message_array = array_from_string(message);
var message_buffer = stack(message_array); var message_buffer = stack(message_array);
var signature_buffer = stack(signature_length); var signature_buffer = stack(signature_length + NULL_BYTE_PADDING_LENGTH);
try { try {
account_method(Module['_olm_account_sign'])( account_method(Module['_olm_account_sign'])(
this.ptr, this.ptr,
@ -111,7 +111,7 @@ Account.prototype['one_time_keys'] = restore_stack(function() {
var keys_length = account_method( var keys_length = account_method(
Module['_olm_account_one_time_keys_length'] Module['_olm_account_one_time_keys_length']
)(this.ptr); )(this.ptr);
var keys = stack(keys_length); var keys = stack(keys_length + NULL_BYTE_PADDING_LENGTH);
account_method(Module['_olm_account_one_time_keys'])( account_method(Module['_olm_account_one_time_keys'])(
this.ptr, keys, keys_length this.ptr, keys, keys_length
); );
@ -152,7 +152,7 @@ Account.prototype['pickle'] = restore_stack(function(key) {
Module['_olm_pickle_account_length'] Module['_olm_pickle_account_length']
)(this.ptr); )(this.ptr);
var key_buffer = stack(key_array); var key_buffer = stack(key_array);
var pickle_buffer = stack(pickle_length); var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH);
try { try {
account_method(Module['_olm_pickle_account'])( account_method(Module['_olm_pickle_account'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
@ -216,7 +216,7 @@ Session.prototype['pickle'] = restore_stack(function(key) {
Module['_olm_pickle_session_length'] Module['_olm_pickle_session_length']
)(this.ptr); )(this.ptr);
var key_buffer = stack(key_array); var key_buffer = stack(key_array);
var pickle_buffer = stack(pickle_length); var pickle_buffer = stack(pickle_length + NULL_BYTE_PADDING_LENGTH);
try { try {
session_method(Module['_olm_pickle_session'])( session_method(Module['_olm_pickle_session'])(
this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length this.ptr, key_buffer, key_array.length, pickle_buffer, pickle_length
@ -316,7 +316,7 @@ Session.prototype['create_inbound_from'] = restore_stack(function(
Session.prototype['session_id'] = restore_stack(function() { Session.prototype['session_id'] = restore_stack(function() {
var id_length = session_method(Module['_olm_session_id_length'])(this.ptr); var id_length = session_method(Module['_olm_session_id_length'])(this.ptr);
var id_buffer = stack(id_length); var id_buffer = stack(id_length + NULL_BYTE_PADDING_LENGTH);
session_method(Module['_olm_session_id'])( session_method(Module['_olm_session_id'])(
this.ptr, id_buffer, id_length this.ptr, id_buffer, id_length
); );
@ -378,7 +378,7 @@ Session.prototype['encrypt'] = restore_stack(function(
plaintext_buffer = malloc(plaintext_length + 1); plaintext_buffer = malloc(plaintext_length + 1);
stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1); stringToUTF8(plaintext, plaintext_buffer, plaintext_length + 1);
message_buffer = malloc(message_length); message_buffer = malloc(message_length + NULL_BYTE_PADDING_LENGTH);
session_method(Module['_olm_encrypt'])( session_method(Module['_olm_encrypt'])(
this.ptr, this.ptr,
@ -387,6 +387,13 @@ Session.prototype['encrypt'] = restore_stack(function(
message_buffer, message_length message_buffer, message_length
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
message_buffer+message_length,
0, "i8"
);
return { return {
"type": message_type, "type": message_type,
"body": UTF8ToString(message_buffer, message_length), "body": UTF8ToString(message_buffer, message_length),
@ -423,7 +430,7 @@ Session.prototype['decrypt'] = restore_stack(function(
// caculating the length destroys the input buffer, so we need to re-copy it. // caculating the length destroys the input buffer, so we need to re-copy it.
writeAsciiToMemory(message, message_buffer, true); writeAsciiToMemory(message, message_buffer, true);
plaintext_buffer = malloc(max_plaintext_length); plaintext_buffer = malloc(max_plaintext_length + NULL_BYTE_PADDING_LENGTH);
var plaintext_length = session_method(Module["_olm_decrypt"])( var plaintext_length = session_method(Module["_olm_decrypt"])(
this.ptr, message_type, this.ptr, message_type,
@ -431,6 +438,13 @@ Session.prototype['decrypt'] = restore_stack(function(
plaintext_buffer, max_plaintext_length plaintext_buffer, max_plaintext_length
); );
// UTF8ToString requires a null-terminated argument, so add the
// null terminator.
setValue(
plaintext_buffer+plaintext_length,
0, "i8"
);
return UTF8ToString(plaintext_buffer, plaintext_length); return UTF8ToString(plaintext_buffer, plaintext_length);
} finally { } finally {
if (message_buffer !== undefined) { if (message_buffer !== undefined) {
@ -473,7 +487,7 @@ Utility.prototype['sha256'] = restore_stack(function(input) {
var output_length = utility_method(Module['_olm_sha256_length'])(this.ptr); var output_length = utility_method(Module['_olm_sha256_length'])(this.ptr);
var input_array = array_from_string(input); var input_array = array_from_string(input);
var input_buffer = stack(input_array); var input_buffer = stack(input_array);
var output_buffer = stack(output_length); var output_buffer = stack(output_length + NULL_BYTE_PADDING_LENGTH);
try { try {
utility_method(Module['_olm_sha256'])( utility_method(Module['_olm_sha256'])(
this.ptr, this.ptr,

View file

@ -30,6 +30,14 @@ if (typeof(OLM_OPTIONS) !== 'undefined') {
} }
} }
/* The 'length' argument to Pointer_stringify doesn't work if the input
* includes characters >= 128, which makes Pointer_stringify unreliable. We
* could use it on strings which are known to be ascii, but that seems
* dangerous. Instead we add a NULL character to all of our strings and just
* use UTF8ToString.
*/
var NULL_BYTE_PADDING_LENGTH = 1;
Module['onRuntimeInitialized'] = function() { Module['onRuntimeInitialized'] = function() {
OLM_ERROR = Module['_olm_error'](); OLM_ERROR = Module['_olm_error']();
olm_exports["PRIVATE_KEY_LENGTH"] = Module['_olm_pk_private_key_length'](); olm_exports["PRIVATE_KEY_LENGTH"] = Module['_olm_pk_private_key_length']();

View file

@ -28,7 +28,7 @@ SAS.prototype['free'] = function() {
SAS.prototype['get_pubkey'] = restore_stack(function() { SAS.prototype['get_pubkey'] = restore_stack(function() {
var pubkey_length = sas_method(Module['_olm_sas_pubkey_length'])(this.ptr); var pubkey_length = sas_method(Module['_olm_sas_pubkey_length'])(this.ptr);
var pubkey_buffer = stack(pubkey_length); var pubkey_buffer = stack(pubkey_length + NULL_BYTE_PADDING_LENGTH);
sas_method(Module['_olm_sas_get_pubkey'])(this.ptr, pubkey_buffer, pubkey_length); sas_method(Module['_olm_sas_get_pubkey'])(this.ptr, pubkey_buffer, pubkey_length);
return UTF8ToString(pubkey_buffer, pubkey_length); return UTF8ToString(pubkey_buffer, pubkey_length);
}); });
@ -66,7 +66,7 @@ SAS.prototype['calculate_mac'] = restore_stack(function(input, info) {
var info_array = array_from_string(info); var info_array = array_from_string(info);
var info_buffer = stack(info_array); var info_buffer = stack(info_array);
var mac_length = sas_method(Module['_olm_sas_mac_length'])(this.ptr); var mac_length = sas_method(Module['_olm_sas_mac_length'])(this.ptr);
var mac_buffer = stack(mac_length); var mac_buffer = stack(mac_length + NULL_BYTE_PADDING_LENGTH);
sas_method(Module['_olm_sas_calculate_mac'])( sas_method(Module['_olm_sas_calculate_mac'])(
this.ptr, this.ptr,
input_buffer, input_array.length, input_buffer, input_array.length,
@ -89,5 +89,5 @@ SAS.prototype['calculate_mac_long_kdf'] = restore_stack(function(input, info) {
info_buffer, info_array.length, info_buffer, info_array.length,
mac_buffer, mac_length mac_buffer, mac_length
); );
return Pointer_stringify(mac_buffer); return UTF8ToString(mac_buffer, mac_length);
}); });