Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secure usage of Emscripten heap #495

Merged
merged 8 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/wrappers/themis/wasm/src/secure_keygen.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ function validateKeyBuffer(buffer, expectedKinds) {
// so we validate the key and query its kind as a single operation
// to avoid copying the key twice.
let buffer_len = buffer.length
let buffer_ptr = libthemis._malloc(buffer_len)
let buffer_ptr = utils.heapAlloc(buffer_len)
if (!buffer_ptr) {
throw new ThemisError(subsystem, ThemisErrorCode.NO_MEMORY)
}

var kind
try {
libthemis.writeArrayToMemory(buffer, buffer_ptr)
utils.heapPutArray(buffer, buffer_ptr)

let err = libthemis._themis_is_valid_asym_key(buffer_ptr, buffer_len)
if (err != ThemisErrorCode.SUCCESS) {
Expand All @@ -82,7 +82,7 @@ function validateKeyBuffer(buffer, expectedKinds) {
kind = libthemis._themis_get_asym_key_kind(buffer_ptr, buffer_len)
}
finally {
libthemis._free(buffer_ptr)
utils.heapFree(buffer_ptr, buffer_len)
}

if (!expectedKinds.includes(kind)) {
Expand Down Expand Up @@ -133,8 +133,8 @@ function generateECKeyPair() {
let private_len = libthemis.getValue(private_len_ptr, 'i32')
let public_len = libthemis.getValue(public_len_ptr, 'i32')

let private_ptr = libthemis._malloc(private_len)
let public_ptr = libthemis._malloc(public_len)
let private_ptr = utils.heapAlloc(private_len)
let public_ptr = utils.heapAlloc(public_len)

try {
if (!private_ptr || !public_ptr) {
Expand All @@ -150,13 +150,13 @@ function generateECKeyPair() {
let public_len = libthemis.getValue(public_len_ptr, 'i32')

return {
private: libthemis.HEAPU8.slice(private_ptr, private_ptr + private_len),
public: libthemis.HEAPU8.slice(public_ptr, public_ptr + public_len),
private: utils.heapGetArray(private_ptr, private_len),
public: utils.heapGetArray(public_ptr, public_len),
}
}
finally {
libthemis._free(private_ptr)
libthemis._free(public_ptr)
utils.heapFree(private_ptr, private_len)
utils.heapFree(public_ptr, public_len)
}
}

Expand Down
35 changes: 35 additions & 0 deletions src/wrappers/themis/wasm/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* Miscellaneous utilities.
*/

const libthemis = require('./libthemis.js')

/**
* Convert an object into a byte buffer.
*
Expand All @@ -31,3 +33,36 @@ module.exports.coerceToBytes = function(buffer) {
}
throw new TypeError('type mismatch, expect "Uint8Array" or "ArrayBuffer"')
}

/**
* Allocate a buffer of specified length on Emscripten heap.
*/
module.exports.heapAlloc = function(length) {
// calloc() in not provided by Emscripten
let buffer = libthemis._malloc(length)
libthemis._memset(buffer, 0, length)
return buffer
}

/**
* Move an array into Emscripten heap from JavaScript heap.
*/
module.exports.heapPutArray = function(array, buffer) {
libthemis.writeArrayToMemory(array, buffer)
}

/**
* Move an array from Emscripten heap into JavaScript heap.
*/
module.exports.heapGetArray = function(buffer, length) {
return libthemis.HEAPU8.slice(buffer, buffer + length)
}

/**
* Free a buffer on Emscripten heap.
*/
module.exports.heapFree = function(buffer, length) {
// Prevent sensitive data leakage througn heap:
libthemis._memset(buffer, 0, length)
libthemis._free(buffer)
}