/openssl-webterm

OpenSSL running in browsers, using WebAssembly (Emscripten) + xterm.js + React

Primary LanguageJavaScript

OpenSSL Webterm

User-friendly web app to use OpenSSL, based on WebAssembly. OpenSSL v3 has been compiled with Emscripten to run in a terminal/tty emulator in the browser. See the Live Demo. You could also host this on your own machine.

We then built a graphical user interface (GUI) on top of that, so it's easy for newbies to operate. Your actions in the GUI are transformed to original OpenSSL commands on the command line, so you easily can learn their syntax.

Disclaimer: This tool is intended for teaching and educational purposes. It was developed in 2021 by the CrypTool project in order to run OpenSSL v3 in a browser. You can also look at its predecessor.

image

Installation

First, install Node.js and npm. Then clone this project and install its dependencies:

$ git clone https://github.com/cryptool-org/openssl-webterm.git
$ cd openssl-webterm
$ npm install

Then start a Webpack development server:

$ npm run serve

You can now view the OpenSSL Webterm at https://localhost:4200.

Internal workings

The React GUI just builds commands (as strings). These are then called upon the terminal, which is an instance of wasm-webterm. If your browser supports WebWorkers (including SharedArrayBuffers and Atomics), a new Worker thread is spawned and the WebAssembly binary (openssl.wasm) is ran there. Otherwise, it is executed on the main browser thread using a fallback (which can freeze the tab).

The WebAssembly binary is executed using the (auto generated) Emscripten JS runtime contained in openssl.js. It initializes a virtual memory filesystem and handles input/output calls.

If the binary asks for input (reads from /dev/stdin), the thread will be paused until the user entered something. If the binary prints to /dev/stdout or /dev/stderr, it will be shown on the xterm.js web terminal.

After each command, the files in the memory filesystem are gathered and passed to the React GUI.

Compiling OpenSSL

You can compile the OpenSSL WebAssembly binary by calling one the following commands. Note that this is not neccessary, as it's already compiled.

Both call the script in emscr/builds/openssl/build.sh. It fetches and extracts the OpenSSL sources as a .tar.gz archive from https://www.openssl.org/source. It then compiles them with Emscripten by calling emconfigure and emmake (both with specific flags).

The created files openssl.wasm and openssl.js are then copied into emscr/binary, where the webpack server will deliver them from.

Option 1: Using Docker

First, install and start Docker. Then run the following command:

$ npm run build:openssl:docker

This will fetch Emscripten's Docker image emscripten/emsdk and run the build script.

This option should work cross-platform.

Option 2: Manually (without Docker)

First, install the Emscripten SDK. Then run the following command:

$ npm run build:openssl

This option may only work using Linux. It failed for us on macOS and we therefore recommend Option 1: Using Docker.

Running this project with Docker

The source code contains a Dockerfile which allows you to create ready-to-run Docker images. These are comparable to snapshots in virtual machines.

First, install and start Docker. Then create a Docker image:

$ docker build -t openssl-webterm .

This installs Alpine Linux with Node.js (v16.3) and nginx into a virtual image, builds the OpenSSL Webterm sources, and copies the built files into nginx's web server directory.

You can then instanciate this image into a Docker container:

$ docker run --rm -it -p 4300:80 -d openssl-webterm

This runs the nginx web server.

You should now be able to view the OpenSSL Webterm at http://localhost:4300

Contributing

Any contributions are greatly appreciated. If you have a suggestion that would make this better, please open an issue or fork the repository and create a pull request.

License

Apache License v2 This mainly requests to keep the name of the original authors and give according credit to them if you change or redistribute the sources.