wasm-sign 0.1.0

WebAssembly module signing and verification tool to proof authenticity and integrity of WebAssembly bytecodes. The signature is attached as Custom-Section to the end of th module. The signed module can be transfered over network. Recipients parsing the signed module will 'see' an additional Custom-Section of type 0 and name 'signature'. The Signature adds an overhead of 86 bytes.
# WebAssembly Module Signature

This repository describing the design and high-level overview of the WebAssembly Module Signature (WAMS)

## Overview

The WebAssembly Module Signature shall proof authenticity and integrity of the WebAssembly module, as file or parsed.

## Requirements

The WebAssembly Module Signature shall provide the following features

- It shall be possible to sign a WebAssembly Module file without parsing
- The signature signs the serialized form being used for files and networ-transfer.
- A module shall be signed as is, completely, including the custom-sections.
- The module sections shall not be re-ordered to meet a canonical form.
- All module signatures shall be of equal size.
- It shall be possible to verify a signature without parsing of the module
- It shall be possible with simple tools to split a WebAssembly module into both parts, the signature and the signed content
- Signatures shall use the ECDSA algorithm with SHA256.
- The public key may be publicly available and may be distributed using DNS-TXT-Records.

## Proposal

- The WebAssembly module signature is a Custom-Section with type id 0, the section name must be formed by 9 characters, so all signatures have equal byte-size
- A module may contain just one signatures (may be extended in future)
- A signature signs the all present sections of the data stream, as is.
- The section name "signature" (9 chars) is the default signature.
- The payload of the custom-section contains the ECDSA signature; the complete section has octet-size 118.
- New signature-sections shall be appended to the end of a module only.
- Removing the last 118 bytes from a module-bytecode, the signature-section is cut off.
- The tool shall support secp256k1 in initial version and in future versions Ed25519 and secp384r1 (hence the reserved bytes at end)


Each signature section ist formed of a sequence of 118 octets:

Fields                   |         Bytes
------------------------ | ----------------------------------------------------------------------------- 
Section Type (Custom):   |   `0x0`
Section Size:            |   `0x84`
Section Name Length:     |   `0x9`
Section Name Octets [9]: |   `[0x115, 0x105, 0x103, 0x110, 0x97, 0x116, 0x117, 0x114, 0x101]`
Signature Type   :       |   `0x0` which stands for ECDSA/SHA256 with max digest length of max. 72 bytes
Signature length:        |   Single byte value 72 or less
Signature:               |   `[...]`
Padding bytes:           |   0..33 padding bytes filling extending the digest-length to up to 104 bytes (secp384r1)

- **Index 12** SIGNATURE_TYPE (for know only 0==secp256k1/SHA256 is defined)
- **Index 13** ECDSA_DATA_LENGTH, may range between 72 and less, filled up by padding bytes
- **Index 14** ECDSA_DATA_START, first byte of ECDSA digest
- **Index 14+ECDSA_DATA_LENGTH**, end of the digest
 
In case the digest has byte size 72 (secp256k1) the preamble looks like (followed by the ECDSA digest):
```
[0, 84, 9, 115, 105, 103, 110, 97, 116, 117, 114, 101, 0, 72 ]
```

The digest is calculated using ciphers secp256k1/SHA256.
Trailing padding bytes fill up to total length of 118 bytes.

## Usage

### Private Key Generation
This is the key that must be kept secret and is used to sign your WASM files.
```
openssl ecparam -name secp256k1 -genkey -noout -out signerkey.pem
```

### Public Key Generation
This is the key that should be published or embedded in your application.
```
openssl ec -in signerkey.pem -pubout -outform pem -out signerkey.pub.pem
```

### Signing the WASM file
The tool returns with exit code 0 on success, otherwise with error code 1
```
wasm-sign -k signerkey.pem module.wasm signed-module.wasm
```

### Verifying the WASM file
The tool returns with exit code 0 on success, otherwise with error code 1
```
wasm-sign -v -k signerkey.pub.pem signed-module.wasm
```

### Signature Example
Output of `hexdump -C signed-module.wasm`:

```
00000120  .. .. .. .. .. .. .. 00  54 09 73 69 67 6e 61 74  |j$......T.signat|
00000130  75 72 65 00 47 30 45 02  21 00 a3 32 3e 3b 82 05  |ure.G0E.!..2>;..|
00000140  e7 d1 93 8a 6a 2d 6e 8c  8c 1d 6d cd 54 5e 2d 04  |....j-n...m.T^-.|
00000150  f4 57 4f fd 00 b7 d2 7b  6f fd 02 20 56 32 33 97  |.WO....{o.. V23.|
00000160  55 7c b2 93 06 62 7b d6  0f a2 f4 e0 8f 6c b8 13  |U|...b{......l..|
00000170  0b ae c4 55 5b 37 26 52  b8 61 6e 6d 00           |...U[7&R.anm.|
0000017d
```

## Build
```
cargo build --release
```
## Unit Test
```
cargo test
```
## End2End Test
```
make test
```