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

Initial WasmThemis wrapper #461

Merged
merged 3 commits into from
Apr 16, 2019
Merged

Initial WasmThemis wrapper #461

merged 3 commits into from
Apr 16, 2019

Conversation

ilammy
Copy link
Collaborator

@ilammy ilammy commented Apr 12, 2019

I'm getting better at writing JavaScript. Here's an initial version of WasmThemis wrapper. This is basic scaffolding that has

  • project structure
  • C API interfacing
  • error handling
  • automated testing
  • packaging

which is good enough for start. It covers only key generation API, but adding other functions should be mostly mechanical job now. (Well, maybe except for Secure Session and its callbacks which are going to get tricky.)


  • Add "wasm_themis" target for Makefile

The new wrapper was christened WasmThemis. Let's get rolling! It will live under src/wrappers/themis/wasm.

Introduce a new submakefile wasmthemis.mk which will contain all specific targets and configuration for building WasmThemis. The main target is wasm_themis, that's our user-facing target which should be used by developers. It will build the wrapper in BUILD_PATH.

We still don't have a proper wrapper so instead we're going to build libthemis.js library for now. This is our 'native code' as far as JavaScript is concerned. It simply links Themis static library and its dependencies with emcc. Note, however, a couple of caveats:

  • Use EMSCRIPTEN_KEEPALIVE marker for public API

    Emscripten does dead-code elimination when linking final WebAssembly application. Anything not called from main() will be removed. And if there is no main() — typical for a library, eh? — then everything will be removed. We don't want that, so we use EMSCRIPTEN_KEEPALIVE to keep LLVM from optimizing out the functions we're going to use.

  • Use EXTRA_EXPORTED_RUNTIME_METHODS to keep preamble.js API

    Emscripten provides a bunch of useful utilities for interacting with its sandbox from JavaScript. However, they are also optimized out by default. We need to explicitly list the APIs we're going to use.

Finally, all WebAssembly builds must be performed in properly configured Emscripten environment. That is, by calling emmake make wasm_themis. Add a simple check before running the build to ensure that the developer did not forget to use emmake.

  • Initial "wasm-themis" npm package

We're going to publish WasmThemis via npm, create a package for that. Let's be nice and provide README and LICENSE files, fill in some informational fields in in package.json, etc. Note also these carefully crafted .gitignore and .npmignore files. They are meant to ensure that developers could do their thing in the working copy without accidentally committing unnecessary files to git or publishing them on npm.

The package is currently marked as private to prevent accidental publish. However, it is going to be named wasm-themis and that's the name used in README.

As for the wrapper code itself, let's start with secure key generation. This gives us a good start as we need to provide all the scaffolding around Node.js modules and Themis error handling. The interface stays similar to JsThemis, but there are no compatibility requirements. Thus we are able to provide strongly typed PrivateKey and PublicKey wrappers over Uint8Array, and expose then as read-only properties of KeyPair.

  • Test harness for "wasm-themis" package

Add some test using Mocha as test runner (just like we do for JsThemis). We don't have much API to check, just verify some basic invariants.

Add test_wasm target to Makefile and integrate that into CI builds. Note that this target has to be run with emmake helper.

@ilammy ilammy added infrastructure Automated building and packaging W-WasmThemis 🌐 Wrapper: WasmThemis, JavaScript API, npm packages labels Apr 12, 2019
@ilammy ilammy mentioned this pull request Apr 16, 2019
1 task
The new wrapper was christened "WasmThemis". Let's get rolling!
It will live under src/wrappers/themis/wasm.

Introduce a new submakefile "wasmthemis.mk" which will contain all
specific targets and configuration for building WasmThemis. The main
target is "wasm_themis", that's our user-facing target which should
be used by developers. It will build the wrapper in BUILD_PATH.

We still don't have a proper wrapper so instead we're going to build
libthemis.js library for now. This is our 'native code' as far as
JavaScript is concerned. It simply links Themis static library and
its dependencies with `emcc`. Note, however, a couple of caveats:

  - Use EMSCRIPTEN_KEEPALIVE marker for public API

    Emscripten does dead-code elimination when linking final WebAssembly
    application. Anything not called from main() will be removed. And if
    there is no main() -- typical for a library, eh? -- then everything
    will be removed. We don't want that, so we use EMSCRIPTEN_KEEPALIVE
    to keep LLVM from optimizing out the functions we're going to use.

  - Use EXTRA_EXPORTED_RUNTIME_METHODS to keep preamble.js API

    Emscripten provides a bunch of useful utilities for interacting with
    its sandbox from JavaScript. However, they are also optimized out by
    default. We need to explicitly list the APIs we're going to use.

Finally, all WebAssembly builds must be performed in properly configured
Emscripten environment. That is, by calling "emmake make wasm_themis".
Add a simple check before running the build to ensure that the developer
did not forget to use emmake.
We're going to publish WasmThemis via npm, create a package for that.
Let's be nice and provide README and LICENSE files, fill in some
informational fields in in package.json, etc. Note also these carefully
crafted .gitignore and .npmignore files. They are meant to ensure that
developers could do their thing in the working copy without accidentally
committing unnecessary files to git or publishing them on npm.

The package is currently marked as _private_ to prevent accidental
publish. However, it is going to be named "wasm-themis" and that's the
name used in README.

As for the wrapper code itself, let's start with secure key generation.
This gives us a good start as we need to provide all the scaffolding
around Node.js modules and Themis error handling. The interface stays
similar to JsThemis, but there are no compatibility requirements. Thus
we are able to provide strongly typed PrivateKey and PublicKey wrappers
over Uint8Array, and expose then as read-only properties of KeyPair.
Add some test using Mocha as test runner (just like we do for JsThemis).
We don't have much API to check, just verify some basic invariants.

Add "test_wasm" target to Makefile and integrate that into CI builds.
Note that this target has to be run with 'emmake' helper.
@ilammy ilammy marked this pull request as ready for review April 16, 2019 11:58
@ilammy
Copy link
Collaborator Author

ilammy commented Apr 16, 2019

Ready for review, please take a look.

Copy link
Collaborator

@Lagovas Lagovas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ilammy ilammy merged commit c25b7b7 into master Apr 16, 2019
@ilammy ilammy deleted the ilammy/wasm-themis branch April 16, 2019 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
infrastructure Automated building and packaging W-WasmThemis 🌐 Wrapper: WasmThemis, JavaScript API, npm packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants